1 /*------------------------------------------------------------------------
5 * partially matched crossover [PMX] routines;
6 * PMX operator according to Goldberg & Lingle
7 * (Proc Int'l Conf on GA's)
9 * $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_pmx.c,v 1.10 2003/11/29 22:39:49 pgsql Exp $
11 *-------------------------------------------------------------------------
15 =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
16 * Martin Utesch * Institute of Automatic Control *
17 = = University of Mining and Technology =
18 * utesch@aut.tu-freiberg.de * Freiberg, Germany *
19 =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
22 /* the pmx algorithm is adopted from Genitor : */
23 /*************************************************************/
25 /* Copyright (c) 1990 */
26 /* Darrell L. Whitley */
27 /* Computer Science Department */
28 /* Colorado State University */
30 /* Permission is hereby granted to copy all or any part of */
31 /* this program for free distribution. The author's name */
32 /* and this copyright notice must be included in any copy. */
34 /*************************************************************/
37 #include "optimizer/geqo_random.h"
38 #include "optimizer/geqo_recombination.h"
43 * partially matched crossover
46 pmx(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene)
48 int *failed = (int *) palloc((num_gene + 1) * sizeof(int));
49 int *from = (int *) palloc((num_gene + 1) * sizeof(int));
50 int *indx = (int *) palloc((num_gene + 1) * sizeof(int));
51 int *check_list = (int *) palloc((num_gene + 1) * sizeof(int));
64 /* no mutation so start up the pmx replacement algorithm */
65 /* initialize failed[], from[], check_list[] */
66 for (k = 0; k < num_gene; k++)
70 check_list[k + 1] = 0;
73 /* locate crossover points */
74 left = geqo_randint(num_gene - 1, 0);
75 right = geqo_randint(num_gene - 1, 0);
85 /* copy tour2 into offspring */
86 for (k = 0; k < num_gene; k++)
88 offspring[k] = tour2[k];
90 check_list[tour2[k]]++;
93 /* copy tour1 into offspring */
94 for (k = left; k <= right; k++)
96 check_list[offspring[k]]--;
97 offspring[k] = tour1[k];
99 check_list[tour1[k]]++;
109 for (k = left; k <= right; k++)
110 { /* for all elements in the tour1-2 */
112 if (tour1[k] == tour2[k])
113 found = 1; /* find match in tour2 */
117 found = 0; /* substitute elements */
120 while (!(found) && (j < num_gene))
122 if ((offspring[j] == tour1[k]) && (from[j] == DAD))
125 check_list[offspring[j]]--;
126 offspring[j] = tour2[k];
128 check_list[tour2[k]]++;
137 { /* failed to replace gene */
138 failed[mx_fail] = (int) tour1[k];
148 /* see if any genes could not be replaced */
153 for (k = 0; k < mx_hold; k++)
158 while (!(found) && (j < num_gene))
161 if ((failed[k] == (int) offspring[j]) && (from[j] == DAD))
163 check_list[offspring[j]]--;
164 offspring[j] = tour2[indx[k]];
165 check_list[tour2[indx[k]]]++;
182 for (k = 1; k <= num_gene; k++)
185 if (check_list[k] > 1)
191 if ((offspring[i] == (Gene) k) && (from[i] == DAD))
195 while (j <= num_gene)
197 if (check_list[j] == 0)
199 offspring[i] = (Gene) j;