void CGeneticSystem::stepGeneration(){ //stepGeneration2(); //return; std::vector<CChromo> newPopulation(m_populationSize*2); for(int i = 0; i < m_populationSize*2; i++) { CChromo p(m_noCitys , m_distMatrix); newPopulation[i] = p; } int newPopulationSize = 0; SortPopulation(m_ChromoPopulation,false); computeFitness(); for(int i = 0; i < m_populationSize; i++) { for(int j = 0; j < m_noCitys; j++) { int test = m_ChromoPopulation[i].getGene(j); newPopulation[i].setGene(j,test ); } newPopulationSize++; } while(newPopulationSize < 2*m_populationSize) { int idx1 =0; //tournamentSelection(); int idx2 =0; //tournamentSelection(); while(idx1 == idx2) { idx2= tournamentSelection(); idx1= tournamentSelection(); } CChromo &pfather=m_ChromoPopulation[idx2]; CChromo &pMother=m_ChromoPopulation[idx1]; CChromo p_offspring1(m_noCitys,m_distMatrix) , p_offspring2(m_noCitys,m_distMatrix); pMother.crossover(&pfather, &p_offspring1, &p_offspring2); newPopulation[newPopulationSize] = p_offspring1; newPopulationSize++; if(newPopulationSize >= newPopulation.size()) break; newPopulation[newPopulationSize] = p_offspring2; newPopulationSize++; } mutatePopulation(newPopulation); SortPopulation(newPopulation , true); //ass for(int i = 0; i < m_populationSize-2; i++) //keep last best { m_ChromoPopulation[i] = newPopulation[i]; } SortPopulation(m_ChromoPopulation , true); updateBestSoFarPath(); }
void CGeneticSystem::stepGeneration2() { std::vector<CChromo> newPopulation(m_populationSize*2); for(int i = 0; i < m_populationSize*2; i++) { CChromo p(m_noCitys , m_distMatrix); newPopulation[i] = p; } int newPopulationSize = 0; SortPopulation(m_ChromoPopulation , false); computeFitness(); for(int i = 0; i < m_populationSize; i++) { for(int j = 0; j < m_noCitys; j++) { int test = m_ChromoPopulation[i].getGene(j); newPopulation[i].setGene(j,test ); } newPopulationSize++; } while (newPopulationSize < 2*m_populationSize) { int idx1 = tournamentSelection(); int idx2 = tournamentSelection(); CChromo offspring = m_ChromoPopulation[idx1].CrossOver2(&m_ChromoPopulation[idx2]); newPopulation[newPopulationSize] = offspring; newPopulationSize++; } mutatePopulation(newPopulation); SortPopulation(newPopulation , true); for(int i = 0; i < m_populationSize; i++) { m_ChromoPopulation[i] = newPopulation[i]; } SortPopulation(m_ChromoPopulation,true); updateBestSoFarPath(); }
void improveGlobalPopulation(int * initialPopulation , int startRow , int offSpringCount , unsigned int **dMat){ int i , k; double dadFitness, tourFitness; struct timeval globalTime; /* Use two most fittest solution to generate children */ int * dad = (int *)malloc(sizeof(int) * NUM_CITIES); int * mom = (int *)malloc(sizeof(int) * NUM_CITIES); /* Temporary Structures */ int ** firstPath, ** secondPath; char ch = 'u'; firstPath = (int **)malloc(sizeof(int *) * (NUM_CITIES + 1)); secondPath = (int **)malloc(sizeof(int *) * (NUM_CITIES + 1)); int * globalPopPool = (int *)malloc(sizeof(int) * NUM_CITIES); char * status = (char * )malloc(sizeof(char) * (NUM_CITIES + 1)); int curLoc , flag, offset , pos , temp , buf; unsigned int distanceMin ; for (i = 0 ; i <= NUM_CITIES ; i++){ firstPath[i] = (int *)malloc(sizeof(int) * 2); firstPath[i][0] = firstPath[0][1] = -1; secondPath[i] = (int *)malloc(sizeof(int) * 2); secondPath[i][0] = secondPath[i][1] = -1; } /* Make temporary copy of most fit solutions */ memcpy(dad , &initialPopulation[startRow * NUM_CITIES] , NUM_CITIES * sizeof(int)) ; memcpy(mom , &initialPopulation[(startRow + 1 ) * NUM_CITIES] , NUM_CITIES * sizeof(int)) ; CheckValidity(dad , "Dad"); CheckValidity(mom , "Mom"); dadFitness = computeFitness(dad , dMat); // printf("Dad"); printTour(dad); printf("\t"); gettimeofday(&globalTime, 0); printf("Dad Fitness : %0.2lf , Global Time %ld\n " , dadFitness, globalTime.tv_usec); // printf("Mom"); printTour(mom); printf("\t"); gettimeofday(&globalTime, 0); printf("Mom Fitness : %0.2lf , Global Time %ld\n " , computeFitness(mom , dMat), globalTime.tv_usec); /* Special cases */ firstPath[dad[0]][1] = -1; secondPath[mom[0]][1] = -1; firstPath[dad[0]][0] = dad[1]; secondPath[mom[0]][0] = mom[1]; firstPath[dad[NUM_CITIES - 1]][0] = -1; secondPath[mom[NUM_CITIES - 1]][0] = -1; firstPath[dad[NUM_CITIES - 1]][1] = dad[NUM_CITIES - 2]; secondPath[mom[NUM_CITIES - 1]][1] = mom[NUM_CITIES - 2]; for (i = 1 ; i < NUM_CITIES - 1 ; i++){ firstPath[dad[i]][0] = dad[i+1]; secondPath[mom[i]][0] = mom[i+1]; firstPath[dad[i]][1] = dad[i-1]; secondPath[mom[i]][1] = mom[i-1]; } /* for (i = 1 ; i <= NUM_CITIES ; i++){ printf("\n\t%d)\t%d %d \t\t%d %d", i , firstPath[i][0] , firstPath[i][1] ,secondPath[i][0] , secondPath[i][1]); } */ curLoc = 0; flag = 0; for (i = 0 ; i < NUM_CITIES ; i++) { if ( ( firstPath[dad[i]][0] != -1) && ((firstPath[dad[i]][0] == secondPath[dad[i]][0]) || (firstPath[dad[i]][0] == secondPath[dad[i]][1])) ) { if (!flag){ globalPopPool[curLoc++] = dad[i]; flag = 1; } } else{ globalPopPool[curLoc++] = dad[i]; flag = 0; } } for (i = 0 ; i < offSpringCount ; i++) { /* To optimize */ for (k = 0 ; k <= NUM_CITIES ; k++) status[k] = 'u'; initialPopulation[(startRow + i) * NUM_CITIES] = globalPopPool[rand_int(curLoc)]; offset = 1; temp = initialPopulation[(startRow + i) * NUM_CITIES] ; status[temp] = 'v'; while(offset < NUM_CITIES) { if ( (firstPath[temp][0] != -1 ) && (status[firstPath[temp][0]] == 'u') && (( firstPath[temp][0] == secondPath[temp][0]) || (firstPath[temp][0] == secondPath[temp][1]) )) { initialPopulation[(startRow + i) * NUM_CITIES + offset] = firstPath[temp][0]; temp = firstPath[temp][0]; status[temp] = 'v'; } else { /* find nearest element from current city */ distanceMin = INT_MAX; pos = 0; for ( k = 0 ; k < curLoc ; k++ ) { buf = dMat[temp-1][globalPopPool[k]-1]; if(status[globalPopPool[k]] == 'u' && buf < distanceMin) { distanceMin = buf; pos = k; } } initialPopulation[(startRow + i) * NUM_CITIES + offset] = globalPopPool[pos]; temp = globalPopPool[pos]; status[temp] = 'v'; } offset += 1; } /******************************************** Tour Statistics *******************************/ CheckValidity(&initialPopulation[(startRow + i) * NUM_CITIES] , "New population Generation"); tourFitness = computeFitness(&initialPopulation[(startRow + i) * NUM_CITIES] , dMat); if (tourFitness < dadFitness){ memcpy(&initialPopulation[(startRow + i) * NUM_CITIES] , dad , NUM_CITIES * sizeof(int)); //printf("\nTour %d : " , i); //tourFitness = computeFitness(&initialPopulation[(startRow + i) * NUM_CITIES] , dMat); // printTour(&initialPopulation[(startRow + i) * NUM_CITIES]); //gettimeofday( &globalTime, 0 ); //printf("\n\tFitness : %0.2lf , Global Time Improved Fitness %ld " , tourFitness, globalTime.tv_usec); } //else /* Reject this new tour because it is less fitter than the parent */ // i--; /********************************************************************************************/ } free(firstPath); free(secondPath); free(globalPopPool); free(status); free(dad); free(mom); }
int main (int argc, const char * argv[]) { #pragma mark Configuration const int generation_size = 40; const int generation_count = 10000; const float mutation = 0.1; const int time_total = 60000; // should be the same as in kernel.cl srand(time(NULL)); #pragma mark Allocate standard memory int * c_position = (int *) malloc(generation_size * sizeof(int)); int * c_velocity = (int *) malloc(generation_size * sizeof(int)); int * p_angle = (int *) malloc(generation_size * sizeof(int)); int * p_velocity = (int *) malloc(generation_size * sizeof(int)); int * fitness = (int *) malloc(generation_size * sizeof(int)); int fitness_sum = 0; int best_key = 0; int * next_c_position = (int *) malloc(generation_size * sizeof(int)); int * next_c_velocity = (int *) malloc(generation_size * sizeof(int)); int * next_p_angle = (int *) malloc(generation_size * sizeof(int)); int * next_p_velocity = (int *) malloc(generation_size * sizeof(int)); #pragma mark Generate first generation for (int i = 0; i < generation_size; i++) { int sign = rand() % 2 == 1 ? 1 : -1; next_c_position[i] = sign * rand() % 1000; next_c_velocity[i] = sign * rand() % 1000; next_p_angle[i] = sign * rand() % 1000; next_p_velocity[i] = sign * rand() % 1000; // fitness[i] = 0; } #pragma mark Genetical algorithm int n; int last_sum = 0; for (n = 0; n < generation_count; n++) { c_position = next_c_position; c_velocity = next_c_velocity; p_angle = next_p_angle; p_velocity = next_p_velocity; fitness_sum = 0; best_key = 0; computeFitness(c_position, c_velocity, p_angle, p_velocity, fitness, generation_size); // prevent computing generation in the last cycle if (n == generation_count - 1) break; int fitness_max = 0; // TODO: allocate it only once int * border = (int *) malloc(generation_size * sizeof(int)); for (int i = 0; i < generation_size; i++) { fitness_sum += fitness[i]; if (fitness[i] > fitness_max) { fitness_max = fitness[i]; best_key = i; } if (i == 0) { border[i] = fitness[i]; } else { border[i] = border[i - 1] + fitness[i]; } } // break if best solution is already found if (fitness_max >= time_total) break; //printf("gen[%d] best_fitness = \t%d\t[%d]\t%s\n", n, fitness_max, fitness_sum, last_sum < fitness_sum ? "up" : "FALLS"); last_sum = fitness_sum; // Elite - always copy the best one next_c_position[0] = c_position[best_key]; next_c_velocity[0] = c_velocity[best_key]; next_p_angle[0] = p_angle[best_key]; next_p_velocity[0] = p_velocity[best_key]; for (int k = 1; k < generation_size; k++) { int key_parent_1 = 0; int key_parent_2 = 0; // Get weighted entity (roulette wheel implementation) int roll = rand() % fitness_sum; int i; for (i = 0; i < generation_size; i++) { if (roll < border[i]) { break; } } key_parent_1 = i; roll = rand() % fitness_sum; for (i = 0; i < generation_size; i++) { if (roll < border[i]) { break; } } key_parent_2 = i; printf("%d\t", c_position[k]); // Prepare next generation as combination of two parens, with mutation next_c_position[k] = c_position[key_parent_1] + mutation * (rand() % 2 == 1 ? 1 : -1) * (rand() % (c_position[key_parent_1] == 0 ? 1 : c_position[key_parent_1])); next_c_velocity[k] = c_velocity[key_parent_1] + mutation * (rand() % 2 == 1 ? 1 : -1) * (rand() % (c_velocity[key_parent_1] == 0 ? 1 : c_velocity[key_parent_1])); next_p_angle[k] = p_angle[key_parent_2] + mutation * (rand() % 2 == 1 ? 1 : -1) * (rand() % (p_angle[key_parent_2] == 0 ? 1 : p_angle[key_parent_2])); next_p_velocity[k] = p_velocity[key_parent_2] + mutation * (rand() % 2 == 1 ? 1 : -1) * (rand() % (p_velocity[key_parent_2] == 0 ? 1 : p_velocity[key_parent_2])); } printf("\n"); } printf("Solution:\n\tfitness = %d\n\tc1 = %d\n\tc2 = %d\n\tc3 = %d\n\tc4 = %d\n", fitness[best_key], c_position[best_key], c_velocity[best_key], p_angle[best_key], p_velocity[best_key]); terminateGPU(); return 0; // comment to run tests #pragma mark - #pragma mark Debug printf("\nENTERING DEBUG SCOPE:\n\n"); initiated = 0; // so the context is new #pragma mark - GPU test printf("GPU fitness again:\n"); int k = generation_size; int * test_c_position = (int *) malloc(k * sizeof(int)); int * test_c_velocity = (int *) malloc(k * sizeof(int)); int * test_p_angle = (int *) malloc(k * sizeof(int)); int * test_p_velocity = (int *) malloc(k * sizeof(int)); int * test_fitness = (int *) malloc(k * sizeof(int)); for (int i = 0; i < k; i++) { test_c_position[i] = c_position[best_key]; test_c_velocity[i] = c_velocity[best_key]; test_p_angle[i] = p_angle[best_key]; test_p_velocity[i] = p_velocity[best_key]; } computeFitness(test_c_position, test_c_velocity, test_p_angle, test_p_velocity, test_fitness, 1); for (int i = 0; i < k; i++) { printf("Test Solution:\n\tfitness = %d\n\tc1 = %d\n\tc2 = %d\n\tc3 = %d\n\tc4 = %d\n", test_fitness[i], test_c_position[i], test_c_velocity[i], test_p_angle[i], test_p_velocity[i]); break; // since all the results are the same } terminateGPU(); #pragma mark - CPU test and Visualization printf("CPU fitness:\n"); char command[254]; FILE *fp; char output[254]; // link this to to the Visualization binary sprintf(command, "/Volumes/Data/Projects/PoleBalanceGPU/Visualization/build/Debug/Visualization %d %d %d %d", c_position[best_key], c_velocity[best_key], p_angle[best_key], p_velocity[best_key]); fp = popen(command, "r"); if (fp == NULL) { printf("Failed to run command\n" ); exit; } while (fgets(output, sizeof(output), fp) != NULL) { printf("\t%s", output); } int cpu_fitness = atoi(output); // this might fail from time to time since CPU and GPU round implementation differs assert(fitness[best_key] == test_fitness[0] && fitness[best_key] == cpu_fitness); return 0; }