move paradiseo/eo to deprecated/ before merge with eodev

This commit is contained in:
Johann Dreo 2012-10-05 15:12:12 +02:00
commit 0c5120f675
717 changed files with 0 additions and 0 deletions

View file

@ -0,0 +1,195 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// eoParseTree.h : eoParseTree class (for Tree-based Genetic Programming)
// (c) Maarten Keijzer 2000
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
mak@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifndef eoParseTree_h
#define eoParseTree_h
#include <iterator>
#include <list>
#include <EO.h>
#include <eoInit.h>
#include <eoOp.h>
#include <gp/parse_tree.h>
using namespace gp_parse_tree;
/** @defgroup ParseTree
Various functions for tree-based Genetic Programming
Example:
@include t-eoSymreg.cpp
@ingroup Representations
*/
/** Implementation of parse-tree for genetic programming
@class eoParseTree eoParseTree.h gp/eoParseTree.h
@ingroup ParseTree
*/
template <class FType, class Node>
class eoParseTree : public EO<FType>, public parse_tree<Node>
{
public:
using parse_tree<Node>::back;
using parse_tree<Node>::ebegin;
using parse_tree<Node>::eend;
using parse_tree<Node>::size;
typedef typename parse_tree<Node>::subtree Subtree;
/* For Compatibility with the intel C++ compiler for Linux 5.x */
typedef Node reference;
typedef const reference const_reference;
/**
* Default Constructor
*/
eoParseTree(void) {}
/**
* Copy Constructor
* @param tree The tree to copy
*/
eoParseTree(const parse_tree<Node>& tree) : parse_tree<Node>(tree) {}
// eoParseTree(const eoParseTree<FType, Node>& tree) : parse_tree<Node>(tree) {}
/**
* To prune me to a certain size
* @param _size My maximum size
*/
virtual void pruneTree(unsigned _size)
{
if (_size < 1)
return;
while (size() > _size)
{
back() = this->operator[](size()-2);
}
}
/**
* To read me from a stream
* @param is The std::istream
*/
eoParseTree(std::istream& is) : EO<FType>(), parse_tree<Node>()
{
readFrom(is);
}
/// My class name
std::string className(void) const { return "eoParseTree"; }
/**
* To print me on a stream
* @param os The std::ostream
*/
void printOn(std::ostream& os) const
{
EO<FType>::printOn(os);
os << ' ';
os << size() << ' ';
std::copy(ebegin(), eend(), std::ostream_iterator<Node>(os, " "));
}
/**
* To read me from a stream
* @param is The std::istream
*/
void readFrom(std::istream& is)
{
EO<FType>::readFrom(is);
unsigned sz;
is >> sz;
std::vector<Node> v(sz);
unsigned i;
for (i = 0; i < sz; ++i)
{
Node node;
is >> node;
v[i] = node;
}
parse_tree<Node> tmp(v.begin(), v.end());
this->swap(tmp);
/*
* old code which caused problems for paradisEO
*
* this can be removed once it has proved itself
EO<FType>::readFrom(is);
// even older code
FType fit;
is >> fit;
fitness(fit);
std::copy(std::istream_iterator<Node>(is), std::istream_iterator<Node>(), back_inserter(*this));
*/
}
};
/** @example t-eoSymreg.cpp
*/
// friend function to print eoParseTree
template <class FType, class Node>
std::ostream& operator<<(std::ostream& os, const eoParseTree<FType, Node>& eot)
{
eot.printOn(os);
return os;
}
// friend function to read eoParseTree
template <class FType, class Node>
std::istream& operator>>(std::istream& is, eoParseTree<FType, Node>& eot)
{
eot.readFrom(is);
return is;
}
// for backward compatibility
#include <gp/eoParseTreeOp.h>
#include <gp/eoParseTreeDepthInit.h>
#endif

View file

@ -0,0 +1,218 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// eoParseTreeDepthInit.h : initializor for eoParseTree class
// (c) Maarten Keijzer 2000 Jeroen Eggermont 2002
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
mak@dhi.dk
jeggermo@liacs.nl
*/
//-----------------------------------------------------------------------------
#ifndef eoParseTreeDepthInit_h
#define eoParseTreeDepthInit_h
#include <EO.h>
#include <gp/eoParseTree.h>
#include <eoInit.h>
#include <eoOp.h>
#include <eoPop.h>
using namespace gp_parse_tree;
/** eoParseTreeDepthInit : the initializer class for eoParseTree
\class eoParseTreeDepthInit eoParseTreeDepthInit.h gp/eoParseTreeDepthInit.h
\ingroup ParseTree
*/
// eoGpDepthInitializer is defined for backward compatibility
#define eoGpDepthInitializer eoParseTreeDepthInit
template <class FType, class Node>
class eoParseTreeDepthInit : public eoInit< eoParseTree<FType, Node> >
{
protected:
// a binary predicate for sorting
// hopefully this will work with M$VC++ 6.0
struct lt_arity:public std::binary_function<Node,Node,bool>
{
bool operator()(const Node &_node1, const Node &_node2) { return (_node1.arity() < _node2.arity());};
};
public :
typedef eoParseTree<FType, Node> EoType;
/**
* Constructor
* @param _max_depth The maximum depth of a tree
* @param _initializor A std::vector containing the possible nodes
* @param _grow False results in a full tree, True result is a randomly grown tree
* @param _ramped_half_and_half True results in Ramped Half and Half Initialization
*/
eoParseTreeDepthInit(
unsigned _max_depth,
const std::vector<Node>& _initializor,
bool _grow = true,
bool _ramped_half_and_half = false)
:
eoInit<EoType>(),
max_depth(_max_depth),
initializor(_initializor),
grow(_grow),
ramped_half_and_half(_ramped_half_and_half),
current_depth(_max_depth)
{
if(initializor.empty())
{
throw std::logic_error("eoParseTreeDepthInit: uhm, wouldn't you rather give a non-empty set of Nodes?");
}
// lets sort the initializor std::vector according to arity (so we can be sure the terminals are in front)
// we use stable_sort so that if element i was in front of element j and they have the same arity i remains in front of j
stable_sort(initializor.begin(), initializor.end(), lt_arity());
}
/// My class name
virtual std::string className() const { return "eoParseTreeDepthInit"; };
/**initialize a tree
* @param _tree : the tree to be initialized
*/
void operator()(EoType& _tree)
{
std::list<Node> sequence;
generate(sequence, current_depth);
parse_tree<Node> tmp(sequence.begin(), sequence.end());
_tree.swap(tmp);
if(ramped_half_and_half)
{
if(grow)
{
if (current_depth > 2)
current_depth--;
else
current_depth = max_depth;
}
// change the grow method from 'grow' to 'full' or from 'full' to 'grow'
grow = !grow;
};
}
private :
void generate(std::list<Node>& sequence, int the_max, int last_terminal = -1)
{
if (last_terminal == -1)
{ // check where the last terminal in the sequence resides
typename std::vector<Node>::iterator it;
for (it = initializor.begin(); it != initializor.end(); ++it)
{
if (it->arity() > 0)
break;
}
last_terminal = it - initializor.begin();
}
if (the_max == 1)
{ // generate terminals only
typename std::vector<Node>::iterator it = initializor.begin() + rng.random(last_terminal);
it->randomize();
sequence.push_front(*it);
return;
}
typename std::vector<Node>::iterator what_it;
if (grow)
{
what_it = initializor.begin() + rng.random(initializor.size());
}
else // full
{
what_it = initializor.begin() + last_terminal + rng.random(initializor.size() - last_terminal);
}
what_it->randomize();
sequence.push_front(*what_it);
for (int i = 0; i < what_it->arity(); ++i)
generate(sequence, the_max - 1, last_terminal);
}
unsigned max_depth;
std::vector<Node> initializor;
bool grow;
bool ramped_half_and_half;
unsigned current_depth;
};
/**
* A template function for ramped half and half initialization of an eoParseTree population
* @param pop the population to be created
* @param population_size the size of the population to be created
* @param init_max_depth the initial maximum tree depth
* @param initializor A std::vector containing the possible nodes
\ingroup ParseTree
*/
template <class FType, class Node>
void eoInitRampedHalfAndHalf(eoPop< eoParseTree<FType,Node> > &pop, unsigned int population_size, unsigned int init_max_depth, std::vector<Node> &initializor)
{
typedef eoParseTree<FType,Node> EoType;
typedef eoPop< EoType > Pop;
unsigned int M = init_max_depth - 1;
unsigned int part_pop_size = population_size / (2*M);
unsigned int m=0;
std::cerr << "EO WARNING: Ramped Half and Half Initialization is now supported by eoParseTreeDepthInit." << std::endl;
std::cerr << " This function is now obsolete and might be removed in the future so you should"<< std::endl;
std::cerr << " update your code to use: " << std::endl << std::endl;
std::cerr << " eoParseTreeDepthInit( _max_depth, _initializer, bool _grow, bool _ramped_half_and_half)" << std::endl << std::endl;
pop.clear();
// initialize with Depth's (D) -> 2
for(m=init_max_depth; m >= 2; m--)
{
eoParseTreeDepthInit<FType, Node> grow_initializer(m, initializor, true);
Pop grow(part_pop_size, grow_initializer);
pop.insert(pop.begin(), grow.begin(), grow.end());
eoParseTreeDepthInit<FType, Node> full_initializer(m, initializor, false);
Pop full(part_pop_size, full_initializer);
pop.insert(pop.begin(), full.begin(), full.end());
}
bool g = true;
while (pop.size() < population_size)
{
eoParseTreeDepthInit<FType, Node> initializer(init_max_depth, initializor, g);
Pop p(1, initializer);
pop.insert(pop.begin(), p.begin(), p.end());
g= !g;
}
}
#endif

View file

@ -0,0 +1,380 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// eoParseTreeOp.h : crossover and mutation operator for the eoParseTree class
// (c) Maarten Keijzer 2000 for eoSubtreeXOver, eoBranchMutation
// (c) Jeroen Eggermont 2001 for other mutation operators
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
mak@dhi.dk
jeggermo@liacs.nl
*/
//-----------------------------------------------------------------------------
#ifndef eoParseTreeOp_h
#define eoParseTreeOp_h
#include <EO.h>
#include <eoOp.h>
#include <gp/eoParseTree.h>
/** eoSubtreeXOver --> subtree xover
\class eoSubtreeXOver eoParseTreeOp.h gp/eoParseTreeOp.h
\ingroup ParseTree
*/
template<class FType, class Node>
class eoSubtreeXOver: public eoQuadOp< eoParseTree<FType, Node> > {
public:
typedef eoParseTree<FType,Node> EoType;
/**
* Constructor
* @param _max_length the maximum size of an individual
*/
eoSubtreeXOver( unsigned _max_length)
: eoQuadOp<EoType>(), max_length(_max_length) {};
/// the ckassname
virtual std::string className() const { return "eoSubtreeXOver"; };
/// Dtor
virtual ~eoSubtreeXOver () {};
/**
* Perform crossover on two individuals
* param _eo1 The first parent individual
* param _eo2 The second parent individual
*/
bool operator()(EoType & _eo1, EoType & _eo2 )
{
int i = rng.random(_eo1.size());
int j = rng.random(_eo2.size());
typename parse_tree<Node>::subtree tmp = _eo1[i];
_eo1[i] = _eo2[j]; // insert subtree
_eo2[j] = tmp;
_eo1.pruneTree(max_length);
_eo2.pruneTree(max_length);
return true;
}
private:
unsigned max_length;
};
/** eoBranchMutation --> replace a subtree with a randomly created subtree
\class eoBranchMutation eoParseTreeOp.h gp/eoParseTreeOp.h
\ingroup ParseTree
*/
template<class FType, class Node>
class eoBranchMutation: public eoMonOp< eoParseTree<FType, Node> >
{
public:
typedef eoParseTree<FType,Node> EoType;
/**
* Constructor
* @param _init An instantiation of eoGpDepthInitializer
* @param _max_length the maximum size of an individual
*/
eoBranchMutation(eoInit<EoType>& _init, unsigned _max_length)
: eoMonOp<EoType>(), max_length(_max_length), initializer(_init)
{};
/// the class name
virtual std::string className() const { return "eoBranchMutation"; };
/// Dtor
virtual ~eoBranchMutation() {};
/**
* Mutate an individual
* @param _eo1 The individual that is to be changed
*/
bool operator()(EoType& _eo1 )
{
int i = rng.random(_eo1.size());
EoType eo2;
initializer(eo2);
int j = rng.random(eo2.size());
_eo1[i] = eo2[j]; // insert subtree
_eo1.pruneTree(max_length);
return true;
}
private :
unsigned max_length;
eoInit<EoType>& initializer;
};
// Additional Mutation operators from
// TITLE:"Genetic Programming~An Introduction"
// AUTHORS: Banzhaf, Nordin, Keller, Francone
// ISBN: 3-920993-58-6
// ISBN: 1-55860-510-X
//
// For the eoParseTree class
/** eoPointMutation --> replace a Node with a Node of the same arity
\class eoPointMutation eoParseTreeOp.h gp/eoParseTreeOp.h
\ingroup ParseTree
*/
template<class FType, class Node>
class eoPointMutation: public eoMonOp< eoParseTree<FType, Node> >
{
public:
typedef eoParseTree<FType,Node> EoType;
/**
* Constructor
* @param _initializor The std::vector of Nodes given to the eoGpDepthInitializer
*/
eoPointMutation( std::vector<Node>& _initializor)
: eoMonOp<EoType>(), initializor(_initializor)
{};
/// the class name
virtual std::string className() const { return "eoPointMutation"; };
/// Dtor
virtual ~eoPointMutation() {};
/**
* Mutate an individual
* @param _eo1 The individual that is to be changed
*/
bool operator()(EoType& _eo1 )
{
// select a random node i that is to be mutated
int i = rng.random(_eo1.size());
// request the arity of the node that is to be replaced
int arity = _eo1[i].arity();
int j=0;
do
{
j = rng.random(initializor.size());
}while ((initializor[j].arity() != arity));
_eo1[i] = initializor[j];
return true;
}
private :
std::vector<Node>& initializor;
};
/** eoExpansionMutation --> replace a terminal with a randomly created subtree
\class eoExpansionMutation eoParseTreeOp.h gp/eoParseTreeOp.h
\ingroup ParseTree
*/
template<class FType, class Node>
class eoExpansionMutation: public eoMonOp< eoParseTree<FType, Node> >
{
public:
typedef eoParseTree<FType, Node> EoType;
/**
* Constructor
* @param _init An instantiation of eoGpDepthInitializer
* @param _max_length the maximum size of an individual
*/
eoExpansionMutation(eoInit<EoType>& _init, unsigned _max_length)
: eoMonOp<EoType>(), max_length(_max_length), initializer(_init)
{};
/// The class name
virtual std::string className() const { return "eoExpansionMutation"; };
/// Dtor
virtual ~eoExpansionMutation() {};
/**
* Mutate an individual
* @param _eo1 The individual that is to be changed
*/
bool operator()(EoType& _eo1 )
{
int i = rng.random(_eo1.size());
// look for a terminal
while (_eo1[i].arity() != 0)
{
i= rng.random(_eo1.size());
};
// create a new tree to
EoType eo2;
// make sure we get a tree with more than just a terminal
do
{
initializer(eo2);
}while(eo2.size() == 1);
int j = rng.random(eo2.size());
// make sure we select a subtree (and not a terminal)
while((eo2[j].arity() == 0))
{
j = rng.random(eo2.size());
};
_eo1[i] = eo2[j]; // insert subtree
_eo1.pruneTree(max_length);
return true;
}
private :
unsigned max_length;
eoInit<EoType>& initializer;
};
/** eoCollapseSubtree --> replace a subtree with a randomly chosen terminal
\class eoCollapseSubtreeMutation eoParseTreeOp.h gp/eoParseTreeOp.h
\ingroup ParseTree
*/
template<class FType, class Node>
class eoCollapseSubtreeMutation: public eoMonOp< eoParseTree<FType, Node> >
{
public:
typedef eoParseTree<FType,Node> EoType;
/**
* Constructor
* @param _init An instantiation of eoGpDepthInitializer
* @param _max_length the maximum size of an individual
*/
eoCollapseSubtreeMutation(eoInit<EoType>& _init, unsigned _max_length)
: eoMonOp<EoType>(), max_length(_max_length), initializer(_init)
{};
/// The class name
virtual std::string className() const { return "eoCollapseSubtreeMutation"; };
/// Dtor
virtual ~eoCollapseSubtreeMutation() {};
/**
* Mutate an individual
* @param _eo1 The individual that is to be changed
*/
bool operator()(EoType& _eo1 )
{
int i = rng.random(_eo1.size());
// look for a subtree
while ((_eo1[i].arity() == 0) && (_eo1.size() > 1))
{
i= rng.random(_eo1.size());
};
// create a new tree to
EoType eo2;
initializer(eo2);
int j = rng.random(eo2.size());
// make sure we select a subtree (and not a terminal)
while(eo2[j].arity() != 0)
{
j = rng.random(eo2.size());
};
_eo1[i] = eo2[j]; // insert subtree
// we don't have to prune because the subtree is always smaller
_eo1.pruneTree(max_length);
return true;
}
private :
unsigned max_length;
eoInit<EoType>& initializer;
};
/** eoHoistMutation --> replace the individual with one of its subtree's
\class eoHoistMutation eoParseTreeOp.h gp/eoParseTreeOp.h
\ingroup ParseTree
*/
template<class FType, class Node>
class eoHoistMutation: public eoMonOp< eoParseTree<FType, Node> >
{
public:
typedef eoParseTree<FType,Node> EoType;
/**
* Constructor
*/
eoHoistMutation()
: eoMonOp<EoType>()
{};
/// The class name
virtual std::string className() const { return "eoHoistMutation"; };
/// Dtor
virtual ~eoHoistMutation() {};
/**
* Mutate an individual
* @param _eo1 The individual that is to be changed
*/
bool operator()(EoType& _eo1 )
{
// select a hoist point
int i = rng.random(_eo1.size());
// and create a new tree
EoType eo2(_eo1[i]);
// we don't have to prune because the new tree is always smaller
//_eo1.pruneTree(max_length);
_eo1 = eo2;
return true;
}
private :
};
#endif

View file

@ -0,0 +1,194 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// eoStParseTreeDepthInit.h : initializor strongly type GP
// (c) Jeroen Eggermont 2001
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
jeggermo@liacs.nl
*/
//-----------------------------------------------------------------------------
#ifndef eoStParseTreeDepthInit_h
#define eoStParseTreeDepthInit_h
#include <EO.h>
#include <gp/eoParseTree.h>
#include <eoInit.h>
#include <eoOp.h>
#include <map>
using namespace gp_parse_tree;
#define TERMINAL 0
#define NONTERMINAL 4
#define ALL 5
/**
\defgroup StParseTree
Various functions for strongly typed tree-based Genetic Programming.
The StParseTree functions use the same eoParseTree class for the
individual but now each node class must have two additional functions.
\li int type(void) which returns the return type of the node
\li int type(int child) which returns the required type for child 0, 1 or 2
Pruning strongly typed trees is not possible at the moment.
\ingroup Representations
*/
/** eoStParseTreeDepthInit : the initializer class for strongly typed tree-based genetic programming
\class eoStParseTreeDepthInit eoStParseTreeDepthInit.h gp/eoStParseTreeDepthInit.h
\ingroup StParseTree
*/
template <class FType, class Node>
class eoStParseTreeDepthInit : public eoInit< eoParseTree<FType, Node> >
{
public :
typedef eoParseTree<FType, Node> EoType;
/**
* Constructor
* @param _max_depth The maximum depth of a tree
* @param _node A std::vector containing the possible nodes
* @param _return_type (JD_2010-11-09: don't know the use of this parameter, maybe to force implicit template instanciation?)
* @param _grow False results in a full tree, True result is a randomly grown tree
*/
eoStParseTreeDepthInit(
unsigned _max_depth,
const std::vector<Node>& _node,
const int& _return_type,
bool _grow = true)
:
eoInit<EoType>(),
max_depth(_max_depth),
return_type(_return_type),
grow(_grow)
{
if(_node.empty())
{
throw std::logic_error("eoStParseTreeDepthInit: uhm, wouldn't you rather give a non-empty set of Nodes?");
}
unsigned int i=0;
int arity=0;
int type=0;
std::vector<Node> node_vector;
for(i=0; i < _node.size(); i++)
{
arity = _node[i].arity();
type = _node[i].type();
if(arity==0)
{
node_vector = node[type][TERMINAL];
node_vector.push_back(_node[i]);
node[type][TERMINAL]= node_vector;
}
else
//if (arity != 0) // non-terminal
{
node_vector = node[type][NONTERMINAL];
node_vector.push_back(_node[i]);
node[type][NONTERMINAL] = node_vector;
}
node_vector = node[type][ALL];
node_vector.push_back(_node[i]);
node[type][ALL] = node_vector;
}
}
/// My class name
virtual std::string className() const { return "eoStParseTreeDepthInit"; };
/**initialize a tree
* @param _tree : the tree to be initialized
*/
void operator()(EoType& _tree)
{
std::list<Node> sequence;
bool good_tree = false;
do
{
sequence.clear();
good_tree = generate(sequence, max_depth, return_type);
}while (!good_tree);
parse_tree<Node> tmp(sequence.begin(), sequence.end());
_tree.swap(tmp);
}
private :
bool generate(std::list<Node>& sequence, int the_max, int request_type)
{
int selected=0;
bool ok = true;
if (the_max == 1)
{ // generate terminals only
if( node[request_type][TERMINAL].empty() ) // no possible terminal node of this type
return false; // we have an invalid tree
else
{
selected = rng.random((node[request_type][TERMINAL]).size());
sequence.push_front(node[request_type][TERMINAL][selected]);
return true;
}
}
int arity=0;
if (grow)
{
selected = rng.random((node[request_type][ALL]).size());
arity = node[request_type][ALL][selected].arity();
sequence.push_front(node[request_type][ALL][selected]);
for (int i = 0; i < arity; ++i)
ok &= generate(sequence, the_max - 1, node[request_type][ALL][selected].type(i));
}
else // full
{
selected = rng.random((node[request_type][NONTERMINAL]).size());
arity = node[request_type][NONTERMINAL][selected].arity();
sequence.push_front(node[request_type][NONTERMINAL][selected]);
for (int i = 0; i < arity; ++i)
ok &=generate(sequence, the_max - 1, node[request_type][NONTERMINAL][selected].type(i));
}
return ok;
}
unsigned max_depth;
std::map < int, std::map < int, std::vector<Node> > > node;
int return_type;
bool grow;
};
#endif

View file

@ -0,0 +1,312 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// eoStParseTreeOp.h : crossover and mutation operators for the strongly typed GP
// (c) Jeroen Eggermont 2001 for other mutation operators
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
mak@dhi.dk
jeggermo@liacs.nl
*/
//-----------------------------------------------------------------------------
#ifndef eoStParseTreeOp_h
#define eoStParseTreeOp_h
#include <EO.h>
#include <eoOp.h>
#include <map.h>
#include <iostream>
#include <set>
#include <gp/eoParseTree.h>
// a help function
template <class EOT>
void get_possible_nodes(const EOT &_eo, std::vector<int> &possible_nodes, const int type)
{
int n=0;
possible_nodes.clear();
// collect the possible crossover points in _eo (nodes with the same type)
for(n=0; n < _eo.size(); n++)
if (type == _eo[n]->type())
possible_nodes.push_back(n);
}
/** eoStSubtreeXOver --> subtree xover for strongly typed tree-based genetic programming
\class eoStSubtreeXOver eoStParseTreeOp.h gp/eoStParseTreeOp.h
\ingroup StParseTree
*/
template<class FType, class Node>
class eoStSubtreeXOver: public eoQuadOp< eoParseTree<FType, Node> > {
public:
typedef eoParseTree<FType,Node> EoType;
/**
* Constructor
* @param _max_length the maximum size of an individual
*/
eoStSubtreeXOver( unsigned _max_length)
: eoQuadOp<EoType>(), max_length(_max_length) {};
/// the ckassname
virtual std::string className() const { return "eoStSubtreeXOver"; };
/// Dtor
virtual ~eoStSubtreeXOver () {};
/**
* Perform crossover on two individuals
* param _eo1 The first parent individual
* param _eo2 The second parent individual
*/
bool operator()(EoType & _eo1, EoType & _eo2 )
{
int i = 0;
std::vector<int> nodes;
int n = 0;
int type = 0;
int j = 0;
std::set<int> test;
do
{
do // select a random node in _eo1 as crossover point, and check if we didn't try it already
{
i = rng.random(_eo1.size());
}while(test.count(i) > 0);
test.insert(i);
type = _eo1[i]->type();
get_possible_nodes<EoType>(_eo2, nodes, type);
}while(nodes.empty() && (test.size() < _eo1.size()));
if (nodes.empty()) // we failed to select a crossover point but tried all points (test.size() == _eo1.size()).
return true; // should this be false ??
// we did find at least one possible crossover point in _eo2
n = rng.random(nodes.size());
j = nodes[n];
typename eoParseTree<FType, Node>::subtree tmp = _eo1[i];
_eo1[i] = _eo2[j]; // insert subtree
_eo2[j] = tmp;
// we can't prune anymore
/*
_eo1.pruneTree(max_length);
_eo2.pruneTree(max_length);
*/
return true;
}
private:
unsigned max_length;
};
/** eoStBranchMutation --> replace a strongly typed subtree with a randomly created strongly typed subtree
\class eoStBranchMutation eoStParseTreeOp.h gp/eoStParseTreeOp.h
\ingroup StParseTree
*/
template<class FType, class Node>
class eoStBranchMutation: public eoMonOp< eoParseTree<FType, Node> >
{
public:
typedef eoParseTree<FType,Node> EoType;
/**
* Constructor
* @param _init An instantiation of eoGpDepthInitializer
* @param _max_length the maximum size of an individual
*/
eoStBranchMutation(eoInit<EoType>& _init, unsigned _max_length)
: eoMonOp<EoType>(), max_length(_max_length), initializer(_init)
{};
/// the class name
virtual std::string className() const { return "eoStBranchMutation"; };
/// Dtor
virtual ~eoStBranchMutation() {};
/**
* Mutate an individual
* @param _eo1 The individual that is to be changed
*/
bool operator()(EoType& _eo1 )
{
int i = rng.random(_eo1.size());
std::vector<int> nodes;
int type = _eo1[i]->type();
int j=0;
int n=0;
EoType eo2;
do
{
initializer(eo2);
get_possible_nodes(eo2, nodes, type);
}while (nodes.empty());
n = rng.random(nodes.size());
j = nodes[n];
_eo1[i] = eo2[j]; // insert subtree
// no more pruning
/*
_eo1.pruneTree(max_length);
*/
return true;
}
private :
unsigned max_length;
eoInit<EoType>& initializer;
};
/** eoStPointMutation --> replace a Node with a Node of the same arity and type
\class eoStPointMutation eoStParseTreeOp.h gp/eoStParseTreeOp.h
\ingroup StParseTree
*/
template<class FType, class Node>
class eoStPointMutation: public eoMonOp< eoParseTree<FType, Node> >
{
public:
typedef eoParseTree<FType,Node> EoType;
/**
* Constructor
* @param _node The std::vector of Nodes given to the eoGpDepthInitializer
*/
eoStPointMutation( std::vector<Node>& _node)
: eoMonOp<EoType>()
{
unsigned int i=0;
int arity=0;
int type=0;
std::vector<Node> node_vector;
for(i=0; i < _node.size(); i++)
{
arity = _node[i].arity();
type = _node[i].type();
node_vector = node[type][arity];
node_vector.push_back(_node[i]);
node[type][arity]= node_vector;
};
};
/// the class name
virtual std::string className() const { return "eoStPointMutation"; };
/// Dtor
virtual ~eoStPointMutation() {};
/**
* Mutate an individual
* @param _eo1 The individual that is to be changed
*/
bool operator()(EoType& _eo1 )
{
// select a random node i that is to be mutated
int i = rng.random(_eo1.size());
int arity = _eo1[i].arity();
int type = _eo1[i]->type();
int j = rng.random(node[type][arity].size());
_eo1[i] = node[type][arity][j];
return true;
}
private :
std::map < int, std::map < int, std::vector<Node> > > node;
};
/** eoStHoistMutation --> replace the individual with one of its strongly typed subtree's
\class eoStHoistMutation eoStParseTreeOp.h gp/eoStParseTreeOp.h
\ingroup StParseTree
*/
template<class FType, class Node>
class eoStHoistMutation: public eoMonOp< eoParseTree<FType, Node> >
{
public:
typedef eoParseTree<FType,Node> EoType;
/**
* Constructor
* @param _init An instantiation of eoStDepthInit
* @param _max_length the maximum size of an individual
*/
eoStHoistMutation(eoInit<EoType>& _init, unsigned _max_length)
: eoMonOp<EoType>(), max_length(_max_length), initializer(_init)
{};
/// the class name
virtual std::string className() const { return "eoStHoistMutation"; };
/// Dtor
virtual ~eoStHoistMutation() {};
/**
* Mutate an individual
* @param _eo1 The individual that is to be changed
*/
bool operator()(EoType& _eo1 )
{
std::vector<int> nodes;
// get the type of the current tree
int type = _eo1[ _eo1.size() - 1 ]->type();
get_possible_nodes(_eo1, nodes, type);
// select a subtree-node to replace the current tree
int n = rng.random(nodes.size());
int i = nodes[n];
EoType eo2(_eo1[i]);
_eo1 = eo2;
return true;
}
private :
unsigned max_length;
eoInit<EoType>& initializer;
};
#endif

View file

@ -0,0 +1,313 @@
/**
* Pool allocator for the subtree and parse tree classes (homebrew and not compliant to ANSI allocator requirements)
* (c) copyright Maarten Keijzer 1999, 2000
* Permission to copy, use, modify, sell and distribute this software is granted provided
* this copyright notice appears in all copies. This software is provided "as is" without
* express or implied warranty, and with no claim as to its suitability for
* any purpose.
* Permission to modify the code and to distribute modified code is granted,
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*/
#ifndef node_pool_h
#define node_pool_h
class MemPool
{
public :
MemPool(unsigned int sz) : esize(sz<sizeof(Link)? sizeof(Link) : sz) {}
~MemPool()
{
Chunk* n = chunks;
while(n)
{
Chunk* p = n;
n = n->next;
delete p;
}
}
void* allocate()
{
if (head == 0) grow();
Link* p = head;
head = p->next;
return static_cast<void*>(p);
}
void deallocate(void* b)
{
Link* p = static_cast<Link*>(b);
p->next = head;
head = p;
}
private :
void grow()
{
Chunk* n = new Chunk;
n->next = chunks;
chunks = n;
const int nelem = Chunk::size/esize;
char* start = n->mem;
char* last = &start[(nelem-1)*esize];
for (char* p = start; p < last; p += esize)
{
reinterpret_cast<Link*>(p)->next =
reinterpret_cast<Link*>(p + esize);
}
reinterpret_cast<Link*>(last)->next = 0;
head = reinterpret_cast<Link*>(start);
}
struct Link
{
Link* next;
};
struct Chunk
{
enum {size = 8 * 1024 - 16};
Chunk* next;
char mem[size];
};
Chunk* chunks;
const unsigned int esize;
Link* head;
};
template<class T>
class Node_alloc
{
public :
T* allocate(void)
{
T* t = static_cast<T*>(mem.allocate());
t = new (t) T;
return t;
}
T* construct(const T& org)
{
T* t = static_cast<T*>(mem.allocate());
t = new (t) T(org);
return t;
}
void deallocate(T* t)
{
t->~T(); // call destructor
mem.deallocate(static_cast<void*>(t));
}
private :
static MemPool mem;
};
template <class T>
class Standard_alloc
{
public :
Standard_alloc() {}
T* allocate(size_t arity = 1)
{
if (arity == 0)
return 0;
return new T [arity];
}
T* construct(size_t arity, T* org)
{
if (arity == 0)
return 0;
T* t = new T [arity];
for (int i = 0; i < arity; ++i)
{
t = T(org[i]);
}
}
void deallocate(T* t, size_t arity = 1)
{
if (arity == 0)
return ;
delete [] t;
}
};
template <class T>
class Standard_Node_alloc
{
public :
Standard_Node_alloc() {}
T* allocate(void)
{
return new T;// [arity];
}
T* construct(const T& org)
{
return new T(org);
}
void deallocate(T* t)
{
delete t;
}
};
template <class T>
class Tree_alloc
{
public :
Tree_alloc() {}
T* allocate(size_t arity)
{
T* t;
switch(arity)
{
case 0 : return 0;
case 1 :
{
t = static_cast<T*>(mem1.allocate());
new (t) T;
break;
}
case 2 :
{
t = static_cast<T*>(mem2.allocate());
new (t) T;
new (&t[1]) T;
break;
}
case 3 :
{
t = static_cast<T*>(mem3.allocate());
new (t) T;
new (&t[1]) T;
new (&t[2]) T;
break;
}
default :
{
return new T[arity];
}
}
return t;
}
T* construct(size_t arity, T* org)
{
T* t;
switch(arity)
{
case 0 : return 0;
case 1 :
{
t = static_cast<T*>(mem1.allocate());
new (t) T(*org);
break;
}
case 2 :
{
t = static_cast<T*>(mem2.allocate());
new (t) T(*org);
new (&t[1]) T(org[1]);
break;
}
case 3 :
{
t = static_cast<T*>(mem3.allocate());
new (t) T(*org);
new (&t[1]) T(org[1]);
new (&t[1]) T(org[2]);
break;
}
default :
{
t = new T[arity]; // does call default ctor
for (int i = 0; i < arity; ++i)
{
t[i] = T(org[i]); // constructs now
}
}
}
return t;
}
void deallocate(T* t, size_t arity)
{
switch(arity)
{
case 0: return;
case 3 :
{
t[2].~T(); t[1].~T(); t[0].~T();
mem3.deallocate(static_cast<void*>(t));
return;
}
case 2 :
{
t[1].~T(); t[0].~T();
mem2.deallocate(static_cast<void*>(t));
return;
}
case 1 :
{
t[0].~T();
mem1.deallocate(static_cast<void*>(t));
return;
}
default :
{
delete [] t;
return;
}
}
}
private :
static MemPool mem1;
static MemPool mem2;
static MemPool mem3;
};
// static (non thread_safe) memory pools
template <class T> MemPool Node_alloc<T>::mem = sizeof(T);
template <class T> MemPool Tree_alloc<T>::mem1 = sizeof(T);
template <class T> MemPool Tree_alloc<T>::mem2 = sizeof(T) * 2;
template <class T> MemPool Tree_alloc<T>::mem3 = sizeof(T) * 3;
#endif

File diff suppressed because it is too large Load diff