mutate.c

来自「Genetic Programing of music」· C语言 代码 · 共 506 行 · 第 1/2 页

C
506
字号
     {          for ( j = 0; j < tree_count; ++j )               md->tree[j] = 1.0;          md->treetotal = tree_count;     }               r = 0.0;     for ( j = 0; j < tree_count; ++j )          r = (md->tree[j] += r);#ifdef DEBUG     if ( !errors )     {          printf ( "mutation options:\n" );          printf ( "   internal: %lf  external: %lf\n", md->internal, md->external );          printf ( "   keep_trying: %d\n", md->keep_trying );          printf ( "   selection: %s\n", md->sname==NULL?"NULL":md->sname );          printf ( "   method: %d    mindepth: %d   maxdepth: %d\n",                  md->method, md->mindepth, md->maxdepth );          printf ( "   tree total: %lf\n", md->treetotal );          for ( j = 0; j < tree_count; ++j )               printf ( "   tree %d: %lf\n", j, md->tree[j] );     }#endif          return errors;}/* operator_mutate_free() * * free mutation stuff. */void operator_mutate_free ( void *data ){     mutate_data * md;     md = (mutate_data *)data;     FREE ( md->sname );     FREE ( md->tree );     FREE ( md );}/* operator_mutate_start() * * get selection context for mutation operator. */void operator_mutate_start ( population *oldpop, void *data ){     mutate_data * md;     select_context_func_ptr select_con;     md = (mutate_data *)data;     select_con = get_select_context ( md->sname );     md->sc = select_con ( SELECT_INIT, NULL, oldpop, md->sname );}/* operator_mutate_end() * * free selection context for mutation operator. */void operator_mutate_end ( void *data ){     mutate_data * md;     md = (mutate_data *)data;     md->sc->context_method ( SELECT_CLEAN, md->sc, NULL, NULL );}/* operator_mutate() * * do the mutation. */void operator_mutate ( population *oldpop, population *newpop,                      void *data ){     int i;     int ps;     lnode *replace[2];     int l, ns;     int badtree;     int repcount;     mutate_data * md;     int t;     double r;     int depth;     int totalnodes;     int p;     int forceany;     double total;          md = (mutate_data *)data;     total = md->internal + md->external;     /* choose a tree to mutate. */     r = random_double() * md->treetotal;     for ( t = 0; r >= md->tree[t]; ++t );     /* select an individual to mutate. */     p = md->sc->select_method ( md->sc );      ps = tree_nodes ( oldpop->ind[p].tr[t].data );     forceany = (ps==1||total==0.0);#ifdef DEBUG_MUTATE     fprintf ( stderr, "the parent size is %d\n", ps );     fprintf ( stderr, "    parent %4d: ", p );     print_tree ( oldpop->ind[p].tr[t].data, stderr );#endif               while(1)     {	  if ( forceany )	  {	       /* choose any point. */	       l = random_int ( ps );	       replace[0] = get_subtree ( oldpop->ind[p].tr[t].data, l );	  }	  else if ( total*random_double() < md->internal )	  {	       /* choose an internal point. */	       l = random_int ( tree_nodes_internal ( oldpop->ind[p].tr[t].data ) );	       replace[0] = get_subtree_internal ( oldpop->ind[p].tr[t].data, l );	  }	  else	  {	       /* choose an external point. */	       l = random_int ( tree_nodes_external ( oldpop->ind[p].tr[t].data ) );	       replace[0] = get_subtree_external ( oldpop->ind[p].tr[t].data, l );	  }	  #ifdef DEBUG_MUTATE          fprintf ( stderr, "selected for replacement: " );          print_tree ( replace[0], stderr );#endif          gensp_reset ( 1 );	  /* pick a value from the depth ramp. */          depth = md->mindepth + random_int ( md->maxdepth - md->mindepth + 1 );	  /* grow the tree. */          switch ( md->method )          {             case GENERATE_GROW:               generate_random_grow_tree ( 1, depth, fset+tree_map[t].fset );               break;             case GENERATE_FULL:               generate_random_full_tree ( 1, depth, fset+tree_map[t].fset );               break;             case GENERATE_HALF_AND_HALF:               if ( random_double() < 0.5 )                    generate_random_grow_tree ( 1, depth, fset+tree_map[t].fset );               else                    generate_random_full_tree ( 1, depth, fset+tree_map[t].fset );               break;          }#ifdef DEBUG_MUTATE          fprintf ( stderr, "the new subtree is: " );          print_tree ( gensp[1].data, stderr );#endif	  /* count the nodes in the new tree. */          ns = ps - tree_nodes ( replace[0] ) + tree_nodes ( gensp[1].data );          totalnodes = ns;	  /* check the mutated tree against node count and/or size limits. */          badtree = 0;          if ( tree_map[t].nodelimit > -1 && ns > tree_map[t].nodelimit )               badtree = 1;          else if ( tree_map[t].depthlimit > -1 )          {               ns = tree_depth_to_subtree ( oldpop->ind[p].tr[t].data,                                           replace[0] ) +                    tree_depth ( gensp[1].data );               if ( ns > tree_map[t].depthlimit )                    badtree = 1;          }	  /* if tree is too big and keep_trying is set, then skip to the	     stop and choose a new mutation point/mutant subtree. */          if ( md->keep_trying && badtree )               continue;	  /* check mutated tree against whole-individual node limits. */          if ( ind_nodelimit > -1 )          {               for ( i = 0; i < tree_count; ++i )                    if ( i != t )                         totalnodes += oldpop->ind[p].tr[i].nodes;               badtree |= (totalnodes > ind_nodelimit);          }	  /* if tree is too big and keep_trying is set, then skip to the	     stop and choose a new mutation point/mutant subtree. */          if ( md->keep_trying && badtree )               continue;          if ( badtree )          {#ifdef DEBUG_MUTATE               fprintf ( stderr,                        "new tree is too big; reproducing parent.\n" );#endif	       /* tree too big but keep_trying not set, just reproduce		  parent tree. */               duplicate_individual ( (newpop->ind)+newpop->next,                                     (oldpop->ind)+p );          }          else          {#ifdef DEBUG_MUTATE               fprintf ( stderr, "new tree is permissible.\n" );#endif	       /* copy the parent tree to the offspring position. */               duplicate_individual ( (newpop->ind)+newpop->next,                                     (oldpop->ind)+p );	       /* free the tree selected for mutation. */               free_tree ( newpop->ind[newpop->next].tr+t );                              /* copy the selected tree, replacing the subtree at the		  mutation point with the randomly generated tree. */               replace[1] = gensp[1].data;               copy_tree_replace_many ( 0, oldpop->ind[p].tr[t].data,                                       replace, replace+1, 1, &repcount );               if ( repcount != 1 )               {                    error ( E_FATAL_ERROR,                           "botched mutation:  this can't happen." );               }	       /* copy the tree to the new individual. */               gensp_dup_tree ( 0, newpop->ind[newpop->next].tr+t );               newpop->ind[newpop->next].evald = EVAL_CACHE_INVALID;               newpop->ind[newpop->next].flags = FLAG_NONE;               #ifdef DEBUG_MUTATE               fprintf ( stderr, "    the mutated individual is: " );               print_individual ( newpop->ind+newpop->next, stderr );#endif          }          ++newpop->next;          break;     }#ifdef DEBUG_MUTATE     printf ( "MUTATION COMPLETE.\n\n\n" );#endif}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?