1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
/*-------------------------------------------------------------------------
*
* geqo_selection.c
* linear selection scheme for the genetic query optimizer
*
* Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/backend/optimizer/geqo/geqo_selection.c
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
* Martin Utesch * Institute of Automatic Control *
= = University of Mining and Technology =
* utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
/* this is adopted from D. Whitley's Genitor algorithm */
/*************************************************************/
/* */
/* Copyright (c) 1990 */
/* Darrell L. Whitley */
/* Computer Science Department */
/* Colorado State University */
/* */
/* Permission is hereby granted to copy all or any part of */
/* this program for free distribution. The author's name */
/* and this copyright notice must be included in any copy. */
/* */
/*************************************************************/
#include "postgres.h"
#include <math.h>
#include "optimizer/geqo_copy.h"
#include "optimizer/geqo_random.h"
#include "optimizer/geqo_selection.h"
static int linear_rand(PlannerInfo *root, int max, double bias);
/*
* geqo_selection
* according to bias described by input parameters,
* first and second genes are selected from the pool
*/
void
geqo_selection(PlannerInfo *root, Chromosome *momma, Chromosome *daddy,
Pool *pool, double bias)
{
int first,
second;
first = linear_rand(root, pool->size, bias);
second = linear_rand(root, pool->size, bias);
/*
* Ensure we have selected different genes, except if pool size is only
* one, when we can't.
*
* This code was observed to hang up in an infinite loop when the
* platform's implementation of erand48() was broken. We now always use
* our own version.
*/
if (pool->size > 1)
{
while (first == second)
second = linear_rand(root, pool->size, bias);
}
geqo_copy(root, momma, &pool->data[first], pool->string_length);
geqo_copy(root, daddy, &pool->data[second], pool->string_length);
}
/*
* linear_rand
* 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_rand(PlannerInfo *root, int pool_size, double bias)
{
double index; /* index between 0 and pool_size */
double max = (double) pool_size;
/*
* If geqo_rand() returns exactly 1.0 then we will get exactly max from
* this equation, whereas we need 0 <= index < max. Also it seems
* possible that roundoff error might deliver values slightly outside the
* range; in particular avoid passing a value slightly less than 0 to
* sqrt(). If we get a bad value just try again.
*/
do
{
double sqrtval;
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);
} while (index < 0.0 || index >= max);
return (int) index;
}
|