📄 gp.c
字号:
n->best[i], n->best[i]->ind->a_fitness );#endif /** here we merge the two "top N" lists into one, discarding the remaining N individuals. **/ temp = (saved_ind **)MALLOC ( total->bestn * sizeof ( saved_ind * ) ); j = 0; /* position in "total"s list */ k = 0; /* position in "n"s list */ for ( i = 0; i < total->bestn; ++i ) { /* if the n list is empty, take from the total list. */ if ( k == -1 ) temp[i] = total->best[j++]; /* if the total list is empty, take from the n list. */ else if ( j == -1 ) { ret |= (i==0); temp[i] = n->best[k++]; } /* if neither list is empty, take the better individual. */ else if ( total->best[j]->ind->a_fitness < n->best[k]->ind->a_fitness ) { ret |= (i==0); temp[i] = n->best[k++]; } else temp[i] = total->best[j++]; /* have we run off the end of either list? */ if ( j >= total->bestn ) j = -1; if ( k >= n->bestn ) k = -1; } /* decrement the reference count of the old "best" list. */ for ( i = 0; i < total->bestn; ++i ) --total->best[i]->refcount; FREE ( total->best ); total->best = temp; #ifdef DEBUG printf ( "new total list:\n" ); for ( i = 0; i < total->bestn; ++i ) printf ( " %08x %lf\n", total->best[i], total->best[i]->ind->a_fitness );#endif } /* increment the reference count of the new "best" list. */ for ( i = 0; i < total->bestn; ++i ) ++total->best[i]->refcount; return ret;}/* saved_individual_gc() * * go through the list of saved individuals, deleting any which are no longer * referred to. */void saved_individual_gc ( void ){ int j; saved_ind *shp = saved_head->next; saved_ind *shm = saved_head; while ( shp ) { if ( shp->refcount == 0 ) { /** found one that needs to be deleted. **/ /* dereference its trees' ERCs and delete the trees. */ for ( j = 0; j < tree_count; ++j ) { reference_ephem_constants ( shp->ind->tr[j].data, -1 ); free_tree ( shp->ind->tr+j ); } FREE ( shp->ind->tr ); FREE ( shp->ind ); /* cut the record out of the linked list. */ shm->next = shp->next; if ( saved_tail == shp ) saved_tail = shm; FREE ( shp ); shp = shm->next; /* the refcount field of the list head (a dummy node) holds the size of the list. */ --saved_head->refcount; } else { /* move down the list. */ shm = shp; shp = shp->next; } }}/* read_saved_individuals() * * reads the list of saved individuals from a checkpoint file. constructs * an index translating indices to addresses. */saved_ind ** read_saved_individuals ( ephem_const **eind, FILE *f ){ char *buffer; int count; int i, j, k; saved_ind *p; saved_ind **sind; buffer = (char *)MALLOC ( MAXCHECKLINELENGTH ); /* read the number of saved individuals. */ fscanf ( f, "%*s %d\n", &count ); /* allocate the index. */ sind = (saved_ind **)MALLOC ( count * sizeof ( saved_ind * ) ); /* allocate the head of the linked list (a dummy node whose refcount equals the number of individuals on the list). */ saved_head = (saved_ind *)MALLOC ( sizeof ( saved_ind ) ); saved_head->ind = NULL; saved_head->refcount = count; p = saved_head; for ( i = 0; i < count; ++i ) { /* allocate the next saved_ind on the list. */ p->next = (saved_ind *)MALLOC ( sizeof ( saved_ind ) ); p = p->next; /* allocate the individual. */ p->ind = (individual *)MALLOC ( sizeof ( individual ) ); /* make the index entry. */ sind[i] = p; /* read the refcount. */ fscanf ( f, "%d ", &(p->refcount) ); /* read the individual. */ read_individual ( p->ind, eind, f, buffer ); } /* mark the end of the list. */ p->next = NULL; saved_tail = p; FREE ( buffer ); return sind;}/* read_stats_checkpoint() * * read the overall run statistics structures from a checkpoint file. */void read_stats_checkpoint ( multipop *mpop, ephem_const **eind, FILE *f ){ int i, j, k; saved_ind **sind; /* read and index the saved individuals list. */ sind = read_saved_individuals ( eind, f ); /* allocate the run_stats array. */ run_stats = (popstats *)MALLOC ( (mpop->size+1)*sizeof ( popstats ) ); for ( i = 0; i < mpop->size+1; ++i ) { /* read lots of integer values into run_stats. */ fscanf ( f, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", &(run_stats[i].size), &(run_stats[i].maxnodes), &(run_stats[i].minnodes), &(run_stats[i].totalnodes), &(run_stats[i].bestnodes), &(run_stats[i].worstnodes), &(run_stats[i].maxdepth), &(run_stats[i].mindepth), &(run_stats[i].totaldepth), &(run_stats[i].bestdepth), &(run_stats[i].worstdepth), &(run_stats[i].maxhits), &(run_stats[i].minhits), &(run_stats[i].totalhits), &(run_stats[i].besthits), &(run_stats[i].worsthits) ); /** double-precision values are stored as hex data to avoid loss of precision. **/ read_hex_block ( &(run_stats[i].bestfit), sizeof ( double ), f ); fgetc ( f ); read_hex_block ( &(run_stats[i].worstfit), sizeof ( double ), f ); fgetc ( f ); read_hex_block ( &(run_stats[i].totalfit), sizeof ( double ), f ); /* they are also printed as decimal values, for the benefit of human readers -- skip these fields. */ fscanf ( f, " %*f %*f %*f\n" ); /* read some more integers. */ fscanf ( f, "%d %d %d %d %d ", &(run_stats[i].bestgen), &(run_stats[i].worstgen), &(run_stats[i].bestpop), &(run_stats[i].worstpop), &(run_stats[i].bestn) ); run_stats[i].best = (saved_ind **)MALLOC ( run_stats[i].bestn * sizeof ( saved_ind * ) ); /** read the indices of the contents of the best array, and look up the addresses in the index. **/ for ( j = 0; j < run_stats[i].bestn; ++j ) { fscanf ( f, "%d\n", &k ); run_stats[i].best[j] = sind[k]; } } FREE ( sind );} /* write_saved_individuals() * * writes the linked list of saved individuals to a checkpoint file. returns * an index for translating saved_ind addresses to integer indices. */saved_ind ** write_saved_individuals ( ephem_index *eind, FILE *f ){ saved_ind **index; saved_ind *shp; int i = 0; index = (saved_ind **)MALLOC ( saved_head->refcount * sizeof ( saved_ind * ) ); /* write the count of individuals. */ fprintf ( f, "saved-individual-count: %d\n", saved_head->refcount ); shp = saved_head->next; /** traverse the linked list. **/ while ( shp ) { /* write the reference count and individual. */ fprintf ( f, "%d ", shp->refcount ); write_individual ( shp->ind, eind, f ); /* record the address in the index. */ index[i++] = shp; shp = shp->next; } return index;}/* write_stats_checkpoint() * * write the overall run statistics structures to a checkpoint file. */void write_stats_checkpoint ( multipop *mpop, ephem_index *eind, FILE *f ){ int i, j, k; saved_ind **sind; /* write and index the saved individuals list. */ sind = write_saved_individuals ( eind, f ); for ( i = 0; i < mpop->size+1; ++i ) { /* write many integer values. */ fprintf ( f, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", run_stats[i].size, run_stats[i].maxnodes, run_stats[i].minnodes, run_stats[i].totalnodes, run_stats[i].bestnodes, run_stats[i].worstnodes, run_stats[i].maxdepth, run_stats[i].mindepth, run_stats[i].totaldepth, run_stats[i].bestdepth, run_stats[i].worstdepth, run_stats[i].maxhits, run_stats[i].minhits, run_stats[i].totalhits, run_stats[i].besthits, run_stats[i].worsthits ); /** write double-precision values as hex data. **/ write_hex_block ( &(run_stats[i].bestfit), sizeof ( double ), f ); fputc ( ' ', f ); write_hex_block ( &(run_stats[i].worstfit), sizeof ( double ), f ); fputc ( ' ', f ); write_hex_block ( &(run_stats[i].totalfit), sizeof ( double ), f ); /* also write them as decimal values. */ fprintf ( f, " %f %f %f\n", run_stats[i].bestfit, run_stats[i].worstfit, run_stats[i].totalfit ); /* write more integers. */ fprintf ( f, "%d %d %d %d %d ", run_stats[i].bestgen, run_stats[i].worstgen, run_stats[i].bestpop, run_stats[i].worstpop, run_stats[i].bestn ); /** write the best array, indexing saved individuals using integers. **/ for ( j = 0; j < run_stats[i].bestn; ++j ) { /** search the index for the address. **/ for ( k = 0; k < saved_head->refcount; ++k ) if ( run_stats[i].best[j] == sind[k] ) { /* print the index to the checkpoint file. */ fprintf ( f, " %d", k ); break; } /** address was not found in the index. **/ if ( k == saved_head->refcount ) { /* this shouldn't ever happen. */ fprintf ( f, " -1" ); error ( E_WARNING, "bestn pointer is bad." ); } } fputc ( '\n', f ); } FREE ( sind );}#if !defined(POSIX_MT) && !defined(SOLARIS_MT)/* return the globaldata structure */globaldata *get_globaldata(void) { return( &global_g );}#else /* continues to end of file *//* provide each thread with seperate copy of 'g' */globaldata *get_globaldata(void) { globaldata *retval;#ifdef POSIX_MT retval = pthread_getspecific( g_key );#endif#ifdef SOLARIS_MT thr_getspecific( g_key, (void *)&retval );#endif if (retval == NULL) { error ( E_FATAL_ERROR, "get_globaldata() tried to return NULL"); } return( retval );}/* * initialize_threading() * * Setup the program for multithreading use. */void initialize_threading( void ) { char *numthreads_str; globaldata *main_g; numthreads_str = getenv( "NUM_THREADS" ); if (numthreads_str == NULL) { error ( E_FATAL_ERROR, "NUM_THREADS undefined"); } numthreads = atoi( numthreads_str ); if (numthreads < 1) { error ( E_FATAL_ERROR, "NUM_THREADS must be > 0"); } /* create the thread key for access to 'g' */#ifdef POSIX_MT pthread_key_create( &g_key, NULL );#endif#ifdef SOLARIS_MT thr_keycreate( &g_key, NULL );#endif /* main thread needs its own 'g' */ main_g = (globaldata *)malloc(sizeof(globaldata));#ifdef POSIX_MT pthread_setspecific(g_key, main_g);#endif#ifdef SOLARIS_MT thr_setspecific(g_key, main_g);#endif#ifdef POSIX_MT /* Setup default thread attributes */ pthread_attr_init(&pthread_attr); pthread_attr_setscope(&pthread_attr, PTHREAD_SCOPE_SYSTEM);#endif#ifdef SOLARIS_MT /* let the OS know how many threads to run at once */ thr_setconcurrency( numthreads );#endif}/* evaluate_pop_chuck() * * Called from evaluate_pop to do a chunk of evaluations on a pop. * This was done to allow multithreading. */void *evaluate_pop_chunk( void *param ) { int k, startidx, endidx; population *pop; globaldata g; struct thread_param_t *t_param; t_param = (struct thread_param_t *)param; pop = t_param->pop; startidx = t_param->startidx; endidx = t_param->endidx;#ifdef POSIX_MT pthread_setspecific(g_key, &t_param->g);#endif#ifdef SOLARIS_MT thr_setspecific(g_key, &t_param->g);#endif/* printf("START: %d,%d\n", startidx, endidx); /* */ for ( k = startidx; k < endidx; ++k ) if ( pop->ind[k].evald != EVAL_CACHE_VALID ) app_eval_fitness ( (pop->ind)+k );}#endif /* !defined(POSIX_MT) && !defined(SOLARIS_MT) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -