main.c
来自「Genetic Programing of music」· C语言 代码 · 共 815 行 · 第 1/2 页
C
815 行
/* 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>#ifdef MEMORY_LOGFILE *mlog;#endif/* do we dup OUT_SYS to stdout? */int quietmode = 0;/* tree generation spaces. */genspace gensp[GENSPACE_COUNT];/* internal copy of function set(s). */function_set *fset;int fset_count;/* information about each tree--which function set it uses, its name, size limits, etc. */treeinfo *tree_map;int tree_count;/* maximum number of nodes per individual. -1 if no limit is enforced. */int ind_nodelimit;int main ( int argc, char **argv ){ multipop *mpop; int startgen; char *param; event start, end, diff; event eval, breed; int startfromcheckpoint;#ifdef MEMORY_LOG /* dump all memory allocations to a file. */ mlog = fopen ( "memory.log", "w" );#endif /* mark the start time, and zero the accumulators for evaluation and breeding time. */ event_init(); event_mark ( &start ); event_zero ( &eval ); event_zero ( &breed ); if ( app_create_output_streams() ) error ( E_FATAL_ERROR, "app_create_output_streams() failure." ); initialize_output_streams(); /* print copyright message and such. */ initial_message(); /* some initialization. */ oprintf ( OUT_SYS, 30, "initialization:\n" ); initialize_parameters(); initialize_ephem_const(); initialize_genspace(); /* process the command line. if starting from a checkpoint file, this function will load the population. */ startfromcheckpoint = process_commandline ( argc, argv, &startgen, &mpop ); /* open the files associated with each stream. */ open_output_streams(); /* make internal copies of function set(s), if it hasn't already been done. */ if ( !startfromcheckpoint ) if ( app_build_function_sets() ) error ( E_FATAL_ERROR, "app_build_function_sets() failure." ); /* read parameters limiting tree node count and/or depth. */ read_tree_limits(); /* if not starting from a checkpoint, seed the random number generator. */ if ( !startfromcheckpoint ) initialize_random(); #if defined(POSIX_MT) || defined(SOLARIS_MT) /* setup for multi-threading if applicable */ initialize_threading();#endif /* modified by BEJ */ if ( app_initialize ( startfromcheckpoint, argc, argv ) ) error ( E_FATAL_ERROR, "app_initialize() failure." ); /* if not starting from a checkpoint, create a random population. */ if ( !startfromcheckpoint ) mpop = initial_multi_population(); /* build the breeding table and the subpop exchange table from the parameter database. */ initialize_topology ( mpop ); initialize_breeding ( mpop ); /* do the GP. */ run_gp ( mpop, startgen, &eval, &breed, startfromcheckpoint ); /* free app stuff. */ app_uninitialize(); /* free lots of stuff. */ free_breeding ( mpop ); free_topology ( mpop ); free_multi_population ( mpop ); free_parameters(); free_ephem_const(); free_genspace(); free_function_sets(); /* mark the finish time. */ event_mark ( &end ); event_diff ( &diff, &start, &end ); /* print memory/time statistics and close output files. */ output_system_stats ( &diff, &eval, &breed ); close_output_streams();#ifdef MEMORY_LOG fclose ( mlog );#endif /* all done. */ return 0;}/* function_sets_init() * * this function is called from user code and passed the function sets * and tree maps and names. it makes internal copies and does some * validation. */int function_sets_init ( function_set *user_fset, int user_fcount, int *user_tree_map, char **user_tree_name, int user_tcount ){ int i, j, k, m, n, p; int errors = 0; function *cur; /* allocate internal copies. */ fset = (function_set *)MALLOC ( user_fcount * sizeof ( function_set ) ); tree_map = (treeinfo *)MALLOC ( user_tcount * sizeof ( treeinfo ) ); fset_count = user_fcount; tree_count = user_tcount; oprintf ( OUT_SYS, 30, "building function set(s):\n" ); /* for each set of functions... */ for ( i = 0; i < fset_count; ++i ) { oprintf ( OUT_SYS, 30, " set %d:", i ); /* allocate memory for the set. */ m = user_fset[i].size; fset[i].cset = (function *)MALLOC ( m * sizeof ( function ) ); fset[i].num_args = 0; k = 0; for ( j = 0; j < m; ++j ) { if ( user_fset[i].cset[j].type == FUNC_DATA || user_fset[i].cset[j].type == FUNC_EXPR || user_fset[i].cset[j].type == EVAL_DATA || user_fset[i].cset[j].type == EVAL_EXPR ) { /** functions and evaluation tokens **/ cur = &(fset[i].cset[k]); /* copy some stuff over. */ cur->code = user_fset[i].cset[j].code; cur->ephem_gen = user_fset[i].cset[j].ephem_gen; cur->ephem_str = user_fset[i].cset[j].ephem_str; cur->arity = user_fset[i].cset[j].arity; cur->type = user_fset[i].cset[j].type; cur->evaltree = user_fset[i].cset[j].evaltree; /* copy the name string. */ n = strlen ( user_fset[i].cset[j].string ); cur->string = (char *)MALLOC ( n+1 ); for ( p = 0; p < n; ++p ) { if ( isspace(user_fset[i].cset[j].string[p]) || user_fset[i].cset[j].string[p] == ':' || user_fset[i].cset[j].string[p] == ')' || user_fset[i].cset[j].string[p] == '(' || user_fset[i].cset[j].string[p] == '[' || user_fset[i].cset[j].string[p] == ']' ) { error ( E_WARNING, "illegal character(s) in function name changed to '_'." ); cur->string[p] = '_'; } else cur->string[p] = user_fset[i].cset[j].string[p]; } cur->string[n] = 0; /* fill in the index field with this function's position in the set. */ cur->index = k; /* the ERC-related fields should be NULL. */ if ( cur->ephem_gen || cur->ephem_str ) { ++errors; error ( E_ERROR, "function has non-NULL ephem_gen and/or ephem_str field(s)." ); } /* do some type-specific checking. */ switch ( cur->type ) { case FUNC_DATA: case FUNC_EXPR: if ( cur->code == NULL ) { ++errors; error ( E_ERROR, "ordinary function has NULL code field." ); } if ( cur->arity < 1 ) { ++errors; error ( E_ERROR, "ordinary function has arity of %d.", cur->arity ); } if ( cur->evaltree != -1 ) { error ( E_WARNING, "ordinary function has evaltree field of %d; this will be ignored.", cur->evaltree ); } break; case EVAL_DATA: case EVAL_EXPR: if ( cur->code != NULL ) { ++errors; error ( E_ERROR, "eval function function has non-NULL code field." ); } if ( cur->arity != -1 ) { error ( E_WARNING, "eval function has arity field of %d; this will be ignored.", cur->arity ); } if ( cur->evaltree < 0 || cur->evaltree >= tree_count ) /* evaluation token refers to a tree that doesn't exist. */ error ( E_FATAL_ERROR, "eval function refers to nonexistent tree (%d).", cur->evaltree ); break; default: ++errors; error ( E_ERROR, "unknown function type %d.", cur->type ); } ++k; } else if ( user_fset[i].cset[j].type == TERM_NORM || user_fset[i].cset[j].type == TERM_ERC || user_fset[i].cset[j].type == TERM_ARG ) { /** terminals (all kinds). **/ /* "cur" is so much easier to type. :) */ cur = &(fset[i].cset[k]); /* copy stuff. */ cur->code = user_fset[i].cset[j].code; cur->ephem_gen = user_fset[i].cset[j].ephem_gen; cur->ephem_str = user_fset[i].cset[j].ephem_str; cur->arity = user_fset[i].cset[j].arity; cur->type = user_fset[i].cset[j].type; cur->evaltree = user_fset[i].cset[j].evaltree; /* copy terminal name. */ n = strlen ( user_fset[i].cset[j].string ); cur->string = (char *)MALLOC ( n+1 ); strcpy ( cur->string, user_fset[i].cset[j].string ); cur->string[n] = 0; /* fill in the index field. */ cur->index = k; if ( cur->arity != 0 ) { ++errors; error ( E_ERROR, "terminal has nonzero arity." ); } /* check for correctness of type-dependent fields. */ switch ( cur->type ) { case TERM_NORM: if ( cur->code == NULL ) { ++errors; error ( E_ERROR, "normal terminal has NULL code field." ); } if ( cur->ephem_gen != NULL || cur->ephem_str != NULL ) { ++errors; error ( E_ERROR, "normal terminal has non-NULL ephem_gen and/or ephem_str field(s)." ); } if ( cur->evaltree != -1 ) { error ( E_WARNING, "normal terminal has evaltree field of %d; this will be ignored." ); } break; case TERM_ERC: if ( cur->code != NULL ) { ++errors; error ( E_ERROR, "ERC terminal has non-NULL code field." ); } if ( cur->ephem_gen == NULL || cur->ephem_str == NULL ) { ++errors; error ( E_ERROR, "ERC terminal has NULL ephem_hen and/or ephem_str field(s)." ); } if ( cur->evaltree != -1 ) { error ( E_WARNING, "ERC terminal has evaltree field of %d; this will be ignored." ); } break; case TERM_ARG: ++fset[i].num_args; if ( cur->code != NULL ) { ++errors; error ( E_ERROR, "argument terminal has non-NULL code field." ); } if ( cur->ephem_gen != NULL || cur->ephem_str != NULL ) { ++errors; error ( E_ERROR, "argument terminal has non-NULL ephem_hen and/or ephem_str field(s)." ); } if ( cur->evaltree < 0 ) { ++errors; error ( E_ERROR, "argument terminal should have nonnegative evaltree field." ); } break; } ++k; } oputs ( OUT_SYS, 30, " " ); oputs ( OUT_SYS, 30, fset[i].cset[k-1].string ); } fset[i].size = k; oputs ( OUT_SYS, 30, "\n" ); } /* if there were any errors, stop now. */ if ( errors ) { error ( E_FATAL_ERROR, "error(s) occurred while processing function set(s)." ); } /* build the internal tree map. */ for ( i = 0; i < tree_count; ++i ) { /* the function set used for this tree. */ tree_map[i].fset = user_tree_map[i]; if ( tree_map[i].fset < 0 || tree_map[i].fset >= fset_count ) error ( E_FATAL_ERROR, "tree %d uses a nonexistent function set.\n", i ); oprintf ( OUT_SYS, 30, " tree %d uses function set %d.\n", i, tree_map[i].fset ); /* these will be filled in by read_tree_limits(). */ tree_map[i].nodelimit = -1; tree_map[i].depthlimit = -1; /* copy the tree name. */ j = strlen ( user_tree_name[i] ); tree_map[i].name = (char *)MALLOC ( (j+1) * sizeof ( char ) ); strcpy ( tree_map[i].name, user_tree_name[i] ); } /* now some more processing on each function set. */ for ( i = 0; i < fset_count; ++i ) { fset[i].function_count = 0;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?