int main( ){ srand( time_seed() ); individual* i; i = create_individual(); print_individual( i, 0 ); evaluate_individual( i ); print_individual( i, 0 ); }
void print_statistic(Population* pop, time_t begin, time_t end) { cout << "+--------------------------------------------------------------------------+" << endl; cout << "| Statistics: " << endl; cout << "+--------------------------------------------------------------------------+" << endl; cout << "| Delta Fitness: " << delta_fitness << endl; print_individual(better_individual(pop), "Better Individual"); print_individual(worse_individual(pop), "Worse Individual"); cout << "| Timer in Second: " << difftime(end, begin) << endl; cout << "+--------------------------------------------------------------------------+" << endl; }
void evaluate_pop(population *pop) { int k; #ifdef DEBUG print_individual ( pop->ind, stdout ); app_eval_fitness ( pop->ind ); exit(0); #endif for (k = 0; k < pop->size; ++k) { if (pop->ind[k].evald != EVAL_CACHE_VALID) { population_No = k; app_eval_fitness((pop->ind) + k); } } if (generation_No != (generationSIZE - 1)) { optimal_in_generation[generation_No + 1] = 1000; } if (optimal_in_generation[generation_No] >= optimal_in_generation[generation_No - 1]) { same_optimal_count++; } else { same_optimal_count = 1; } if (same_optimal_count > 3) { //current_max_importance++; printf("Printing File"); FILE *out_file = fopen("regress.asim", "w"); if (out_file) { //output_stream_open( OUT_ERROR); int i; double v, dv, disp; float error = 0.0f; for (i = 0; i < fitness_cases; ++i) { g.x = app_fitness_cases[0][i]; v = evaluate_tree( ((pop->ind) + optimal_index_in_generation[generation_No])->tr[0].data, 0); dv = app_fitness_cases[1][i]; disp = fabs(dv - v); error += disp; } error = error / fitness_cases; fprintf( out_file, 50, "%f", (float)g.x); fprintf( out_file, 50, " %f", (float) error); fprintf( out_file, 50, "\n"); fclose(out_file); // output_stream_close( OUT_ERROR); termination_override = 1; } } printf("Index: %d ERR : %f -Index %d Same : %i\n", generation_No, optimal_in_generation[generation_No], optimal_index_in_generation[generation_No], same_optimal_count); }
/* print an individual fitness record */ void print_individual_fitness( const individual_fitness* i_fit, int tablevel ) { tabs( tablevel ); printf( "<Individual Fitness Record>\n" ); tabs( tablevel + 1 ); printf("Fitness: %d\n", i_fit->fitness ); print_individual( i_fit->individual, tablevel + 1 ); tabs( tablevel ); printf( "</Individual Fitness Record>\n" ); }
void print_individual_stdout ( individual *ind ) { print_individual ( ind, stdout ); }
void operator_crossover ( population *oldpop, population *newpop, void *data ) { crossover_data * cd; int p1, p2; int ps1, ps2; int l1, l2; lnode *st[3]; int sts1, sts2; int ns1, ns2; int badtree1, badtree2; double total; int forceany1, forceany2; int repcount; int f, t1, t2, j; double r, r2; int totalnodes1, totalnodes2; int i; /* get the crossover-specific data structure. */ cd = (crossover_data *)data; total = cd->internal + cd->external; /* choose a function set. */ r = random_double() * cd->treetotal; for ( f = 0; r >= cd->func[f]; ++f ); /* fill in the "treecumul" array, zeroing all trees which don't use the selected function set. */ r = 0.0; t1 = 0; for ( j = 0; j < tree_count; ++j ) { if ( tree_map[j].fset == f ) r = (cd->treecumul[j] = r + cd->tree[j]); else cd->treecumul[j] = r; } /* select the first and second trees. */ r2 = random_double() * r; for ( t1 = 0; r2 >= cd->treecumul[t1]; ++t1 ); r2 = random_double() * r; for ( t2 = 0; r2 >= cd->treecumul[t2]; ++t2 ); #ifdef DEBUG_CROSSOVER printf ( "selected function set %d --> t1: %d; t2: %d\n", f, t1, t2 ); #endif /* choose two parents */ p1 = cd->sc->select_method ( cd->sc ); ps1 = oldpop->ind[p1].tr[t1].nodes; /* if the tree only has one node, we obviously can't do fucntionpoint crossover. use anypoint instead. */ forceany1 = (ps1==1||total==0.0); p2 = cd->sc2->select_method ( cd->sc2 ); ps2 = oldpop->ind[p2].tr[t2].nodes; forceany2 = (ps2==1||total==0.0); #ifdef DEBUG_CROSSOVER fprintf ( stderr, "parent 1 is:\n" ); print_individual ( oldpop->ind+p1, stderr ); fprintf ( stderr, "parent 2 is:\n" ); print_individual ( oldpop->ind+p2, stderr ); #endif while(1) { /* choose two crossover points */ if ( forceany1 ) { /* choose any point. */ l1 = random_int ( ps1 ); st[1] = get_subtree ( oldpop->ind[p1].tr[t1].data, l1 ); } else if ( total*random_double() < cd->internal ) { /* choose an internal point. */ l1 = random_int ( tree_nodes_internal (oldpop->ind[p1].tr[t1].data) ); st[1] = get_subtree_internal ( oldpop->ind[p1].tr[t1].data, l1 ); } else { /* choose an external point. */ l1 = random_int ( tree_nodes_external (oldpop->ind[p1].tr[t1].data) ); st[1] = get_subtree_external ( oldpop->ind[p1].tr[t1].data, l1 ); } if ( forceany2 ) { /* choose any point on second parent. */ l2 = random_int ( ps2 ); st[2] = get_subtree ( oldpop->ind[p2].tr[t2].data, l2 ); } else if ( total*random_double() < cd->internal ) { /* choose internal point. */ l2 = random_int ( tree_nodes_internal (oldpop->ind[p2].tr[t2].data) ); st[2] = get_subtree_internal ( oldpop->ind[p2].tr[t2].data, l2 ); } else { /* choose external point. */ l2 = random_int ( tree_nodes_external (oldpop->ind[p2].tr[t2].data) ); st[2] = get_subtree_external ( oldpop->ind[p2].tr[t2].data, l2 ); } #ifdef DEBUG_CROSSOVER printf ( "subtree 1 is: " ); print_tree ( st[1], stdout ); printf ( "subtree 2 is: " ); print_tree ( st[2], stdout ); #endif /* count the nodes in the selected subtrees. */ sts1 = tree_nodes ( st[1] ); sts2 = tree_nodes ( st[2] ); /* calculate the sizes of the offspring. */ ns1 = ps1 - sts1 + sts2; ns2 = ps2 - sts2 + sts1; totalnodes1 = ns1; totalnodes2 = ns2; #ifdef DEBUG_CROSSOVER printf ( "newtree 1 has size %d; limit is %d\n", ns1, tree_map[t1].nodelimit ); #endif /** validate the first offspring against the tree node and depth limits; set "badtree1" if any are violated. **/ badtree1 = 0; if ( tree_map[t1].nodelimit > -1 && ns1 > tree_map[t1].nodelimit ) badtree1 = 1; else if ( tree_map[t1].depthlimit > -1 ) { ns1 = tree_depth_to_subtree ( oldpop->ind[p1].tr[t1].data, st[1] ) + tree_depth ( st[2] ); #ifdef DEBUG_CROSSOVER printf ( "newtree 1 has depth %d; limit is %d\n", ns1, tree_map[t1].depthlimit ); #endif if ( ns1 > tree_map[t1].depthlimit ) badtree1 = 1; } /* if we're supposed to keep trying, skip up and choose new crossover points. */ if ( cd->keep_trying && badtree1 ) continue; /** validate the second offspring against the tree node and depth limits; set "badtree2" if any are violated. **/ badtree2 = 0; if ( tree_map[t2].nodelimit > -1 && ns2 > tree_map[t2].nodelimit ) badtree2 = 1; else if ( tree_map[t2].depthlimit > -1 ) { ns2 = tree_depth_to_subtree ( oldpop->ind[p2].tr[t2].data, st[2] ) + tree_depth ( st[1] ); if ( ns2 > tree_map[t2].depthlimit ) badtree2 = 1; } /* if we're supposed to keep trying, skip up and choose new crossover points. */ if ( cd->keep_trying && badtree2 ) continue; /* check both offspring against the individual node limits, set badtree1 and/or badtree2 if either is too big. */ if ( ind_nodelimit > -1 ) { for ( i = 0; i < tree_count; ++i ) { if ( i != t1 ) totalnodes1 += oldpop->ind[p1].tr[i].nodes; if ( i != t2 ) totalnodes2 += oldpop->ind[p2].tr[i].nodes; } badtree1 |= (totalnodes1 > ind_nodelimit); badtree2 |= (totalnodes2 > ind_nodelimit); #ifdef DEBUG_CROSSOVER printf ( "newind 1 has %d nodes; limit is %d\n", totalnodes1, ind_nodelimit ); #endif } /* choose new crossover points if either tree is too big. */ if ( cd->keep_trying && (badtree1 || badtree2) ) continue; /* copy the first parent to the first offspring position */ duplicate_individual ( newpop->ind+newpop->next, oldpop->ind+p1 ); if ( !badtree1 ) { /* if the first offspring is allowable... */ #ifdef DEBUG_CROSSOVER fprintf ( stderr, "offspring 1 is allowable.\n" ); #endif /* make a copy of the crossover tree, replacing the selected subtree with the crossed-over subtree. */ copy_tree_replace_many ( 0, oldpop->ind[p1].tr[t1].data, st+1, st+2, 1, &repcount ); if ( repcount != 1 ) { /* this can't happen, but check anyway. */ error ( E_FATAL_ERROR, "botched crossover: this can't happen" ); } /* free the appropriate tree of the new individual */ free_tree ( newpop->ind[newpop->next].tr+t1 ); /* copy the crossovered tree to the freed space */ gensp_dup_tree ( 0, newpop->ind[newpop->next].tr+t1 ); /* the new individual's fitness fields are of course invalid. */ newpop->ind[newpop->next].evald = EVAL_CACHE_INVALID; newpop->ind[newpop->next].flags = FLAG_NONE; } else { /* offspring too big but keep_trying not set, just leave the copied parent 1 in the offspring position. */ #ifdef DEBUG_CROSSOVER fprintf ( stderr, "offspring 1 is too big; copying parent 1.\n" ); #endif } /* we've just filled in one member of the new population. */ ++newpop->next; #ifdef DEBUG_CROSSOVER fprintf ( stderr, "offspring 1:" ); if ( newpop->ind[newpop->next-1].evald == EVAL_CACHE_VALID ) fprintf ( stderr, " (valid)\n" ); else fprintf ( stderr, " (invalid)\n" ); print_individual ( newpop->ind+(newpop->next-1), stderr ); #endif /* if the new population needs another member (it's not full) */ if ( newpop->next < newpop->size ) { /* copy the second parent to the second offspring position. */ duplicate_individual ( newpop->ind+newpop->next, oldpop->ind+p2 ); if ( !badtree2 ) { /* if the second offspring is allowable... */ #ifdef DEBUG_CROSSOVER fprintf ( stderr, "offspring 2 is allowable.\n" ); #endif /* then make a copy of the tree, replacing the crossover subtree. */ copy_tree_replace_many ( 0, oldpop->ind[p2].tr[t2].data, st+2, st+1, 1, &repcount ); if ( repcount != 1 ) { error ( E_FATAL_ERROR, "bad crossover: this can't happen" ); } /* free the old tree in the new individual, and replace it with the crossover tree. */ free_tree ( newpop->ind[newpop->next].tr+t2 ); gensp_dup_tree ( 0, newpop->ind[newpop->next].tr+t2 ); newpop->ind[newpop->next].evald = EVAL_CACHE_INVALID; newpop->ind[newpop->next].flags = FLAG_NONE; } else { /* offspring too big but keep_trying not set; just leave the copy of parent 2 where it is. */ #ifdef DEBUG_CROSSOVER fprintf ( stderr, "offspring 2 is big; copying parent 2.\n" ); #endif } ++newpop->next; #ifdef DEBUG_CROSSOVER fprintf ( stderr, "offspring 2:" ); if ( newpop->ind[newpop->next-1].evald == EVAL_CACHE_VALID ) fprintf ( stderr, " (valid)\n" ); else fprintf ( stderr, " (invalid)\n" ); print_individual ( newpop->ind+(newpop->next-1), stderr ); #endif } #ifdef DEBUG_CROSSOVER else { /* the first offspring filled the population, discard the second. */ fprintf ( stderr, "offspring 2 not needed.\n\n" ); } #endif break; } #ifdef DEBUG_CROSSOVER printf ( "CROSSOVER COMPLETE.\n\n\n" ); #endif }
int main ( int argc, char **argv ) { // check if param is given and used to seed if ( argc <= 1 ) { printf("Usage: %s <seed>\n", argv[0]); return -1; } // get the seed from the user int seed = atoi(argv[1]); // initialize the random generator srand(seed); // the most-used variable around :) int i; ///// // initialize the population int population[MAX_MUTATIONS]; for ( i = 0 ; i < MAX_MUTATIONS ; i++ ) population[i] = 0; // generate the first random individual int a[GENOTYPE_LENGTH]; rand_init(a); // mark it as known in the population population[hash(a)] = 1; // generate the second random individual (different) int b[GENOTYPE_LENGTH]; do { rand_init(b); } while ( population[hash(b)] != 0 ); population[hash(b)] = 1; int winner[GENOTYPE_LENGTH], loser[GENOTYPE_LENGTH]; int winner_bitflipped[GENOTYPE_LENGTH], loser_bitflipped[GENOTYPE_LENGTH]; ///// // the actual GA int round_tot = evolve_both(a, b, winner, loser, population); ///// // regenerate the complementary individuals bitflip(winner, winner_bitflipped); bitflip(loser, loser_bitflipped); printf("%d (%d %d)\t", round_tot, sum(winner), prod(winner_bitflipped)); print_individual(winner); printf("\t"); print_individual(winner_bitflipped); printf("\n"); return 0; }