|
6 | 6 | * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
7 | 7 | * Portions Copyright (c) 1994, Regents of the University of California
|
8 | 8 | *
|
9 |
| - * $Id: geqo_selection.c,v 1.12 2001/01/24 19:42:57 momjian Exp $ |
| 9 | + * $Id: geqo_selection.c,v 1.12.4.1 2005/06/14 14:21:43 tgl Exp $ |
10 | 10 | *
|
11 | 11 | *-------------------------------------------------------------------------
|
12 | 12 | */
|
|
43 | 43 |
|
44 | 44 | static int linear(int max, double bias);
|
45 | 45 |
|
46 |
| -/* geqo_selection |
47 |
| - * |
| 46 | + |
| 47 | +/* |
| 48 | + * geqo_selection |
48 | 49 | * according to bias described by input parameters,
|
49 |
| - * second genes are selected from the pool |
| 50 | + * first and second genes are selected from the pool |
50 | 51 | */
|
51 | 52 | void
|
52 | 53 | geqo_selection(Chromosome *momma, Chromosome *daddy, Pool *pool, double bias)
|
53 | 54 | {
|
54 | 55 | int first,
|
55 | 56 | second;
|
56 | 57 |
|
57 |
| - first = (int) linear(pool->size, bias); |
58 |
| - second = (int) linear(pool->size, bias); |
| 58 | + first = linear(pool->size, bias); |
| 59 | + second = linear(pool->size, bias); |
59 | 60 |
|
60 | 61 | if (pool->size > 1)
|
61 | 62 | {
|
62 | 63 | while (first == second)
|
63 |
| - second = (int) linear(pool->size, bias); |
| 64 | + second = linear(pool->size, bias); |
64 | 65 | }
|
65 | 66 |
|
66 | 67 | geqo_copy(momma, &pool->data[first], pool->string_length);
|
67 | 68 | geqo_copy(daddy, &pool->data[second], pool->string_length);
|
68 | 69 | }
|
69 | 70 |
|
70 |
| -/* linear |
| 71 | +/* |
| 72 | + * linear |
71 | 73 | * generates random integer between 0 and input max number
|
72 | 74 | * using input linear bias
|
73 | 75 | *
|
74 | 76 | * probability distribution function is: f(x) = bias - 2(bias - 1)x
|
75 | 77 | * bias = (prob of first rule) / (prob of middle rule)
|
76 |
| - * |
77 | 78 | */
|
78 |
| - |
79 | 79 | static int
|
80 | 80 | linear(int pool_size, double bias) /* bias is y-intercept of linear
|
81 | 81 | * distribution */
|
82 | 82 | {
|
83 | 83 | double index; /* index between 0 and pop_size */
|
84 | 84 | double max = (double) pool_size;
|
85 | 85 |
|
86 |
| - index = max * (bias - sqrt((bias * bias) - 4.0 * (bias - 1.0) * geqo_rand())) |
87 |
| - / 2.0 / (bias - 1.0); |
| 86 | + /* |
| 87 | + * If geqo_rand() returns exactly 1.0 then we will get exactly max from |
| 88 | + * this equation, whereas we need 0 <= index < max. Also it seems possible |
| 89 | + * that roundoff error might deliver values slightly outside the range; |
| 90 | + * in particular avoid passing a value slightly less than 0 to sqrt(). |
| 91 | + * If we get a bad value just try again. |
| 92 | + */ |
| 93 | + do { |
| 94 | + double sqrtval; |
| 95 | + |
| 96 | + sqrtval = (bias * bias) - 4.0 * (bias - 1.0) * geqo_rand(); |
| 97 | + if (sqrtval > 0.0) |
| 98 | + sqrtval = sqrt(sqrtval); |
| 99 | + index = max * (bias - sqrtval) / 2.0 / (bias - 1.0); |
| 100 | + } while (index < 0.0 || index >= max); |
88 | 101 |
|
89 | 102 | return (int) index;
|
90 | 103 | }
|
0 commit comments