📄 crossovr.c
字号:
/* lil-gp Genetic Programming System, version 1.0, 11 July 1995 * Copyright (C) 1995 Michigan State University * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Douglas Zongker (zongker@isl.cps.msu.edu) * Dr. Bill Punch (punch@isl.cps.msu.edu) * * Computer Science Department * A-714 Wells Hall * Michigan State University * East Lansing, Michigan 48824 * USA * */#include <lilgp.h>typedef struct{ int keep_trying; double internal; double external; double *tree; /* probability that a given tree will be selected for crossover. */ double *treecumul; /* running sum of "tree" field. */ double treetotal; /* total of all tree fields. */ double *func; /* probability that a given function set will be selected for crossover. */ char *sname; sel_context *sc; char *sname2; sel_context *sc2;} crossover_data;/* operator_crossver_init() * * called to parse crossover options and initialize one record * of a breedphase table appropriately. */int operator_crossover_init ( char *options, breedphase *bp ){ int errors = 0; crossover_data *cd; int i, j, k, m; double r; char **argv, **targv; int internalset = 0, externalset = 0; char *cp; cd = (crossover_data *)MALLOC ( sizeof ( crossover_data ) ); /* place values into the breedphase table record. */ bp->operator = OPERATOR_CROSSOVER; bp->data = (void *)cd; bp->operator_free = operator_crossover_free; bp->operator_start = operator_crossover_start; bp->operator_end = operator_crossover_end; bp->operator_operate = operator_crossover; /* default values for all the crossover options. */ cd->keep_trying = 0; cd->internal = 0.9; cd->external = 0.1; cd->tree = (double *)MALLOC ( tree_count * sizeof ( double ) ); cd->treecumul = (double *)MALLOC ( tree_count * sizeof ( double ) ); for ( j = 0; j < tree_count; ++j ) cd->tree[j] = 0.0; cd->treetotal = 0.0; cd->func = (double *)MALLOC ( fset_count * sizeof ( double ) ); cd->sname = NULL; cd->sname2 = NULL; /* break the options string into an argv-style array of strings. */ j = parse_o_rama ( options, &argv ); for ( i = 0; i < j; ++i ) { /* parse "keep_trying" option. */ if ( strcmp ( "keep_trying", argv[i] ) == 0 ) { /* translate a string into a binary value. returns -1 if the string is not one of the valid strings meaning yes or no. */ cd->keep_trying = translate_binary ( argv[++i] ); if ( cd->keep_trying == -1 ) { ++errors; error ( E_ERROR, "crossover: \"%s\" is not a valid setting for \"keep_trying\".", argv[i] ); } } /* parse "internal" option. */ else if ( strcmp ( "internal", argv[i] ) == 0 ) { internalset = 1; cd->internal = strtod ( argv[++i], NULL ); if ( cd->internal < 0.0 ) { ++errors; error ( E_ERROR, "crossover: \"internal\" must be nonnegative." ); } } /* parse "external" option. */ else if ( strcmp ( "external", argv[i] ) == 0 ) { externalset = 1; cd->external = strtod ( argv[++i], NULL ); if ( cd->external < 0.0 ) { ++errors; error ( E_ERROR, "crossover: \"external\" must be nonnegative." ); } } /* parse "select" option. */ else if ( strcmp ( "select", argv[i] ) == 0 ) { if ( !exists_select_method ( argv[++i] ) ) { ++errors; error ( E_ERROR, "crossover: \"%s\" is not a known selection method.", argv[i] ); } FREE ( cd->sname ); cd->sname = (char *)MALLOC ( (strlen(argv[i])+1) * sizeof ( char ) ); strcpy ( cd->sname, argv[i] ); if ( cd->sname2 == NULL ) cd->sname2 = cd->sname; } /* parse "select2" option. */ else if ( strcmp ( "select2", argv[i] ) == 0 ) { if ( !exists_select_method ( argv[++i] ) ) { ++errors; error ( E_ERROR, "crossover: \"%s\" is not a known selection method.", argv[i] ); } if ( cd->sname2 && cd->sname != cd->sname2 ) FREE ( cd->sname2 ); cd->sname2 = (char *)MALLOC ( (strlen(argv[i])+1) * sizeof ( char ) ); strcpy ( cd->sname2, argv[i] ); } /* parse "tree" option. */ else if ( strcmp ( "tree", argv[i] ) == 0 ) { k = parse_o_rama ( argv[++i], &targv ); if ( k != tree_count ) { ++errors; error ( E_ERROR, "crossover: wrong number of tree fields: \"%s\".", argv[i] ); } else { for ( m = 0; m < k; ++m ) { cd->tree[m] = strtod ( targv[m], &cp ); if ( *cp ) { ++errors; error ( E_ERROR, "crossover: \"%s\" is not a number.", targv[m] ); } } } free_o_rama ( k, &targv ); } /* parse "tree#" option. */ else if ( strncmp ( "tree", argv[i], 4 ) == 0 ) { k = strtol ( argv[i]+4, &cp, 10 ); if ( *cp ) { ++errors; error ( E_ERROR, "crossover: unknown option \"%s\".", argv[i] ); } if ( k < 0 || k >= tree_count ) { ++errors; error ( E_ERROR, "crossover: \"%s\" is out of range.", argv[i] ); } else { cd->tree[k] = strtod ( argv[++i], &cp ); if ( *cp ) { ++errors; error ( E_ERROR, "crossover: \"%s\" is not a number.", argv[i] ); } } } else { ++errors; error ( E_ERROR, "crossover: unknown option \"%s\".", argv[i] ); } } free_o_rama ( j, &argv ); if ( internalset && !externalset ) cd->external = 0.0; else if ( !internalset && externalset ) cd->internal = 0.0; if ( cd->sname == NULL ) { ++errors; error ( E_ERROR, "crossover: no selection method specified." ); } /** compute "func" array from the "tree" array. **/ for ( j = 0; j < tree_count; ++j ) cd->treetotal += cd->tree[j]; if ( cd->treetotal == 0.0 ) { for ( j = 0; j < tree_count; ++j ) cd->tree[j] = 1.0; cd->treetotal = tree_count; } for ( j = 0; j < fset_count; ++j ) cd->func[j] = 0.0; for ( j = 0; j < tree_count; ++j ) cd->func[tree_map[j].fset] += cd->tree[j]; r = 0.0; for ( j = 0; j < fset_count; ++j ) r = (cd->func[j] += r);#ifdef DEBUG if ( !errors ) { printf ( "crossover options:\n" ); printf ( " internal: %lf external: %lf\n", cd->internal, cd->external ); printf ( " keep_trying: %d\n", cd->keep_trying ); printf ( " primary selection: %s\n", cd->sname==NULL?"NULL":cd->sname ); printf ( " second selection: %s\n", cd->sname2==NULL?"NULL":(cd->sname2==cd->sname?"same as primary":cd->sname2) ); printf ( " tree total: %lf\n", cd->treetotal ); for ( j = 0; j < tree_count; ++j ) printf ( " tree %d: %lf\n", j, cd->tree[j] ); for ( j = 0; j < fset_count; ++j ) printf ( " fset %d: %lf\n", j, cd->func[j] ); }#endif return errors;}/* operator_crossover_free() * * free the crossover-specific data structure. */void operator_crossover_free ( void *data ){ crossover_data * cd; cd = (crossover_data *)data; FREE ( cd->sname ); if ( cd->sname != cd->sname2 ) FREE ( cd->sname2 ); FREE ( cd->tree ); FREE ( cd->treecumul ); FREE ( cd->func ); FREE ( cd );}/* operator_crossover_start() * * called at the start of the breeding process each generation. * initializes the selection contexts for this phase. */void operator_crossover_start ( population *oldpop, void *data ){ crossover_data * cd; select_context_func_ptr select_con; cd = (crossover_data *)data; select_con = get_select_context ( cd->sname ); cd->sc = select_con ( SELECT_INIT, NULL, oldpop, cd->sname ); /* if there is a separate selection method specified for the second parent... */ if ( cd->sname2 != cd->sname ) { /* ...then initialize it too. */ select_con = get_select_context ( cd->sname2 ); cd->sc2 = select_con ( SELECT_INIT, NULL, oldpop, cd->sname2 ); } else /* ...otherwise use the first context. */ cd->sc2 = cd->sc;}/* operator_crossover_end() * * called when breeding is finished each generation. frees up selection * contexts for this phase. */void operator_crossover_end ( void *data ){ crossover_data * cd; cd = (crossover_data *)data; cd->sc->context_method ( SELECT_CLEAN, cd->sc, NULL, NULL ); if ( cd->sname != cd->sname2 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -