*
* 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;
+ int i,
+ j;
- /* 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;
+ /*
+ * 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 = 0; i < num_gene; i++)
+ for (i = 1; 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--;
+ 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);
}
-
- pfree(tmp);
}
/* alloc_city_table