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 #include "postgres.h"
00026
00027 #include <math.h>
00028
00029 #include "optimizer/geqo_misc.h"
00030 #include "optimizer/geqo_mutation.h"
00031 #include "optimizer/geqo_pool.h"
00032 #include "optimizer/geqo_random.h"
00033 #include "optimizer/geqo_selection.h"
00034
00035
00036
00037
00038
00039 int Geqo_effort;
00040 int Geqo_pool_size;
00041 int Geqo_generations;
00042 double Geqo_selection_bias;
00043 double Geqo_seed;
00044
00045
00046 static int gimme_pool_size(int nr_rel);
00047 static int gimme_number_generations(int pool_size);
00048
00049
00050 #if !defined(ERX) && \
00051 !defined(PMX) && \
00052 !defined(CX) && \
00053 !defined(PX) && \
00054 !defined(OX1) && \
00055 !defined(OX2)
00056 #define ERX
00057 #endif
00058
00059
00060
00061
00062
00063
00064
00065
00066 RelOptInfo *
00067 geqo(PlannerInfo *root, int number_of_rels, List *initial_rels)
00068 {
00069 GeqoPrivateData private;
00070 int generation;
00071 Chromosome *momma;
00072 Chromosome *daddy;
00073 Chromosome *kid;
00074 Pool *pool;
00075 int pool_size,
00076 number_generations;
00077
00078 #ifdef GEQO_DEBUG
00079 int status_interval;
00080 #endif
00081 Gene *best_tour;
00082 RelOptInfo *best_rel;
00083
00084 #if defined(ERX)
00085 Edge *edge_table;
00086 int edge_failures = 0;
00087 #endif
00088 #if defined(CX) || defined(PX) || defined(OX1) || defined(OX2)
00089 City *city_table;
00090 #endif
00091 #if defined(CX)
00092 int cycle_diffs = 0;
00093 int mutations = 0;
00094 #endif
00095
00096
00097 root->join_search_private = (void *) &private;
00098 private.initial_rels = initial_rels;
00099
00100
00101 geqo_set_seed(root, Geqo_seed);
00102
00103
00104 pool_size = gimme_pool_size(number_of_rels);
00105 number_generations = gimme_number_generations(pool_size);
00106 #ifdef GEQO_DEBUG
00107 status_interval = 10;
00108 #endif
00109
00110
00111 pool = alloc_pool(root, pool_size, number_of_rels);
00112
00113
00114 random_init_pool(root, pool);
00115
00116
00117 sort_pool(root, pool);
00118
00119
00120
00121 #ifdef GEQO_DEBUG
00122 elog(DEBUG1, "GEQO selected %d pool entries, best %.2f, worst %.2f",
00123 pool_size,
00124 pool->data[0].worth,
00125 pool->data[pool_size - 1].worth);
00126 #endif
00127
00128
00129 momma = alloc_chromo(root, pool->string_length);
00130 daddy = alloc_chromo(root, pool->string_length);
00131
00132 #if defined (ERX)
00133 #ifdef GEQO_DEBUG
00134 elog(DEBUG2, "using edge recombination crossover [ERX]");
00135 #endif
00136
00137 edge_table = alloc_edge_table(root, pool->string_length);
00138 #elif defined(PMX)
00139 #ifdef GEQO_DEBUG
00140 elog(DEBUG2, "using partially matched crossover [PMX]");
00141 #endif
00142
00143 kid = alloc_chromo(root, pool->string_length);
00144 #elif defined(CX)
00145 #ifdef GEQO_DEBUG
00146 elog(DEBUG2, "using cycle crossover [CX]");
00147 #endif
00148
00149 kid = alloc_chromo(root, pool->string_length);
00150 city_table = alloc_city_table(root, pool->string_length);
00151 #elif defined(PX)
00152 #ifdef GEQO_DEBUG
00153 elog(DEBUG2, "using position crossover [PX]");
00154 #endif
00155
00156 kid = alloc_chromo(root, pool->string_length);
00157 city_table = alloc_city_table(root, pool->string_length);
00158 #elif defined(OX1)
00159 #ifdef GEQO_DEBUG
00160 elog(DEBUG2, "using order crossover [OX1]");
00161 #endif
00162
00163 kid = alloc_chromo(root, pool->string_length);
00164 city_table = alloc_city_table(root, pool->string_length);
00165 #elif defined(OX2)
00166 #ifdef GEQO_DEBUG
00167 elog(DEBUG2, "using order crossover [OX2]");
00168 #endif
00169
00170 kid = alloc_chromo(root, pool->string_length);
00171 city_table = alloc_city_table(root, pool->string_length);
00172 #endif
00173
00174
00175
00176
00177
00178 for (generation = 0; generation < number_generations; generation++)
00179 {
00180
00181 geqo_selection(root, momma, daddy, pool, Geqo_selection_bias);
00182
00183 #if defined (ERX)
00184
00185 gimme_edge_table(root, momma->string, daddy->string, pool->string_length, edge_table);
00186
00187 kid = momma;
00188
00189
00190 edge_failures += gimme_tour(root, edge_table, kid->string, pool->string_length);
00191 #elif defined(PMX)
00192
00193 pmx(root, momma->string, daddy->string, kid->string, pool->string_length);
00194 #elif defined(CX)
00195
00196 cycle_diffs = cx(root, momma->string, daddy->string, kid->string, pool->string_length, city_table);
00197
00198 if (cycle_diffs == 0)
00199 {
00200 mutations++;
00201 geqo_mutation(root, kid->string, pool->string_length);
00202 }
00203 #elif defined(PX)
00204
00205 px(root, momma->string, daddy->string, kid->string, pool->string_length, city_table);
00206 #elif defined(OX1)
00207
00208 ox1(root, momma->string, daddy->string, kid->string, pool->string_length, city_table);
00209 #elif defined(OX2)
00210
00211 ox2(root, momma->string, daddy->string, kid->string, pool->string_length, city_table);
00212 #endif
00213
00214
00215
00216 kid->worth = geqo_eval(root, kid->string, pool->string_length);
00217
00218
00219 spread_chromo(root, kid, pool);
00220
00221
00222 #ifdef GEQO_DEBUG
00223 if (status_interval && !(generation % status_interval))
00224 print_gen(stdout, pool, generation);
00225 #endif
00226
00227 }
00228
00229
00230 #if defined(ERX) && defined(GEQO_DEBUG)
00231 if (edge_failures != 0)
00232 elog(LOG, "[GEQO] failures: %d, average: %d",
00233 edge_failures, (int) number_generations / edge_failures);
00234 else
00235 elog(LOG, "[GEQO] no edge failures detected");
00236 #endif
00237
00238 #if defined(CX) && defined(GEQO_DEBUG)
00239 if (mutations != 0)
00240 elog(LOG, "[GEQO] mutations: %d, generations: %d",
00241 mutations, number_generations);
00242 else
00243 elog(LOG, "[GEQO] no mutations processed");
00244 #endif
00245
00246 #ifdef GEQO_DEBUG
00247 print_pool(stdout, pool, 0, pool_size - 1);
00248 #endif
00249
00250 #ifdef GEQO_DEBUG
00251 elog(DEBUG1, "GEQO best is %.2f after %d generations",
00252 pool->data[0].worth, number_generations);
00253 #endif
00254
00255
00256
00257
00258
00259
00260 best_tour = (Gene *) pool->data[0].string;
00261
00262 best_rel = gimme_tree(root, best_tour, pool->string_length);
00263
00264
00265 #ifdef NOT_USED
00266 print_plan(best_plan, root);
00267 #endif
00268
00269
00270 free_chromo(root, momma);
00271 free_chromo(root, daddy);
00272
00273 #if defined (ERX)
00274 free_edge_table(root, edge_table);
00275 #elif defined(PMX)
00276 free_chromo(root, kid);
00277 #elif defined(CX)
00278 free_chromo(root, kid);
00279 free_city_table(root, city_table);
00280 #elif defined(PX)
00281 free_chromo(root, kid);
00282 free_city_table(root, city_table);
00283 #elif defined(OX1)
00284 free_chromo(root, kid);
00285 free_city_table(root, city_table);
00286 #elif defined(OX2)
00287 free_chromo(root, kid);
00288 free_city_table(root, city_table);
00289 #endif
00290
00291 free_pool(root, pool);
00292
00293
00294 root->join_search_private = NULL;
00295
00296 return best_rel;
00297 }
00298
00299
00300
00301
00302
00303
00304
00305
00306 static int
00307 gimme_pool_size(int nr_rel)
00308 {
00309 double size;
00310 int minsize;
00311 int maxsize;
00312
00313
00314 if (Geqo_pool_size >= 2)
00315 return Geqo_pool_size;
00316
00317 size = pow(2.0, nr_rel + 1.0);
00318
00319 maxsize = 50 * Geqo_effort;
00320 if (size > maxsize)
00321 return maxsize;
00322
00323 minsize = 10 * Geqo_effort;
00324 if (size < minsize)
00325 return minsize;
00326
00327 return (int) ceil(size);
00328 }
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 static int
00339 gimme_number_generations(int pool_size)
00340 {
00341 if (Geqo_generations > 0)
00342 return Geqo_generations;
00343
00344 return pool_size;
00345 }