⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 crossovr.c

📁 Genetic Programing of music
💻 C
📖 第 1 页 / 共 2 页
字号:
          cd->sc2->context_method ( SELECT_CLEAN, cd->sc2, NULL, NULL );}/* operator_crossover() * * performs the crossover, inserting one or both offspring into the * new population. */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     }

⌨️ 快捷键说明

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