📄 exch.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>/* initialize_topology() * * reads the parameter database and builds the exchange table. */void initialize_topology ( multipop *mpop ){ char pnamebuf[100], pnamebuf2[100]; char *param, *param2, *param3; int i, j, k; int errors = 0; if ( mpop->size == 1 ) { /* singlepop problem -- no topology needed. */ mpop->exch = NULL; mpop->exchanges = -1; return; } oprintf ( OUT_SYS, 30, "building subpopulation exchange topology:\n" ); param = get_parameter ( "multiple.exchanges" ); if ( param == NULL ) { /* multipop problem, but no exchanges specified. */ mpop->exch = NULL; mpop->exchanges = 0; return; } else { mpop->exchanges = atoi ( param ); if ( mpop->exchanges < 0 ) error ( E_FATAL_ERROR, "\"exchanges\" must be nonnegative." ); } mpop->exch = (exchange *)MALLOC ( mpop->exchanges * sizeof ( exchange ) ); for ( i = 0; i < mpop->exchanges; ++i ) { /** read the destination subpop. **/ sprintf ( pnamebuf, "exch[%d].to", i+1 ); param = get_parameter ( pnamebuf ); if ( param == NULL ) { ++errors; error ( E_ERROR, "\"%s\" must be set.", pnamebuf ); } else { mpop->exch[i].to = atoi ( param ) - 1; if ( mpop->exch[i].to < 0 || mpop->exch[i].to >= mpop->size ) { ++errors; error ( E_ERROR, "\"%s\" is out of range.\n", pnamebuf ); } } /** read how the individuals to be replaced in the destination subpop are selected. **/ sprintf ( pnamebuf, "exch[%d].toselect", i+1 ); mpop->exch[i].tosc = get_parameter ( pnamebuf ); if ( mpop->exch[i].tosc == NULL ) { ++errors; error ( E_ERROR, "\"%s\" must be set.", pnamebuf ); } else { if ( ! exists_select_method ( mpop->exch[i].tosc ) ) { ++errors; error ( E_ERROR, "\"%s\": \"%s\" is not a selection method.", pnamebuf, mpop->exch[i].tosc ); } } /** read how many individuals are to be exchanged in this manner. **/ sprintf ( pnamebuf, "exch[%d].count", i+1 ); param = get_parameter ( pnamebuf ); if ( param == NULL ) { ++errors; error ( E_ERROR, "\"%s\" must be set.", pnamebuf ); } else { mpop->exch[i].count = atoi ( param ); if ( mpop->exch[i].count < 0 ) { ++errors; error ( E_ERROR, "\"%s\" must be nonnegative.", pnamebuf ); } } /** check to see if "from" is specified without a "tree[#]". **/ sprintf ( pnamebuf, "exch[%d].from", i+1 ); param = get_parameter ( pnamebuf ); if ( param ) { /** if "from" is specified, then we're copying whole individuals from one subpop to another. **/ /* these arrays are not needed. */ mpop->exch[i].from = NULL; mpop->exch[i].as = NULL; /* allocate an array of one string (to hold the selection method). */ mpop->exch[i].fromsc = (char **)MALLOC ( sizeof ( char * ) ); /* the subpop that individuals are taken from. */ mpop->exch[i].copywhole = atoi ( param ) - 1; if ( mpop->exch[i].copywhole < 0 || mpop->exch[i].copywhole >= mpop->size ) { ++errors; error ( E_ERROR, "\"%s\" is out of range.", pnamebuf ); } /* the selection method used to pick the individuals from the source subpop. */ sprintf ( pnamebuf, "exch[%d].fromselect", i+1 ); mpop->exch[i].fromsc[0] = get_parameter ( pnamebuf ); if ( mpop->exch[i].fromsc[0] == NULL ) { ++errors; error ( E_ERROR, "\"%s\" must be set.", pnamebuf ); } else { if ( ! exists_select_method ( mpop->exch[i].fromsc[0] ) ) { ++errors; error ( E_ERROR, "\"%s\": \"%s\" is not a selection method.", pnamebuf, mpop->exch[i].fromsc[0] ); } } } else { /** since "from" is not defined, we're taking trees from different subpops and merging them to create a composite individual to place in the destination subpop. **/ mpop->exch[i].copywhole = -1; /* this array lists, for each tree, which subpop it comes from. */ mpop->exch[i].from = (int *)MALLOC ( tree_count * sizeof ( int ) ); /* this array keeps track of when two trees are supposed to always come from the same individual (not just the same subpop). */ mpop->exch[i].as = (int *)MALLOC ( tree_count * sizeof ( int ) ); /* this array holds the selection method strings used for each tree. */ mpop->exch[i].fromsc = (char **)MALLOC ( tree_count * sizeof ( char * ) ); /* get the default selection method, if one is specified. */ sprintf ( pnamebuf, "exch[%d].fromselect", i+1 ); param3 = get_parameter ( pnamebuf ); for ( j = 0; j < tree_count; ++j ) { /** for each tree, attempt to read the "from" and "fromselect" parameters. **/ sprintf ( pnamebuf, "exch[%d].from.tree[%d]", i+1, j ); param = get_parameter ( pnamebuf ); sprintf ( pnamebuf2, "exch[%d].fromselect.tree[%d]", i+1, j ); param2 = get_parameter ( pnamebuf2 ); if ( param == NULL && param2 == NULL ) { /* neither is set, we're supposed to leave this tree untouched in the destination individual. */ mpop->exch[i].from[j] = -1; mpop->exch[i].as[j] = -1; mpop->exch[i].fromsc[j] = NULL; } else if ( param2 == NULL ) { /* only "from" is set, examine param3 for default selection method. */ /* source subpop. */ mpop->exch[i].from[j] = atoi ( param ) - 1; if ( mpop->exch[i].from[j] < 0 || mpop->exch[i].from[j] >= mpop->size ) { ++errors; error ( E_ERROR, "\"%s\" is out of range.", pnamebuf ); } /* no default set, error. */ if ( param3 == NULL ) { ++errors; error ( E_ERROR, "\"%s\" must be set.", pnamebuf2 ); } else { mpop->exch[i].as[j] = -1; if ( ! exists_select_method ( param3 ) ) { ++errors; error ( E_ERROR, "\"%s\": \"%s\" is not a selection method.", pnamebuf, param3 ); } } mpop->exch[i].fromsc[j] = param3; } else if ( param == NULL ) { /* only "fromselect" is set; it better be of the form "as_#". */ if ( strncmp ( param2, "as_", 3 ) == 0 ) { mpop->exch[i].from[j] = -1; mpop->exch[i].fromsc[j] = NULL; /* "as" stores which tree this one comes from the same subpop as. */ mpop->exch[i].as[j] = atoi ( param2 + 3 ); if ( mpop->exch[i].as[j] < 0 || mpop->exch[i].as[j] >= tree_count ) { ++errors; error ( E_ERROR, "\"%s\" is out of range.", pnamebuf2 ); } } else { ++errors; error ( E_ERROR, "\"%s\" must be \"as_#\".", pnamebuf2 ); } } else { /* they're both set. */ mpop->exch[i].as[j] = -1; mpop->exch[i].from[j] = atoi ( param ) - 1; if ( mpop->exch[i].from[j] < 0 || mpop->exch[i].from[j] >= mpop->size ) { ++errors; error ( E_ERROR, "\"%s\" is out of range.", pnamebuf ); } mpop->exch[i].fromsc[j] = param2; if ( ! exists_select_method ( param2 ) ) { ++errors; error ( E_ERROR, "\"%s\": \"%s\" is not a selection method.", pnamebuf2, param2 ); } } } /* now we need to resolve any chains of "as_" references: if tree 2 comes from the same individual as tree 1, and tree 1 comes from the same individual as tree 0, we need to change that to say that both 2 and 1 come from tree 0. also detect circular references. */ for ( j = 0; j < tree_count; ++j ) { if ( mpop->exch[i].as[j] == -1 ) continue; k = mpop->exch[i].as[j]; while ( k != -1 ) { if ( k == j ) { ++errors; error ( E_ERROR, "Circular reference resolving \"exch[%d].fromselect.tree[%d]\".", i+1, j ); j = tree_count; break; } mpop->exch[i].as[j] = k; k = mpop->exch[i].as[k]; } k = mpop->exch[i].as[j]; if ( mpop->exch[i].from[k] == -1 && mpop->exch[i].as[k] == -1 ) mpop->exch[i].as[j] = -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -