void geqo_mutation(Gene *tour, int num_gene) { int swap1; int swap2; int num_swaps = geqo_randint(num_gene / 3, 0); Gene temp; while (num_swaps > 0) { swap1 = geqo_randint(num_gene - 1, 0); swap2 = geqo_randint(num_gene - 1, 0); while (swap1 == swap2) swap2 = geqo_randint(num_gene - 1, 0); temp = tour[swap1]; tour[swap1] = tour[swap2]; tour[swap2] = temp; num_swaps -= 1; } }
/* ox1 * * position crossover */ void ox1(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table) { int left, right, k, p, temp; /* initialize city table */ for (k = 1; k <= num_gene; k++) city_table[k].used = 0; /* select portion to copy from tour1 */ left = geqo_randint(root, num_gene - 1, 0); right = geqo_randint(root, num_gene - 1, 0); if (left > right) { temp = left; left = right; right = temp; } /* copy portion from tour1 to offspring */ for (k = left; k <= right; k++) { offspring[k] = tour1[k]; city_table[(int) tour1[k]].used = 1; } k = (right + 1) % num_gene; /* index into offspring */ p = k; /* index into tour2 */ /* copy stuff from tour2 to offspring */ while (k != left) { if (!city_table[(int) tour2[p]].used) { offspring[k] = tour2[p]; k = (k + 1) % num_gene; city_table[(int) tour2[p]].used = 1; } p = (p + 1) % num_gene; /* increment tour2-index */ } }
/* * init_tour * * Randomly generates a legal "traveling salesman" tour * (i.e. where each point is visited only once.) * Essentially, this routine fills an array with all possible * points on the tour and randomly chooses the 'next' city from * this array. When a city is chosen, the array is shortened * and the procedure repeated. */ void init_tour(PlannerInfo *root, Gene *tour, int num_gene) { Gene *tmp; int remainder; int next, i; /* Fill a temp array with the IDs of all not-yet-visited cities */ tmp = (Gene *) palloc(num_gene * sizeof(Gene)); for (i = 0; i < num_gene; i++) tmp[i] = (Gene) (i + 1); remainder = num_gene - 1; for (i = 0; i < num_gene; i++) { /* choose value between 0 and remainder inclusive */ next = geqo_randint(root, remainder, 0); /* output that element of the tmp array */ tour[i] = tmp[next]; /* and delete it */ tmp[next] = tmp[remainder]; remainder--; } pfree(tmp); }
/* * init_tour * * Randomly generates a legal "traveling salesman" tour * (i.e. where each point is visited only once.) */ void init_tour(PlannerInfo *root, Gene *tour, int num_gene) { int i, j; /* * We must fill the tour[] array with a random permutation of the numbers * 1 .. num_gene. We can do that in one pass using the "inside-out" * variant of the Fisher-Yates shuffle algorithm. Notionally, we append * each new value to the array and then swap it with a randomly-chosen * array element (possibly including itself, else we fail to generate * permutations with the last city last). The swap step can be optimized * by combining it with the insertion. */ if (num_gene > 0) tour[0] = (Gene) 1; for (i = 1; i < num_gene; i++) { j = geqo_randint(root, i, 0); /* i != j check avoids fetching uninitialized array element */ if (i != j) tour[i] = tour[j]; tour[j] = (Gene) (i + 1); } }
/* gimme_tour * * creates a new tour using edges from the edge table. * priority is given to "shared" edges (i.e. edges which * all parent genes possess and are marked as negative * in the edge table.) * */ int gimme_tour(planner_info_n* root, Edge* edge_table, Gene* new_gene, int num_gene) { int i; int edge_failures = 0; /* choose int between 1 and num_gene */ new_gene[0] = (Gene) geqo_randint(root, num_gene, 1); for (i = 1; i < num_gene; i++) { /* * as each point is entered into the tour, remove it from the edge * table */ remove_gene(root, new_gene[i - 1], edge_table[(int) new_gene[i - 1]], edge_table); /* find destination for the newly entered point */ if (edge_table[new_gene[i - 1]].unused_edges > 0) new_gene[i] = gimme_gene( root, edge_table[(int) new_gene[i - 1]], edge_table); else { /* cope with fault */ edge_failures++; new_gene[i] = edge_failure(root, new_gene, i - 1, edge_table, num_gene); } /* mark this node as incorporated */ edge_table[(int) new_gene[i - 1]].unused_edges = -1; } /* for (i=1; i<num_gene; i++) */ return edge_failures; }
/* ox2 * * position crossover */ void ox2(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table) { int k, j, count, pos, select, num_positions; /* initialize city table */ for (k = 1; k <= num_gene; k++) { city_table[k].used = 0; city_table[k - 1].select_list = -1; } /* determine the number of positions to be inherited from tour1 */ num_positions = geqo_randint(root, 2 * num_gene / 3, num_gene / 3); /* make a list of selected cities */ for (k = 0; k < num_positions; k++) { pos = geqo_randint(root, num_gene - 1, 0); city_table[pos].select_list = (int) tour1[pos]; city_table[(int) tour1[pos]].used = 1; /* mark used */ } count = 0; k = 0; /* consolidate the select list to adjacent positions */ while (count < num_positions) { if (city_table[k].select_list == -1) { j = k + 1; while ((city_table[j].select_list == -1) && (j < num_gene)) j++; city_table[k].select_list = city_table[j].select_list; city_table[j].select_list = -1; count++; } else count++; k++; } select = 0; for (k = 0; k < num_gene; k++) { if (city_table[(int) tour2[k]].used) { offspring[k] = (Gene) city_table[select].select_list; select++; /* next city in the select list */ } else /* city isn't used yet, so inherit from tour2 */ offspring[k] = tour2[k]; } }
/* px * * position crossover */ void px(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table) { int num_positions; int i, pos, tour2_index, offspring_index; /* initialize city table */ for (i = 1; i <= num_gene; i++) city_table[i].used = 0; /* choose random positions that will be inherited directly from parent */ num_positions = geqo_randint(root, 2 * num_gene / 3, num_gene / 3); /* choose random position */ for (i = 0; i < num_positions; i++) { pos = geqo_randint(root, num_gene - 1, 0); offspring[pos] = tour1[pos]; /* transfer cities to child */ city_table[(int) tour1[pos]].used = 1; /* mark city used */ } tour2_index = 0; offspring_index = 0; /* px main part */ while (offspring_index < num_gene) { /* next position in offspring filled */ if (!city_table[(int) tour1[offspring_index]].used) { /* next city in tour1 not used */ if (!city_table[(int) tour2[tour2_index]].used) { /* inherit from tour1 */ offspring[offspring_index] = tour2[tour2_index]; tour2_index++; offspring_index++; } else { /* next city in tour2 has been used */ tour2_index++; } } else { /* next position in offspring is filled */ offspring_index++; } } }
/* cx * * cycle crossover */ int cx(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table) { int i, start_pos, curr_pos; int count = 0; int num_diffs = 0; /* initialize city table */ for (i = 1; i <= num_gene; i++) { city_table[i].used = 0; city_table[tour2[i - 1]].tour2_position = i - 1; city_table[tour1[i - 1]].tour1_position = i - 1; } /* choose random cycle starting position */ start_pos = geqo_randint(num_gene - 1, 0); /* child inherits first city */ offspring[start_pos] = tour1[start_pos]; /* begin cycle with tour1 */ curr_pos = start_pos; city_table[(int) tour1[start_pos]].used = 1; count++; /* cx main part */ /* STEP 1 */ while (tour2[curr_pos] != tour1[start_pos]) { city_table[(int) tour2[curr_pos]].used = 1; curr_pos = city_table[(int) tour2[curr_pos]].tour1_position; offspring[curr_pos] = tour1[curr_pos]; count++; } /* STEP 2 */ /* failed to create a complete tour */ if (count < num_gene) { for (i = 1; i <= num_gene; i++) { if (!city_table[i].used) { offspring[city_table[i].tour2_position] = tour2[(int) city_table[i].tour2_position]; count++; } } } /* STEP 3 */ /* still failed to create a complete tour */ if (count < num_gene) { /* count the number of differences between mom and offspring */ for (i = 0; i < num_gene; i++) if (tour1[i] != offspring[i]) num_diffs++; } return num_diffs; }
if (edge_table[(int) friend].unused_edges < minimum_edges) { minimum_edges = edge_table[(int) friend].unused_edges; minimum_count = 1; } else if (minimum_count == -1) elog(ERROR, "minimum_count not set"); else if (edge_table[(int) friend].unused_edges == minimum_edges) minimum_count++; } /* for (i=0; i<edge.unused_edges; i++) */ /* random decision of the possible candidates to use */ rand_decision = geqo_randint(root, minimum_count - 1, 0); for (i = 0; i < edge.unused_edges; i++) { friend = (Gene) edge.edge_list[i]; /* return the chosen candidate point */ if (edge_table[(int) friend].unused_edges == minimum_edges) { minimum_count--; if (minimum_count == rand_decision) return friend; } }