//HJJA
population *change_population ( population *oldpop, breedphase *bp )
{
     population *newpop;
     int i, j;
     int numphases;
     double totalrate = 0.0;
     double r, r2;
     int prob_oper = atoi ( get_parameter ( "probabilistic_operators" ) );

     /* allocate the new population. */
     newpop = allocate_population ( oldpop->size );

	globaldata* g = get_globaldata();//get the lists

	if(g->bUseHFC){
		if( IsHighestActiveLevel(g->current_population)){
			 /*reproduce best guys into the new population. */
 			for(i=0;i<run_stats[0].bestn;i++){
				//printf("best %d ind\n", i);
				 duplicate_individual ( (newpop->ind)+newpop->next, run_stats[0].best[i]->ind);
				 newpop->ind[newpop->next].flags = FLAG_NONE;
				 ++(newpop->next);

				//HJJS  structure niching: mutation
				//Assumption: we think any structure mutation will create a new structure
				//for numeric mutation, we won't change the structure
				CStruct* pSt;

				int structID = newpop->ind[newpop->next].structID;
				pSt = g->pStructHash->find(structID);

				if(pSt==NULL){ //make sure,though redudency code
					  pSt = new CStruct();
					  pSt->structID = ++(g->currMaxStructID);
					  pSt->age=1;
					  pSt->lastGen=g->current_generation+1;
					  pSt->nIndividuals=0;
					  pSt->nIndNextGen=1;
					  newpop->ind[newpop->next].structID=pSt->structID;
					  g->pStructHash->insert(pSt);
				}
				else{
					if(pSt->lastGen != g->current_generation+1){//the first individual in this generation
					   pSt->age++;
					   pSt->lastGen = g->current_generation+1;
					}
					pSt->nIndNextGen++;//increase the ind no of this population
				}
				//HJJS end
			}
		}
		 //End HJJ_ELITISM

	}//End useHFC


     /* the first element of the breedphase table is a dummy -- its
				operator field stores the number of phases. */
     numphases = bp[0].operatorID;

     /* call the start method for each phase. */
     for ( i = 1; i <= numphases; ++i )
     {
          totalrate += bp[i].rate;
          if ( bp[i].operator_start )
               bp[i].operator_start ( oldpop, bp[i].data );
     }

     /* now fill the new population. */
     while ( newpop->next < newpop->size )
     {

	  /** select an operator, either stochastically or not depending on
	    the probabilistic_operators parameter. **/
          if ( prob_oper )
               r = totalrate * random_double();
          else
               r = totalrate * ((double)newpop->next/(double)newpop->size);

          r2 = bp[1].rate;
          for ( i = 1; r2 < r; )
               r2 += bp[++i].rate;
#ifdef DEBUG
          fprintf ( stderr, "picked %10.3lf; operator %d\n", r, i );
#endif


	  /* call the phase's method to do the operation. */
          if ( bp[i].operator_operate ){
               bp[i].operator_operate ( oldpop, newpop, bp[i].data );
		  }
     }

     /* call each phase's method to do cleanup. */
     for ( i = 1; i <= numphases; ++i )
     {

          if ( bp[i].operator_end )
               bp[i].operator_end ( bp[i].data );
     }

     /* mark all the ERCs referenced in the new population. */
     for ( i = 0; i < newpop->size; ++i )
          for ( j = 0; j < tree_count; ++j )
               reference_ephem_constants ( newpop->ind[i].tr[j].data, 1 );


     /* free the old population. */
     free_population ( oldpop );  //Bug when do reproduction ?


     return ( newpop );
     
}
/* operator_mutate_erc()
 *
 * do the mutation.
 */
void operator_mutate_erc ( population *oldpop, population *newpop,
                      void *data )
{
			int i;
			int ps;
			mutate_erc_data * md;
			int t;
			double r;
			int p;
			int count=0;

			md = (mutate_erc_data *)data;

			/* choose a tree to mutate. */
			//t: the tTH tree of the individual
			r = random_double() * md->treetotal;
			for ( t = 0; r >= md->tree[t]; ++t );

			/* select an individual to mutate. */
			//p:  parent invidualIP
			//ps: parent tree size
			p = md->sc->select_method ( md->sc ); 
			ps = tree_nodes ( oldpop->ind[p].tr[t].data );

			vector<lnode*> ParamNodeList;		//the root nodes of all numeric subtree
			vector<lnode*> MutatedParamNodelist;////the root nodes of all numeric subtree to be mutated
			vector<lnode*> ERCNodelist;			//ERC nodelist for a subtree

			get_subtree_parameter_list(oldpop->ind[p].tr[t].data, &ParamNodeList);

			//decide which parameters needs to be mutated
			int nParam = ParamNodeList.size();

			if (nParam >= 1){
				int nParamMutated = nParam * md->var_percent;
				//at least we mutate one parameter!
				if (nParamMutated<1) nParamMutated = 1;

				//we randomly select nParamMutated parameters to be mutated. 
				//we allow duplicate selection of parameters.
				for(i=0;i<nParamMutated;i++){
					int vi = random_int (nParam);
					MutatedParamNodelist.push_back(ParamNodeList[vi]);
				}

				//for each parameter subtree, we randomly selection a portion of 
				//its ERCs and mutate them.
				for(i=0;i<nParamMutated;i++){
								ERCNodelist.clear();
								lnode* pNode = MutatedParamNodelist[i];
								/*	there are too possiblility
										1: the root node of numeric subtree is a ERC itself.
										2: it is a internal node*/

								if( pNode->f->type == TERM_ERC){
										//we mutate a ERC by ERC+ 5%ERC* N(0,1)
										++pNode; //HJJ!!!!!! The next node of pNode->f is the ERC node!

										double value = pNode->d->d;
										pNode->d->d = value * (0.05* gauss_dist()+1); 
										#ifdef DEBUG_ERC_MUTATE 
											printf("ERC  init_value = %f   new value = %f\n", value, pNode->d->d);
										#endif
								}
								else{
										int tSize = tree_nodes(pNode);
										get_tree_nodes_ERC(pNode,tSize-1, &ERCNodelist);
					
										//decide how many ERCs of this subtree is to be mutated.
										int nERC = ERCNodelist.size();
										
										if (nERC<1) continue;	//no ERC in this subtree. Is this possible?
										int nERCmut= nERC * md->erc_percent;
										if (nERCmut <1) nERCmut=1; //at least mutate one ERC
										
										for(int j=0;j<nERCmut;j++){
												lnode* pNode = ERCNodelist[ random_int(nERC)];
												//we mutate a ERC by ERC+ 5%ERC* N(0,1)
												++pNode;
												double value = pNode->d->d;
												pNode->d->d = value * (0.05* gauss_dist()+1); 
												#ifdef DEBUG_ERC_MUTATE 
													printf("ERC  init_value = %f   new value = %f\n", value, pNode->d->d);
												#endif
										}
								}//end else
				}

			}//end parameter mutation



			//Now copy the mutated individual to the new population
			/* ...and reproduce it into the new population. */
			duplicate_individual ( (newpop->ind)+newpop->next, (oldpop->ind)+p );
			newpop->ind[newpop->next].flags = FLAG_NONE;


			//HJJS  structure niching: mutation
			//Assumption: we think any structure mutation will create a new structure
			//for numeric mutation, we won't change the structure
			globaldata* g = get_globaldata();
			CStruct* pSt;

			int structID = newpop->ind[newpop->next].structID;
			pSt = g->pStructHash->find(structID);

			if(pSt==NULL){ //make sure,though redudency code
				pSt = new CStruct();
				pSt->structID = ++(g->currMaxStructID);
				pSt->age=1;
				pSt->lastGen=g->current_generation+1;
				pSt->nIndividuals=0;
				pSt->nIndNextGen=1;
				newpop->ind[newpop->next].structID=pSt->structID;
				g->pStructHash->insert(pSt);
			}
			else{
			if(pSt->lastGen != g->current_generation+1){//the first individual in this generation
				 pSt->age++;
				 pSt->lastGen = g->current_generation+1;
			}
			pSt->nIndNextGen++;//increase the ind no of this population
			}
			//HJJS end	 

			++newpop->next;

			#ifdef DEBUG_ERC_MUTATE
				 printf ( "ERC MUTATION COMPLETE.\n\n\n" );
			#endif
}
Esempio n. 3
0
void calculate_pop_stats(popstats *s, population *pop, int gen, int subpop) {
	int i, j, k, l;
	int b;
	saved_ind *shp;
	individual **temp;

	/* allocate a list of the top N individuals. */
	s->best = (saved_ind **) MALLOC(s->bestn * sizeof(saved_ind *));
	temp = (individual **) MALLOC((s->bestn + 1) * sizeof(individual *));

	s->size = pop->size;

	/** this is all pretty obvious -- set all the max and min values to the
	 first individual's values, then go through the population looking for
	 things that are bigger/smaller/better/worse/etc. **/

	s->maxnodes = s->minnodes = s->totalnodes = s->bestnodes = s->worstnodes =
			individual_size(pop->ind + 0);
	s->maxdepth = s->mindepth = s->totaldepth = s->bestdepth = s->worstdepth =
			individual_depth(pop->ind + 0);
	s->maxhits = s->minhits = s->totalhits = s->besthits = s->worsthits =
			pop->ind[0].hits;
	s->bestfit = s->worstfit = s->totalfit = pop->ind[0].a_fitness;
	temp[0] = pop->ind;
	b = 1;
	s->bestgen = s->worstgen = gen;
	s->bestpop = s->worstpop = subpop;

	for (i = 1; i < s->size; ++i) {
		j = individual_size(pop->ind + i);
		s->totalnodes += j;
		if (j < s->minnodes)
			s->minnodes = j;
		if (j > s->maxnodes)
			s->maxnodes = j;

		k = individual_depth(pop->ind + i);
		s->totaldepth += k;
		if (k < s->mindepth)
			s->mindepth = k;
		if (k > s->maxdepth)
			s->maxdepth = k;

		l = pop->ind[i].hits;
		s->totalhits += l;
		if (l < s->minhits)
			s->minhits = l;
		if (l > s->maxhits)
			s->maxhits = l;

		s->totalfit += pop->ind[i].a_fitness;
		if (pop->ind[i].a_fitness > s->bestfit) {
			s->bestfit = pop->ind[i].a_fitness;
			s->bestnodes = j;
			s->bestdepth = k;
			s->besthits = l;
		} else if (pop->ind[i].a_fitness < s->worstfit) {
			s->worstfit = pop->ind[i].a_fitness;
			s->worstnodes = j;
			s->worstdepth = k;
			s->worsthits = l;
		}

		/** insert the current individual into the top N list
		 (if it belongs there). **/

		for (j = b; j > 0; --j) {
			if (pop->ind[i].a_fitness < temp[j - 1]->a_fitness)
				break;
			temp[j] = temp[j - 1];
		}
		if (j < s->bestn)
			temp[j] = pop->ind + i;
		if (b < s->bestn)
			++b;
	}

	/** now save copies of the individuals in the "temp" list **/
	for (i = 0; i < b; ++i) {
		shp = (saved_ind *) MALLOC(sizeof(saved_ind));
		shp->ind = (individual *) MALLOC(sizeof(individual));
		shp->ind->tr = (tree *) MALLOC(tree_count * sizeof(tree));
		duplicate_individual(shp->ind, temp[i]);
		for (j = 0; j < tree_count; ++j)
			reference_ephem_constants(shp->ind->tr[j].data, 1);
		shp->refcount = 1;
		shp->next = NULL;

		saved_tail->next = shp;
		saved_tail = shp;
		++saved_head->refcount;

		s->best[i] = shp;
	}

#ifdef DEBUG
	printf ( "the best list is:\n" );
	for ( j = 0; j < s->bestn; ++j )
	printf ( "     %08x  %lf\n", s->best[j], s->best[j]->ind->a_fitness );
#endif

	FREE(temp);

}
Esempio n. 4
0
void operator_crossover ( population *oldpop, population *newpop,
                         void *data )
{
     crossover_data * cd;
     int p1, p2;
     int ps1, ps2;
     int l1, l2;
     lnode *st[3];
     int sts1, sts2;
     int ns1, ns2;
     int badtree1, badtree2;
     double total;
     int forceany1, forceany2;
     int repcount;
     int f, t1, t2, j;
     double r, r2;
     int totalnodes1, totalnodes2;
     int i;

     /* get the crossover-specific data structure. */
     cd = (crossover_data *)data;
     total = cd->internal + cd->external;

     /* choose a function set. */
     r = random_double() * cd->treetotal;
     for ( f = 0; r >= cd->func[f]; ++f );

     /* fill in the "treecumul" array, zeroing all trees which
	don't use the selected function set. */
     r = 0.0;
     t1 = 0;
     for ( j = 0; j < tree_count; ++j )
     {
          if ( tree_map[j].fset == f )
               r = (cd->treecumul[j] = r + cd->tree[j]);
          else
               cd->treecumul[j] = r;
     }

     /* select the first and second trees. */
     r2 = random_double() * r;
     for ( t1 = 0; r2 >= cd->treecumul[t1]; ++t1 );
     r2 = random_double() * r;
     for ( t2 = 0; r2 >= cd->treecumul[t2]; ++t2 );

#ifdef DEBUG_CROSSOVER
     printf ( "selected function set %d --> t1: %d; t2: %d\n", f, t1, t2 );
#endif
     
     /* choose two parents */
     p1 = cd->sc->select_method ( cd->sc );
     ps1 = oldpop->ind[p1].tr[t1].nodes;
     /* if the tree only has one node, we obviously can't do
	fucntionpoint crossover.  use anypoint instead. */
     forceany1 = (ps1==1||total==0.0);
     
     p2 = cd->sc2->select_method ( cd->sc2 );
     ps2 = oldpop->ind[p2].tr[t2].nodes;
     forceany2 = (ps2==1||total==0.0);

#ifdef DEBUG_CROSSOVER
     fprintf ( stderr, "parent 1 is:\n" );
     print_individual ( oldpop->ind+p1, stderr );
     fprintf ( stderr, "parent 2 is:\n" );
     print_individual ( oldpop->ind+p2, stderr );
#endif

     while(1)
     {
          
          /* choose two crossover points */

          if ( forceany1 )
          {
	       /* choose any point. */
               l1 = random_int ( ps1 );
               st[1] = get_subtree ( oldpop->ind[p1].tr[t1].data, l1 );
          }
          else if ( total*random_double() < cd->internal )
          {
	       /* choose an internal point. */
               l1 = random_int ( tree_nodes_internal (oldpop->ind[p1].tr[t1].data) );
               st[1] = get_subtree_internal ( oldpop->ind[p1].tr[t1].data, l1 );
          }
          else
          {
	       /* choose an external point. */
               l1 = random_int ( tree_nodes_external (oldpop->ind[p1].tr[t1].data) );
               st[1] = get_subtree_external ( oldpop->ind[p1].tr[t1].data, l1 );
          }
                                
          if ( forceany2 )
          {
	       /* choose any point on second parent. */
               l2 = random_int ( ps2 );
               st[2] = get_subtree ( oldpop->ind[p2].tr[t2].data, l2 );
          }
          else if ( total*random_double() < cd->internal )
          {
	       /* choose internal point. */
               l2 = random_int ( tree_nodes_internal (oldpop->ind[p2].tr[t2].data) );
               st[2] = get_subtree_internal ( oldpop->ind[p2].tr[t2].data, l2 );
          }
          else
          {
	       /* choose external point. */
               l2 = random_int ( tree_nodes_external (oldpop->ind[p2].tr[t2].data) );
               st[2] = get_subtree_external ( oldpop->ind[p2].tr[t2].data, l2 );
          }

#ifdef DEBUG_CROSSOVER
          printf ( "subtree 1 is: " );
          print_tree ( st[1], stdout );
          printf ( "subtree 2 is: " );
          print_tree ( st[2], stdout );
#endif

	  /* count the nodes in the selected subtrees. */
          sts1 = tree_nodes ( st[1] );
          sts2 = tree_nodes ( st[2] );

	  /* calculate the sizes of the offspring. */
          ns1 = ps1 - sts1 + sts2;
          ns2 = ps2 - sts2 + sts1;

          totalnodes1 = ns1;
          totalnodes2 = ns2;

#ifdef DEBUG_CROSSOVER
          printf ( "newtree 1 has size %d; limit is %d\n",
                  ns1, tree_map[t1].nodelimit );
#endif

	  /** validate the first offspring against the tree node and depth
	    limits; set "badtree1" if any are violated. **/
	  
          badtree1 = 0;
          if ( tree_map[t1].nodelimit > -1 && ns1 > tree_map[t1].nodelimit )
               badtree1 = 1;
          else if ( tree_map[t1].depthlimit > -1 )
          {
               ns1 = tree_depth_to_subtree ( oldpop->ind[p1].tr[t1].data, st[1] ) +
                     tree_depth ( st[2] );
#ifdef DEBUG_CROSSOVER
               printf ( "newtree 1 has depth %d; limit is %d\n",
                       ns1, tree_map[t1].depthlimit );
#endif
               if ( ns1 > tree_map[t1].depthlimit )
                    badtree1 = 1;
          }

	  /* if we're supposed to keep trying, skip up and choose new crossover
	     points. */
          if ( cd->keep_trying && badtree1 )
               continue;

	  /** validate the second offspring against the tree node and depth
	    limits; set "badtree2" if any are violated. **/
	  
          badtree2 = 0;
          if ( tree_map[t2].nodelimit > -1 && ns2 > tree_map[t2].nodelimit )
               badtree2 = 1;
          else if ( tree_map[t2].depthlimit > -1 )
          {
               ns2 = tree_depth_to_subtree ( oldpop->ind[p2].tr[t2].data, st[2] ) +
                     tree_depth ( st[1] );
               if ( ns2 > tree_map[t2].depthlimit )
                    badtree2 = 1;
          }

	  /* if we're supposed to keep trying, skip up and choose new crossover
	     points. */
	  
          if ( cd->keep_trying && badtree2 )
               continue;

	  /* check both offspring against the individual node limits, set
	     badtree1 and/or badtree2 if either is too big. */
	  
          if ( ind_nodelimit > -1 )
          {
               for ( i = 0; i < tree_count; ++i )
               {
                    if ( i != t1 )
                         totalnodes1 += oldpop->ind[p1].tr[i].nodes;
                    if ( i != t2 )
                         totalnodes2 += oldpop->ind[p2].tr[i].nodes;
               }
               badtree1 |= (totalnodes1 > ind_nodelimit);
               badtree2 |= (totalnodes2 > ind_nodelimit);
#ifdef DEBUG_CROSSOVER
               printf ( "newind 1 has %d nodes; limit is %d\n",
                       totalnodes1, ind_nodelimit );
#endif
          }

	  /* choose new crossover points if either tree is too big. */
          if ( cd->keep_trying && (badtree1 || badtree2) )
               continue;
          
          /* copy the first parent to the first offspring position */
          duplicate_individual ( newpop->ind+newpop->next,
                                oldpop->ind+p1 );
          if ( !badtree1 )
          {
	       /* if the first offspring is allowable... */
	       
#ifdef DEBUG_CROSSOVER
               fprintf ( stderr, "offspring 1 is allowable.\n" );
#endif
	       
	       /* make a copy of the crossover tree, replacing the
		  selected subtree with the crossed-over subtree. */
               copy_tree_replace_many ( 0, oldpop->ind[p1].tr[t1].data,
                                       st+1, st+2, 1, &repcount );
               if ( repcount != 1 )
               {
		    /* this can't happen, but check anyway. */
                    error ( E_FATAL_ERROR,
                           "botched crossover:  this can't happen" );
               }

               /* free the appropriate tree of the new individual */
               free_tree ( newpop->ind[newpop->next].tr+t1 );
               /* copy the crossovered tree to the freed space */
               gensp_dup_tree ( 0, newpop->ind[newpop->next].tr+t1 );

	       /* the new individual's fitness fields are of course invalid. */
               newpop->ind[newpop->next].evald = EVAL_CACHE_INVALID;
               newpop->ind[newpop->next].flags = FLAG_NONE;
          }
          else
          {
	       /* offspring too big but keep_trying not set, just leave the copied
		  parent 1 in the offspring position. */
#ifdef DEBUG_CROSSOVER
               fprintf ( stderr, "offspring 1 is too big; copying parent 1.\n" );
#endif
          }

	  /* we've just filled in one member of the new population. */
          ++newpop->next;
          
#ifdef DEBUG_CROSSOVER
          fprintf ( stderr, "offspring 1:" );
          if ( newpop->ind[newpop->next-1].evald == EVAL_CACHE_VALID )
               fprintf ( stderr, "  (valid)\n" );
          else
               fprintf ( stderr, "  (invalid)\n" );
          print_individual ( newpop->ind+(newpop->next-1), stderr );
#endif          

	  /* if the new population needs another member (it's not full) */
          if ( newpop->next < newpop->size )
          {
	       /* copy the second parent to the second offspring position. */
               duplicate_individual ( newpop->ind+newpop->next,
                                     oldpop->ind+p2 );
               if ( !badtree2 )
               {
		    /* if the second offspring is allowable... */
#ifdef DEBUG_CROSSOVER
                    fprintf ( stderr, "offspring 2 is allowable.\n" );
#endif
		    /* then make a copy of the tree, replacing the crossover
		       subtree. */
                    copy_tree_replace_many ( 0, oldpop->ind[p2].tr[t2].data,
                                            st+2, st+1, 1, &repcount );
                    if ( repcount != 1 )
                    {
                         error ( E_FATAL_ERROR,
                                "bad crossover:  this can't happen" );
                    }

		    /* free the old tree in the new individual, and replace
		       it with the crossover tree. */
                    free_tree ( newpop->ind[newpop->next].tr+t2 );
                    gensp_dup_tree ( 0, newpop->ind[newpop->next].tr+t2 );
                    
                    newpop->ind[newpop->next].evald = EVAL_CACHE_INVALID;
                    newpop->ind[newpop->next].flags = FLAG_NONE;
               }
               else
               {
		    /* offspring too big but keep_trying not set; just leave
		       the copy of parent 2 where it is. */
#ifdef DEBUG_CROSSOVER
                    fprintf ( stderr, "offspring 2 is big; copying parent 2.\n" );
#endif
               }
               
               ++newpop->next;
               
#ifdef DEBUG_CROSSOVER
               fprintf ( stderr, "offspring 2:" );
               if ( newpop->ind[newpop->next-1].evald == EVAL_CACHE_VALID )
                    fprintf ( stderr, "  (valid)\n" );
               else
                    fprintf ( stderr, "  (invalid)\n" );
               print_individual ( newpop->ind+(newpop->next-1), stderr );
#endif          
          
          }
#ifdef DEBUG_CROSSOVER
          else
          {
	       /* the first offspring filled the population, discard the
		  second. */
               fprintf ( stderr, "offspring 2 not needed.\n\n" );
          }
#endif

          break;
     }

#ifdef DEBUG_CROSSOVER
     printf ( "CROSSOVER COMPLETE.\n\n\n" );
#endif
     
}