00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <Sym.h>
00020 #include <NodeSelector.h>
00021
00022 #include <eoSymCrossover.h>
00023 #include <utils/eoRNG.h>
00024 #include <vector>
00025
00026 using namespace std;
00027
00028 bool subtree_quad(Sym& a, Sym& b, NodeSelector& select) {
00029 NodeSelector::NodeSelection sel_a = select.select_node(a);
00030 NodeSelector::NodeSelection sel_b = select.select_node(b);
00031
00032 Sym aprime = insert_subtree(a, sel_a.idx(), sel_b.subtree() );
00033 Sym bprime = insert_subtree(b, sel_b.idx(), sel_a.subtree() );
00034
00035 a = aprime;
00036 b = bprime;
00037 return true;
00038 }
00039
00040 bool subtree_bin(Sym& a, const Sym& b, NodeSelector& select) {
00041 NodeSelector::NodeSelection sel_a = select.select_node(a);
00042 NodeSelector::NodeSelection sel_b = select.select_node(b);
00043
00044 a = insert_subtree(a, sel_a.idx(), sel_b.subtree());
00045
00046 return true;
00047 }
00048
00049 Sym homologous_binimpl(Sym a, Sym b) {
00050
00051 if(a == b) { return a; }
00052
00053 bool use_a = rng.random(2);
00054
00055 token_t head = (use_a? a : b).token();
00056 SymVec args = use_a?a.args() : b.args();
00057
00058 const SymVec& a_args = a.args();
00059 const SymVec& b_args = b.args();
00060 unsigned mn = std::min(a_args.size(), b_args.size());
00061
00062 bool changed = !use_a;
00063
00064 for (unsigned i = 0; i < mn; ++i) {
00065 args[i] = homologous_binimpl(a_args[i], b_args[i]);
00066 if (args[i] != a_args[i]) {
00067 changed = true;
00068 }
00069 }
00070
00071 return changed? Sym(head, args) : a;
00072 }
00073
00074 bool homologous_bin(Sym& a, const Sym& b) {
00075 if (a==b) return false;
00076 Sym org = a;
00077 a = homologous_binimpl(a,b);
00078 return org != a;
00079 }
00080
00081 void set_size_levels(Sym sym, vector<unsigned>& l, vector<unsigned>& s, unsigned level = 1) {
00082 l.push_back(level);
00083 s.push_back(sym.size());
00084
00085 for (unsigned i = 0; i < sym.args().size(); ++i) {
00086 set_size_levels(sym.args()[i], l, s, level+1);
00087 }
00088 }
00089
00090
00091 bool size_level_xover(Sym& a, const Sym& b) {
00092
00093 Sym org = a;
00094
00095 vector<unsigned> levela;
00096 vector<unsigned> sizesa;
00097 vector<unsigned> levelb;
00098 vector<unsigned> sizesb;
00099
00100 set_size_levels(a, levela, sizesa);
00101 set_size_levels(b, levelb, sizesb);
00102
00103 unsigned p0;
00104 unsigned p1;
00105
00106 for (unsigned tries = 0;; ++tries) {
00107 p0 = rng.random(a.size());
00108 p1 = rng.random(b.size());
00109
00110 if (tries < 5 && (sizesa[p0] != sizesb[p1] && levela[p0] != levelb[p1])) {
00111 continue;
00112 }
00113
00114 break;
00115 }
00116
00117 a = insert_subtree(a, p0, get_subtree(b, p1));
00118
00119 return org != a;
00120
00121 }
00122
00123