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 + -
显示快捷键?