// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- //----------------------------------------------------------------------------- // eoOp.h // (c) GeNeura Team, 1998 //----------------------------------------------------------------------------- #ifndef _eoOp_H #define _eoOp_H #include #include #include /** @name Genetic operators What is a genetic algorithm without genetic operators? There is a genetic operator hierarchy, with eoOp as father and eoMonOp (monary or unary operator) and eoBinOp (binary operator) as siblings. Nobody should subclass eoOp, you should subclass eoBinOp or eoMonOp, those are the ones actually used here.\\ #eoOp#s are only printable objects, so if you want to build them from a file, it has to be done in another class, namely factories. Each hierarchy of #eoOp#s should have its own factory, which know how to build them from a description in a file. @author GeNeura Team @version 0.1 @see eoOpFactory */ //@{ /// enum Arity { unary = 0, binary = 1, Nary = 2}; /** Abstract data types for EO operators. * Genetic operators act on chromosomes, changing them. The type to instantiate them should * be an eoObject, but in any case, they are type-specific; each kind of evolvable object * can have its own operators */ template class eoOp: public eoObject, public eoPrintable { public: /// Ctor eoOp( Arity _arity = unary ) :arity( _arity ) {}; /// Copy Ctor eoOp( const eoOp& _eop ) :arity( _eop.arity ) {}; /// Needed virtual destructor virtual ~eoOp(){}; /// Arity: number of operands Arity readArity() const {return arity;}; /** @name Methods from eoObject */ //@{ /** * Write object. It's called printOn since it prints the object _on_ a stream. * @param _os A ostream. */ virtual void printOn(ostream& _os) const { _os << className(); // _os << arity; }; /** Inherited from eoObject @see eoObject */ virtual string className() const {return "eoOp";}; //@} private: /// arity is the number of operands it takes Arity arity; }; /** Binary genetic operator: subclasses eoOp, and defines basically the operator() with two operands */ template class eoBinOp: public eoOp { public: /// Ctor eoBinOp() :eoOp( binary ) {}; /// Copy Ctor eoBinOp( const eoBinOp& _ebop ) : eoOp( _ebop ){}; /// Dtor ~eoBinOp () {}; /** applies operator, to the object. If arity is more than 1, * keeps a copy of the operand in a cache. */ virtual void operator()( EOType& _eo1, EOType& _eo2 ) const = 0; /** @name Methods from eoObject readFrom and printOn are directly inherited from eoObject */ //@{ /** Inherited from eoObject @see eoObject */ virtual string className() const {return "eoBinOp";}; //@} }; /** eoMonOp is the monary operator: genetic operator that takes only one EO */ template class eoMonOp: public eoOp { public: /// Ctor eoMonOp( ) :eoOp( unary ) {}; /// Copy Ctor eoMonOp( const eoMonOp& _emop ) : eoOp( _emop ){}; /// Dtor ~eoMonOp() {}; /** applies randomly operator, to the object. If arity is more than 1, * keeps a copy of the operand in a cache. */ virtual void operator()( EOType& _eo1) const = 0; /** @name Methods from eoObject readFrom and printOn are directly inherited from eoObject */ //@{ /** Inherited from eoObject @see eoObject */ virtual string className() const {return "eoMonOp";}; //@} }; /** eoNaryOp is the N-ary operator: genetic operator that takes several EOs. It could be called an {\em orgy} operator */ template class eoNaryOp: public eoOp { public: /// Ctor eoNaryOp( ) :eoOp( Nary ) {}; /// Copy Ctor eoNaryOp( const eoNaryOp& _emop ) : eoOp( _emop ){}; /// Dtor ~eoNaryOp() {}; /** applies randomly operator, to the object. */ // virtual void operator()( EOPop & _eop) const = 0; /** @name Methods from eoObject readFrom and printOn are directly inherited from eoObject. */ //@{ /** Inherited from eoObject @see eoObject */ string className() const {return "eoNaryOp";}; //@} }; //@} #endif