main.c

来自「Genetic Programing of music」· C语言 代码 · 共 814 行 · 第 1/2 页

C
814
字号
/*  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     if ( app_initialize ( startfromcheckpoint ) )          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 + -
显示快捷键?