Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2b91c8c

Browse files
committed
The random selection in function linear() could deliver a value equal to max
if geqo_rand() returns exactly 1.0, resulting in failure due to indexingoff the end of the pool array. Also, since this is using inexact float math,it seems wise to guard against roundoff error producing values slightlyoutside the expected range. Per report from bug@zedware.org.
1 parente4ce3e7 commit2b91c8c

File tree

1 file changed

+25
-12
lines changed

1 file changed

+25
-12
lines changed

‎src/backend/optimizer/geqo/geqo_selection.c

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
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 $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -43,48 +43,61 @@
4343

4444
staticintlinear(intmax,doublebias);
4545

46-
/* geqo_selection
47-
*
46+
47+
/*
48+
* geqo_selection
4849
* according to bias described by input parameters,
49-
* second genes are selected from the pool
50+
*first andsecond genes are selected from the pool
5051
*/
5152
void
5253
geqo_selection(Chromosome*momma,Chromosome*daddy,Pool*pool,doublebias)
5354
{
5455
intfirst,
5556
second;
5657

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);
5960

6061
if (pool->size>1)
6162
{
6263
while (first==second)
63-
second=(int)linear(pool->size,bias);
64+
second=linear(pool->size,bias);
6465
}
6566

6667
geqo_copy(momma,&pool->data[first],pool->string_length);
6768
geqo_copy(daddy,&pool->data[second],pool->string_length);
6869
}
6970

70-
/* linear
71+
/*
72+
* linear
7173
* generates random integer between 0 and input max number
7274
* using input linear bias
7375
*
7476
* probability distribution function is: f(x) = bias - 2(bias - 1)x
7577
* bias = (prob of first rule) / (prob of middle rule)
76-
*
7778
*/
78-
7979
staticint
8080
linear(intpool_size,doublebias)/* bias is y-intercept of linear
8181
* distribution */
8282
{
8383
doubleindex;/* index between 0 and pop_size */
8484
doublemax= (double)pool_size;
8585

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+
doublesqrtval;
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);
88101

89102
return (int)index;
90103
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp