📄 galib bug list.htm
字号:
<LI>The <STRONG>read</STRONG> member function of 1D, 2D, and 3D binary string
genomes will cause a segmentation fault in cases where the genome has length
(width, height) of zero. The fix is to change the <CODE>do...while</CODE> loop
into a <CODE>while</CODE> loop. This should be done in GA1DBinStringGenome.C,
GA2DBinStringGenome.C, and GA3DBinStringGenome.C. <BR><BR>
<LI>Examples 5 and 14 do not work correctly because the
<CODE>_evaluated</CODE> flag is not properly reset in the initialize, mutate,
and crossover methods. In any custom-defined genome, you must set
<CODE>_evaluated</CODE> to <CODE>gaFalse</CODE> whenever you change the state
of a genome, otherwise the genome's evaluator will not be invoked (the cached
score will be used instead). <BR><BR>
<LI>On some platforms, using a GARealGenome with the GARealGaussianMutator
will occasionally result in a crash when GAUnitGaussian takes the square root
of a negative number. To be sure this never happens, change the following code
in garandom.C so that this: <PRE>101 } while(rsquare >= 1.0 || rsquare == 0.0);
102
103 factor = sqrt( -2.0 * log(rsquare) / rsquare );
104
105 cachevalue = var1 * factor;
</PRE>becomes this: <PRE>101 } while(rsquare >= 1.0 || rsquare == 0.0);
102
double val = -2.0 * log(rsquare) / rsquare;
if(val > 0.0) factor = sqrt(val);
else factor = 0.0;
104
105 cachevalue = var1 * factor;
</PRE>
<LI>In the DemeGA, changing the number of populations to a larger number after
the GA has been created will result in a segmentation fault. The nPopulations
member function should be modified as follows. Insert a line of code that
modifies the population in GADemeGA::nPopulations(unsigned int n) so that
this: <PRE>264 }
265 return npop;
266 }
</PRE>becomes this: <PRE>264 }
pop->size(npop);
265 return npop;
266 }
</PRE>
<LI>The PC and Mac GAlib packages have a typo in example 5. My PERL script for
converting UNIX to PC got a little carried away. Change: <PRE>69 CompositeGenome(int element, int bond, GABin2DecPhenotype& p,
70 GAGenome::Evaluator f, void* u) :
71 GAGenome.cppompositeInitializer,
72 CompositeMutator,
73 CompositeComparator) {
</PRE>to: <PRE>69 CompositeGenome(int element, int bond, GABin2DecPhenotype& p,
70 GAGenome::Evaluator f, void* u) :
71 GAGenome(CompositeInitializer,
72 CompositeMutator,
73 CompositeComparator) {
</PRE></LI></UL><BR><BR><BR><BR><BR><STRONG>bugs in version
2.4.1</STRONG></A><BR><SMALL><I>fixed in release 2.4.2</I></SMALL><BR>
<HR>
<UL>
<LI>The random number seed may occasionally be set to 0, resulting in all 0s
from the GARandomBit function. This bug was introduced in the 2.4.1 release as
I tried to make the seed generator more robust with respect to various
implementations of 'time()' on different OSes. To fix the problem, make the
following change to random.C in the function GARandomSeed. Change line 56
from: <PRE>56 for(unsigned int i=0; i<sizeof(unsigned int); i++) {
</PRE>to: <PRE>56 for(unsigned int i=0; i<BITS_IN_WORD * sizeof(unsigned int); i++) {
</PRE>
<LI>If you are compiling with NO_STREAMS defined, you will have to fix error.C
so that it includes stdio.h. Just move '#include <stdio.h>' so that it
is outside of the '#ifndef NO_STREAMS ... #endif' directive.
<LI>The filenames used in this distribution may conflict with system files.
For example, 'list.h' conflicts with Metrowerks' 'list.h' in Codewarrior 9 and
later, and 'tree.h' conflicts with borland's 'tree.h' in version 5.x of their
compiler. </LI></UL><BR><BR><BR><BR><BR><STRONG>bugs in version
2.4</STRONG><BR><SMALL><I>fixed in release 2.4.1</I></SMALL><BR>
<HR>
<UL>
<LI>The default population evaluator forces unnecessary genome evaluations. In
population.C, remove 'gaTrue' from the call to the genome 'evaluate' member
function in GAPopulation::DefaultEvaluator.
<LI>The GANode and GANodeBASE classes do not have virtual destructors, so any
classes derived from them do not destruct properly.
<LI>The statistics object does not work properly with genetic algorithms that
are configured to minimize. 'best' and 'worst' are reversed when minimizing
and the lowest score is not always maintained.
<LI>The simple genetic algorithm does not properly maintain the best
individual when minimizing. </LI></UL><BR><BR><BR><BR><BR><A
name=version_2.3.2><STRONG>bugs in version 2.3.2</STRONG></A><BR>
<HR>
<UL>
<LI>The <B>remove</B> method was never defined for the GABin2DecPhenotype
class in bin2dec.ph.C (it was declared in the header file). Ooops, sorry about
that. Upgrade to version 2.4. <BR><BR>
<LI>A population size of 1 will cause a crash when the statistics are updated.
This has been fixed in the 2.4 release. <BR><BR>
<LI>The <B>remove</B> member of the GATree class does not properly re-set the
node pointers on the subtree that is removed. To fix this problem, make the
following modifications to treetmpl.C: <PRE>69 if(node->prev != node) iter.eldest();
70 else if(node->parent) iter.parent();
71 else iter.node = (GANodeBASE *)0;
72 t->insert((GANode<T> *)GATreeBASE::remove(node), (GANode<T> *)0,
73 GATreeBASE::ROOT);
74
75 return t;
76 }
</PRE>should be modified to <PRE>69 if(node->prev != node) iter.eldest();
70 else if(node->parent) iter.parent();
71 else iter.node = (GANodeBASE *)0;
GANode<T> *tmpnode = (GANode<T>*)GATreeBASE::remove(node);
tmpnode->prev = tmpnode;
tmpnode->next = tmpnode;
tmpnode->parent = (GANodeBASE *)0;
t->insert(tmpnode, (GANode<T> *)0, GATreeBASE::ROOT);
74
75 return t;
76 }
</PRE>
<LI>The array swap and flip mutators have a bug in them that will prevent
mutation in some cases. To fix it, do the following.
<P>Change lines 83 and 114 in array1.op.C. The first change is in
GA1DArrayFlipMutator: <PRE>83 for(n=1; n<nMut; n++){
</PRE>should be <PRE>83 for(n=0; n<nMut; n++){
</PRE>The second change is in GA1DArraySwapMutator: <PRE>114 for(n=1; n<nMut; n++)
</PRE>should be <PRE>114 for(n=0; n<nMut; n++)
</PRE>
<LI>Be careful with the random number generator. If you use GAlib right out of
the box, the GARandomBit function caches bits rather than calling the random
function multiple times. This may or may not be a problem, depending on the
underlying random function you use. The default configuration for GAlib is to
use your system's rand() or random() function to generate random numbers.
Typically, the system random number generators are not very robust. The actual
implementation varies from system to system, but most use some sort of linear
congruential generator, and you <I>should not</I> expect the bits of the
numbers these RNGs generate to be uniformly random. For many applications, the
default GAlib configuration will suffice, but if you are doing extensive
statistical evaluation of results obtained using GAlib you should consider
writing your own random number generator and plugging it in to replace rand()
or random(). You can do this by modifying random.h to use your random
function.
<P>See <A href="http://nr.harvard.edu/nr/bookc.html">Numerical Recipes in
C</A> for details about the issues of using various random number generators.
These issues have been resolved in the 2.4 release of GAlib. </P>
<LI>The <B>scaling</B> member function of the GAPopulation object does not
properly update the scaling object when it is changed. If you try to change
the scaling during the course of an evolution, your program will crash (the
selector returns nil pointers after you change the selector). The 'evaluate'
member of the scaling object must be called before the selector accesses the
scaling data.
<P>In the <B>scaling</B> member function in population.C, add one line of code
so that <PRE>275 sm->resize(n);
276 return *sm;
</PRE>becomes <PRE>275 sm->resize(n);
if(evaluated) sm->evaluate(*this);
276 return *sm;
</PRE>
<LI>The <B>copy</B> member function of the GAPopulation object has a typo in
it. Whenever you try to copy a population, the copy member clones the worst
individual in the population rather than copying each individual in the
population. To fix the problem, change [0] to [i] as shown here.
<P>In population.C, change 0 to an i in line 153 so that <PRE>151 ind = new GAGenome * [N];
152 for(i=0; i<n; i++)
153 ind[i] = arg.ind[<B>0</B>]->clone();
154
155 if(arg.sm) sm = arg.sm->clone();
</PRE>becomes <PRE>151 ind = new GAGenome * [N];
152 for(i=0; i<n; i++)
153 ind[i] = arg.ind[<B>i</B>]->clone();
154
155 if(arg.sm) sm = arg.sm->clone();
</PRE>
<LI>The <B>initialize</B> member function of any GA class must be called
<I>after</I> any calls to the <B>populationSize</B> member function, otherwise
the scaling object does not get updated and your GA will crash on its first
selection. This means that you cannot change the population size during the
course of an evolution. To fix the problem make the following changes:
<P>In population.C, insert a line and modify a line to change <PRE>209 sm->resize(pops);
210 statted = sorted = evaluated = gaFalse;
211 n = pops;
</PRE>to <PRE>209 sm->resize(pops);
210 statted = sorted = gaFalse;
211 n = pops;
if(evaluated == gaTrue) evaluate(gaTrue);
</PRE>and in the file scaling.C, insert a single line to change <PRE>102 fitSum = fitAve = fitMax = fitMin = fitVar = fitDev = 0.0;
103 return(n = popsize);
</PRE>to <PRE>102 fitSum = fitAve = fitMax = fitMin = fitVar = fitDev = 0.0;
evaluated = gaFalse;
103 return(n = popsize);
</PRE></LI></UL><BR><BR><BR><BR><BR><A name=version_2.3.1><STRONG>bugs in
version 2.3.1</STRONG></A><BR>
<HR>
<UL>
<LI>There was a typo in population.C. In the function <CODE>GAGenome *
GAPopulation::replace(GAGenome * repl, const int which)</CODE>, <PRE><CODE>
if(sorted)
rawMax = ind[n-1]->score();
else if(orig->score() == rawMax){
rawMax = ind[0]->score();
for(i=1; i<n; i++)
rawMax = Min(rawMax, ind[i]->score());
}
else
rawMax = Max(rawMax, repl->score());
</CODE></PRE>The 'Min' should be 'Max': <PRE><CODE> rawMax = Max(rawMax, ind[i]->score());
</CODE></PRE>
<LI>Functions that return NULL would not compile with some compilers.
Functions that have this problem include member functions of the ListBASE and
List objects in listbase.h and listtmpl.h, and the TreeBASE and Tree objects
in treebase.h and treetmpl.h. ANSI C++ requires an explicit cast of NULL.
<LI>Many of the 'for' loops will not compile with some compilers. In some
cases, the loop variable is used outside the 'for' loop. Files with this
problem include allele.h, array1.op.C, binstr3.ch.C, ga.C, list.op.C,
population.C, scaling.C, selector.C, and many of the examples. ANSI C++
specifies that a variable declared in a for loop loses scope after the loop
ends.
<LI>The population object does not initialize genomes when it is resized.
<LI>SimpleGA has a bug in it that delays convergence. A workaround is to use a
SteadyStateGA with 100% replacement. This will be only marginally slower than
using a bug-free SimpleGA.
<LI>Roundoff errors in the population object could lead to negative numbers
passed to the sqrt function. The fix is to check for a sign change before the
call to sqrt. The only way a sign change can occur is if there is a roundoff
error. (There are only two calls to sqrt in population.C. The error can only
occur in the sqrt call in the function <CODE>GAGenome *
GAPopulation::replace(GAGenome * repl, const int which)</CODE>)
<LI>The copy constructor for the GAObjectiveVector object did not initialize
the 'a' member to NULL </LI></UL></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -