int Reproduction::breed(System* system, Population* src, vector<Program>* newpop, int index) { // Big complex mess // First select individuals vector<Program*> p = getSelections(1, src, index); Program* a = p[0]; // Swap subtrees rooted at a and b to form new nodes newpop->push_back(Program(system)); Program* dsta=&newpop->at(newpop->size()-1); a->copy(*dsta); #ifdef DEBUG if (!a->checkConsistency()) throw runtime_error("Resulting program from architecture altering operation is not consistent"); #endif return 1; }
int Crossover::breed(System* system, Population* src, vector<Program>* newpop, int index) { // Big complex mess // First select individuals vector<Program*> prgms=getSelections(2, src, index); Program* a = prgms[0]; Program* b = prgms[1]; // Subtree selection int branch=rand()%(a->branch.size()); int i,j; vector<int> strees=getSelectionTrees(branch, &prgms); i=strees[0]; j=strees[1]; if (i<0 || j<0) return 0; // Detect early on if crossover will be unsuccessful due to depth limits if (system->maxdepth>0) { // Only need to check the new branch to see if it exceeds the limit int deptha=b->branch[branch][j].parentOffset; int depthb=a->branch[branch][i].parentOffset; int parent; parent=i; while (parent>0) { parent+=a->branch[branch][parent].parentOffset; deptha++; } parent=j; while (parent>0) { parent+=b->branch[branch][parent].parentOffset; depthb++; } if (deptha>system->maxdepth || depthb>system->maxdepth) return 0; } if (system->maxnodes>0) { // Check if either program will have too many nodes if (a->branch[branch][0].nodes-a->branch[branch][i].nodes+b->branch[branch][j].nodes>system->maxnodes) return 0; if (b->branch[branch][0].nodes-b->branch[branch][j].nodes+a->branch[branch][i].nodes>system->maxnodes) return 0; } // Swap subtrees rooted at a and b to form new nodes newpop->push_back(Program(system)); newpop->push_back(Program(system)); Program* dsta=&newpop->at(newpop->size()-2); Program* dstb=&newpop->at(newpop->size()-1); a->copy(*dsta); b->copy(*dstb); copyTree(TreeNodeIter(&dsta->branch[branch], i), TreeNodeIter(&b->branch[branch], j)); copyTree(TreeNodeIter(&dstb->branch[branch], j), TreeNodeIter(&a->branch[branch], i)); #ifdef DEBUG if (!a->checkConsistency()) throw runtime_error("Resulting program from architecture altering operation is not consistent"); if (!b->checkConsistency()) throw runtime_error("Resulting program from architecture altering operation is not consistent"); #endif return 2; }
int GrowTree::breed(System* system, Population* src, vector<Program>* newpop, int index) { Program* newp; newpop->push_back(Program(system)); newp=&newpop->back(); newp->functions.assign(system->adf.begin(), system->adf.end()); newp->branch.push_back(vector<TreeNode>()); // Push the main program branch on growtree(system, system->returntype, TreeNodeIter(&newp->branch[0], 0), (maxdepth<=mindepth?0:(rand()%(maxdepth-mindepth+1)))+mindepth); // Need to add ADF branches for (int i=0;i<system->adf.size();++i) newp->branch.push_back(vector<TreeNode>()); ADF* curfunc; for (int i=system->adf.size()-1;i>=0;--i) { curfunc = (ADF*)(system->adf[i]); // Remove current function from list if (system->recursiveDepth<=0) { #ifdef DEBUG if (system->functions[curfunc->arg_type[0]].back()!=curfunc) throw runtime_error("Function being popped off of system does not match last adf entry"); #endif system->functions[curfunc->arg_type[0]].pop_back(); } // Push function arguments for (int j=1;j<curfunc->arg_type.size();++j) system->functions[curfunc->arg_type[j]].push_back(curfunc->args[j-1]); // Generate tree growtree(system, curfunc->arg_type[0], TreeNodeIter(&newp->branch[i+1], 0), (maxdepth<=mindepth?0:(rand()%(maxdepth-mindepth+1)))+mindepth); // Pop function arguments for (int j=curfunc->arg_type.size()-1;j>=1;--j) { system->functions[curfunc->arg_type[j]].pop_back(); } } if (system->recursiveDepth<=0) { for (int i=0;i<system->adf.size();++i) { curfunc = (ADF*)system->adf[i]; system->functions[curfunc->arg_type[0]].push_back(curfunc); } } #ifdef DEBUG if (!newp->checkConsistency()) { throw runtime_error("Invalid produced program"); } #endif return 1; }