1 /*------------------------------------------------------------------------
4 * Genetic Algorithm (GA) pool stuff
6 * Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
9 * $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_pool.c,v 1.25 2004/08/29 05:06:43 momjian 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 /* -- parts of this are adapted from D. Whitley's Genitor algorithm -- */
30 #include "optimizer/geqo.h"
31 #include "optimizer/geqo_copy.h"
32 #include "optimizer/geqo_pool.h"
33 #include "optimizer/geqo_recombination.h"
36 static int compare(const void *arg1, const void *arg2);
40 * allocates memory for GA pool
43 alloc_pool(int pool_size, int string_length)
50 new_pool = (Pool *) palloc(sizeof(Pool));
51 new_pool->size = (int) pool_size;
52 new_pool->string_length = (int) string_length;
55 new_pool->data = (Chromosome *) palloc(pool_size * sizeof(Chromosome));
58 chromo = (Chromosome *) new_pool->data; /* vector of all chromos */
59 for (i = 0; i < pool_size; i++)
60 chromo[i].string = palloc((string_length + 1) * sizeof(Gene));
67 * deallocates memory for GA pool
76 chromo = (Chromosome *) pool->data; /* vector of all chromos */
77 for (i = 0; i < pool->size; i++)
78 pfree(chromo[i].string);
89 * initialize genetic pool
92 random_init_pool(Pool *pool, GeqoEvalData *evaldata)
94 Chromosome *chromo = (Chromosome *) pool->data;
99 * We immediately discard any invalid individuals (those that
100 * geqo_eval returns DBL_MAX for), thereby not wasting pool space on
103 * If we fail to make any valid individuals after 10000 tries, give up;
104 * this probably means something is broken, and we shouldn't just let
105 * ourselves get stuck in an infinite loop.
108 while (i < pool->size)
110 init_tour(chromo[i].string, pool->string_length);
111 pool->data[i].worth = geqo_eval(chromo[i].string,
114 if (pool->data[i].worth < DBL_MAX)
119 if (i == 0 && bad >= 10000)
120 elog(ERROR, "failed to make a valid plan");
126 elog(DEBUG1, "%d invalid tours found while selecting %d pool entries",
133 * sorts input pool according to worth, from smallest to largest
135 * maybe you have to change compare() for different ordering ...
138 sort_pool(Pool *pool)
140 qsort(pool->data, pool->size, sizeof(Chromosome), compare);
145 * qsort comparison function for sort_pool
148 compare(const void *arg1, const void *arg2)
150 const Chromosome *chromo1 = (const Chromosome *) arg1;
151 const Chromosome *chromo2 = (const Chromosome *) arg2;
153 if (chromo1->worth == chromo2->worth)
155 else if (chromo1->worth > chromo2->worth)
162 * allocates a chromosome and string space
165 alloc_chromo(int string_length)
169 chromo = (Chromosome *) palloc(sizeof(Chromosome));
170 chromo->string = (Gene *) palloc((string_length + 1) * sizeof(Gene));
176 * deallocates a chromosome and string space
179 free_chromo(Chromosome *chromo)
181 pfree(chromo->string);
186 * inserts a new chromosome into the pool, displacing worst gene in pool
187 * assumes best->worst = smallest->largest
190 spread_chromo(Chromosome *chromo, Pool *pool)
197 Chromosome swap_chromo,
200 /* new chromo is so bad we can't use it */
201 if (chromo->worth > pool->data[pool->size - 1].worth)
204 /* do a binary search to find the index of the new chromo */
207 mid = pool->size / 2;
208 bot = pool->size - 1;
213 /* these 4 cases find a new location */
215 if (chromo->worth <= pool->data[top].worth)
217 else if (chromo->worth == pool->data[mid].worth)
219 else if (chromo->worth == pool->data[bot].worth)
221 else if (bot - top <= 1)
226 * these 2 cases move the search indices since a new location has
227 * not yet been found.
230 else if (chromo->worth < pool->data[mid].worth)
233 mid = top + ((bot - top) / 2);
236 { /* (chromo->worth > pool->data[mid].worth) */
238 mid = top + ((bot - top) / 2);
242 /* now we have index for chromo */
245 * move every gene from index on down one position to make room for
250 * copy new gene into pool storage; always replace worst gene in pool
253 geqo_copy(&pool->data[pool->size - 1], chromo, pool->string_length);
255 swap_chromo.string = pool->data[pool->size - 1].string;
256 swap_chromo.worth = pool->data[pool->size - 1].worth;
258 for (i = index; i < pool->size; i++)
260 tmp_chromo.string = pool->data[i].string;
261 tmp_chromo.worth = pool->data[i].worth;
263 pool->data[i].string = swap_chromo.string;
264 pool->data[i].worth = swap_chromo.worth;
266 swap_chromo.string = tmp_chromo.string;
267 swap_chromo.worth = tmp_chromo.worth;