├── plots ├── speedup.png ├── fitness_a280_imp.png ├── fitness_berlin52.png ├── speedup_a280_imp.png ├── speedup_berlin52.png ├── plot.py └── runtimes ├── Makefile ├── Report Travelling-Salesmann-Problem-Using-Genetic-Algorithm-for-Parallel-and-Distributed-Computing.pdf ├── map.h ├── common.h ├── LICENSE ├── maps ├── berlin52.tsp ├── a280.tsp └── brazil58.tsp ├── population.h ├── README.md ├── map.c ├── tspgen.c ├── common.c └── population.c /plots/speedup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kakshak07/Travelling-Salesmann-Problem-Using-Genetic-Algorithm-for-Parallel-and-Distributed-Computing/HEAD/plots/speedup.png -------------------------------------------------------------------------------- /plots/fitness_a280_imp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kakshak07/Travelling-Salesmann-Problem-Using-Genetic-Algorithm-for-Parallel-and-Distributed-Computing/HEAD/plots/fitness_a280_imp.png -------------------------------------------------------------------------------- /plots/fitness_berlin52.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kakshak07/Travelling-Salesmann-Problem-Using-Genetic-Algorithm-for-Parallel-and-Distributed-Computing/HEAD/plots/fitness_berlin52.png -------------------------------------------------------------------------------- /plots/speedup_a280_imp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kakshak07/Travelling-Salesmann-Problem-Using-Genetic-Algorithm-for-Parallel-and-Distributed-Computing/HEAD/plots/speedup_a280_imp.png -------------------------------------------------------------------------------- /plots/speedup_berlin52.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kakshak07/Travelling-Salesmann-Problem-Using-Genetic-Algorithm-for-Parallel-and-Distributed-Computing/HEAD/plots/speedup_berlin52.png -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC=mpicc 2 | CFLAGS=-O2 3 | 4 | tspgen: 5 | $(CC) -O3 -o tspgen *.c -lm -DDEBUG 6 | 7 | .PHONY: clean 8 | clean: 9 | rm -f tspgen 10 | 11 | .PHONY: all 12 | all: tspgen 13 | -------------------------------------------------------------------------------- /Report Travelling-Salesmann-Problem-Using-Genetic-Algorithm-for-Parallel-and-Distributed-Computing.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kakshak07/Travelling-Salesmann-Problem-Using-Genetic-Algorithm-for-Parallel-and-Distributed-Computing/HEAD/Report Travelling-Salesmann-Problem-Using-Genetic-Algorithm-for-Parallel-and-Distributed-Computing.pdf -------------------------------------------------------------------------------- /map.h: -------------------------------------------------------------------------------- 1 | #ifndef MAP_H_ 2 | #define MAP_H_ 3 | 4 | #include"common.h" 5 | 6 | typedef struct{ 7 | unsigned int x; 8 | unsigned int y; 9 | } tspsNode; 10 | 11 | typedef struct{ 12 | int numNodes; 13 | tspsNode *nodes; 14 | } tspsMap_t; 15 | 16 | int parseMap(tspsMap_t *map); 17 | int loadMap(char **file); 18 | 19 | #endif /* MAP_H_ */ 20 | -------------------------------------------------------------------------------- /common.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_H_ 2 | #define COMMON_H_ 3 | 4 | #define TSPS_RC_SUCCESS 0 5 | #define TSPS_RC_FAILURE 1 6 | 7 | #define NUM_NODES 52 8 | #define MPI_MIGRATION_TAG 100 9 | 10 | // Default values 11 | #define DFLT_POPSIZE 5000 12 | #define DFLT_MUTRATE 0.1 13 | #define DFLT_NUMGEN 10000 14 | #define DFLT_NUMELIT 100 15 | #define DFLT_MUTSIZE 2 16 | #define DFLT_MIGRATE 500 17 | #define DFLT_MIGSHAR 0.01 18 | 19 | typedef struct{ 20 | int populationSize; 21 | double mutationRate; 22 | int numGenerations; 23 | int numElitism; 24 | int mutationSize; 25 | int migrationRate; 26 | float migrationShare; 27 | } tspsConfig_t; 28 | 29 | void logg(const char * format, ...); 30 | int readConfig(tspsConfig_t *config, int argc, char **argv); 31 | 32 | #endif /* COMMON_H_ */ 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Kakshak 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /maps/berlin52.tsp: -------------------------------------------------------------------------------- 1 | NAME: berlin52 2 | TYPE: TSP 3 | COMMENT: 52 locations in Berlin (Groetschel) 4 | DIMENSION: 52 5 | EDGE_WEIGHT_TYPE: EUC_2D 6 | NODE_COORD_SECTION 7 | 1 565.0 575.0 8 | 2 25.0 185.0 9 | 3 345.0 750.0 10 | 4 945.0 685.0 11 | 5 845.0 655.0 12 | 6 880.0 660.0 13 | 7 25.0 230.0 14 | 8 525.0 1000.0 15 | 9 580.0 1175.0 16 | 10 650.0 1130.0 17 | 11 1605.0 620.0 18 | 12 1220.0 580.0 19 | 13 1465.0 200.0 20 | 14 1530.0 5.0 21 | 15 845.0 680.0 22 | 16 725.0 370.0 23 | 17 145.0 665.0 24 | 18 415.0 635.0 25 | 19 510.0 875.0 26 | 20 560.0 365.0 27 | 21 300.0 465.0 28 | 22 520.0 585.0 29 | 23 480.0 415.0 30 | 24 835.0 625.0 31 | 25 975.0 580.0 32 | 26 1215.0 245.0 33 | 27 1320.0 315.0 34 | 28 1250.0 400.0 35 | 29 660.0 180.0 36 | 30 410.0 250.0 37 | 31 420.0 555.0 38 | 32 575.0 665.0 39 | 33 1150.0 1160.0 40 | 34 700.0 580.0 41 | 35 685.0 595.0 42 | 36 685.0 610.0 43 | 37 770.0 610.0 44 | 38 795.0 645.0 45 | 39 720.0 635.0 46 | 40 760.0 650.0 47 | 41 475.0 960.0 48 | 42 95.0 260.0 49 | 43 875.0 920.0 50 | 44 700.0 500.0 51 | 45 555.0 815.0 52 | 46 830.0 485.0 53 | 47 1170.0 65.0 54 | 48 830.0 610.0 55 | 49 605.0 625.0 56 | 50 595.0 360.0 57 | 51 1340.0 725.0 58 | 52 1740.0 245.0 59 | EOF 60 | 61 | -------------------------------------------------------------------------------- /population.h: -------------------------------------------------------------------------------- 1 | #ifndef POPULATION_H_ 2 | #define POPULATION_H_ 3 | 4 | #include "common.h" 5 | #include "map.h" 6 | 7 | typedef struct{ 8 | int chrom[NUM_NODES]; 9 | int fitness; 10 | double probability; 11 | int index; 12 | 13 | }tspsIndividual_t; 14 | 15 | typedef struct{ 16 | tspsIndividual_t *individuals; 17 | int numIndividuals; 18 | double totalFitness; 19 | }tspsPopulation_t; 20 | 21 | int generatePopulation(tspsPopulation_t *pop, tspsConfig_t *config); 22 | int generateRandomChromosome(tspsIndividual_t *ind, int index); 23 | int generateRandomChromosome2(tspsIndividual_t *ind); 24 | void swap(int *a, int *b); 25 | double calculateFitnessChromosome(int *chromosome, tspsMap_t *map); 26 | int generateNewPopulation(tspsPopulation_t *pop, tspsConfig_t *config); 27 | int compare (const void *a, const void *b); 28 | int sortPopulation(tspsPopulation_t *pop); 29 | int crossoverPopulation(tspsPopulation_t *pop, tspsConfig_t *config); 30 | int mutatePopulation(tspsPopulation_t *pop, tspsConfig_t *config); 31 | int calculateFitnessPopulation(tspsPopulation_t *pop, tspsMap_t *map); 32 | int migrateIndividuals(tspsPopulation_t *pop, int mpiId, int numProcs, tspsConfig_t *config); 33 | int joinPopulations(tspsPopulation_t *pop, int mpiId, int mpiNumProcs); 34 | void printIndividual(tspsIndividual_t *ind, const char *label); 35 | #endif /* POPULATION_H_ */ 36 | 37 | -------------------------------------------------------------------------------- /plots/plot.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import seaborn as sns 3 | import numpy as np 4 | 5 | def fitness(): 6 | T1 = 26501 7 | T2 = 25225 8 | T4 = 21356 9 | T8 = 11669 10 | #T12 = 442 11 | T16 = 6015 12 | #T20 = 522 13 | T24 = 6426 14 | #X = [ T1/T1, T1/T2, T1/T4, T1/T8, T1/T12, T1/T16, T1/T20, T1/T24 ] 15 | X = [ T1, T2, T4, T8, T16, T24 ] 16 | X = np.asarray(X) 17 | 18 | #labels = ['1', '2', '4', '8', '12', '16', '20', '24'] 19 | labels = ['1', '2', '4', '8', '16', '24'] 20 | 21 | fig, ax = plt.subplots() 22 | fig.canvas.draw() 23 | ax.set_xticklabels(labels) 24 | plt.plot(X.T) 25 | plt.ylabel('Fitness') 26 | plt.xlabel('#Cores') 27 | plt.title('Fitness per cores') 28 | 29 | # draw vertical line from (70,100) to (70, 250) 30 | plt.axhline(y=2579) 31 | 32 | plt.show() 33 | 34 | def speedup(): 35 | T1 = 3706 36 | T2 = 2236 37 | T4 = 1461 38 | T8 = 1076 39 | #T12 = 442 40 | T16 = 810 41 | #T20 = 522 42 | T24 = 688 43 | #X = [ T1/T1, T1/T2, T1/T4, T1/T8, T1/T12, T1/T16, T1/T20, T1/T24 ] 44 | X = [ T1/T1, T1/T2, T1/T4, T1/T8, T1/T16, T1/T24 ] 45 | X = np.asarray(X) 46 | 47 | #labels = ['1', '2', '4', '8', '12', '16', '20', '24'] 48 | labels = ['1', '2', '4', '8', '16', '24'] 49 | 50 | fig, ax = plt.subplots() 51 | fig.canvas.draw() 52 | ax.set_xticklabels(labels) 53 | plt.plot(X.T) 54 | plt.ylabel('Speedup') 55 | plt.xlabel('#Cores') 56 | plt.title('Speedup graph') 57 | plt.show() 58 | 59 | if __name__ == '__main__': 60 | #speedup() 61 | fitness() -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Travelling-Salesmann-Problem-Using-Genetic-Algorithm-for-Parallel-and-Distributed-Computing 2 | 3 | Travelling Salesperson Problem being a classic combinatorial optimization problem is an interesting but a challenging problem to be solved. It falls under the class of NP hard problem and becomes non-solvable for large data set by traditional methods like integer linear programming and branch and bound method, being the earlier popular approaches. Given the list of cities and distances between them, the problem is to find the shortest tour possible which visits all the cities in list exactly once and ends in the city where it starts. Despite the Traveling Salesman Problem is NP-Hard, a lot of methods and solutions are proposed to the problem. One of them is Genetic Algorithm (GA). GA is a simple but an efficient heuristic method that can be used to solve Traveling Salesman Problem. Genetic algorithm is powerful technique to discover optimal for traveling salesman problem (TSP). Genetic Algorithm based solutions emerged as the most popular tool to solve this which is a heuristic mechanism to find the closest approximate solution to the problem. In this project, we approach Travelling Salesman Problem using GA approach, a natural selection technique which repeatedly modifies a population of individual solutions, with the added power of modern computing systems. Here I come up with a parallel version of GA for both multicore and many core architectures in order to make some of the challenging problems like Vehicle Routing Problem for google maps, DNA sequencing and many more optimization problems involving a good amount of complex computation and data handling. The project presents a comparative analysis of the results for various degree and structure of graphs depicting close approximation to the accuracy in terms of most optimal path for traversal with highly reduced execution time. 4 | 5 | Genetic parallel algorithm for approximating the Travelling Salesman Problem 6 | 7 | ### Contributing 8 | 9 | * Install lib `mpich2` 10 | 11 | ```bash 12 | $ sudo apt-get install mpich2 13 | ``` 14 | 15 | * Compile 16 | 17 | ```bash 18 | $ make 19 | ``` 20 | 21 | * Run 22 | 23 | ```bash 24 | $ mpiexec -n 2 ./tspgen 25 | 26 | 27 | If you have any query please feel free to contact me on : kakshak@gmail.com 28 | -------------------------------------------------------------------------------- /map.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "common.h" 4 | #include "map.h" 5 | #include "string.h" 6 | 7 | 8 | int parseMap(tspsMap_t *map){ 9 | 10 | char *file = NULL; 11 | char *weights = NULL; 12 | char *aux = NULL; 13 | int i, j; 14 | 15 | if(loadMap(&file) != TSPS_RC_SUCCESS) 16 | return TSPS_RC_FAILURE; 17 | 18 | weights = strstr(file, "NODE_COORD_SECTION"); 19 | weights += 19; 20 | 21 | map->numNodes = NUM_NODES; 22 | map->nodes = (tspsNode*)malloc(sizeof(tspsNode)*map->numNodes); 23 | 24 | aux = weights; 25 | i = 0; 26 | while(aux != NULL){ 27 | if(i >= map->numNodes) 28 | break; 29 | 30 | // skip the node id 31 | if(i==0) 32 | aux = strtok(weights, " "); 33 | else 34 | aux = strtok(NULL, " "); 35 | 36 | if(i!=atoi(aux)-1){ 37 | printf("Error! i is [%d], should be [%d]\n", i, atoi(aux)); 38 | } 39 | 40 | aux = strtok(NULL, " "); 41 | map->nodes[i].x = atoi(aux); 42 | 43 | aux = strtok(NULL, " \n"); 44 | map->nodes[i].y = atoi(aux); 45 | 46 | if(*aux == '\n'){ 47 | aux++; 48 | } 49 | 50 | i++; 51 | } 52 | 53 | free(file); 54 | return TSPS_RC_SUCCESS; 55 | } 56 | 57 | int loadMap(char **file){ 58 | 59 | FILE * pFile; 60 | long lSize; 61 | char *buffer; 62 | size_t result; 63 | 64 | if((pFile = fopen("maps/berlin52.tsp", "rb")) == NULL && 65 | (pFile = fopen("../maps/berlin52.tsp", "rb")) == NULL && 66 | (pFile = fopen("berlin52.tsp", "rb")) == NULL){ 67 | 68 | return TSPS_RC_FAILURE; 69 | } 70 | 71 | // obtain file size: 72 | fseek (pFile , 0 , SEEK_END); 73 | lSize = ftell (pFile); 74 | rewind (pFile); 75 | 76 | // allocate memory to contain the whole file: 77 | buffer = (char*) malloc (sizeof(char)*lSize); 78 | if (buffer == NULL) 79 | return TSPS_RC_FAILURE; 80 | 81 | // copy the file into the buffer: 82 | result = fread (buffer,1,lSize,pFile); 83 | if (result != lSize) 84 | return TSPS_RC_FAILURE; 85 | 86 | // terminate 87 | fclose (pFile); 88 | *file = buffer; 89 | return TSPS_RC_SUCCESS; 90 | 91 | } 92 | 93 | 94 | -------------------------------------------------------------------------------- /tspgen.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "mpi.h" 6 | #include "common.h" 7 | #include "map.h" 8 | #include "population.h" 9 | 10 | int mpiId = 0; 11 | 12 | int main(int argc, char **argv){ 13 | tspsMap_t map; 14 | tspsConfig_t config; 15 | tspsPopulation_t population; 16 | 17 | unsigned long int numGenerations = 0; 18 | int mpiNumProcs = 0; 19 | double start, end; 20 | 21 | //starting MPI directives 22 | MPI_Init(NULL,NULL); 23 | MPI_Comm_size(MPI_COMM_WORLD,&mpiNumProcs); 24 | MPI_Comm_rank(MPI_COMM_WORLD,&mpiId); 25 | 26 | logg("* Starting tspgen...\n"); 27 | 28 | // parse the command line args 29 | if(readConfig(&config, argc, argv) != TSPS_RC_SUCCESS){ 30 | return TSPS_RC_FAILURE; 31 | } 32 | 33 | // parse the map 34 | logg("* Parsing map...\n"); 35 | if(parseMap(&map) != TSPS_RC_SUCCESS){ 36 | logg("Error! Unable to read map 'maps/brazil58.tsp'!\n"); 37 | return TSPS_RC_FAILURE; 38 | } 39 | 40 | // initialize random seed: 41 | srand ( time(NULL)*mpiId ); 42 | 43 | logg("* Generating population...\n"); 44 | if(generatePopulation(&population, &config) != TSPS_RC_SUCCESS){ 45 | logg("Error! Failed to create a new random population!"); 46 | return TSPS_RC_FAILURE; 47 | } 48 | 49 | // start a timer (mpi_barrier + mpi_wtime) 50 | MPI_Barrier(MPI_COMM_WORLD); 51 | start = MPI_Wtime(); 52 | 53 | logg("* Initializing reproduction loop...\n"); 54 | while(1){ 55 | 56 | numGenerations++; 57 | 58 | calculateFitnessPopulation(&population, &map); 59 | 60 | if(numGenerations % 500 == 0){ 61 | logg("- Generation %d...\n", numGenerations); 62 | printIndividual(&population.individuals[0], "Current Top Individual"); 63 | } 64 | 65 | sortPopulation(&population); 66 | 67 | if(config.numGenerations > 0 && numGenerations == config.numGenerations){ 68 | logg("* Max number of generations [%d] reached!\n", config.numGenerations); 69 | break; 70 | } 71 | 72 | crossoverPopulation(&population, &config); 73 | 74 | mutatePopulation(&population, &config); 75 | 76 | // migrate population at every n generation 77 | if(numGenerations % config.migrationRate == 0){ 78 | migrateIndividuals(&population, mpiId, mpiNumProcs, &config); 79 | } 80 | } 81 | 82 | // join all the populations 83 | joinPopulations(&population, mpiId, mpiNumProcs); 84 | sortPopulation(&population); 85 | 86 | // get the best inidividual and print it 87 | printIndividual(&population.individuals[0], "Top Individual"); 88 | printIndividual(&population.individuals[config.populationSize-1], "Worst (of the top ones) Individual"); 89 | 90 | // stop the timer 91 | MPI_Barrier(MPI_COMM_WORLD); /* IMPORTANT */ 92 | end = MPI_Wtime(); 93 | 94 | if(mpiId == 0) { /* use time on master node */ 95 | printf("* Runtime = %f\n", end-start); 96 | } 97 | 98 | logg("* tspgen finished!\n"); 99 | free(population.individuals); 100 | free(map.nodes); 101 | MPI_Finalize(); 102 | 103 | return TSPS_RC_SUCCESS; 104 | } 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /common.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "stdio.h" 3 | #include 4 | #include 5 | 6 | extern int mpiId; 7 | 8 | void logg(const char * format, ...){ 9 | #ifdef DEBUG 10 | if(mpiId != 0) 11 | return; 12 | 13 | va_list(args); 14 | va_start(args, format); 15 | vprintf(format, args); 16 | va_end(args); 17 | #endif 18 | } 19 | 20 | int readConfig(tspsConfig_t *config, int argc, char **argv){ 21 | int populationSize = DFLT_POPSIZE; 22 | double mutationRate = DFLT_MUTRATE; 23 | int numGenerations = DFLT_NUMGEN; 24 | int numElitism = DFLT_NUMELIT; 25 | int mutationSize = DFLT_MUTSIZE; 26 | int migrationRate = DFLT_MIGRATE; 27 | float migrationShare = DFLT_MIGSHAR; 28 | 29 | if(argc > 1){ 30 | if(argc != 8){ 31 | logg("Invalid number of args\n Usage: ./tspgen \n"); 32 | return TSPS_RC_FAILURE; 33 | } 34 | 35 | populationSize = atoi(argv[1]); 36 | if(populationSize <= 0){ 37 | logg("Invalid population size (> 0)!\n Usage: ./tspgen \n"); 38 | return TSPS_RC_FAILURE; 39 | } 40 | 41 | mutationRate = atof(argv[2]); 42 | if(mutationRate < 0 || mutationRate > 1){ 43 | logg("Invalid mutation rate (0..1)!\n Usage: ./tspgen \n"); 44 | return TSPS_RC_FAILURE; 45 | } 46 | 47 | numGenerations = atoi(argv[3]); 48 | if(numGenerations < 100){ 49 | logg("Invalid number of generations (>= 100)!\n Usage: ./tspgen \n"); 50 | return TSPS_RC_FAILURE; 51 | } 52 | 53 | numElitism = atoi(argv[4]); 54 | if(numElitism < 0 || numElitism >= populationSize){ 55 | logg("Invalid elitism number (population size < elitism <= 0)!\n Usage: ./tspgen \n"); 56 | return TSPS_RC_FAILURE; 57 | } 58 | 59 | mutationSize = atoi(argv[5]); 60 | if(mutationSize < 1 || mutationSize > NUM_NODES/2){ 61 | logg("Invalid mutation size (%d < mutation size < 0)!\n Usage: ./tspgen \n", NUM_NODES/2); 62 | return TSPS_RC_FAILURE; 63 | } 64 | 65 | migrationRate = atoi(argv[6]); 66 | if(migrationRate >= numGenerations){ 67 | logg("Invalid migration rate size (migration rate < num generations)!\n Usage: ./tspgen \n", NUM_NODES/2); 68 | return TSPS_RC_FAILURE; 69 | } 70 | 71 | migrationShare = atof(argv[7]); 72 | if(migrationShare > 0.5 || migrationShare < 0.0){ 73 | logg("Invalid migration share (0 < migration share <= 0.5)!\n Usage: ./tspgen \n", NUM_NODES/2); 74 | return TSPS_RC_FAILURE; 75 | } 76 | } 77 | 78 | config->populationSize = populationSize; 79 | config->mutationRate = mutationRate; 80 | config->numGenerations = numGenerations; 81 | config->numElitism = numElitism; 82 | config->mutationSize = mutationSize; 83 | config->migrationRate = migrationRate; 84 | config->migrationShare = migrationShare; 85 | 86 | logg("* Config:\n"); 87 | logg("-- Population Size = [%d]\n", config->populationSize); 88 | logg("-- Mutation Rate = [%f]\n", config->mutationRate); 89 | logg("-- Num of Generations = [%d]\n", config->numGenerations); 90 | logg("-- Num of Elitism = [%d]\n", config->numElitism); 91 | logg("-- Mutation Size = [%d]\n", config->mutationSize); 92 | logg("-- Migration Rate = [%d]\n", config->migrationRate); 93 | logg("-- Migration Share = [%f]\n", config->migrationShare); 94 | 95 | return TSPS_RC_SUCCESS; 96 | 97 | } 98 | -------------------------------------------------------------------------------- /maps/a280.tsp: -------------------------------------------------------------------------------- 1 | NAME : a280 2 | COMMENT : drilling problem (Ludwig) 3 | TYPE : TSP 4 | DIMENSION: 280 5 | EDGE_WEIGHT_TYPE : EUC_2D 6 | NODE_COORD_SECTION 7 | 1 288 149 8 | 2 288 129 9 | 3 270 133 10 | 4 256 141 11 | 5 256 157 12 | 6 246 157 13 | 7 236 169 14 | 8 228 169 15 | 9 228 161 16 | 10 220 169 17 | 11 212 169 18 | 12 204 169 19 | 13 196 169 20 | 14 188 169 21 | 15 196 161 22 | 16 188 145 23 | 17 172 145 24 | 18 164 145 25 | 19 156 145 26 | 20 148 145 27 | 21 140 145 28 | 22 148 169 29 | 23 164 169 30 | 24 172 169 31 | 25 156 169 32 | 26 140 169 33 | 27 132 169 34 | 28 124 169 35 | 29 116 161 36 | 30 104 153 37 | 31 104 161 38 | 32 104 169 39 | 33 90 165 40 | 34 80 157 41 | 35 64 157 42 | 36 64 165 43 | 37 56 169 44 | 38 56 161 45 | 39 56 153 46 | 40 56 145 47 | 41 56 137 48 | 42 56 129 49 | 43 56 121 50 | 44 40 121 51 | 45 40 129 52 | 46 40 137 53 | 47 40 145 54 | 48 40 153 55 | 49 40 161 56 | 50 40 169 57 | 51 32 169 58 | 52 32 161 59 | 53 32 153 60 | 54 32 145 61 | 55 32 137 62 | 56 32 129 63 | 57 32 121 64 | 58 32 113 65 | 59 40 113 66 | 60 56 113 67 | 61 56 105 68 | 62 48 99 69 | 63 40 99 70 | 64 32 97 71 | 65 32 89 72 | 66 24 89 73 | 67 16 97 74 | 68 16 109 75 | 69 8 109 76 | 70 8 97 77 | 71 8 89 78 | 72 8 81 79 | 73 8 73 80 | 74 8 65 81 | 75 8 57 82 | 76 16 57 83 | 77 8 49 84 | 78 8 41 85 | 79 24 45 86 | 80 32 41 87 | 81 32 49 88 | 82 32 57 89 | 83 32 65 90 | 84 32 73 91 | 85 32 81 92 | 86 40 83 93 | 87 40 73 94 | 88 40 63 95 | 89 40 51 96 | 90 44 43 97 | 91 44 35 98 | 92 44 27 99 | 93 32 25 100 | 94 24 25 101 | 95 16 25 102 | 96 16 17 103 | 97 24 17 104 | 98 32 17 105 | 99 44 11 106 | 100 56 9 107 | 101 56 17 108 | 102 56 25 109 | 103 56 33 110 | 104 56 41 111 | 105 64 41 112 | 106 72 41 113 | 107 72 49 114 | 108 56 49 115 | 109 48 51 116 | 110 56 57 117 | 111 56 65 118 | 112 48 63 119 | 113 48 73 120 | 114 56 73 121 | 115 56 81 122 | 116 48 83 123 | 117 56 89 124 | 118 56 97 125 | 119 104 97 126 | 120 104 105 127 | 121 104 113 128 | 122 104 121 129 | 123 104 129 130 | 124 104 137 131 | 125 104 145 132 | 126 116 145 133 | 127 124 145 134 | 128 132 145 135 | 129 132 137 136 | 130 140 137 137 | 131 148 137 138 | 132 156 137 139 | 133 164 137 140 | 134 172 125 141 | 135 172 117 142 | 136 172 109 143 | 137 172 101 144 | 138 172 93 145 | 139 172 85 146 | 140 180 85 147 | 141 180 77 148 | 142 180 69 149 | 143 180 61 150 | 144 180 53 151 | 145 172 53 152 | 146 172 61 153 | 147 172 69 154 | 148 172 77 155 | 149 164 81 156 | 150 148 85 157 | 151 124 85 158 | 152 124 93 159 | 153 124 109 160 | 154 124 125 161 | 155 124 117 162 | 156 124 101 163 | 157 104 89 164 | 158 104 81 165 | 159 104 73 166 | 160 104 65 167 | 161 104 49 168 | 162 104 41 169 | 163 104 33 170 | 164 104 25 171 | 165 104 17 172 | 166 92 9 173 | 167 80 9 174 | 168 72 9 175 | 169 64 21 176 | 170 72 25 177 | 171 80 25 178 | 172 80 25 179 | 173 80 41 180 | 174 88 49 181 | 175 104 57 182 | 176 124 69 183 | 177 124 77 184 | 178 132 81 185 | 179 140 65 186 | 180 132 61 187 | 181 124 61 188 | 182 124 53 189 | 183 124 45 190 | 184 124 37 191 | 185 124 29 192 | 186 132 21 193 | 187 124 21 194 | 188 120 9 195 | 189 128 9 196 | 190 136 9 197 | 191 148 9 198 | 192 162 9 199 | 193 156 25 200 | 194 172 21 201 | 195 180 21 202 | 196 180 29 203 | 197 172 29 204 | 198 172 37 205 | 199 172 45 206 | 200 180 45 207 | 201 180 37 208 | 202 188 41 209 | 203 196 49 210 | 204 204 57 211 | 205 212 65 212 | 206 220 73 213 | 207 228 69 214 | 208 228 77 215 | 209 236 77 216 | 210 236 69 217 | 211 236 61 218 | 212 228 61 219 | 213 228 53 220 | 214 236 53 221 | 215 236 45 222 | 216 228 45 223 | 217 228 37 224 | 218 236 37 225 | 219 236 29 226 | 220 228 29 227 | 221 228 21 228 | 222 236 21 229 | 223 252 21 230 | 224 260 29 231 | 225 260 37 232 | 226 260 45 233 | 227 260 53 234 | 228 260 61 235 | 229 260 69 236 | 230 260 77 237 | 231 276 77 238 | 232 276 69 239 | 233 276 61 240 | 234 276 53 241 | 235 284 53 242 | 236 284 61 243 | 237 284 69 244 | 238 284 77 245 | 239 284 85 246 | 240 284 93 247 | 241 284 101 248 | 242 288 109 249 | 243 280 109 250 | 244 276 101 251 | 245 276 93 252 | 246 276 85 253 | 247 268 97 254 | 248 260 109 255 | 249 252 101 256 | 250 260 93 257 | 251 260 85 258 | 252 236 85 259 | 253 228 85 260 | 254 228 93 261 | 255 236 93 262 | 256 236 101 263 | 257 228 101 264 | 258 228 109 265 | 259 228 117 266 | 260 228 125 267 | 261 220 125 268 | 262 212 117 269 | 263 204 109 270 | 264 196 101 271 | 265 188 93 272 | 266 180 93 273 | 267 180 101 274 | 268 180 109 275 | 269 180 117 276 | 270 180 125 277 | 271 196 145 278 | 272 204 145 279 | 273 212 145 280 | 274 220 145 281 | 275 228 145 282 | 276 236 145 283 | 277 246 141 284 | 278 252 125 285 | 279 260 129 286 | 280 280 133 287 | EOF 288 | -------------------------------------------------------------------------------- /plots/runtimes: -------------------------------------------------------------------------------- 1 | * 1: Runtime = 4560.907294 2 | * 2: Runtime = 2378.866794 3 | * 4: Runtime = 1113.100300 4 | * 8: Runtime = 586.383440 5 | * 12: Runtime = 442.161445 6 | * 16: Runtime = 507.853073 7 | * 20: Runtime = 522.657613 8 | * 24: Runtime = 542.611265 9 | 10 | 11 | == Berlin52 12 | ** Best know fitness: 7542 13 | 14 | ** 1 15 | -- fitness = [17319] 16 | -- chromos = [6][39][36][26][4][2][21][41][1][29] 17 | [20][17][16][40][8][32][42][31][18][3] 18 | [23][19][43][15][12][25][45][24][5][47] 19 | [22][30][49][28][51][50][27][46][13][10] 20 | [11][14][44][34][0][33][35][38][7][9] 21 | [48][37] 22 | -------------------------------------------------------------- 23 | * Runtime = 1248.187445 24 | 25 | ** 2 26 | -- fitness = [15605] 27 | -- chromos = [48][20][30][39][24][31][0][21][22][17] 28 | [18][44][32][27][25][12][26][11][50][8] 29 | [7][40][23][2][16][41][6][1][29][28] 30 | [37][46][13][10][51][42][43][45][36][15] 31 | [5][47][49][19][34][35][33][4][3][38] 32 | [9][14] 33 | -------------------------------------------------------------- 34 | * Runtime = 827.780406 35 | 36 | ** 4 37 | -- fitness = [12338] 38 | -- chromos = [39][4][3][5][45][37][36][0][30][21] 39 | [34][43][15][47][23][11][24][25][26][12] 40 | [13][51][10][32][50][27][46][28][22][49] 41 | [41][6][1][29][19][16][20][17][2][7] 42 | [18][9][8][44][38][42][40][33][14][31] 43 | [48][35] 44 | -------------------------------------------------------------- 45 | * Runtime = 382.320177 46 | 47 | ** 8 48 | -- fitness = [9216] 49 | -- chromos = [3][5][24][43][15][28][29][19][49][45] 50 | [27][26][25][46][12][13][51][10][50][11] 51 | [32][42][9][8][40][7][18][2][17][16] 52 | [6][1][41][20][22][21][30][0][33][35] 53 | [36][23][47][14][44][31][48][34][38][39] 54 | [37][4] 55 | -------------------------------------------------------------- 56 | * Runtime = 240.396721 57 | 58 | ** 16 59 | -- fitness = [8057] 60 | -- chromos = [15][43][33][0][21][48][31][44][18][40] 61 | [7][8][9][42][32][50][11][27][10][51] 62 | [13][12][26][25][46][28][29][1][6][41] 63 | [20][16][2][17][30][22][19][49][45][24] 64 | [3][5][14][4][23][47][37][36][39][38] 65 | [35][34] 66 | -------------------------------------------------------------- 67 | * Runtime = 180.385604 68 | 69 | ** 24 70 | -- fitness = [7674] 71 | -- chromos = [35][48][31][0][21][30][22][19][49][28] 72 | [29][1][6][41][20][16][2][17][44][18] 73 | [40][7][8][9][42][32][50][10][51][13] 74 | [12][46][25][26][27][11][24][3][5][14] 75 | [4][23][47][37][36][39][38][34][33][43] 76 | [45][15] 77 | * Runtime = 129.190179 78 | * tspgen finished! 79 | 80 | == a280 81 | ** Best known fitness: 2579 82 | 83 | 84 | ** 16 85 | -- fitness = [6015] 86 | -- chromos = [172][106][105][104][103][102][168][169][171][170] 87 | [167][166][165][175][176][150][151][19][18][131] 88 | [17][16][132][133][134][135][129][29][30][32] 89 | [33][35][36][48][47][46][84][87][82][83] 90 | [60][41][42][59][173][164][163][162][161][160] 91 | [155][130][24][21][25][26][39][40][43][58] 92 | [63][64][65][73][72][71][70][69][68][67] 93 | [66][108][101][98][99][100][123][124][31][27] 94 | [28][122][107][91][92][93][77][76][74][75] 95 | [78][89][88][81][80][79][94][95][96][97] 96 | [90][110][113][118][152][153][154][128][127][125] 97 | [126][20][136][211][202][201][195][185][181][180] 98 | [177][261][276][278][243][237][232][226][190][189] 99 | [188][187][186][184][179][178][267][15][14][38] 100 | [53][54][55][56][57][44][45][37][34][251] 101 | [249][246][240][239][238][245][250][209][224][223] 102 | [222][221][220][219][218][217][216][215][203][204] 103 | [212][214][225][213][210][242][241][1][2][3] 104 | [277][255][231][236][235][234][233][227][229][228] 105 | [230][244][275][5][6][7][8][274][208][206] 106 | [205][143][198][183][182][61][62][85][86][111] 107 | [109][174][149][264][263][262][4][0][279][247] 108 | [248][258][259][260][256][200][194][193][196][191] 109 | [192][197][199][140][139][265][138][147][145][144] 110 | [142][141][146][148][137][266][268][269][270][271] 111 | [272][273][257][254][252][207][253][9][10][11] 112 | [12][13][23][22][121][120][117][116][115][112] 113 | [114][159][158][157][156][119][52][51][50][49] 114 | 115 | -------------------------------------------------------------- 116 | * Runtime = 810.476294 117 | 118 | ** 24 119 | -- fitness = [6426] 120 | -- chromos = [62][58][43][44][40][41][42][118][151][155] 121 | [120][121][57][67][66][64][116][117][156][157] 122 | [150][134][133][132][20][29][33][34][38][39] 123 | [46][47][37][123][122][60][61][54][53][52] 124 | [51][48][27][24][22][23][16][17][18][19] 125 | [127][126][125][124][128][129][130][5][4][278] 126 | [277][3][276][264][148][178][166][167][104][103] 127 | [107][108][114][59][45][55][56][72][73][78] 128 | [89][109][146][246][243][244][250][199][198][145] 129 | [147][268][269][14][11][10][8][207][206][204] 130 | [203][143][144][142][141][263][262][261][213][224] 131 | [223][222][221][218][217][216][214][225][226][233] 132 | [234][232][205][139][32][35][68][69][70][71] 133 | [65][63][85][86][87][81][88][111][110][159] 134 | [158][176][6][7][9][12][13][270][271][272] 135 | [259][258][257][247][249][248][255][254][253][256] 136 | [260][15][21][25][28][30][36][49][50][31] 137 | [26][0][1][279][2][208][209][211][215][219] 138 | [220][194][190][171][170][169][172][105][106][113] 139 | [112][82][75][74][76][77][93][97][98][99] 140 | [100][92][96][95][94][101][197][200][201][202] 141 | [240][242][241][239][238][237][230][245][275][274] 142 | [273][131][153][154][138][140][210][227][235][236] 143 | [231][265][152][119][115][84][83][80][79][90] 144 | [91][102][168][165][164][163][183][182][160][174] 145 | [181][180][179][175][177][149][137][136][135][267] 146 | [266][252][251][229][228][212][195][196][193][191] 147 | [192][185][186][184][189][188][187][162][161][173] 148 | 149 | -------------------------------------------------------------- 150 | * Runtime = 688.412901 151 | -------------------------------------------------------------------------------- /maps/brazil58.tsp: -------------------------------------------------------------------------------- 1 | NAME: brazil58 2 | TYPE: TSP 3 | COMMENT: 58 cities in Brazil (Ferreira) 4 | DIMENSION: 58 5 | EDGE_WEIGHT_TYPE: EXPLICIT 6 | EDGE_WEIGHT_FORMAT: UPPER_ROW 7 | EDGE_WEIGHT_SECTION 8 | 2635 2713 2437 1600 2845 6002 1743 594 2182 2906 1658 464 3334 3987 2870 2601 330 3049 1302 3399 1946 1278 669 627 2878 1737 3124 2878 307 5217 799 3305 3716 2251 2878 3467 4316 2963 512 2515 4850 1937 367 3601 3936 2430 2691 2087 1861 2358 2263 1425 2266 2166 3870 1417 739 9 | 314 2636 666 1096 4645 693 2889 287 772 1135 2875 1424 2185 1193 846 2142 1127 3104 1484 490 990 1950 2855 975 926 1214 599 2535 3860 3027 1407 1811 359 1060 1557 2959 394 2740 98 3538 856 2026 1710 1733 508 194 532 2906 435 335 2470 137 234 2072 1196 1517 10 | 2730 706 791 4588 922 2991 217 760 1050 2915 1119 1776 1451 5410 2182 846 3333 578 721 1030 1990 2895 670 835 909 287 2575 3803 3067 1102 1505 158 439 1248 2902 287 2780 276 3436 771 2066 1395 1740 407 279 334 3135 337 235 2699 451 546 1882 2699 1557 11 | 2824 3457 6083 2120 2040 2844 2973 3937 1958 3710 4363 2941 3207 1991 3512 1571 3392 2013 2922 2368 2170 3336 3503 3500 2884 2109 5298 2108 3643 4092 2934 3093 3843 4391 2763 2083 2543 4925 3236 2107 3939 4274 3008 2522 3006 806 2936 3026 947 2464 2364 4208 3116 2390 12 | 1247 4746 716 2223 584 1442 694 2089 1577 2230 1609 1003 1260 1297 2535 1511 908 324 1116 2183 1126 260 1367 996 1863 3961 2355 1565 1959 660 1106 1710 3060 991 2068 523 3594 434 1354 1861 2196 658 750 563 2929 586 668 2493 494 557 2130 524 851 13 | 5126 1653 3545 708 1298 1342 3451 347 1126 1989 250 2736 138 3786 888 1452 1671 2336 3431 124 1165 189 640 3110 4341 3603 489 855 730 364 598 3440 841 3316 919 3974 1063 2620 940 1090 722 921 761 3866 652 754 3430 1096 1191 1232 1582 2098 14 | 4267 6553 4826 3830 5951 6417 5423 6089 3142 4876 5676 5181 6678 4720 4074 5071 5724 6675 5000 4993 5221 4494 6265 785 6776 5265 5756 4628 4747 5511 1686 4276 6472 4447 2230 5167 5784 5561 5891 4902 4353 4922 6480 4759 4771 6044 4299 4199 5830 5271 5404 15 | 2296 923 1175 1282 2162 1906 2559 1133 1352 1422 1651 2423 1588 209 1030 1461 2420 1538 965 1716 1112 2010 3482 2521 1839 2288 1000 1289 2039 2551 955 2217 715 3125 1145 1529 2131 2466 1087 718 1083 2225 1015 960 1789 537 436 2400 1238 1199 16 | 2869 3459 2366 147 3741 4399 3417 3163 924 3462 681 3734 2493 1934 1377 130 3402 2449 3531 3219 343 5766 228 3724 4128 2883 3277 3870 4835 3214 184 2746 4875 2492 925 4017 4362 2985 2973 2831 1544 2913 2891 1103 2717 2655 4504 1972 1447 17 | 1004 781 2793 1036 1694 1694 458 1844 757 3125 1096 827 908 1702 2773 587 844 826 455 2453 4041 2945 1019 1423 75 572 1165 3140 560 2658 227 3674 502 1944 1312 1650 170 383 169 3136 98 80 2700 411 508 1584 948 1435 18 | 2128 3322 1609 2266 693 1041 2585 1353 3586 887 974 2553 2624 3583 1177 1488 1398 673 3173 3045 3684 1444 1935 941 926 1686 2149 455 3380 894 2688 1433 2692 1740 2070 1081 696 1101 3388 1009 950 2952 1063 964 2009 1972 2286 19 | 2265 1695 2353 2819 1117 1557 1416 2636 1755 1608 456 1002 2245 1246 257 1485 1225 1925 5166 2417 1678 2082 871 1231 1824 4265 1290 2130 1019 4799 279 1441 1971 2309 772 1148 618 2844 700 802 2413 1188 1248 2243 248 1210 20 | 3607 4265 3283 3029 931 3328 817 3600 2359 1876 1267 200 3158 2339 3397 3120 211 5632 366 3590 4004 2766 3134 3736 4701 3185 135 2914 5274 2267 815 3883 4221 2667 3043 2606 1451 2595 2697 1011 2563 2623 4155 1834 1337 21 | 665 2300 578 2845 474 4116 1216 1705 1901 2693 3848 652 1480 224 968 3547 4648 4020 176 394 1153 692 137 3752 1169 3744 1301 4291 1420 3047 479 629 1059 1249 1079 4119 982 967 3683 1424 1421 771 1939 2901 22 | 2957 1236 3706 992 4774 1471 2358 2654 3346 4589 1177 2151 887 1564 4099 5304 4591 818 262 1716 1350 528 4408 1827 4306 1905 4947 2073 3590 562 607 1717 2093 1742 4772 1645 1747 4036 2082 2179 760 2592 3554 23 | 1734 2543 2044 3544 1578 932 1939 2582 3304 1868 1861 2089 1362 3131 2357 3642 2133 2624 1491 1615 2379 1456 1144 3338 1310 1990 2035 2650 2429 2759 1770 1216 1790 3346 1622 1639 2910 1162 1062 2698 2139 2278 24 | 2267 300 3542 638 1202 1328 2094 3187 129 915 368 390 2866 4091 3359 561 965 480 114 711 3190 591 3072 669 3724 846 2379 854 1192 392 671 511 3565 408 388 3129 846 950 1126 1347 1860 25 | 2566 1273 2905 1619 1175 564 1068 2600 1638 2841 2470 770 5113 1240 3039 3433 2134 2580 3184 4182 2465 953 1997 4756 1834 114 3335 3670 2388 2349 1984 1715 2068 2074 1284 1968 2031 3604 1340 636 26 | 3841 945 1507 1627 2393 3486 178 1214 254 652 3165 4396 3658 531 730 1079 374 476 3495 856 3371 968 4029 1140 2678 806 960 691 978 810 3864 707 687 3428 1145 1249 1096 1646 2159 27 | 3998 2620 2217 1647 693 3665 2676 3906 3487 1052 5893 537 4108 4503 3201 3635 4249 4962 3366 800 3064 5536 2804 1385 4401 4739 3199 3129 3032 1070 3122 3209 634 2948 2846 4673 2395 1681 28 | 1383 1835 2627 3846 767 1771 788 520 3380 3925 3872 938 1200 842 524 943 3024 607 3585 892 3558 1470 2871 1288 1438 1118 742 1143 3801 1046 976 3365 1076 1174 1185 1989 2951 29 | 1238 1612 2617 1332 1174 1495 875 2211 3289 2718 1634 2087 774 1109 1838 2388 754 2414 607 2922 1348 1726 1930 2265 991 517 983 2422 919 880 1986 459 359 2199 1438 1350 30 | 801 1865 1450 554 2243 1546 1545 4286 2037 1889 2293 984 1542 2040 3385 1315 1750 847 3919 600 1061 2182 2510 1093 1074 887 2425 1021 992 1994 818 881 2454 432 1394 31 | 1256 2083 1252 2324 2058 936 4929 1428 2517 2686 1841 2057 2806 4038 2123 1141 1849 4572 1275 452 2805 3143 1610 2020 1612 1869 1542 1642 1422 1748 1811 3082 754 259 32 | 3310 2324 3551 3185 372 5890 190 3754 4148 2849 3295 3899 4959 3180 125 2712 5533 2524 954 4050 4385 2836 2939 2644 1669 2764 2857 1233 2683 2746 4319 2004 1326 33 | 1044 432 519 2995 4215 3487 709 908 609 243 639 3314 720 3200 798 3848 969 2486 984 1138 528 800 640 3751 536 517 3315 975 1078 1274 1329 1189 34 | 1275 1023 2004 4208 2496 1468 1637 669 1022 1627 3307 1088 2209 783 3841 184 1524 1756 2094 570 946 523 3178 498 600 2742 754 817 2033 498 1460 35 | 758 3236 4436 4225 283 606 848 482 359 3535 959 3441 1037 4069 1210 2727 701 851 702 1039 879 3929 777 756 3493 1214 1311 1494 1570 2532 36 | 2865 3709 3036 478 1293 354 274 1036 2808 366 3070 447 3342 949 2356 708 837 577 367 623 3325 525 523 2889 631 728 1635 1304 2266 37 | 5480 549 3434 3828 2529 2975 3579 4549 2860 257 2392 5123 2204 656 3730 4065 2527 2619 2354 1608 2444 2537 1172 2406 2305 3999 1684 1006 38 | 5991 4480 4971 3843 3962 4791 901 3491 5687 3662 1445 4615 4999 4776 5106 4117 3568 4137 5695 3969 3986 5259 3514 3414 5045 4708 4619 39 | 3926 4320 3021 3467 4171 5060 3352 297 2884 5634 2696 1126 4222 4557 3008 3114 2846 1607 2936 3162 1171 2855 2918 4491 2176 1498 40 | 547 1041 675 290 3579 1152 3639 1230 4113 1402 2925 213 435 802 1232 1072 4052 970 949 3616 1407 1511 413 1763 2725 41 | 1444 1016 257 4002 1493 4041 1638 4604 1802 3319 354 229 1356 1849 1475 4501 1139 1352 4065 1839 1931 300 1932 2899 42 | 594 1187 2942 329 2734 148 3476 567 2020 1335 1672 243 287 268 3213 171 107 2777 315 419 1606 1087 2049 43 | 759 3061 705 3180 635 3595 971 2466 968 1306 506 705 625 3502 524 502 3066 960 1064 1240 1303 1974 44 | 3825 1236 3784 1381 4359 1553 3070 342 492 1099 1592 1218 4252 1115 1095 3816 1560 1672 634 1908 2570 45 | 2590 4848 2761 544 3481 4068 3875 4505 3145 2667 3236 4764 3073 3083 4328 2613 2513 4144 3590 3718 46 | 3065 432 3124 1014 2351 1445 1783 602 345 688 3168 590 488 2732 498 589 1717 1369 2331 47 | 2597 5330 2409 839 3935 4270 2721 2923 2559 1582 2649 2753 1146 2568 2651 4204 1889 1211 48 | 3294 722 1883 1423 1783 391 192 416 2928 319 217 2492 184 282 1795 1095 2042 49 | 4015 4642 4409 4739 3750 3201 3770 5338 3607 3617 4902 3147 3047 4678 4124 4252 50 | 1720 1698 2037 554 852 339 3004 429 533 2571 889 993 1967 527 1123 51 | 3221 3556 2274 2235 1870 1601 1954 1960 1170 1854 1917 3490 1226 522 52 | 273 1340 1525 1355 4344 1258 942 3908 1700 1798 312 2051 3033 53 | 1668 1863 1693 4679 1596 1580 4243 2038 2134 254 2389 3351 54 | 520 86 3299 72 170 2864 558 662 1489 856 1434 55 | 543 2931 448 342 2495 239 288 1797 1266 1878 56 | 3295 97 199 2859 588 692 1637 858 1339 57 | 3227 3206 446 2750 2649 4617 2417 1882 58 | 102 2791 486 590 1535 8700 1441 59 | 2770 389 497 1514 888 1543 60 | 2314 2213 4181 2105 1446 61 | 112 1972 994 1345 62 | 2076 1057 1408 63 | 2328 2986 64 | 962 65 | EOF 66 | -------------------------------------------------------------------------------- /population.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "common.h" 9 | #include "population.h" 10 | #include "map.h" 11 | 12 | //Each process generates its own sub-population using the pseudo random number generator 13 | int generatePopulation(tspsPopulation_t *pop, tspsConfig_t *config){ 14 | 15 | pop->numIndividuals = config->populationSize; 16 | pop->individuals = (tspsIndividual_t*)malloc(pop->numIndividuals * sizeof(tspsIndividual_t)); 17 | 18 | int i; 19 | for(i=0; inumIndividuals; i++){ 20 | generateRandomChromosome(&pop->individuals[i], i); 21 | } 22 | 23 | return TSPS_RC_SUCCESS; 24 | } 25 | 26 | //Generates a new random chromossome 27 | int generateRandomChromosome(tspsIndividual_t *ind, int index){ 28 | int ii; 29 | for(ii=0; iichrom[ii] = ii; // city index starts from zero 31 | } 32 | 33 | struct timeval tv; 34 | gettimeofday(&tv, NULL); 35 | int usec = tv.tv_usec+index; 36 | srand48(usec); 37 | 38 | size_t i; 39 | for (i = NUM_NODES - 1; i > 0; i--) { 40 | size_t j = (unsigned int) (drand48()*(i+1)); 41 | int t = ind->chrom[j]; 42 | ind->chrom[j] = ind->chrom[i]; 43 | ind->chrom[i] = t; 44 | } 45 | 46 | return TSPS_RC_SUCCESS; 47 | } 48 | 49 | //This function calculates the fitness value of each chromosome the parsed map stored in the directory 50 | double calculateFitnessChromosome(int *chromosome, tspsMap_t *map){ 51 | int fitnessValue = 0.0; 52 | int i, firstCity, secondCity; 53 | int xd, yd; 54 | for (i=0; inodes[firstCity].x - map->nodes[secondCity].x; 58 | yd = map->nodes[firstCity].y - map->nodes[secondCity].y; 59 | fitnessValue = fitnessValue + rint(sqrt(xd*xd + yd*yd)); 60 | } 61 | return fitnessValue; 62 | } 63 | 64 | void swap (int *a, int *b){ 65 | int temp = *a; 66 | *a = *b; 67 | *b = temp; 68 | } 69 | 70 | int compare (const void *a, const void *b) 71 | { 72 | 73 | tspsIndividual_t * popA = (tspsIndividual_t *)a; 74 | tspsIndividual_t * popB = (tspsIndividual_t *)b; 75 | 76 | return ( popA->fitness - popB->fitness ); 77 | } 78 | 79 | //mutate the population 80 | int mutatePopulation(tspsPopulation_t *pop, tspsConfig_t *config){ 81 | 82 | tspsIndividual_t *ind = NULL; 83 | int alreadySwaped[NUM_NODES]; 84 | int mutationRate = config->mutationRate * 100; 85 | int index1, index2; //the index of the nodes to be swapped 86 | int aux; 87 | int i, j; 88 | 89 | for(i=config->numElitism; inumIndividuals; i++){ 90 | if(rand()%100 > mutationRate) 91 | continue; 92 | 93 | memset(alreadySwaped, 0, sizeof(alreadySwaped)); 94 | ind = &pop->individuals[i]; 95 | 96 | //mutate! 97 | //swap mutationSize nodes in the chromosome 98 | for(j=0; jmutationSize; j++){ 99 | index1 = rand() % NUM_NODES; 100 | 101 | //if already swaped, jump to the next of the list 102 | while(alreadySwaped[index1] !=0){ 103 | if(index1 + 1 < NUM_NODES) 104 | index1++; 105 | else 106 | index1 = 0; 107 | } 108 | alreadySwaped[index1] = 1; 109 | 110 | index2 = rand() % NUM_NODES; 111 | 112 | //if already swaped, jump to the next of the list 113 | while(alreadySwaped[index2] !=0){ 114 | if(index2 + 1 < NUM_NODES) 115 | index2++; 116 | else 117 | index2 = 0; 118 | } 119 | alreadySwaped[index2] = 1; 120 | 121 | //swap the nodes 122 | aux = ind->chrom[index1]; 123 | ind->chrom[index1] = ind->chrom[index2]; 124 | ind->chrom[index2] = aux; 125 | } 126 | } 127 | 128 | return TSPS_RC_SUCCESS; 129 | 130 | } 131 | 132 | //sort the population by increasing fitness 133 | int sortPopulation(tspsPopulation_t *pop){ 134 | qsort(pop->individuals, pop->numIndividuals, sizeof(tspsIndividual_t), compare); 135 | return TSPS_RC_SUCCESS; 136 | } 137 | 138 | //This function is an implementation of PMX crossover operation 139 | int crossoverPopulation(tspsPopulation_t *pop, tspsConfig_t *config){ 140 | 141 | int i, j, k, l; 142 | for (i=0; i < config->populationSize; i++){ 143 | pop->individuals[i].probability = pop->individuals[i].fitness/pop->totalFitness; 144 | } 145 | 146 | double rndNumber_one, rndNumber_two ; 147 | int cross_pone, cross_ptwo; 148 | 149 | double offset_one = 0.0; 150 | double offset_two = 0.0; 151 | 152 | int pick_one = 0, pick_two = 0; 153 | int count = config->numElitism; 154 | 155 | int temp; 156 | int max = NUM_NODES -1; 157 | int min = 1; 158 | for (count = 0 ; count<500; count= count+2){ 159 | // selection of two parents based on sampling from the multinomial distribution 160 | rndNumber_one = rand() / (double) RAND_MAX; 161 | rndNumber_two = rand() / (double) RAND_MAX; 162 | //count = count+2; 163 | for (i = 0; i < config->populationSize; i++) { 164 | offset_one += pop->individuals[i].probability; 165 | if (rndNumber_one < offset_one) { 166 | pick_one = i; 167 | break; 168 | } 169 | } 170 | for (i = 0; i < config->populationSize; i++) { 171 | offset_two += pop->individuals[i].probability; 172 | 173 | if (rndNumber_two < offset_two) { 174 | pick_two = i; 175 | break; 176 | } 177 | } 178 | offset_one=0; offset_two=0; 179 | 180 | //pmx function 181 | //random selection of two delimiters - crossover points 182 | cross_pone = (max - min + 1)*(double)rand()/RAND_MAX + min; 183 | cross_ptwo = (max - min + 1)*(double)rand()/RAND_MAX + min; 184 | 185 | if(cross_ptwoindividuals[pick_one].chrom[i]; //parent(1) number 10 195 | child_2[i] = pop->individuals[pick_two].chrom[i]; //parent(2) number 11 196 | } 197 | int *vec_1 = (int*)malloc((cross_ptwo-cross_pone)*sizeof(int)); 198 | int *vec_2 = (int*)malloc((cross_ptwo-cross_pone)*sizeof(int)); 199 | int num=0; 200 | 201 | //swapping the segment of chromosome between the two delimiters 202 | for (i = cross_pone; i < cross_ptwo; i++ ){ 203 | int tem = child_1[i]; 204 | child_1[i] = child_2[i]; // 205 | child_2[i] = tem; // 206 | 207 | vec_1[num] = child_1[i]; 208 | vec_2[num] = child_2[i]; 209 | num++; 210 | } 211 | 212 | //copy rest of the segment from parents to children 213 | for(i = 0; iindividuals[pick_one].chrom[i]; 215 | child_2[i] = pop->individuals[pick_two].chrom[i]; 216 | } 217 | for(i = cross_ptwo; iindividuals[pick_one].chrom[i]; 219 | child_2[i] = pop->individuals[pick_two].chrom[i]; 220 | } 221 | int buf, flag=0; 222 | //solving the conflicts that arise due to above swapping procedure. 223 | for (i = 0; i < num; i++ ){ 224 | if(flag==1){ 225 | i=i-1; 226 | flag=0; 227 | } 228 | for (j = 0; j < num; j++ ){ 229 | if((vec_1[i]==vec_2[j])&&(vec_1[i]!=vec_2[i] )){ 230 | buf = vec_1[i]; 231 | vec_1[i] = vec_1[j]; 232 | vec_1[j] = buf; 233 | flag=1; 234 | continue; 235 | } 236 | } 237 | } 238 | for (i=0; iindividuals[config->populationSize-count-1].chrom[i] = child_1[i]; 260 | pop->individuals[config->populationSize-count-2].chrom[i] = child_2[i]; 261 | } 262 | free(vec_1); 263 | free(vec_2); 264 | } 265 | 266 | return 0; 267 | } 268 | 269 | // This function calculates the fitness value of each chromosome. 270 | int calculateFitnessPopulation(tspsPopulation_t *pop, tspsMap_t *map){ 271 | int i; 272 | int totalFitness = 0.0; 273 | 274 | for(i=0; inumIndividuals; i++){ 275 | pop->individuals[i].fitness = calculateFitnessChromosome(&pop->individuals[i].chrom[0], map); 276 | totalFitness += pop->individuals[i].fitness; 277 | } 278 | 279 | pop->totalFitness = totalFitness; 280 | 281 | return TSPS_RC_SUCCESS; 282 | } 283 | 284 | // COMMUNICATION : using RED-BLACK communication 285 | int migrateIndividuals(tspsPopulation_t *pop, int mpiId, int numProcs, tspsConfig_t *config){ 286 | 287 | tspsIndividual_t *emigrant1 = NULL, *emigrant2 = NULL; 288 | tspsIndividual_t *imigrant1 = NULL, *imigrant2 = NULL; 289 | int i=0, j=-1; 290 | MPI_Status status; 291 | 292 | // define how many individuals are going to migrate 293 | int numMigrants = floor(pop->numIndividuals * config->migrationShare); 294 | 295 | //choose randomly for now the individual to migrate 296 | i = rand() % (pop->numIndividuals - numMigrants); 297 | emigrant1 = &pop->individuals[i]; 298 | imigrant1 = (tspsIndividual_t *)malloc(sizeof(tspsIndividual_t) * numMigrants); 299 | 300 | // choose another emigrant if they are in the middle of the process chain 301 | if(mpiId > 0 && mpiId < numProcs-1){ 302 | do{ 303 | j = rand() % (pop->numIndividuals - numMigrants); 304 | } while(j == i); 305 | 306 | emigrant2 = &pop->individuals[j]; 307 | imigrant2 = (tspsIndividual_t *)malloc(sizeof(tspsIndividual_t) * numMigrants); 308 | } 309 | 310 | /* red/black communication*/ 311 | if (mpiId % 2 != 0){ 312 | /* i'm red */ 313 | 314 | if(mpiId < numProcs - 1){ 315 | /* send emigrant to black at my right */ 316 | //printf("+ Pr[%d]: Sending to [%d]... \n", mpiId, mpiId+1); 317 | MPI_Send(emigrant1, sizeof(tspsIndividual_t) * numMigrants, MPI_CHAR, mpiId+1, MPI_MIGRATION_TAG, MPI_COMM_WORLD); 318 | 319 | /* receive imigrant from black at my right */ 320 | //printf("+ Pr[%d]: Receiving from [%d]... \n", mpiId, mpiId+1); 321 | MPI_Recv(imigrant1, sizeof(tspsIndividual_t) * numMigrants, MPI_CHAR, mpiId+1, MPI_MIGRATION_TAG, MPI_COMM_WORLD, &status ); 322 | } 323 | 324 | if(mpiId > 0){ 325 | /* send emigrant to black at my left */ 326 | //printf("+ Pr[%d]: Sending to [%d]... \n", mpiId, mpiId-1); 327 | MPI_Send((mpiId < numProcs - 1? emigrant2 : emigrant1), sizeof(tspsIndividual_t) * numMigrants, MPI_CHAR, mpiId-1, MPI_MIGRATION_TAG, MPI_COMM_WORLD); 328 | 329 | /* receive imigrant from black at my left */ 330 | //printf("+ Pr[%d]: Receiving from [%d]... \n", mpiId, mpiId-1); 331 | MPI_Recv((mpiId < numProcs - 1? imigrant2 : imigrant1), sizeof(tspsIndividual_t) * numMigrants, MPI_CHAR, mpiId-1, MPI_MIGRATION_TAG, MPI_COMM_WORLD, &status ); 332 | } 333 | 334 | } else { 335 | /* i'm black */ 336 | if(mpiId > 0){ 337 | /* receive imigrant from red at my left */ 338 | //printf("- Pr[%d]: Receiving from [%d]... \n", mpiId, mpiId-1); 339 | MPI_Recv(imigrant1, sizeof(tspsIndividual_t) * numMigrants, MPI_CHAR, mpiId-1, MPI_MIGRATION_TAG, MPI_COMM_WORLD, &status ); 340 | 341 | 342 | /* send emigrant to red at my left */ 343 | //printf("- Pr[%d]: Sending to [%d]... \n", mpiId, mpiId-1); 344 | MPI_Send(emigrant1, sizeof(tspsIndividual_t) * numMigrants, MPI_CHAR, mpiId-1, MPI_MIGRATION_TAG, MPI_COMM_WORLD); 345 | } 346 | 347 | if(mpiId < numProcs-1){ 348 | /* receive imigrant from red at my right */ 349 | //printf("- Pr[%d]: Receiving from [%d]... \n", mpiId, mpiId+1); 350 | MPI_Recv((mpiId > 0? imigrant2 : imigrant1), sizeof(tspsIndividual_t) * numMigrants, MPI_CHAR, mpiId+1, MPI_MIGRATION_TAG, MPI_COMM_WORLD, &status ); 351 | 352 | /* send emigrant to red at my right */ 353 | //printf("- Pr[%d]: Sending to [%d]... \n", mpiId, mpiId+1); 354 | MPI_Send((mpiId > 0? emigrant2 : emigrant1), sizeof(tspsIndividual_t) * numMigrants, MPI_CHAR, mpiId+1, MPI_MIGRATION_TAG, MPI_COMM_WORLD); 355 | } 356 | } 357 | 358 | // move imigrants to our current population 359 | if(numProcs > 1){ 360 | memcpy(&pop->individuals[i], imigrant1, sizeof(tspsIndividual_t) * numMigrants); 361 | } 362 | 363 | if(mpiId > 0 && mpiId < numProcs-1){ 364 | memcpy(&pop->individuals[j], imigrant2, sizeof(tspsIndividual_t) * numMigrants); 365 | } 366 | 367 | free(imigrant1); 368 | free(imigrant2); 369 | } 370 | 371 | int joinPopulations(tspsPopulation_t *pop, int mpiId, int mpiNumProcs){ 372 | MPI_Status status; 373 | int i, j; 374 | int indPerPop = floor(pop->numIndividuals / mpiNumProcs); 375 | int indIdx = indPerPop; 376 | 377 | if(mpiId == 0){ 378 | // get the top individuals from other populations 379 | for(i=1; iindividuals[indIdx], sizeof(tspsIndividual_t), MPI_CHAR, i, MPI_MIGRATION_TAG, MPI_COMM_WORLD, &status); 382 | indIdx++; 383 | } 384 | } 385 | }else{ 386 | for(j=0; jindividuals[j], sizeof(tspsIndividual_t), MPI_CHAR, 0, MPI_MIGRATION_TAG, MPI_COMM_WORLD); 388 | indIdx++; 389 | } 390 | } 391 | } 392 | 393 | void printIndividual(tspsIndividual_t *ind, const char *label){ 394 | int i; 395 | logg("** %s\n", label); 396 | logg("-- fitness = [%d]\n", ind->fitness); 397 | logg("-- chromos = "); 398 | for(i=0; ichrom[i]); 400 | if((i+1) % 10 == 0) 401 | logg("\n\t"); 402 | } 403 | logg("\n--------------------------------------------------------------\n"); 404 | } 405 | --------------------------------------------------------------------------------