Header And Logo

PostgreSQL
| The world's most advanced open source database.

geqo_pool.c

Go to the documentation of this file.
00001 /*------------------------------------------------------------------------
00002  *
00003  * geqo_pool.c
00004  *    Genetic Algorithm (GA) pool stuff
00005  *
00006  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00007  * Portions Copyright (c) 1994, Regents of the University of California
00008  *
00009  * src/backend/optimizer/geqo/geqo_pool.c
00010  *
00011  *-------------------------------------------------------------------------
00012  */
00013 
00014 /* contributed by:
00015    =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
00016    *  Martin Utesch              * Institute of Automatic Control      *
00017    =                             = University of Mining and Technology =
00018    *  [email protected]  * Freiberg, Germany                   *
00019    =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
00020  */
00021 
00022 /* -- parts of this are adapted from D. Whitley's Genitor algorithm -- */
00023 
00024 #include "postgres.h"
00025 
00026 #include <float.h>
00027 #include <limits.h>
00028 #include <math.h>
00029 
00030 #include "optimizer/geqo_copy.h"
00031 #include "optimizer/geqo_pool.h"
00032 #include "optimizer/geqo_recombination.h"
00033 
00034 
00035 static int  compare(const void *arg1, const void *arg2);
00036 
00037 /*
00038  * alloc_pool
00039  *      allocates memory for GA pool
00040  */
00041 Pool *
00042 alloc_pool(PlannerInfo *root, int pool_size, int string_length)
00043 {
00044     Pool       *new_pool;
00045     Chromosome *chromo;
00046     int         i;
00047 
00048     /* pool */
00049     new_pool = (Pool *) palloc(sizeof(Pool));
00050     new_pool->size = (int) pool_size;
00051     new_pool->string_length = (int) string_length;
00052 
00053     /* all chromosome */
00054     new_pool->data = (Chromosome *) palloc(pool_size * sizeof(Chromosome));
00055 
00056     /* all gene */
00057     chromo = (Chromosome *) new_pool->data;     /* vector of all chromos */
00058     for (i = 0; i < pool_size; i++)
00059         chromo[i].string = palloc((string_length + 1) * sizeof(Gene));
00060 
00061     return new_pool;
00062 }
00063 
00064 /*
00065  * free_pool
00066  *      deallocates memory for GA pool
00067  */
00068 void
00069 free_pool(PlannerInfo *root, Pool *pool)
00070 {
00071     Chromosome *chromo;
00072     int         i;
00073 
00074     /* all gene */
00075     chromo = (Chromosome *) pool->data; /* vector of all chromos */
00076     for (i = 0; i < pool->size; i++)
00077         pfree(chromo[i].string);
00078 
00079     /* all chromosome */
00080     pfree(pool->data);
00081 
00082     /* pool */
00083     pfree(pool);
00084 }
00085 
00086 /*
00087  * random_init_pool
00088  *      initialize genetic pool
00089  */
00090 void
00091 random_init_pool(PlannerInfo *root, Pool *pool)
00092 {
00093     Chromosome *chromo = (Chromosome *) pool->data;
00094     int         i;
00095 
00096     for (i = 0; i < pool->size; i++)
00097     {
00098         init_tour(root, chromo[i].string, pool->string_length);
00099         pool->data[i].worth = geqo_eval(root, chromo[i].string,
00100                                         pool->string_length);
00101     }
00102 }
00103 
00104 /*
00105  * sort_pool
00106  *   sorts input pool according to worth, from smallest to largest
00107  *
00108  *   maybe you have to change compare() for different ordering ...
00109  */
00110 void
00111 sort_pool(PlannerInfo *root, Pool *pool)
00112 {
00113     qsort(pool->data, pool->size, sizeof(Chromosome), compare);
00114 }
00115 
00116 /*
00117  * compare
00118  *   qsort comparison function for sort_pool
00119  */
00120 static int
00121 compare(const void *arg1, const void *arg2)
00122 {
00123     const Chromosome *chromo1 = (const Chromosome *) arg1;
00124     const Chromosome *chromo2 = (const Chromosome *) arg2;
00125 
00126     if (chromo1->worth == chromo2->worth)
00127         return 0;
00128     else if (chromo1->worth > chromo2->worth)
00129         return 1;
00130     else
00131         return -1;
00132 }
00133 
00134 /* alloc_chromo
00135  *    allocates a chromosome and string space
00136  */
00137 Chromosome *
00138 alloc_chromo(PlannerInfo *root, int string_length)
00139 {
00140     Chromosome *chromo;
00141 
00142     chromo = (Chromosome *) palloc(sizeof(Chromosome));
00143     chromo->string = (Gene *) palloc((string_length + 1) * sizeof(Gene));
00144 
00145     return chromo;
00146 }
00147 
00148 /* free_chromo
00149  *    deallocates a chromosome and string space
00150  */
00151 void
00152 free_chromo(PlannerInfo *root, Chromosome *chromo)
00153 {
00154     pfree(chromo->string);
00155     pfree(chromo);
00156 }
00157 
00158 /* spread_chromo
00159  *   inserts a new chromosome into the pool, displacing worst gene in pool
00160  *   assumes best->worst = smallest->largest
00161  */
00162 void
00163 spread_chromo(PlannerInfo *root, Chromosome *chromo, Pool *pool)
00164 {
00165     int         top,
00166                 mid,
00167                 bot;
00168     int         i,
00169                 index;
00170     Chromosome  swap_chromo,
00171                 tmp_chromo;
00172 
00173     /* new chromo is so bad we can't use it */
00174     if (chromo->worth > pool->data[pool->size - 1].worth)
00175         return;
00176 
00177     /* do a binary search to find the index of the new chromo */
00178 
00179     top = 0;
00180     mid = pool->size / 2;
00181     bot = pool->size - 1;
00182     index = -1;
00183 
00184     while (index == -1)
00185     {
00186         /* these 4 cases find a new location */
00187 
00188         if (chromo->worth <= pool->data[top].worth)
00189             index = top;
00190         else if (chromo->worth == pool->data[mid].worth)
00191             index = mid;
00192         else if (chromo->worth == pool->data[bot].worth)
00193             index = bot;
00194         else if (bot - top <= 1)
00195             index = bot;
00196 
00197 
00198         /*
00199          * these 2 cases move the search indices since a new location has not
00200          * yet been found.
00201          */
00202 
00203         else if (chromo->worth < pool->data[mid].worth)
00204         {
00205             bot = mid;
00206             mid = top + ((bot - top) / 2);
00207         }
00208         else
00209         {                       /* (chromo->worth > pool->data[mid].worth) */
00210             top = mid;
00211             mid = top + ((bot - top) / 2);
00212         }
00213     }                           /* ... while */
00214 
00215     /* now we have index for chromo */
00216 
00217     /*
00218      * move every gene from index on down one position to make room for chromo
00219      */
00220 
00221     /*
00222      * copy new gene into pool storage; always replace worst gene in pool
00223      */
00224 
00225     geqo_copy(root, &pool->data[pool->size - 1], chromo, pool->string_length);
00226 
00227     swap_chromo.string = pool->data[pool->size - 1].string;
00228     swap_chromo.worth = pool->data[pool->size - 1].worth;
00229 
00230     for (i = index; i < pool->size; i++)
00231     {
00232         tmp_chromo.string = pool->data[i].string;
00233         tmp_chromo.worth = pool->data[i].worth;
00234 
00235         pool->data[i].string = swap_chromo.string;
00236         pool->data[i].worth = swap_chromo.worth;
00237 
00238         swap_chromo.string = tmp_chromo.string;
00239         swap_chromo.worth = tmp_chromo.worth;
00240     }
00241 }