Added mathsym+tcc and boost against all advice

This commit is contained in:
maartenkeijzer 2005-10-06 12:13:53 +00:00
commit 90702a435d
136 changed files with 14409 additions and 0 deletions

View file

@ -0,0 +1,62 @@
/*
* Copyright (C) 2005 Maarten Keijzer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef EOSYM_H_
#define EOSYM_H_
#include <EO.h>
#include <Sym.h>
#include <FunDef.h>
template <class Fitness>
class EoSym : public EO<Fitness>, public Sym {
public:
void set(const Sym& sym) {
invalidate();
static_cast<Sym*>(this)->operator=(sym);
}
virtual void printOn(ostream& os) const;
virtual void readFrom(istream& is);
};
template <class Fitness>
void EoSym<Fitness>::printOn(ostream& os) const {
EO<Fitness>::printOn(os);
os << ' ';
write_raw(os, *this);
}
template <class Fitness>
void EoSym<Fitness>::readFrom(istream& is) {
EO<Fitness>::readFrom(is);
read_raw(is, *this);
}
template <class Fitness>
inline std::ostream& operator<<(std::ostream& os, const EoSym<Fitness>& f) { f.printOn(os); return os; }
template <class Fitness>
inline istream& operator>>(std::istream& is, EoSym<Fitness>& f) { f.readFrom(is); return os; }
#endif

View file

@ -0,0 +1,76 @@
/*
* Copyright (C) 2005 Maarten Keijzer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <Sym.h>
#include <NodeSelector.h>
#include <eoSymCrossover.h>
#include <utils/eoRNG.h>
bool subtree_quad(Sym& a, Sym& b, NodeSelector& select) {
unsigned i = select.select_node(a);
unsigned j = select.select_node(b);
Sym aprime = insert_subtree(a, i, get_subtree(b, j));
Sym bprime = insert_subtree(b, j, get_subtree(a, i));
a = aprime;
b = bprime;
return true;
}
bool subtree_bin(Sym& a, const Sym& b, NodeSelector& select) {
unsigned i = select.select_node(a);
unsigned j = select.select_node(b);
a = insert_subtree(a, i, get_subtree(b,j));
return true;
}
Sym homologous_binimpl(Sym a, Sym b) {
bool use_a = rng.random(2);
token_t head = (use_a? a : b).token();
SymVec args = use_a?a.args() : b.args();
const SymVec& a_args = a.args();
const SymVec& b_args = b.args();
unsigned mn = std::min(a_args.size(), b_args.size());
bool changed = !use_a;
for (unsigned i = 0; i < mn; ++i) {
args[i] = homologous_binimpl(a_args[i], b_args[i]);
if (args[i] != a_args[i]) {
changed = true;
}
}
return changed? Sym(head, args) : a;
}
bool homologous_bin(Sym& a, const Sym& b) {
if (a==b) return false;
Sym org = a;
a = homologous_binimpl(a,b);
return org != a;
}

View file

@ -0,0 +1,64 @@
/*
* Copyright (C) 2005 Maarten Keijzer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef EOSYMCROSSOVER_H
#define EOSYMCROSSOVER_H
class NodeSelector;
class Sym;
#include <eoOp.h>
extern bool subtree_quad(Sym& a, Sym& b, NodeSelector& select);
template <class EoType>
class eoQuadSubtreeCrossover : public eoQuadOp<EoType> {
NodeSelector& node_selector;
public:
eoQuadSubtreeCrossover(NodeSelector& _node_selector) : node_selector(_node_selector) {}
bool operator()(EoType& a, EoType& b) { return subtree_quad(a,b, node_selector); }
};
extern bool subtree_bin(Sym& a, const Sym& b, NodeSelector& select);
template <class EoType>
class eoBinSubtreeCrossover : public eoBinOp<EoType> {
NodeSelector& node_selector;
public :
eoBinSubtreeCrossover(NodeSelector& _node_selector) : node_selector(_node_selector) {}
bool operator()(EoType& a, const EoType& b) { return subtree_bin(a, b, node_selector); }
};
/** Yet another homologous crossover, afaik not particularly
* defined in the literature
*/
extern bool homologous_bin(Sym& a, const Sym& b);
template <class EoType>
class eoBinHomologousCrossover : public eoBinOp<EoType> {
public:
bool operator()(EoType& a, const EoType& b) {
return homologous_bin(a,b);
}
};
#endif

View file

@ -0,0 +1,94 @@
/*
* Copyright (C) 2005 Maarten Keijzer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef SYMEVAL_H
#define SYMEVAL_H
#include <Sym.h>
#include <ErrorMeasure.h>
#include <BoundsCheck.h>
#include <eoPopEvalFunc.h>
template <class EoType>
class eoSymPopEval : public eoPopEvalFunc<EoType> {
BoundsCheck& check;
ErrorMeasure& measure;
public:
eoSymPopEval(BoundsCheck& _check, ErrorMeasure& _measure) :
check(_check), measure(_measure) {}
/** apparently this thing works on two populations, why?
*
* In any case, currently only implemented the population wide
* evaluation version, as that one is much faster. This because the
* compile going on behind the scenes is much faster when done in one
* go (and using subtree similarity) then when done on a case by case
* basis.
*/
void operator()(eoPop<EoType>& p1, eoPop<EoType>& p2) {
std::vector<unsigned> unevaluated;
std::vector<Sym> tmppop;
for (unsigned i = 0; i < p1.size(); ++i) {
if (p1[i].invalid()) {
if (check.in_bounds(p1[i])) {
unevaluated.push_back(i);
tmppop.push_back( static_cast<Sym>(p1[i]) );
} else {
p1[i].fitness( measure.worst_performance() );
}
}
}
for (unsigned i = 0; i < p2.size(); ++i) {
if (p2[i].invalid()) {
if (check.in_bounds(p2[i])) {
unevaluated.push_back(p1.size() + i);
tmppop.push_back( static_cast<Sym>(p2[i]) );
} else {
p2[i].fitness( measure.worst_performance() ); // pretty bad error
}
}
}
std::vector<ErrorMeasure::result> result = measure.calc_error(tmppop);
for (unsigned i = 0; i < result.size(); ++i) {
unsigned idx = unevaluated[i];
if (idx < p1.size()) {
p1[idx].fitness(result[i].error);
} else {
idx -= p1.size();
p2[idx].fitness(result[i].error);
}
}
}
};
#endif

View file

@ -0,0 +1,64 @@
/*
* Copyright (C) 2005 Maarten Keijzer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef EOSYMINIT_H
#define EOSYMINIT_H
#include <eoInit.h>
#include <TreeBuilder.h>
/** Default initializer, Koza style */
template <class EoType>
class eoSymInit : public eoInit<EoType> {
TreeBuilder& builder;
double own_grow_prob;
unsigned own_max_depth;
double& grow_prob;
unsigned& max_depth;
public:
/** By default build ramped half and half with max depth 6 */
eoSymInit(TreeBuilder& _builder)
: builder(_builder),
own_grow_prob(0.5),
own_max_depth(6),
grow_prob(own_grow_prob),
max_depth(own_max_depth)
{}
/** Control the grow_prob and max_depth externally */
eoSymInit(TreeBuilder& _builder, double& _grow_prob, unsigned& _max_depth)
: builder(_builder),
grow_prob(_grow_prob),
max_depth(_max_depth)
{}
/** build the tree */
void operator()(EoType& tree) {
int depth_to_use = rng.random(max_depth-2) + 2; // two levels minimum
builder.build_tree(tree, depth_to_use, rng.flip(grow_prob));
}
};
#endif

View file

@ -0,0 +1,122 @@
/*
* Copyright (C) 2005 Maarten Keijzer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef SYMMUTATE_H
#define SYMMUTATE_H
#include <TreeBuilder.h>
#include <NodeSelector.h>
#include <eoSym.h>
#include <eoOp.h>
template <class EoType>
class eoSymSubtreeMutate : public eoMonOp<EoType> {
TreeBuilder& subtree_builder;
NodeSelector& node_selector;
public :
eoSymSubtreeMutate(TreeBuilder& _subtree_builder, NodeSelector& _node_selector)
: subtree_builder(_subtree_builder), node_selector(_node_selector) {}
bool operator()(EoType& tomutate) {
unsigned xover_point = node_selector.select_node(tomutate);
// create subtree
Sym newtree = subtree_builder.build_tree(6, true); // TODO, parameterize
static_cast<Sym&>(tomutate) = insert_subtree(tomutate, xover_point, newtree);
return true;
}
};
/** Class for doing node mutation
* Two parameters:
*
* mutation_rate (the rate at which to do mutation)
* is_rate_absolute : don't rescale the rate to the size of the tree
*/
template <class EoType>
class eoSymNodeMutate : public eoMonOp<EoType> {
LanguageTable& table;
double own_mutation_rate;
bool own_is_rate_absolute;
// these two can (should?) move to an impl file
bool mutate(Sym& sym, double p) {
std::pair<Sym, bool> r = do_mutate(sym, p);
sym = r.first;
return r.second;
}
std::pair<Sym, bool> do_mutate(Sym sym, double p) {
bool changed = false;
SymVec args = sym.args();
if (rng.flip(p)) {
token_t new_token = table.get_random_function( args.size());
if (new_token != sym.token()) changed = true;
sym = Sym(new_token, args);
}
for (unsigned i = 0; i < args.size(); ++i) {
std::pair<Sym,bool> r = do_mutate(args[i], p);
changed |= r.second;
if (r.second)
args[i] = r.first;
}
if (changed)
return std::make_pair(Sym(sym.token(), args), true);
// else
return std::make_pair(sym, false);
}
public:
double& mutation_rate;
bool& is_rate_absolute;
eoSymNodeMutate(LanguageTable& _table)
: table(_table),
own_mutation_rate(1.0),
own_is_rate_absolute(false), // this means a probability of node mutation of 1/sym.size()
mutation_rate(own_mutation_rate),
is_rate_absolute(own_is_rate_absolute)
{}
eoSymNodeMutate(LanguageTable& _table, double& _mutation_rate, bool& _is_rate_absolute)
: table(_table),
mutation_rate(_mutation_rate),
is_rate_absolute(_is_rate_absolute)
{}
bool operator()(EoType& _eo) {
double p = mutation_rate;
if (!is_rate_absolute) p /= _eo.size();
return mutate(_eo, p);
}
};
#endif