# eoSymCrossover.cpp

    00001 /*
    00002  *             Copyright (C) 2005 Maarten Keijzer
    00003  *
    00004  *          This program is free software; you can redistribute it and/or modify
    00005  *          it under the terms of version 2 of the GNU General Public License as
    00006  *          published by the Free Software Foundation.
    00007  *
    00008  *          This program is distributed in the hope that it will be useful,
    00009  *          but WITHOUT ANY WARRANTY; without even the implied warranty of
    00010  *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00011  *          GNU General Public License for more details.
    00012  *
    00013  *          You should have received a copy of the GNU General Public License
    00014  *          along with this program; if not, write to the Free Software
    00015  *          Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    00016  */
    00017
    00018
    00019 #include <Sym.h>
    00020 #include <NodeSelector.h>
    00021
    00022 #include <eoSymCrossover.h>
    00023 #include <utils/eoRNG.h>
    00024
    00025 bool subtree_quad(Sym& a, Sym& b, NodeSelector& select) {
    00026     NodeSelector::NodeSelection sel_a = select.select_node(a);
    00027     NodeSelector::NodeSelection sel_b = select.select_node(b);
    00028
    00029     Sym aprime = insert_subtree(a, sel_a.idx(), sel_b.subtree() );
    00030     Sym bprime = insert_subtree(b, sel_b.idx(), sel_a.subtree() );
    00031
    00032     a = aprime;
    00033     b = bprime;
    00034     return true;
    00035 }
    00036
    00037 bool subtree_bin(Sym& a, const Sym& b, NodeSelector& select) {
    00038     NodeSelector::NodeSelection sel_a = select.select_node(a);
    00039     NodeSelector::NodeSelection sel_b = select.select_node(b);
    00040
    00041     a = insert_subtree(a, sel_a.idx(), sel_b.subtree());
    00042
    00043     return true;
    00044 }
    00045
    00046 Sym homologous_binimpl(Sym a, Sym b) {
    00047
    00048     if(a == b) { return a; } // no point
    00049
    00050     bool use_a = rng.random(2);
    00051
    00052     token_t head = (use_a? a : b).token();
    00053     SymVec args = use_a?a.args() : b.args();
    00054
    00055     const SymVec& a_args = a.args();
    00056     const SymVec& b_args = b.args();
    00057     unsigned mn = std::min(a_args.size(), b_args.size());
    00058
    00059     bool changed = !use_a;
    00060
    00061     for (unsigned i = 0; i < mn; ++i) {
    00062         args[i] = homologous_binimpl(a_args[i], b_args[i]);
    00063         if (args[i] != a_args[i]) {
    00064             changed = true;
    00065         }
    00066     }
    00067
    00068     return changed? Sym(head, args) : a;
    00069 }
    00070
    00071 bool homologous_bin(Sym& a, const Sym& b) {
    00072     if (a==b) return false;
    00073     Sym org = a;
    00074     a = homologous_binimpl(a,b);
    00075     return org != a;
    00076 }
    00077
    00078