bat_t algorithm(float A, float r, uint pop_size, uint max_it, fit_t (*fit_fnc)(bat_t &), float q_min=0, float q_max=MAX/10, uint debug=1, std::vector<float> *avg_fit_at_it=NULL, std::vector<float> *best_at_iter=NULL) { srand(time(NULL)); /*inits randomness*/ bats_t population; bats_fit_t fit; std::vector<float> Q(pop_size); /*frequency*/ std::vector<bat_t> v(pop_size); /*bats velocity*/ /*inits bats velocity to zero*/ std::for_each(v.begin(), v.end(), [](bat_t &velocity) { velocity = init_bat(BAT_LENGTH, 0.0, 0.0); }); init_population(population, pop_size, BAT_LENGTH); init_fit(fit, pop_size); uint it = 0; do { /*one iteration of bat alg.*/ evaluate_population(fit, population, fit_fnc); bat_t best_bat = utils::return_best_bat(population, fit); if (debug >=2) { best_at_iter->push_back(fit_fnc(best_bat)); avg_fit_at_it->push_back(std::accumulate(fit.begin(), fit.end(), 0.0) / fit.size()); } uint index = 0; std::for_each(population.begin(), population.end(), [&](bat_t &bat) { //Q[index] = utils::rand_in<float>(Q_MIN, Q_MAX); Q[index] = utils::rand_in<float>(0.0, 0.1); bat_t candidate_v = v[index] + (bat - best_bat)*Q[index]; bat_t candidate_bat = bat + candidate_v; if (utils::rand_in<float>(0.0,1.0) > r) { /*random walk in direction of candidate_v scalled down by q_max/100 factor*/ for (int i=0;i<2;i++) { candidate_v = init_bat(BAT_LENGTH)*(q_max/100); candidate_bat = best_bat+candidate_v; } } /*evaluate candidate solution, it might be either solution found by appling movement equotions to current solution or by using random walk around best solution*/ float candidate_bat_fit = fit_fnc(candidate_bat); /*accept candidate solution as current solution if better or if not better accept solution with some small probability*/ if (candidate_bat_fit < fit[index] || utils::rand_in<float>(0.0,1.0) < A) { bat = candidate_bat; v[index] = candidate_v; fit[index] = candidate_bat_fit; } index++; }); if (debug>=1 && it%100==1) { evaluate_population(fit, population, fit_fnc); bat_t best = utils::return_best_bat(population, fit); std::cout << "at iteration: " << it << " pop avg fit: " << std::accumulate(fit.begin(), fit.end(), 0.0) / fit.size() << " best bat fit: " << fit_fnc(best) << std::endl; } }while(++it < max_it); /*find and return best solution*/ evaluate_population(fit, population, fit_fnc); return utils::return_best_bat(population, fit); }
int main() { extern counter; /* test create_population */ population* pop; population_fitness* pop_fit; int x; counter = 0; pop = create_population( 0, &create_individual ); if( pop == 0 ) { printf( "population not created at line: %d\n", __LINE__ ); } else { print_population( pop, 0 ); delete_population( pop ); pop = 0; } counter = 0; pop = create_population( 1, &create_individual ); if( pop == 0 ) { printf( "population not created at line: %d\n", __LINE__ ); } else { print_population( pop, 0 ); delete_population( pop ); pop = 0; } counter = 0; pop = create_population( 10, &create_individual ); if( pop == 0 ) { printf( "population not created at line: %d\n", __LINE__ ); } else { print_population( pop, 0 ); print_population_compact( pop ); delete_population( pop ); pop = 0; } counter = 0; printf( "create_population large test: " ); fflush( stdout ); pop = create_population( INT_MAX / 64, &create_individual ); if( pop == 0 ) { printf( "population not created at line: %d\n", __LINE__ ); } else { delete_population( pop ); pop = 0; } printf( "complete\n" ); /* memory leak test */ printf( "create_population memory test: " ); #ifdef MEMLEAK fflush( stdout ); for( x = 0; x < INT_MAX; x++ ) { counter = 0; pop = create_population( 10, &create_individual ); if( pop == 0 ) { eprintf( "population not created at line: %d\n", __LINE__ ); } else { delete_population( pop ); pop = 0; } } printf( "complete\n" ); # else printf( "skipped\n" ); #endif /* test create_empty_population */ pop = create_empty_population( -1 ); if( pop == 0 ) { printf( "population not created at line: %d\n", __LINE__ ); } else { print_population( pop, 0 ); delete_population( pop ); pop = 0; } pop = create_empty_population( 0 ); if( pop == 0 ) { printf( "population not created at line: %d\n", __LINE__ ); } else { print_population( pop, 0 ); delete_population( pop ); pop = 0; } pop = create_empty_population( 1 ); if( pop == 0 ) { printf( "population not created at line: %d\n", __LINE__ ); } else { print_population( pop, 0 ); delete_population( pop ); pop = 0; } pop = create_empty_population( 10 ); if( pop == 0 ) { printf( "population not created at line: %d\n", __LINE__ ); } else { print_population( pop, 0 ); print_population_compact( pop ); delete_population( pop ); pop = 0; } printf( "create_empty_population large test: " ); fflush( stdout ); pop = create_empty_population( INT_MAX / 64 ); if( pop == 0 ) { printf( "population not created at line: %d\n", __LINE__ ); } else { delete_population( pop ); pop = 0; } printf( "complete\n" ); /* memory leak test */ printf( "create_population memory test: " ); #ifdef MEMLEAK fflush( stdout ); for( x = 0; x < INT_MAX; x++ ) { counter = 0; pop = create_empty_population( 10 ); if( pop == 0 ) { eprintf( "population not created at line: %d\n", __LINE__ ); } else { delete_population( pop ); pop = 0; } } printf( "complete\n" ); #else printf( "skipped\n" ); #endif /* test evaluate_population */ counter = 0; pop = create_empty_population( 1 ); if( pop == 0 ) { printf( "population not created at line: %d\n", __LINE__ ); } else { pop_fit = evaluate_population( pop, &evaluate_individual ); if( pop_fit == 0 ) { printf( "population fitness not created at line: %d\n", __LINE__ ); } else { print_population_fitness( pop_fit, 0 ); print_population_fitness_compact( pop_fit ); delete_population_fitness( pop_fit ); pop_fit = 0; } delete_population( pop ); pop = 0; } pop = create_population( 1, &create_individual ); if( pop == 0 ) { printf( "population not created at line: %d\n", __LINE__ ); } else { pop_fit = evaluate_population( pop, &evaluate_individual ); if( pop_fit == 0 ) { printf( "population fitness not created at line: %d\n", __LINE__ ); } else { print_population_fitness( pop_fit, 0 ); print_population_fitness_compact( pop_fit ); delete_population_fitness( pop_fit ); pop_fit = 0; } delete_population( pop ); pop = 0; } pop = create_population( 10, &create_individual ); if( pop == 0 ) { printf( "population not created at line: %d\n", __LINE__ ); } else { pop_fit = evaluate_population( pop, &evaluate_individual ); if( pop_fit == 0 ) { printf( "population fitness not created at line: %d\n", __LINE__ ); } else { print_population_fitness( pop_fit, 0 ); print_population_fitness_compact( pop_fit ); delete_population_fitness( pop_fit ); pop_fit = 0; } delete_population( pop ); pop = 0; } printf( "evaluate_population large test: " ); fflush( stdout ); pop = create_population( INT_MAX / 64, &create_individual ); if( pop == 0 ) { printf( "population not created at line: %d\n", __LINE__ ); } else { pop_fit = evaluate_population( pop, &evaluate_individual ); if( pop_fit == 0 ) { printf( "population_fitness not created at line: %d\n", __LINE__ ); } else { delete_population_fitness( pop_fit ); pop_fit = 0; } delete_population( pop ); pop = 0; } printf( "complete\n" ); /* memory leak test */ printf( "evaluate_population memory test: " ); #ifdef MEMLEAK fflush( stdout ); counter = 0; pop = create_population( 10, &create_individual ); if( pop == 0 ) { eprintf( "population not created at line: %d\n", __LINE__ ); } else { for( x = 0; x < INT_MAX; x++ ) { pop_fit = evaluate_population( pop, &evaluate_individual ); delete_population_fitness( pop_fit ); pop_fit = 0; } delete_population( pop ); pop = 0; } printf( "complete\n" ); #else printf( "skipped\n" ); #endif /* test sort_population */ counter = 0; pop = create_population( 100, &create_individual ); pop_fit = evaluate_population( pop, &evaluate_individual ); sort_population( pop_fit ); delete_population_fitness( pop_fit ); pop_fit = 0; delete_population( pop ); pop = 0; /* test create_next_generation */ counter = 0; pop = create_population( 100, &create_individual ); pop_fit = evaluate_population( pop, &evaluate_individual ); counter = 0; population* pop_next = create_next_generation( 10, 10, 80, pop, pop_fit, &compare_individuals_fitness ); delete_population_fitness( pop_fit ); pop_fit = 0; delete_population( pop ); pop = 0; delete_population( pop_next ); pop_next = 0; /* test create_population_fitness */ // pop_fit = create_population_fitness( 100 ); /* test delete_population_fitness */ // delete_population_fitness( pop_fit ); /* former tests */ /* srand( time_seed() ); population* pop; population_fitness* pop_fit; population_fitness* pop_fit_sorted; pop = create_population( 3, &create_individual ); print_population( pop, 0 ); pop_fit = evaluate_population( pop, &evaluate_individual ); print_population_fitness( pop_fit, 0 ); delete_population_fitness( pop_fit ); delete_population( pop ); pop = create_population( 4, &create_individual ); individual* ic; individual* im; ic = copy_individual( pop->individuals[0] ); im = mutate_individual( pop->individuals[0], 2 ); delete_individual( pop->individuals[1] ); pop->individuals[1] = ic; delete_individual( pop->individuals[2] ); pop->individuals[2] = im; evaluate_population( pop, &evaluate_individual ); printf( "i1: original, i2: copy, i3 mutant (degree 2)\n" ); print_population( pop, 0 ); delete_population( pop ); pop = create_population( 3, &create_individual ); individual* off; off = mate_individuals( pop->individuals[0], pop->individuals[1], 1 ); delete_individual( pop->individuals[2] ); pop->individuals[2] = off; evaluate_population( pop, &evaluate_individual ); printf( "i1: parent1, i2: parent2, i3 offspring\n" ); print_population( pop, 0 ); delete_population( pop ); */ /* pop = create_population( 100, &create_individual ); pop_fit = evaluate_population( pop, &evaluate_individual ); print_population_fitness( pop_fit, 0 ); pop_fit_sorted = sort_population( pop_fit ); printf( "Original Population Fitness\n" ); print_population_fitness( pop_fit, 0 ); printf( "Sorted Population Fitness\n" ); print_population_fitness( pop_fit_sorted, 0 ); */ }