mirror of
https://github.com/postgres/postgres.git
synced 2025-07-20 05:03:10 +03:00
Make GEQO's planning deterministic by having it start from a predictable
random number seed each time. This is how it used to work years ago, but we got rid of the seed reset because it was resetting the main random() sequence and thus having undesirable effects on the rest of the system. To fix, establish a private random number state for each execution of geqo(), and initialize the state using the new GUC variable geqo_seed. People who want to experiment with different random searches can do so by changing geqo_seed, but you'll always get the same plan for the same value of geqo_seed (if holding all other planner inputs constant, of course). The new state is kept in PlannerInfo by adding a "void *" field reserved for use by join_search hooks. Most of the rather bulky code changes in this commit are just arranging to pass PlannerInfo around to all the GEQO functions (many of which formerly didn't receive it). Andres Freund, with some editorialization by Tom
This commit is contained in:
@ -5,7 +5,7 @@
|
||||
#
|
||||
# Copyright (c) 1994, Regents of the University of California
|
||||
#
|
||||
# $PostgreSQL: pgsql/src/backend/optimizer/geqo/Makefile,v 1.20 2008/02/19 10:30:07 petere Exp $
|
||||
# $PostgreSQL: pgsql/src/backend/optimizer/geqo/Makefile,v 1.21 2009/07/16 20:55:44 tgl Exp $
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@ -14,7 +14,7 @@ top_builddir = ../../../..
|
||||
include $(top_builddir)/src/Makefile.global
|
||||
|
||||
OBJS = geqo_copy.o geqo_eval.o geqo_main.o geqo_misc.o \
|
||||
geqo_mutation.o geqo_pool.o geqo_recombination.o \
|
||||
geqo_mutation.o geqo_pool.o geqo_random.o geqo_recombination.o \
|
||||
geqo_selection.o \
|
||||
geqo_erx.o geqo_pmx.o geqo_cx.o geqo_px.o geqo_ox1.o geqo_ox2.o
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_copy.c,v 1.19 2009/01/01 17:23:43 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_copy.c,v 1.20 2009/07/16 20:55:44 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -42,7 +42,8 @@
|
||||
*
|
||||
*/
|
||||
void
|
||||
geqo_copy(Chromosome *chromo1, Chromosome *chromo2, int string_length)
|
||||
geqo_copy(PlannerInfo *root, Chromosome *chromo1, Chromosome *chromo2,
|
||||
int string_length)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
* CX operator according to Oliver et al
|
||||
* (Proc 2nd Int'l Conf on GA's)
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_cx.c,v 1.10 2003/11/29 22:39:49 pgsql Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_cx.c,v 1.11 2009/07/16 20:55:44 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -44,7 +44,8 @@
|
||||
* cycle crossover
|
||||
*/
|
||||
int
|
||||
cx(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)
|
||||
cx(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring,
|
||||
int num_gene, City *city_table)
|
||||
{
|
||||
|
||||
int i,
|
||||
@ -62,7 +63,7 @@ cx(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)
|
||||
}
|
||||
|
||||
/* choose random cycle starting position */
|
||||
start_pos = geqo_randint(num_gene - 1, 0);
|
||||
start_pos = geqo_randint(root, num_gene - 1, 0);
|
||||
|
||||
/* child inherits first city */
|
||||
offspring[start_pos] = tour1[start_pos];
|
||||
|
@ -3,7 +3,7 @@
|
||||
* geqo_erx.c
|
||||
* edge recombination crossover [ER]
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_erx.c,v 1.20 2005/10/15 02:49:19 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_erx.c,v 1.21 2009/07/16 20:55:44 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -36,11 +36,11 @@
|
||||
#include "optimizer/geqo_random.h"
|
||||
|
||||
|
||||
static int gimme_edge(Gene gene1, Gene gene2, Edge *edge_table);
|
||||
static void remove_gene(Gene gene, Edge edge, Edge *edge_table);
|
||||
static Gene gimme_gene(Edge edge, Edge *edge_table);
|
||||
static int gimme_edge(PlannerInfo *root, Gene gene1, Gene gene2, Edge *edge_table);
|
||||
static void remove_gene(PlannerInfo *root, Gene gene, Edge edge, Edge *edge_table);
|
||||
static Gene gimme_gene(PlannerInfo *root, Edge edge, Edge *edge_table);
|
||||
|
||||
static Gene edge_failure(Gene *gene, int index, Edge *edge_table, int num_gene);
|
||||
static Gene edge_failure(PlannerInfo *root, Gene *gene, int index, Edge *edge_table, int num_gene);
|
||||
|
||||
|
||||
/* alloc_edge_table
|
||||
@ -50,7 +50,7 @@ static Gene edge_failure(Gene *gene, int index, Edge *edge_table, int num_gene);
|
||||
*/
|
||||
|
||||
Edge *
|
||||
alloc_edge_table(int num_gene)
|
||||
alloc_edge_table(PlannerInfo *root, int num_gene)
|
||||
{
|
||||
Edge *edge_table;
|
||||
|
||||
@ -70,7 +70,7 @@ alloc_edge_table(int num_gene)
|
||||
*
|
||||
*/
|
||||
void
|
||||
free_edge_table(Edge *edge_table)
|
||||
free_edge_table(PlannerInfo *root, Edge *edge_table)
|
||||
{
|
||||
pfree(edge_table);
|
||||
}
|
||||
@ -89,7 +89,8 @@ free_edge_table(Edge *edge_table)
|
||||
*
|
||||
*/
|
||||
float
|
||||
gimme_edge_table(Gene *tour1, Gene *tour2, int num_gene, Edge *edge_table)
|
||||
gimme_edge_table(PlannerInfo *root, Gene *tour1, Gene *tour2,
|
||||
int num_gene, Edge *edge_table)
|
||||
{
|
||||
int i,
|
||||
index1,
|
||||
@ -121,11 +122,11 @@ gimme_edge_table(Gene *tour1, Gene *tour2, int num_gene, Edge *edge_table)
|
||||
* twice per edge
|
||||
*/
|
||||
|
||||
edge_total += gimme_edge(tour1[index1], tour1[index2], edge_table);
|
||||
gimme_edge(tour1[index2], tour1[index1], edge_table);
|
||||
edge_total += gimme_edge(root, tour1[index1], tour1[index2], edge_table);
|
||||
gimme_edge(root, tour1[index2], tour1[index1], edge_table);
|
||||
|
||||
edge_total += gimme_edge(tour2[index1], tour2[index2], edge_table);
|
||||
gimme_edge(tour2[index2], tour2[index1], edge_table);
|
||||
edge_total += gimme_edge(root, tour2[index1], tour2[index2], edge_table);
|
||||
gimme_edge(root, tour2[index2], tour2[index1], edge_table);
|
||||
}
|
||||
|
||||
/* return average number of edges per index */
|
||||
@ -147,7 +148,7 @@ gimme_edge_table(Gene *tour1, Gene *tour2, int num_gene, Edge *edge_table)
|
||||
* 0 if edge was already registered and edge_table is unchanged
|
||||
*/
|
||||
static int
|
||||
gimme_edge(Gene gene1, Gene gene2, Edge *edge_table)
|
||||
gimme_edge(PlannerInfo *root, Gene gene1, Gene gene2, Edge *edge_table)
|
||||
{
|
||||
int i;
|
||||
int edges;
|
||||
@ -189,13 +190,13 @@ gimme_edge(Gene gene1, Gene gene2, Edge *edge_table)
|
||||
*
|
||||
*/
|
||||
int
|
||||
gimme_tour(Edge *edge_table, Gene *new_gene, int num_gene)
|
||||
gimme_tour(PlannerInfo *root, Edge *edge_table, Gene *new_gene, int num_gene)
|
||||
{
|
||||
int i;
|
||||
int edge_failures = 0;
|
||||
|
||||
new_gene[0] = (Gene) geqo_randint(num_gene, 1); /* choose int between 1
|
||||
* and num_gene */
|
||||
/* choose int between 1 and num_gene */
|
||||
new_gene[0] = (Gene) geqo_randint(root, num_gene, 1);
|
||||
|
||||
for (i = 1; i < num_gene; i++)
|
||||
{
|
||||
@ -204,18 +205,18 @@ gimme_tour(Edge *edge_table, Gene *new_gene, int num_gene)
|
||||
* table
|
||||
*/
|
||||
|
||||
remove_gene(new_gene[i - 1], edge_table[(int) new_gene[i - 1]], edge_table);
|
||||
remove_gene(root, new_gene[i - 1], edge_table[(int) new_gene[i - 1]], edge_table);
|
||||
|
||||
/* find destination for the newly entered point */
|
||||
|
||||
if (edge_table[new_gene[i - 1]].unused_edges > 0)
|
||||
new_gene[i] = gimme_gene(edge_table[(int) new_gene[i - 1]], edge_table);
|
||||
new_gene[i] = gimme_gene(root, edge_table[(int) new_gene[i - 1]], edge_table);
|
||||
|
||||
else
|
||||
{ /* cope with fault */
|
||||
edge_failures++;
|
||||
|
||||
new_gene[i] = edge_failure(new_gene, i - 1, edge_table, num_gene);
|
||||
new_gene[i] = edge_failure(root, new_gene, i - 1, edge_table, num_gene);
|
||||
}
|
||||
|
||||
/* mark this node as incorporated */
|
||||
@ -235,7 +236,7 @@ gimme_tour(Edge *edge_table, Gene *new_gene, int num_gene)
|
||||
*
|
||||
*/
|
||||
static void
|
||||
remove_gene(Gene gene, Edge edge, Edge *edge_table)
|
||||
remove_gene(PlannerInfo *root, Gene gene, Edge edge, Edge *edge_table)
|
||||
{
|
||||
int i,
|
||||
j;
|
||||
@ -277,7 +278,7 @@ remove_gene(Gene gene, Edge edge, Edge *edge_table)
|
||||
*
|
||||
*/
|
||||
static Gene
|
||||
gimme_gene(Edge edge, Edge *edge_table)
|
||||
gimme_gene(PlannerInfo *root, Edge edge, Edge *edge_table)
|
||||
{
|
||||
int i;
|
||||
Gene friend;
|
||||
@ -340,7 +341,7 @@ gimme_gene(Edge edge, Edge *edge_table)
|
||||
|
||||
|
||||
/* random decision of the possible candidates to use */
|
||||
rand_decision = (int) geqo_randint(minimum_count - 1, 0);
|
||||
rand_decision = geqo_randint(root, minimum_count - 1, 0);
|
||||
|
||||
|
||||
for (i = 0; i < edge.unused_edges; i++)
|
||||
@ -368,7 +369,7 @@ gimme_gene(Edge edge, Edge *edge_table)
|
||||
*
|
||||
*/
|
||||
static Gene
|
||||
edge_failure(Gene *gene, int index, Edge *edge_table, int num_gene)
|
||||
edge_failure(PlannerInfo *root, Gene *gene, int index, Edge *edge_table, int num_gene)
|
||||
{
|
||||
int i;
|
||||
Gene fail_gene = gene[index];
|
||||
@ -401,7 +402,7 @@ edge_failure(Gene *gene, int index, Edge *edge_table, int num_gene)
|
||||
if (four_count != 0)
|
||||
{
|
||||
|
||||
rand_decision = (int) geqo_randint(four_count - 1, 0);
|
||||
rand_decision = geqo_randint(root, four_count - 1, 0);
|
||||
|
||||
for (i = 1; i <= num_gene; i++)
|
||||
{
|
||||
@ -423,7 +424,7 @@ edge_failure(Gene *gene, int index, Edge *edge_table, int num_gene)
|
||||
else if (remaining_edges != 0)
|
||||
{
|
||||
/* random decision of the gene with remaining edges */
|
||||
rand_decision = (int) geqo_randint(remaining_edges - 1, 0);
|
||||
rand_decision = geqo_randint(root, remaining_edges - 1, 0);
|
||||
|
||||
for (i = 1; i <= num_gene; i++)
|
||||
{
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_eval.c,v 1.88 2009/01/01 17:23:43 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_eval.c,v 1.89 2009/07/16 20:55:44 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -42,7 +42,7 @@ static bool desirable_join(PlannerInfo *root,
|
||||
* Returns cost of a query tree as an individual of the population.
|
||||
*/
|
||||
Cost
|
||||
geqo_eval(Gene *tour, int num_gene, GeqoEvalData *evaldata)
|
||||
geqo_eval(PlannerInfo *root, Gene *tour, int num_gene)
|
||||
{
|
||||
MemoryContext mycontext;
|
||||
MemoryContext oldcxt;
|
||||
@ -94,13 +94,13 @@ geqo_eval(Gene *tour, int num_gene, GeqoEvalData *evaldata)
|
||||
* (If we are dealing with enough join rels, which we very likely are, a
|
||||
* new hash table will get built and used locally.)
|
||||
*/
|
||||
savelength = list_length(evaldata->root->join_rel_list);
|
||||
savehash = evaldata->root->join_rel_hash;
|
||||
savelength = list_length(root->join_rel_list);
|
||||
savehash = root->join_rel_hash;
|
||||
|
||||
evaldata->root->join_rel_hash = NULL;
|
||||
root->join_rel_hash = NULL;
|
||||
|
||||
/* construct the best path for the given combination of relations */
|
||||
joinrel = gimme_tree(tour, num_gene, evaldata);
|
||||
joinrel = gimme_tree(root, tour, num_gene);
|
||||
|
||||
/*
|
||||
* compute fitness
|
||||
@ -117,9 +117,9 @@ geqo_eval(Gene *tour, int num_gene, GeqoEvalData *evaldata)
|
||||
* Restore join_rel_list to its former state, and put back original
|
||||
* hashtable if any.
|
||||
*/
|
||||
evaldata->root->join_rel_list = list_truncate(evaldata->root->join_rel_list,
|
||||
savelength);
|
||||
evaldata->root->join_rel_hash = savehash;
|
||||
root->join_rel_list = list_truncate(root->join_rel_list,
|
||||
savelength);
|
||||
root->join_rel_hash = savehash;
|
||||
|
||||
/* release all the memory acquired within gimme_tree */
|
||||
MemoryContextSwitchTo(oldcxt);
|
||||
@ -134,7 +134,6 @@ geqo_eval(Gene *tour, int num_gene, GeqoEvalData *evaldata)
|
||||
* order.
|
||||
*
|
||||
* 'tour' is the proposed join order, of length 'num_gene'
|
||||
* 'evaldata' contains the context we need
|
||||
*
|
||||
* Returns a new join relation whose cheapest path is the best plan for
|
||||
* this join order. NB: will return NULL if join order is invalid.
|
||||
@ -153,8 +152,9 @@ geqo_eval(Gene *tour, int num_gene, GeqoEvalData *evaldata)
|
||||
* plans.
|
||||
*/
|
||||
RelOptInfo *
|
||||
gimme_tree(Gene *tour, int num_gene, GeqoEvalData *evaldata)
|
||||
gimme_tree(PlannerInfo *root, Gene *tour, int num_gene)
|
||||
{
|
||||
GeqoPrivateData *private = (GeqoPrivateData *) root->join_search_private;
|
||||
RelOptInfo **stack;
|
||||
int stack_depth;
|
||||
RelOptInfo *joinrel;
|
||||
@ -193,7 +193,7 @@ gimme_tree(Gene *tour, int num_gene, GeqoEvalData *evaldata)
|
||||
|
||||
/* Get the next input relation and push it */
|
||||
cur_rel_index = (int) tour[rel_count];
|
||||
stack[stack_depth] = (RelOptInfo *) list_nth(evaldata->initial_rels,
|
||||
stack[stack_depth] = (RelOptInfo *) list_nth(private->initial_rels,
|
||||
cur_rel_index - 1);
|
||||
stack_depth++;
|
||||
|
||||
@ -211,7 +211,7 @@ gimme_tree(Gene *tour, int num_gene, GeqoEvalData *evaldata)
|
||||
* have exhausted the input, the heuristics can't prevent popping.
|
||||
*/
|
||||
if (rel_count < num_gene - 1 &&
|
||||
!desirable_join(evaldata->root, outer_rel, inner_rel))
|
||||
!desirable_join(root, outer_rel, inner_rel))
|
||||
break;
|
||||
|
||||
/*
|
||||
@ -220,7 +220,7 @@ gimme_tree(Gene *tour, int num_gene, GeqoEvalData *evaldata)
|
||||
* root->join_rel_list yet, and so the paths constructed for it
|
||||
* will only include the ones we want.
|
||||
*/
|
||||
joinrel = make_join_rel(evaldata->root, outer_rel, inner_rel);
|
||||
joinrel = make_join_rel(root, outer_rel, inner_rel);
|
||||
|
||||
/* Can't pop stack here if join order is not valid */
|
||||
if (!joinrel)
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_main.c,v 1.56 2009/01/01 17:23:43 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_main.c,v 1.57 2009/07/16 20:55:44 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -27,7 +27,9 @@
|
||||
#include <math.h>
|
||||
|
||||
#include "optimizer/geqo_misc.h"
|
||||
#include "optimizer/geqo_mutation.h"
|
||||
#include "optimizer/geqo_pool.h"
|
||||
#include "optimizer/geqo_random.h"
|
||||
#include "optimizer/geqo_selection.h"
|
||||
|
||||
|
||||
@ -38,6 +40,7 @@ int Geqo_effort;
|
||||
int Geqo_pool_size;
|
||||
int Geqo_generations;
|
||||
double Geqo_selection_bias;
|
||||
double Geqo_seed;
|
||||
|
||||
|
||||
static int gimme_pool_size(int nr_rel);
|
||||
@ -63,7 +66,7 @@ static int gimme_number_generations(int pool_size);
|
||||
RelOptInfo *
|
||||
geqo(PlannerInfo *root, int number_of_rels, List *initial_rels)
|
||||
{
|
||||
GeqoEvalData evaldata;
|
||||
GeqoPrivateData private;
|
||||
int generation;
|
||||
Chromosome *momma;
|
||||
Chromosome *daddy;
|
||||
@ -88,9 +91,12 @@ geqo(PlannerInfo *root, int number_of_rels, List *initial_rels)
|
||||
int mutations = 0;
|
||||
#endif
|
||||
|
||||
/* set up evaldata */
|
||||
evaldata.root = root;
|
||||
evaldata.initial_rels = initial_rels;
|
||||
/* set up private information */
|
||||
root->join_search_private = (void *) &private;
|
||||
private.initial_rels = initial_rels;
|
||||
|
||||
/* initialize private number generator */
|
||||
geqo_set_seed(root, Geqo_seed);
|
||||
|
||||
/* set GA parameters */
|
||||
pool_size = gimme_pool_size(number_of_rels);
|
||||
@ -98,13 +104,13 @@ geqo(PlannerInfo *root, int number_of_rels, List *initial_rels)
|
||||
status_interval = 10;
|
||||
|
||||
/* allocate genetic pool memory */
|
||||
pool = alloc_pool(pool_size, number_of_rels);
|
||||
pool = alloc_pool(root, pool_size, number_of_rels);
|
||||
|
||||
/* random initialization of the pool */
|
||||
random_init_pool(pool, &evaldata);
|
||||
random_init_pool(root, pool);
|
||||
|
||||
/* sort the pool according to cheapest path as fitness */
|
||||
sort_pool(pool); /* we have to do it only one time, since all
|
||||
sort_pool(root, pool); /* we have to do it only one time, since all
|
||||
* kids replace the worst individuals in
|
||||
* future (-> geqo_pool.c:spread_chromo ) */
|
||||
|
||||
@ -116,49 +122,49 @@ geqo(PlannerInfo *root, int number_of_rels, List *initial_rels)
|
||||
#endif
|
||||
|
||||
/* allocate chromosome momma and daddy memory */
|
||||
momma = alloc_chromo(pool->string_length);
|
||||
daddy = alloc_chromo(pool->string_length);
|
||||
momma = alloc_chromo(root, pool->string_length);
|
||||
daddy = alloc_chromo(root, pool->string_length);
|
||||
|
||||
#if defined (ERX)
|
||||
#ifdef GEQO_DEBUG
|
||||
elog(DEBUG2, "using edge recombination crossover [ERX]");
|
||||
#endif
|
||||
/* allocate edge table memory */
|
||||
edge_table = alloc_edge_table(pool->string_length);
|
||||
edge_table = alloc_edge_table(root, pool->string_length);
|
||||
#elif defined(PMX)
|
||||
#ifdef GEQO_DEBUG
|
||||
elog(DEBUG2, "using partially matched crossover [PMX]");
|
||||
#endif
|
||||
/* allocate chromosome kid memory */
|
||||
kid = alloc_chromo(pool->string_length);
|
||||
kid = alloc_chromo(root, pool->string_length);
|
||||
#elif defined(CX)
|
||||
#ifdef GEQO_DEBUG
|
||||
elog(DEBUG2, "using cycle crossover [CX]");
|
||||
#endif
|
||||
/* allocate city table memory */
|
||||
kid = alloc_chromo(pool->string_length);
|
||||
city_table = alloc_city_table(pool->string_length);
|
||||
kid = alloc_chromo(root, pool->string_length);
|
||||
city_table = alloc_city_table(root, pool->string_length);
|
||||
#elif defined(PX)
|
||||
#ifdef GEQO_DEBUG
|
||||
elog(DEBUG2, "using position crossover [PX]");
|
||||
#endif
|
||||
/* allocate city table memory */
|
||||
kid = alloc_chromo(pool->string_length);
|
||||
city_table = alloc_city_table(pool->string_length);
|
||||
kid = alloc_chromo(root, pool->string_length);
|
||||
city_table = alloc_city_table(root, pool->string_length);
|
||||
#elif defined(OX1)
|
||||
#ifdef GEQO_DEBUG
|
||||
elog(DEBUG2, "using order crossover [OX1]");
|
||||
#endif
|
||||
/* allocate city table memory */
|
||||
kid = alloc_chromo(pool->string_length);
|
||||
city_table = alloc_city_table(pool->string_length);
|
||||
kid = alloc_chromo(root, pool->string_length);
|
||||
city_table = alloc_city_table(root, pool->string_length);
|
||||
#elif defined(OX2)
|
||||
#ifdef GEQO_DEBUG
|
||||
elog(DEBUG2, "using order crossover [OX2]");
|
||||
#endif
|
||||
/* allocate city table memory */
|
||||
kid = alloc_chromo(pool->string_length);
|
||||
city_table = alloc_city_table(pool->string_length);
|
||||
kid = alloc_chromo(root, pool->string_length);
|
||||
city_table = alloc_city_table(root, pool->string_length);
|
||||
#endif
|
||||
|
||||
|
||||
@ -168,45 +174,45 @@ geqo(PlannerInfo *root, int number_of_rels, List *initial_rels)
|
||||
for (generation = 0; generation < number_generations; generation++)
|
||||
{
|
||||
/* SELECTION: using linear bias function */
|
||||
geqo_selection(momma, daddy, pool, Geqo_selection_bias);
|
||||
geqo_selection(root, momma, daddy, pool, Geqo_selection_bias);
|
||||
|
||||
#if defined (ERX)
|
||||
/* EDGE RECOMBINATION CROSSOVER */
|
||||
difference = gimme_edge_table(momma->string, daddy->string, pool->string_length, edge_table);
|
||||
difference = gimme_edge_table(root, momma->string, daddy->string, pool->string_length, edge_table);
|
||||
|
||||
kid = momma;
|
||||
|
||||
/* are there any edge failures ? */
|
||||
edge_failures += gimme_tour(edge_table, kid->string, pool->string_length);
|
||||
edge_failures += gimme_tour(root, edge_table, kid->string, pool->string_length);
|
||||
#elif defined(PMX)
|
||||
/* PARTIALLY MATCHED CROSSOVER */
|
||||
pmx(momma->string, daddy->string, kid->string, pool->string_length);
|
||||
pmx(root, momma->string, daddy->string, kid->string, pool->string_length);
|
||||
#elif defined(CX)
|
||||
/* CYCLE CROSSOVER */
|
||||
cycle_diffs = cx(momma->string, daddy->string, kid->string, pool->string_length, city_table);
|
||||
cycle_diffs = cx(root, momma->string, daddy->string, kid->string, pool->string_length, city_table);
|
||||
/* mutate the child */
|
||||
if (cycle_diffs == 0)
|
||||
{
|
||||
mutations++;
|
||||
geqo_mutation(kid->string, pool->string_length);
|
||||
geqo_mutation(root, kid->string, pool->string_length);
|
||||
}
|
||||
#elif defined(PX)
|
||||
/* POSITION CROSSOVER */
|
||||
px(momma->string, daddy->string, kid->string, pool->string_length, city_table);
|
||||
px(root, momma->string, daddy->string, kid->string, pool->string_length, city_table);
|
||||
#elif defined(OX1)
|
||||
/* ORDER CROSSOVER */
|
||||
ox1(momma->string, daddy->string, kid->string, pool->string_length, city_table);
|
||||
ox1(root, momma->string, daddy->string, kid->string, pool->string_length, city_table);
|
||||
#elif defined(OX2)
|
||||
/* ORDER CROSSOVER */
|
||||
ox2(momma->string, daddy->string, kid->string, pool->string_length, city_table);
|
||||
ox2(root, momma->string, daddy->string, kid->string, pool->string_length, city_table);
|
||||
#endif
|
||||
|
||||
|
||||
/* EVALUATE FITNESS */
|
||||
kid->worth = geqo_eval(kid->string, pool->string_length, &evaldata);
|
||||
kid->worth = geqo_eval(root, kid->string, pool->string_length);
|
||||
|
||||
/* push the kid into the wilderness of life according to its worth */
|
||||
spread_chromo(kid, pool);
|
||||
spread_chromo(root, kid, pool);
|
||||
|
||||
|
||||
#ifdef GEQO_DEBUG
|
||||
@ -249,7 +255,7 @@ geqo(PlannerInfo *root, int number_of_rels, List *initial_rels)
|
||||
*/
|
||||
best_tour = (Gene *) pool->data[0].string;
|
||||
|
||||
best_rel = gimme_tree(best_tour, pool->string_length, &evaldata);
|
||||
best_rel = gimme_tree(root, best_tour, pool->string_length);
|
||||
|
||||
if (best_rel == NULL)
|
||||
elog(ERROR, "failed to make a valid plan");
|
||||
@ -260,28 +266,31 @@ geqo(PlannerInfo *root, int number_of_rels, List *initial_rels)
|
||||
#endif
|
||||
|
||||
/* ... free memory stuff */
|
||||
free_chromo(momma);
|
||||
free_chromo(daddy);
|
||||
free_chromo(root, momma);
|
||||
free_chromo(root, daddy);
|
||||
|
||||
#if defined (ERX)
|
||||
free_edge_table(edge_table);
|
||||
free_edge_table(root, edge_table);
|
||||
#elif defined(PMX)
|
||||
free_chromo(kid);
|
||||
free_chromo(root, kid);
|
||||
#elif defined(CX)
|
||||
free_chromo(kid);
|
||||
free_city_table(city_table);
|
||||
free_chromo(root, kid);
|
||||
free_city_table(root, city_table);
|
||||
#elif defined(PX)
|
||||
free_chromo(kid);
|
||||
free_city_table(city_table);
|
||||
free_chromo(root, kid);
|
||||
free_city_table(root, city_table);
|
||||
#elif defined(OX1)
|
||||
free_chromo(kid);
|
||||
free_city_table(city_table);
|
||||
free_chromo(root, kid);
|
||||
free_city_table(root, city_table);
|
||||
#elif defined(OX2)
|
||||
free_chromo(kid);
|
||||
free_city_table(city_table);
|
||||
free_chromo(root, kid);
|
||||
free_city_table(root, city_table);
|
||||
#endif
|
||||
|
||||
free_pool(pool);
|
||||
free_pool(root, pool);
|
||||
|
||||
/* ... clear root pointer to our private storage */
|
||||
root->join_search_private = NULL;
|
||||
|
||||
return best_rel;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
*
|
||||
* TSP mutation routines
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_mutation.c,v 1.9 2003/11/29 22:39:49 pgsql Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_mutation.c,v 1.10 2009/07/16 20:55:44 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -36,21 +36,21 @@
|
||||
#include "optimizer/geqo_random.h"
|
||||
|
||||
void
|
||||
geqo_mutation(Gene *tour, int num_gene)
|
||||
geqo_mutation(PlannerInfo *root, Gene *tour, int num_gene)
|
||||
{
|
||||
int swap1;
|
||||
int swap2;
|
||||
int num_swaps = geqo_randint(num_gene / 3, 0);
|
||||
int num_swaps = geqo_randint(root, num_gene / 3, 0);
|
||||
Gene temp;
|
||||
|
||||
|
||||
while (num_swaps > 0)
|
||||
{
|
||||
swap1 = geqo_randint(num_gene - 1, 0);
|
||||
swap2 = geqo_randint(num_gene - 1, 0);
|
||||
swap1 = geqo_randint(root, num_gene - 1, 0);
|
||||
swap2 = geqo_randint(root, num_gene - 1, 0);
|
||||
|
||||
while (swap1 == swap2)
|
||||
swap2 = geqo_randint(num_gene - 1, 0);
|
||||
swap2 = geqo_randint(root, num_gene - 1, 0);
|
||||
|
||||
temp = tour[swap1];
|
||||
tour[swap1] = tour[swap2];
|
||||
|
@ -6,7 +6,7 @@
|
||||
* OX1 operator according to Davis
|
||||
* (Proc Int'l Joint Conf on AI)
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_ox1.c,v 1.9 2003/11/29 22:39:49 pgsql Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_ox1.c,v 1.10 2009/07/16 20:55:44 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -43,7 +43,8 @@
|
||||
* position crossover
|
||||
*/
|
||||
void
|
||||
ox1(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)
|
||||
ox1(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene,
|
||||
City *city_table)
|
||||
{
|
||||
int left,
|
||||
right,
|
||||
@ -56,8 +57,8 @@ ox1(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)
|
||||
city_table[k].used = 0;
|
||||
|
||||
/* select portion to copy from tour1 */
|
||||
left = geqo_randint(num_gene - 1, 0);
|
||||
right = geqo_randint(num_gene - 1, 0);
|
||||
left = geqo_randint(root, num_gene - 1, 0);
|
||||
right = geqo_randint(root, num_gene - 1, 0);
|
||||
|
||||
if (left > right)
|
||||
{
|
||||
|
@ -6,7 +6,7 @@
|
||||
* OX2 operator according to Syswerda
|
||||
* (The Genetic Algorithms Handbook, ed L Davis)
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_ox2.c,v 1.10 2004/10/07 15:21:52 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_ox2.c,v 1.11 2009/07/16 20:55:44 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -43,7 +43,7 @@
|
||||
* position crossover
|
||||
*/
|
||||
void
|
||||
ox2(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)
|
||||
ox2(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)
|
||||
{
|
||||
int k,
|
||||
j,
|
||||
@ -60,12 +60,12 @@ ox2(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)
|
||||
}
|
||||
|
||||
/* determine the number of positions to be inherited from tour1 */
|
||||
num_positions = geqo_randint(2 * num_gene / 3, num_gene / 3);
|
||||
num_positions = geqo_randint(root, 2 * num_gene / 3, num_gene / 3);
|
||||
|
||||
/* make a list of selected cities */
|
||||
for (k = 0; k < num_positions; k++)
|
||||
{
|
||||
pos = geqo_randint(num_gene - 1, 0);
|
||||
pos = geqo_randint(root, num_gene - 1, 0);
|
||||
city_table[pos].select_list = (int) tour1[pos];
|
||||
city_table[(int) tour1[pos]].used = 1; /* mark used */
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
* PMX operator according to Goldberg & Lingle
|
||||
* (Proc Int'l Conf on GA's)
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_pmx.c,v 1.10 2003/11/29 22:39:49 pgsql Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_pmx.c,v 1.11 2009/07/16 20:55:44 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -43,7 +43,7 @@
|
||||
* partially matched crossover
|
||||
*/
|
||||
void
|
||||
pmx(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene)
|
||||
pmx(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene)
|
||||
{
|
||||
int *failed = (int *) palloc((num_gene + 1) * sizeof(int));
|
||||
int *from = (int *) palloc((num_gene + 1) * sizeof(int));
|
||||
@ -71,8 +71,8 @@ pmx(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene)
|
||||
}
|
||||
|
||||
/* locate crossover points */
|
||||
left = geqo_randint(num_gene - 1, 0);
|
||||
right = geqo_randint(num_gene - 1, 0);
|
||||
left = geqo_randint(root, num_gene - 1, 0);
|
||||
right = geqo_randint(root, num_gene - 1, 0);
|
||||
|
||||
if (left > right)
|
||||
{
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_pool.c,v 1.33 2009/01/01 17:23:43 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_pool.c,v 1.34 2009/07/16 20:55:44 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -39,7 +39,7 @@ static int compare(const void *arg1, const void *arg2);
|
||||
* allocates memory for GA pool
|
||||
*/
|
||||
Pool *
|
||||
alloc_pool(int pool_size, int string_length)
|
||||
alloc_pool(PlannerInfo *root, int pool_size, int string_length)
|
||||
{
|
||||
Pool *new_pool;
|
||||
Chromosome *chromo;
|
||||
@ -66,7 +66,7 @@ alloc_pool(int pool_size, int string_length)
|
||||
* deallocates memory for GA pool
|
||||
*/
|
||||
void
|
||||
free_pool(Pool *pool)
|
||||
free_pool(PlannerInfo *root, Pool *pool)
|
||||
{
|
||||
Chromosome *chromo;
|
||||
int i;
|
||||
@ -88,7 +88,7 @@ free_pool(Pool *pool)
|
||||
* initialize genetic pool
|
||||
*/
|
||||
void
|
||||
random_init_pool(Pool *pool, GeqoEvalData *evaldata)
|
||||
random_init_pool(PlannerInfo *root, Pool *pool)
|
||||
{
|
||||
Chromosome *chromo = (Chromosome *) pool->data;
|
||||
int i;
|
||||
@ -105,10 +105,9 @@ random_init_pool(Pool *pool, GeqoEvalData *evaldata)
|
||||
i = 0;
|
||||
while (i < pool->size)
|
||||
{
|
||||
init_tour(chromo[i].string, pool->string_length);
|
||||
pool->data[i].worth = geqo_eval(chromo[i].string,
|
||||
pool->string_length,
|
||||
evaldata);
|
||||
init_tour(root, chromo[i].string, pool->string_length);
|
||||
pool->data[i].worth = geqo_eval(root, chromo[i].string,
|
||||
pool->string_length);
|
||||
if (pool->data[i].worth < DBL_MAX)
|
||||
i++;
|
||||
else
|
||||
@ -133,7 +132,7 @@ random_init_pool(Pool *pool, GeqoEvalData *evaldata)
|
||||
* maybe you have to change compare() for different ordering ...
|
||||
*/
|
||||
void
|
||||
sort_pool(Pool *pool)
|
||||
sort_pool(PlannerInfo *root, Pool *pool)
|
||||
{
|
||||
qsort(pool->data, pool->size, sizeof(Chromosome), compare);
|
||||
}
|
||||
@ -160,7 +159,7 @@ compare(const void *arg1, const void *arg2)
|
||||
* allocates a chromosome and string space
|
||||
*/
|
||||
Chromosome *
|
||||
alloc_chromo(int string_length)
|
||||
alloc_chromo(PlannerInfo *root, int string_length)
|
||||
{
|
||||
Chromosome *chromo;
|
||||
|
||||
@ -174,7 +173,7 @@ alloc_chromo(int string_length)
|
||||
* deallocates a chromosome and string space
|
||||
*/
|
||||
void
|
||||
free_chromo(Chromosome *chromo)
|
||||
free_chromo(PlannerInfo *root, Chromosome *chromo)
|
||||
{
|
||||
pfree(chromo->string);
|
||||
pfree(chromo);
|
||||
@ -185,7 +184,7 @@ free_chromo(Chromosome *chromo)
|
||||
* assumes best->worst = smallest->largest
|
||||
*/
|
||||
void
|
||||
spread_chromo(Chromosome *chromo, Pool *pool)
|
||||
spread_chromo(PlannerInfo *root, Chromosome *chromo, Pool *pool)
|
||||
{
|
||||
int top,
|
||||
mid,
|
||||
@ -247,7 +246,7 @@ spread_chromo(Chromosome *chromo, Pool *pool)
|
||||
* copy new gene into pool storage; always replace worst gene in pool
|
||||
*/
|
||||
|
||||
geqo_copy(&pool->data[pool->size - 1], chromo, pool->string_length);
|
||||
geqo_copy(root, &pool->data[pool->size - 1], chromo, pool->string_length);
|
||||
|
||||
swap_chromo.string = pool->data[pool->size - 1].string;
|
||||
swap_chromo.worth = pool->data[pool->size - 1].worth;
|
||||
|
@ -6,7 +6,7 @@
|
||||
* PX operator according to Syswerda
|
||||
* (The Genetic Algorithms Handbook, L Davis, ed)
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_px.c,v 1.10 2003/11/29 22:39:49 pgsql Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_px.c,v 1.11 2009/07/16 20:55:44 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -43,7 +43,8 @@
|
||||
* position crossover
|
||||
*/
|
||||
void
|
||||
px(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)
|
||||
px(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene,
|
||||
City *city_table)
|
||||
{
|
||||
|
||||
int num_positions;
|
||||
@ -57,12 +58,12 @@ px(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)
|
||||
city_table[i].used = 0;
|
||||
|
||||
/* choose random positions that will be inherited directly from parent */
|
||||
num_positions = geqo_randint(2 * num_gene / 3, num_gene / 3);
|
||||
num_positions = geqo_randint(root, 2 * num_gene / 3, num_gene / 3);
|
||||
|
||||
/* choose random position */
|
||||
for (i = 0; i < num_positions; i++)
|
||||
{
|
||||
pos = geqo_randint(num_gene - 1, 0);
|
||||
pos = geqo_randint(root, num_gene - 1, 0);
|
||||
|
||||
offspring[pos] = tour1[pos]; /* transfer cities to child */
|
||||
city_table[(int) tour1[pos]].used = 1; /* mark city used */
|
||||
|
40
src/backend/optimizer/geqo/geqo_random.c
Normal file
40
src/backend/optimizer/geqo/geqo_random.c
Normal file
@ -0,0 +1,40 @@
|
||||
/*------------------------------------------------------------------------
|
||||
*
|
||||
* geqo_random.c
|
||||
* random number generator
|
||||
*
|
||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_random.c,v 1.1 2009/07/16 20:55:44 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include "optimizer/geqo_random.h"
|
||||
|
||||
|
||||
void
|
||||
geqo_set_seed(PlannerInfo *root, double seed)
|
||||
{
|
||||
GeqoPrivateData *private = (GeqoPrivateData *) root->join_search_private;
|
||||
|
||||
/*
|
||||
* XXX. This seeding algorithm could certainly be improved - but
|
||||
* it is not critical to do so.
|
||||
*/
|
||||
memset(private->random_state, 0, sizeof(private->random_state));
|
||||
memcpy(private->random_state,
|
||||
&seed,
|
||||
Min(sizeof(private->random_state), sizeof(seed)));
|
||||
}
|
||||
|
||||
double
|
||||
geqo_rand(PlannerInfo *root)
|
||||
{
|
||||
GeqoPrivateData *private = (GeqoPrivateData *) root->join_search_private;
|
||||
|
||||
return erand48(private->random_state);
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
* geqo_recombination.c
|
||||
* misc recombination procedures
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_recombination.c,v 1.15 2005/10/15 02:49:19 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_recombination.c,v 1.16 2009/07/16 20:55:44 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -35,7 +35,7 @@
|
||||
* and the procedure repeated.
|
||||
*/
|
||||
void
|
||||
init_tour(Gene *tour, int num_gene)
|
||||
init_tour(PlannerInfo *root, Gene *tour, int num_gene)
|
||||
{
|
||||
Gene *tmp;
|
||||
int remainder;
|
||||
@ -53,7 +53,7 @@ init_tour(Gene *tour, int num_gene)
|
||||
for (i = 0; i < num_gene; i++)
|
||||
{
|
||||
/* choose value between 0 and remainder inclusive */
|
||||
next = (int) geqo_randint(remainder, 0);
|
||||
next = geqo_randint(root, remainder, 0);
|
||||
/* output that element of the tmp array */
|
||||
tour[i] = tmp[next];
|
||||
/* and delete it */
|
||||
@ -81,7 +81,7 @@ init_tour(Gene *tour, int num_gene)
|
||||
* allocate memory for city table
|
||||
*/
|
||||
City *
|
||||
alloc_city_table(int num_gene)
|
||||
alloc_city_table(PlannerInfo *root, int num_gene)
|
||||
{
|
||||
City *city_table;
|
||||
|
||||
@ -99,7 +99,7 @@ alloc_city_table(int num_gene)
|
||||
* deallocate memory of city table
|
||||
*/
|
||||
void
|
||||
free_city_table(City *city_table)
|
||||
free_city_table(PlannerInfo *root, City *city_table)
|
||||
{
|
||||
pfree(city_table);
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_selection.c,v 1.24 2009/01/01 17:23:43 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_selection.c,v 1.25 2009/07/16 20:55:44 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -42,7 +42,7 @@
|
||||
#include "optimizer/geqo_random.h"
|
||||
#include "optimizer/geqo_selection.h"
|
||||
|
||||
static int linear(int max, double bias);
|
||||
static int linear(PlannerInfo *root, int max, double bias);
|
||||
|
||||
|
||||
/*
|
||||
@ -51,22 +51,23 @@ static int linear(int max, double bias);
|
||||
* first and second genes are selected from the pool
|
||||
*/
|
||||
void
|
||||
geqo_selection(Chromosome *momma, Chromosome *daddy, Pool *pool, double bias)
|
||||
geqo_selection(PlannerInfo *root, Chromosome *momma, Chromosome *daddy,
|
||||
Pool *pool, double bias)
|
||||
{
|
||||
int first,
|
||||
second;
|
||||
|
||||
first = linear(pool->size, bias);
|
||||
second = linear(pool->size, bias);
|
||||
first = linear(root, pool->size, bias);
|
||||
second = linear(root, pool->size, bias);
|
||||
|
||||
if (pool->size > 1)
|
||||
{
|
||||
while (first == second)
|
||||
second = linear(pool->size, bias);
|
||||
second = linear(root, pool->size, bias);
|
||||
}
|
||||
|
||||
geqo_copy(momma, &pool->data[first], pool->string_length);
|
||||
geqo_copy(daddy, &pool->data[second], pool->string_length);
|
||||
geqo_copy(root, momma, &pool->data[first], pool->string_length);
|
||||
geqo_copy(root, daddy, &pool->data[second], pool->string_length);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -74,12 +75,13 @@ geqo_selection(Chromosome *momma, Chromosome *daddy, Pool *pool, double bias)
|
||||
* generates random integer between 0 and input max number
|
||||
* using input linear bias
|
||||
*
|
||||
* bias is y-intercept of linear distribution
|
||||
*
|
||||
* probability distribution function is: f(x) = bias - 2(bias - 1)x
|
||||
* bias = (prob of first rule) / (prob of middle rule)
|
||||
*/
|
||||
static int
|
||||
linear(int pool_size, double bias) /* bias is y-intercept of linear
|
||||
* distribution */
|
||||
linear(PlannerInfo *root, int pool_size, double bias)
|
||||
{
|
||||
double index; /* index between 0 and pop_size */
|
||||
double max = (double) pool_size;
|
||||
@ -95,7 +97,7 @@ linear(int pool_size, double bias) /* bias is y-intercept of linear
|
||||
{
|
||||
double sqrtval;
|
||||
|
||||
sqrtval = (bias * bias) - 4.0 * (bias - 1.0) * geqo_rand();
|
||||
sqrtval = (bias * bias) - 4.0 * (bias - 1.0) * geqo_rand(root);
|
||||
if (sqrtval > 0.0)
|
||||
sqrtval = sqrt(sqrtval);
|
||||
index = max * (bias - sqrtval) / 2.0 / (bias - 1.0);
|
||||
|
Reference in New Issue
Block a user