00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "postgres.h"
00035 #include "optimizer/geqo_recombination.h"
00036 #include "optimizer/geqo_random.h"
00037
00038
00039 static int gimme_edge(PlannerInfo *root, Gene gene1, Gene gene2, Edge *edge_table);
00040 static void remove_gene(PlannerInfo *root, Gene gene, Edge edge, Edge *edge_table);
00041 static Gene gimme_gene(PlannerInfo *root, Edge edge, Edge *edge_table);
00042
00043 static Gene edge_failure(PlannerInfo *root, Gene *gene, int index, Edge *edge_table, int num_gene);
00044
00045
00046
00047
00048
00049
00050
00051
00052 Edge *
00053 alloc_edge_table(PlannerInfo *root, int num_gene)
00054 {
00055 Edge *edge_table;
00056
00057
00058
00059
00060
00061
00062 edge_table = (Edge *) palloc((num_gene + 1) * sizeof(Edge));
00063
00064 return edge_table;
00065 }
00066
00067
00068
00069
00070
00071
00072 void
00073 free_edge_table(PlannerInfo *root, Edge *edge_table)
00074 {
00075 pfree(edge_table);
00076 }
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 float
00092 gimme_edge_table(PlannerInfo *root, Gene *tour1, Gene *tour2,
00093 int num_gene, Edge *edge_table)
00094 {
00095 int i,
00096 index1,
00097 index2;
00098 int edge_total;
00099
00100
00101 for (i = 1; i <= num_gene; i++)
00102 {
00103 edge_table[i].total_edges = 0;
00104 edge_table[i].unused_edges = 0;
00105 }
00106
00107
00108
00109 edge_total = 0;
00110
00111 for (index1 = 0; index1 < num_gene; index1++)
00112 {
00113
00114
00115
00116
00117
00118 index2 = (index1 + 1) % num_gene;
00119
00120
00121
00122
00123
00124
00125 edge_total += gimme_edge(root, tour1[index1], tour1[index2], edge_table);
00126 gimme_edge(root, tour1[index2], tour1[index1], edge_table);
00127
00128 edge_total += gimme_edge(root, tour2[index1], tour2[index2], edge_table);
00129 gimme_edge(root, tour2[index2], tour2[index1], edge_table);
00130 }
00131
00132
00133 return ((float) (edge_total * 2) / (float) num_gene);
00134 }
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 static int
00151 gimme_edge(PlannerInfo *root, Gene gene1, Gene gene2, Edge *edge_table)
00152 {
00153 int i;
00154 int edges;
00155 int city1 = (int) gene1;
00156 int city2 = (int) gene2;
00157
00158
00159
00160 edges = edge_table[city1].total_edges;
00161
00162 for (i = 0; i < edges; i++)
00163 {
00164 if ((Gene) Abs(edge_table[city1].edge_list[i]) == city2)
00165 {
00166
00167
00168 edge_table[city1].edge_list[i] = 0 - city2;
00169
00170 return 0;
00171 }
00172 }
00173
00174
00175 edge_table[city1].edge_list[edges] = city2;
00176
00177
00178 edge_table[city1].total_edges++;
00179 edge_table[city1].unused_edges++;
00180
00181 return 1;
00182 }
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 int
00193 gimme_tour(PlannerInfo *root, Edge *edge_table, Gene *new_gene, int num_gene)
00194 {
00195 int i;
00196 int edge_failures = 0;
00197
00198
00199 new_gene[0] = (Gene) geqo_randint(root, num_gene, 1);
00200
00201 for (i = 1; i < num_gene; i++)
00202 {
00203
00204
00205
00206
00207
00208 remove_gene(root, new_gene[i - 1], edge_table[(int) new_gene[i - 1]], edge_table);
00209
00210
00211
00212 if (edge_table[new_gene[i - 1]].unused_edges > 0)
00213 new_gene[i] = gimme_gene(root, edge_table[(int) new_gene[i - 1]], edge_table);
00214
00215 else
00216 {
00217 edge_failures++;
00218
00219 new_gene[i] = edge_failure(root, new_gene, i - 1, edge_table, num_gene);
00220 }
00221
00222
00223 edge_table[(int) new_gene[i - 1]].unused_edges = -1;
00224
00225 }
00226
00227 return edge_failures;
00228
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238 static void
00239 remove_gene(PlannerInfo *root, Gene gene, Edge edge, Edge *edge_table)
00240 {
00241 int i,
00242 j;
00243 int possess_edge;
00244 int genes_remaining;
00245
00246
00247
00248
00249
00250
00251 for (i = 0; i < edge.unused_edges; i++)
00252 {
00253 possess_edge = (int) Abs(edge.edge_list[i]);
00254 genes_remaining = edge_table[possess_edge].unused_edges;
00255
00256
00257 for (j = 0; j < genes_remaining; j++)
00258 {
00259
00260 if ((Gene) Abs(edge_table[possess_edge].edge_list[j]) == gene)
00261 {
00262
00263 edge_table[possess_edge].unused_edges--;
00264
00265 edge_table[possess_edge].edge_list[j] =
00266 edge_table[possess_edge].edge_list[genes_remaining - 1];
00267
00268 break;
00269 }
00270 }
00271 }
00272 }
00273
00274
00275
00276
00277
00278
00279
00280 static Gene
00281 gimme_gene(PlannerInfo *root, Edge edge, Edge *edge_table)
00282 {
00283 int i;
00284 Gene friend;
00285 int minimum_edges;
00286 int minimum_count = -1;
00287 int rand_decision;
00288
00289
00290
00291
00292
00293
00294 minimum_edges = 5;
00295
00296
00297
00298 for (i = 0; i < edge.unused_edges; i++)
00299 {
00300 friend = (Gene) edge.edge_list[i];
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 if (friend < 0)
00311 return (Gene) Abs(friend);
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330 if (edge_table[(int) friend].unused_edges < minimum_edges)
00331 {
00332 minimum_edges = edge_table[(int) friend].unused_edges;
00333 minimum_count = 1;
00334 }
00335 else if (minimum_count == -1)
00336 elog(ERROR, "minimum_count not set");
00337 else if (edge_table[(int) friend].unused_edges == minimum_edges)
00338 minimum_count++;
00339
00340 }
00341
00342
00343
00344 rand_decision = geqo_randint(root, minimum_count - 1, 0);
00345
00346
00347 for (i = 0; i < edge.unused_edges; i++)
00348 {
00349 friend = (Gene) edge.edge_list[i];
00350
00351
00352 if (edge_table[(int) friend].unused_edges == minimum_edges)
00353 {
00354 minimum_count--;
00355
00356 if (minimum_count == rand_decision)
00357 return friend;
00358 }
00359 }
00360
00361
00362 elog(ERROR, "neither shared nor minimum number nor random edge found");
00363 return 0;
00364 }
00365
00366
00367
00368
00369
00370
00371 static Gene
00372 edge_failure(PlannerInfo *root, Gene *gene, int index, Edge *edge_table, int num_gene)
00373 {
00374 int i;
00375 Gene fail_gene = gene[index];
00376 int remaining_edges = 0;
00377 int four_count = 0;
00378 int rand_decision;
00379
00380
00381
00382
00383
00384
00385
00386 for (i = 1; i <= num_gene; i++)
00387 {
00388 if ((edge_table[i].unused_edges != -1) && (i != (int) fail_gene))
00389 {
00390 remaining_edges++;
00391
00392 if (edge_table[i].total_edges == 4)
00393 four_count++;
00394 }
00395 }
00396
00397
00398
00399
00400
00401
00402 if (four_count != 0)
00403 {
00404
00405 rand_decision = geqo_randint(root, four_count - 1, 0);
00406
00407 for (i = 1; i <= num_gene; i++)
00408 {
00409
00410 if ((Gene) i != fail_gene &&
00411 edge_table[i].unused_edges != -1 &&
00412 edge_table[i].total_edges == 4)
00413 {
00414
00415 four_count--;
00416
00417 if (rand_decision == four_count)
00418 return (Gene) i;
00419 }
00420 }
00421
00422 elog(LOG, "no edge found via random decision and total_edges == 4");
00423 }
00424 else if (remaining_edges != 0)
00425 {
00426
00427 rand_decision = geqo_randint(root, remaining_edges - 1, 0);
00428
00429 for (i = 1; i <= num_gene; i++)
00430 {
00431
00432 if ((Gene) i != fail_gene &&
00433 edge_table[i].unused_edges != -1)
00434 {
00435
00436 remaining_edges--;
00437
00438 if (rand_decision == remaining_edges)
00439 return i;
00440 }
00441 }
00442
00443 elog(LOG, "no edge found via random decision with remaining edges");
00444 }
00445
00446
00447
00448
00449
00450
00451
00452 else
00453 {
00454
00455
00456
00457 for (i = 1; i <= num_gene; i++)
00458 if (edge_table[i].unused_edges >= 0)
00459 return (Gene) i;
00460
00461 elog(LOG, "no edge found via looking for the last ununsed point");
00462 }
00463
00464
00465
00466 elog(ERROR, "no edge found");
00467 return 0;
00468 }