📄 ckpoint.c
字号:
void read_individual ( individual *ind, ephem_const **eind, FILE *f, char *buffer ){ int j, k[3]; /* read the evald and flags fields. */ fscanf ( f, "%d %d ", &(ind->evald), &(ind->flags) ); if ( ind->evald == EVAL_CACHE_VALID ) { /** if the individual has valid fitness values saved in the file, read them. **/ /* skip over the human-readable fitness values and read the hits count. */ fscanf ( f, "%*f %*f %*f %d ", &(ind->hits) ); /** the fitness values, which are double precision, are dumped out in hex so that no significant digits are lost. **/ read_hex_block ( &(ind->r_fitness), sizeof(double), f ); fgetc ( f ); read_hex_block ( &(ind->s_fitness), sizeof(double), f ); fgetc ( f ); read_hex_block ( &(ind->a_fitness), sizeof(double), f ); fgetc ( f ); } #ifdef DEBUG fprintf ( stderr, "%d: %lf %lf %lf %d %d %d\n", i, ind->r_fitness, ind->s_fitness, ind->a_fitness, ind->hits, ind->evald, ind->flags );#endif /* allocate the array of trees. */ ind->tr = (tree *)MALLOC ( tree_count * sizeof ( tree ) ); for ( j = 0; j < tree_count; ++j ) { /* read the tree number, tree size, and tree node count. */ fscanf ( f, "%d %d %d ", k+0, k+1, k+2 ); /** read the tree into a generation space, then copy it to it's final location. **/ gensp_reset ( 0 ); read_tree_recurse ( 0, eind, f, j, buffer ); gensp_dup_tree ( 0, ind->tr+j ); #ifdef DEBUG_READTREE fprintf ( stderr, "file: %d %d %d here: %d %d %d\n", k[0], k[1], k[2], j, ind->tr[j].size, ind->tr[j].nodes ); print_tree ( ind->tr[j].data, stderr );#endif if ( k[0] != j || k[1] != ind->tr[j].size || k[2] != ind->tr[j].nodes ) { /** if the values in the checkpoint file don't match the values of the tree we read, this is a problem. this, of course should never happen. **/ error ( E_FATAL_ERROR, "checkpoint file corrupted in population section." ); } }}/* read_tree_recurse() * * function to recursively read a tree from a checkpoint file. */void read_tree_recurse ( int space, ephem_const **eind, FILE *fil, int tree, char *string ){ function *f; int i, j; ephem_const *ep; /* read up until a nonwhitespace character in file. the nonwhitespace character is saved in string[0]. */ while ( isspace(string[0]=fgetc(fil)) ); /* get the next character. */ i = fgetc ( fil ); if ( isspace(i) ) /* if the next character is whitespace, then string[0] is a one-character function name. null-terminate the string. */ string[1] = 0; else { /** if the next character is not whitespace, then string[0] is either an open parenthesis or the first character of a multi-character function name. **/ /* push the next character back. */ ungetc ( i, fil ); /* read the function name. skip over an open parenthesis, if there is one. */ fscanf ( fil, "%s ", string+(string[0]!='(') ); }#ifdef DEBUG_READTREE fprintf ( stderr, "function name is [%s]\n", string );#endif /* look up the function name in this tree's function set. if the function is an ERC terminal (the name is of the form "name:ERCindex"), then place the ERC address in ep. */ f = get_function_by_name ( tree, string, &ep, eind ); /* add an lnode to the tree. */ gensp_next(space)->f = f; switch ( f->type ) { case TERM_NORM: case TERM_ARG: case EVAL_TERM: break; case TERM_ERC: /* record the ERC address as the next lnode in the array. */ gensp_next(space)->d = ep; break; case FUNC_DATA: case EVAL_DATA: /** recursively read child functions, no skip nodes needed. **/ for ( i = 0; i < f->arity; ++i ) read_tree_recurse ( space, eind, fil, tree, string ); break; case FUNC_EXPR: case EVAL_EXPR: /** recursively read child functions, recording skip values. **/ for ( i = 0; i < f->arity; ++i ) { /* save an lnode for the skip value. */ j = gensp_next_int ( space ); /* read the child tree. */ read_tree_recurse ( space, eind, fil, tree, string ); /* figure out how big the child tree was, and save that number in the skip node. */ gensp[space].data[j].s = gensp[space].used-j-1; } break; }}/* get_function_by_name() * * looks up a function name in the function set for the given tree. if * the function is an ERC, looks up the index (encoded in the name) * and stores the ERC address in ep. */function * get_function_by_name ( int tree, char *string, ephem_const **ep, ephem_const **eind ){ int i, j, k; function_set *fs = fset+tree_map[tree].fset; k = strlen ( string ); for ( i = 0; i < k; ++i ) { if ( string[i] == ':' ) { /* names of the form "name:index" are chopped at the colon, and the value of the index saved. */ string[i] = 0; j = atoi ( string+i+1 ); break; } else if ( string[i] == ')' ) { /* chop the name at the first closing parenthesis, since we could be passed a string like "function))))" */ string[i] = 0; break; } } /* find the string in the function set. */ for ( i = 0; i < fs->size; ++i ) if ( strcmp ( string, fs->cset[i].string ) == 0 ) { if ( fs->cset[i].type == TERM_ERC ) { /* if this is an ERC, lookup the saved index in the eind table, and store the looked-up address in ep. */ *ep = eind[j]; (*ep)->f = fs->cset+i; } /* return a pointer to the function. */ return fs->cset+i; } /* this, of course, should never happen. */ return NULL;} /* write_population() * * writes a population to a checkpoint file. */void write_population ( population *pop, ephem_index *eind, FILE *f ){ int i, j; /* write size and next fields. */ fprintf ( f, "size: %d\nnext: %d\n", pop->size, pop->next ); /* write each individual. */ for ( i = 0; i < pop->size; ++i ) { write_individual ( pop->ind+i, eind, f ); }}/* write_individual() * * writes an individual to a checkpoint file. uses eind to change ERC * addresses to integer indices. */void write_individual ( individual *ind, ephem_index *eind, FILE *f ){ int j; lnode *l; /* write evald and flags fields. */ fprintf ( f, "%d %d ", ind->evald, ind->flags ); if ( ind->evald == EVAL_CACHE_VALID ) { /** if the fitness values are valid... **/ /* ...write them in human-readable form. */ fprintf ( f, "%lf %lf %lf %d ", ind->r_fitness, ind->s_fitness, ind->a_fitness, ind->hits ); /** then write the double-precision values as hex blocks, so as not to lose significant digits. **/ write_hex_block ( &(ind->r_fitness), sizeof(double), f ); fputc ( ' ', f ); write_hex_block ( &(ind->s_fitness), sizeof(double), f ); fputc ( ' ', f ); write_hex_block ( &(ind->a_fitness), sizeof(double), f ); } fputc ( '\n', f ); /** now write the trees of the individual. **/ for ( j = 0; j < tree_count; ++j ) { /* write tree number, size, nodes. */ fprintf ( f, "%d %d %d ", j, ind->tr[j].size, ind->tr[j].nodes ); /** write tree data. **/ l = ind->tr[j].data; write_tree_recurse ( &l, eind, f ); fputc ( '\n', f ); }}/* write_tree_recurse() * * function to recursively write trees to a checkpoint file. the same * as print_tree_recurse(), except that ERC nodes are written as * "name:index" rather than the value, using eind to translate addresses * to indices. */void write_tree_recurse ( lnode **l, ephem_index *eind, FILE *fil ){ function *f; int i; /* remember which function we are. */ f = (**l).f; /* a space, then an open-paren if this function is not a terminal. */ fputc ( ' ', fil ); if ( f->arity != 0 ) fprintf ( fil, "(" ); ++*l; if ( f->type == TERM_ERC ) { /* ERCs printed as "name:index". */ fprintf ( fil, "%s:%d", f->string, lookup_ephem ( eind, (**l).d ) ); ++*l; } else /* everything else printed normally. */ fprintf ( fil, "%s", f->string ); switch ( f->type ) { case FUNC_DATA: case EVAL_DATA: /** recursively print children. **/ for ( i = 0; i < f->arity; ++i ) write_tree_recurse ( l, eind, fil ); break; case FUNC_EXPR: case EVAL_EXPR: /** recursive print children, ignoring the skip nodes. **/ for ( i = 0; i < f->arity; ++i ) { ++*l; write_tree_recurse ( l, eind, fil ); } break; } if ( f->arity != 0 ) fprintf ( fil, ")" );}/* write_hex_block() * * writes a block of memory to a file, as a string of hex characters. */void write_hex_block ( void *buf, int n, FILE *f ){ int i; unsigned char *b = (unsigned char *)buf; for ( i = 0; i < n; ++i ) fprintf ( f, "%02x", b[i] );}/* read_hex_block() * * reads hex characters into a block of memory, the inverse of * write_hex_block(). */void read_hex_block ( void *buf, int n, FILE *f ){ int i; unsigned char *b = (unsigned char *)buf; int c[2] = { 0, 0 }; for ( i = 0; i < n; ++i ) { c[0] = fgetc ( f ); c[1] = fgetc ( f ); /* convert hex chars to base 10. */ c[0] = c[0]>'9' ? c[0]-'a'+10 : c[0]-'0'; c[1] = c[1]>'9' ? c[1]-'a'+10 : c[1]-'0'; b[i] = c[0] * 16 + c[1]; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -