📄 chrome.cxx
字号:
retval Chrome::evalAll() // eval the whole expression anew#endif{#ifndef FASTEVAL#ifdef MULTREE ip=tree_starts[tree]-1;#else ip=-1;#endif return eval();#else #ifdef MULTREE IP=fast_tree_starts[tree];#else IP=ExprGlobal;#endif //cout<<"FUNC="<< IP->op; return (IP->ef)();#endif}void Chrome::SetupEval(const int tree /*= -1*/){#ifdef FASTEVAL // expand stack into evalnodes in global eval stack int args; evalnode* ip=ExprGlobal;#ifdef MULTREE node* spp; int start; int end; if(tree==-1) { spp=expr; start = 0; end = NUM_TREES;} else { spp=expr+tree_starts[tree]; start = tree; end = tree+1;} for (int t = start; t < end; t++ ){ fast_tree_starts[t] = ip;#else node* spp=expr;?#endif args=1; while (args > 0) { SETEVALNODE(ip,spp->op,spp->idx); args=args+PARGNUM(spp)-1; ip++; spp++; } if(tree!=-1) { ip->op = 0; //clear next opcode Beware array bounds //and set other pointers for(t = 0; t<NUM_TREES; t++) { if(t!=tree) fast_tree_starts[t] = ip;} } // set global eval pointers#ifdef MULTREE }//end for each tree#endif ChromeGlobal=this;#endif}#ifdef MULTREEvoid Chrome::SubInit(CSelector* funcbag, int argstogo, int depth, int isfull, BOOL isstart, int tree)#elsevoid Chrome::SubInit(CSelector* funcbag, int argstogo,int depth,int isfull, BOOL isstart) // Initialize a subtree half full#endif{//cout <<"SubInit( " << argstogo << ", " << depth << ", " << isfull <<//", " << isstart << " )\n"; int i; int maxargs,thisargs;//calculate max number of args there is space to add. maxargs = params->params[pMaxExpr] -(ip+argstogo); assert(maxargs>=0); //can sometimes trip this WBL #ifdef MULTREE {int m = params->params[pMaxTreeExpr]-(ip-tree_starts[tree]+argstogo); if((m>=0) && (m<maxargs)) maxargs = m; }#endif//cout <<"SubInit Calling roulette() 1\n"; i=funcbag->roulette();//cout <<"SubInit roulette() 1, returned "<<i<<endl; // terminal required if (maxargs == 0 || depth == 0 ) while (funclist[i]->argnum>0) i=funcbag->roulette(); // node required else if (isfull || isstart) //support for MULTREE if (maxargs > 5) while (funclist[i]->argnum == 0) i=funcbag->roulette(); else // not enough room. // Take what you can get. // NB may cause prog to loop WBL // Hence added assert 25/8/94WBL while (funclist[i]->argnum>maxargs) i=funcbag->roulette(); // terminal allowed 50% of the time else if (rnd(2)) // terminal required while (funclist[i]->argnum>0) i=funcbag->roulette(); else // node required if (maxargs > 5) while (funclist[i]->argnum == 0) i=funcbag->roulette(); else // not enough room. Take what you can get. while (funclist[i]->argnum>maxargs)i=funcbag->roulette(); if (funclist[i]->varnum == 0) {SETNODE(expr[ip],i,0);} //WBL bug fix 001 12-May-94 else {SETNODE(expr[ip],i,rnd(funclist[i]->varnum));} ip++; thisargs=funclist[i]->argnum; argstogo += funclist[i]->argnum-1; for (i=0;i<thisargs;i++) {#ifdef MULTREE SubInit(funcbag,argstogo,depth-1,isfull, FALSE, tree);#else SubInit(funcbag,argstogo,depth-1,isfull, FALSE);#endif argstogo--; }//cout <<"ENDSubI( " << argstogo << ", " << depth << ", " << isfull << //", " << isstart << " )\n";}void Chrome::Traverse() { // skip the next expression int args = 1; while (args > 0) { args=args+ARGNUM()-1; ip++; }}void Chrome::TraverseGlobal() { // skip the next expression int args = 1; while (args > 0) { args=args+PARGNUM(IP)-1; IP++; }}int Chrome::Depth(int ip, int end) //Relative depth of end from ip{ //assume end>=start// int tree_stack[end-ip+2]; int tree_stack [EXPRLEN]; tree_stack[0] = -1; int sp = 0; while (ip<=end) { while (tree_stack[sp] == 0) { //remove finished branches tree_stack[--sp] -= 1; } tree_stack[++sp] = ARGNUM(); ip++; } return sp;}//end Depthint Chrome::DepthMax(int ip, int end) //Max Relative depth { //assume end>=start// int tree_stack[end-ip+2]; int tree_stack[EXPRLEN]; tree_stack[0] = -1; int sp = 0; int max = 0; while (ip<=end) { while (tree_stack[sp] == 0) { //remove finished branches tree_stack[--sp] -= 1; } tree_stack[++sp] = ARGNUM(); if(sp>max) max = sp; ip++; } return max;}//end DepthMax // Write the next subexpression to a stream // pretty flag controls parentheses, indenting // PRETTY_NONE = no indenting, just a stream, with parens // PRETTY_NOPARENS = indented, one function per line, no parens // PRETTY_PARENS = indented, one function per line, parensvoid Chrome::SubWrite(ostream& ostr,int pretty, int depth) { int args,i; ip++; args = ARGNUM(); if (pretty) // indent? { ostr<<endl; for (i=0;i<depth;i++){ ostr << " : "; } } else ostr << ' '; if (args>0) { // write (FUNC args) if (pretty != PRETTY_NOPARENS) ostr << '('; ostr << funclist[FUNCNUM(expr[ip])]->getprint(this) <<flush; depth++; while (args-- > 0) SubWrite(ostr,pretty,depth); depth--; if (pretty != PRETTY_NOPARENS) ostr << ")"; } else { // write an atom ostr << funclist[FUNCNUM(expr[ip])]->getprint(this) <<flush; }}#ifdef MULTREEChrome* Chrome::CrossTree(Chrome* mate, int tree ) //work on one tree only#elseChrome* Chrome::CrossTree(Chrome* mate)#endif// Return a new Chrome that is a cross with mate{//debug//cout<<"\nSTART CrossTree, this=";//this->write(PRETTY_NONE,cout);//cout<<"\nCrossTree, mate=";//mate->write(PRETTY_NONE,cout); Chrome* newexpr = new Chrome(params,probl,funclist,constlist,FALSE);#ifdef STACK_LIB tree = rnd(NUM_TREES); //work on one tree only#endif#ifdef TRACE num_children++; newexpr->mum.birth = birth;#endif newexpr->nfitness->Copy(this->nfitness); //to suuport STORE_FIT //load of stuff done by Dup but dont need as also done by new Chrome() newexpr->ip=0;#ifdef TRACE mate->num_children++; //this incremented by Copy()#endif int thislen; // total length of expression int thissubptr; // pointer to subexpression int thissublen; int matelen; int matesubptr; int matesublen;#ifdef MULTREE thislen=tree_starts[NUM_TREES-1] + SubLen(tree_starts[NUM_TREES-1]); matelen=mate->tree_starts[NUM_TREES-1] + mate->SubLen(mate->tree_starts[NUM_TREES-1]);#else thislen=SubLen(0); matelen=mate->SubLen(0);#endif#ifdef MULTREE#ifndef STACK_LIB do { //while static_check says not ok#endif#endif if (rnd(101)>params->params[pUnRestrictWt]) //should this be 100<?? {#ifdef MULTREE thissubptr=GetIntNode(tree); matesubptr=mate->GetIntNode(tree);#else thissubptr=GetIntNode(); matesubptr=mate->GetIntNode();#endif } else {#ifdef MULTREE thissubptr=GetAnyNode(tree); matesubptr=mate->GetAnyNode(tree);#else thissubptr=GetAnyNode(); matesubptr=mate->GetAnyNode();#endif } thissublen = SubLen(thissubptr); matesublen=mate->SubLen(matesubptr);//cout<<"\ntree="<<tree;//cout<<" thislen="<<thislen<<" matelen="<<matelen;//cout<<" thissubptr="<<thissubptr<<" thissublen="<<thissublen;//cout<<" matesubptr="<<matesubptr<<" matesublen="<<matesublen<<endl;#ifdef CROSSFILE if(crossfile) { crossfile<<"cross "<<tree<<" "; crossfile<<"mum "; crossfile<<this->birth<<" "; crossfile<<this->nfitness->fvalue<<" "; crossfile<<thislen<<" "; //size of program crossfile<<SubLen(this->tree_starts[tree])<<" "; //size of tree crossfile<<thissubptr<<" "; //root of crossover point crossfile<<thissublen<<" "; //size of crossover tree crossfile<<Depth(tree_starts[tree],thissubptr)<<" "<<flush; //depth of crossover point crossfile<<DepthMax(thissubptr,thissubptr+thissublen-1)<<" "; //depth of crossover fragment crossfile<<"dad "<<flush; crossfile<<mate->birth<<" "; crossfile<<mate->nfitness->fvalue<<" "; crossfile<<matelen<<" "; //size of program crossfile<<mate->SubLen(mate->tree_starts[tree])<<" "; crossfile<<matesubptr<<" "; //root of crossover point crossfile<<matesublen<<" "; //size of crossover tree crossfile<<mate->Depth(mate->tree_starts[tree],matesubptr)<<" "; //depth of crossover point crossfile<<mate->DepthMax(matesubptr,matesubptr+matesublen-1) <<" "<<flush; //depth of crossover fragment }#endif if(((params->params[pMaxDepth] != 0) && ((Depth(tree_starts[tree],thissubptr) + mate->DepthMax(matesubptr,matesubptr+matesublen-1)) -1 > params->params[pMaxDepth])) || (thislen+matesublen-thissublen >params->params[pMaxExpr])){ // take smaller side of swap assert(matelen+thissublen-matesublen<=params->params[pMaxExpr]);#ifdef CROSSFILE if(crossfile) crossfile<< ", 1 ";#endif memcpy(newexpr->expr,mate->expr,matesubptr*sizeof(node)); memcpy(&(newexpr->expr[matesubptr]),&(expr[thissubptr]),thissublen*sizeof(node)); memcpy(&(newexpr->expr[matesubptr+thissublen]),&(mate->expr[matesubptr+matesublen]),(matelen-(matesubptr+matesublen))*sizeof(node));#ifdef MULTREE memcpy(newexpr->tree_starts,mate->tree_starts,(tree+1)*sizeof(tree_starts[0])); for (int i=tree+1; i<NUM_TREES; i++) {newexpr->tree_starts[i] = mate->tree_starts[i] - matesublen + thissublen;}#endif#ifdef TRACE newexpr->mum.birth = mate->birth; newexpr->mum.xpoint = matesubptr;#ifdef MULTREE newexpr->mum.xtree = tree;#endif newexpr->dad.birth = birth; newexpr->dad.xpoint = thissubptr;#ifdef MULTREE newexpr->dad.xtree = tree;#endif#endif } else {#ifdef CROSSFILE if(crossfile) crossfile<< ", 0 ";#endif memcpy(newexpr->expr,expr,thissubptr*sizeof(node)); memcpy(&(newexpr->expr[thissubptr]),&(mate->expr[matesubptr]),matesublen*sizeof(node)); memcpy(&(newexpr->expr[thissubptr+matesublen]),&(expr[thissubptr+thissublen]),(thislen-(thissubptr+thissublen))*sizeof(node));#ifdef MULTREE memcpy(newexpr->tree_starts,tree_starts,(tree+1)*sizeof(tree_starts[0])); for (int i=tree+1; i<NUM_TREES; i++) {newexpr->tree_starts[i] = tree_starts[i] + matesublen - thissublen;}#endif#ifdef TRACE newexpr->mum.birth = birth; newexpr->mum.xpoint = thissubptr;#ifdef MULTREE newexpr->mum.xtree = tree;#endif newexpr->dad.birth = mate->birth; newexpr->dad.xpoint = matesubptr;#ifdef MULTREE newexpr->dad.xtree = tree;#endif#endif }#ifdef MULTREE#ifndef STACK_LIB }while (probl->static_check(newexpr,tree)>rnd(100));#endif#endif#ifdef CROSSFILEif(crossfile) {crossfile<<same(newexpr); //same as mum?crossfile<<" ";crossfile<<mate->same(newexpr); //same as dad?crossfile<<" ";crossfile<<same(mate); //mum same as dad?crossfile<<" ";}#endif//cout<<"CrossTree, newexpr=";//newexpr->write(PRETTY_NONE,cout);//cout<<endl; return newexpr;}#ifdef MULTREEint Chrome::GetAnyNode(int tree) // get a node for crossover{ return tree_starts[tree] + rnd(SubLen(tree_starts[tree]));}#elseint Chrome::GetAnyNode() // get a node for crossover{ return rnd(SubLen(0));}#endif#ifdef MULTREEint Chrome::GetIntNode(int tree) // get an internal node for crossover{ int rval; int l=SubLen(tree_starts[tree]); if (l>2) { rval=tree_starts[tree] + rnd(l); while (funclist[FUNCNUM(expr[rval])]->argnum <1) rval=tree_starts[tree] + rnd(l); } else rval=tree_starts[tree];#elseint Chrome::GetIntNode() // get an internal node for crossover{ int rval;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -