Retarded Bugs need help. Still needing somehelp.

Started by
15 comments, last by WILL at RedAnt 20 years, 11 months ago
Not setting a Random seed is no real problem. Without it, you still get random values. You just get the same every time you start your app. The problem here is that you don''t get a random number in the first place if it''s an interger randomizer.

Anyway, i read through the code again and I think I found the bug. And it''s not the randomizer. You are selecting the wrong individual after the roulette wheel selection. I worked it all out on paper with some numbers. The selection is fine (if Random returns a value between 0 and 1). But after this, you have this bit of code:

for k := 0 to Population[j - 1].NumberOfValues - 1 do
SelectionA[k] := Population[j - 1].Values[k];
AFitness := Population[j - 1].FitnessScore;

The individual that has been selected is j and not (j-1). So in the above bit of code change [j-1] to [j] and it should evolve a lot better.

Sander Maréchal
[Lone Wolves GD][RoboBlast][Articles][GD Emporium][Webdesign][E-mail]

<hr />
Sander Marechal<small>[Lone Wolves][Hearts for GNOME][E-mail][Forum FAQ]</small>

Advertisement
Just to clairify; The Delphi Random function returns a real value from 0 to 1 when no parameters are given. It is only when an integer is fed to Random does it return an integer.

ie.

A := Random; {0 < A < 1}
B := Random(256); {0 < B < 256}


Also, so you guys know, I do set the actual Random Seed at the start of my program using the milliseconds of the current time. If you guys want to really see my code or binary you can go to my AI projects site and download it here: http://aiworkshop.tripod.com/

smarechal: Thanks, I'll try that now actually. BTW, are you taking into account that j is being incremented after RandomSelectionA/B is being assigned?

[edited by - WILL at RedAnt on April 23, 2003 7:05:06 PM]
Yes, I have taken that into account. Here''s a list of fitnesses for a population:

p[0]=10
p[1]=20
p[2]=50
p[3]=5
p[4]=15

TotalFitness=100

Now take a random number to select: Say 82. Your code should select p[3] here. (p[2] gets all values between 31 and 80. p[3] gets all values between 81 and 85). Lets follow your code:

SelectA=82-10=72; j=1; 72>10=true so continue
SelectA=72-20=52; j=2; 52>20=true so continue
SelectA=52-50=2; j=3; 2>50=false so STOP.

You have selected a population member now. j=3 and is correct. p[j] is the one you want. p[j-1]=p[2] and is incorrect (your code). I hope you can follow this. It makes a lot more sense working it al out on paper.



Sander Maréchal
[Lone Wolves GD][RoboBlast][Articles][GD Emporium][Webdesign][E-mail]

<hr />
Sander Marechal<small>[Lone Wolves][Hearts for GNOME][E-mail][Forum FAQ]</small>

Well, I''ve fixed my algorithm so that it doesn''t do it anymore. But what I think you may have missed is the inc(j) function I use doesn''t quit when I have the right bug. it incriments once more. Hence the j - 1 to account for the unneeded increment. I''ve changed it to make sure this doesn''t happen. Good eye though.

My program still doesn''t function as exspected. I''m wondering if anyone has figured out why yet. I''m going to update to build 10 and see if anyone can figure it out from this.
Nope, I haven't missed that. It just the way your selection code works. It is because you decrease the SelectA score first and then check against the given fitness after that. This means that you need to increment j by one to get the correct population member because you check against SelectA < fintess and not against SelectA < 0. After that, you need to decrease it again because you incremented one time too many in the loop (like you said). Total sum: j+1-1=j.

You could ofcourse rewrite your code to something like this (I don't know delphi but i'll copy-paste some)

{Select A}
RandomSelectionA := Random * TotalFitness;
j := 0;
repeat
begin
if (j > NumberOfPopulation - 1) then
j := 0;
RandomSelectionA := RandomSelectionA - Population[j].FitnessScore;
inc(j);
end;
until (RandomSelectionA < 0); {This is changed}

for k := 0 to Population[j - 1].NumberOfValues - 1 do
SelectionA[k] := Population[j - 1].Values[k];
AFitness := Population[j - 1].FitnessScore;

Makes sense. Say pop[0] has fitness 10 and SelectA=6. Thren it follows:
SelectA-pop[0].fitness; {SelectA=-4}
inc(j); {j=1}

SelectA<0 is true so you select j-1 (which is pop[0])



Sander Maréchal
[Lone Wolves GD][RoboBlast][Articles][GD Emporium][Webdesign][E-mail]


[edited by - smarechal on April 25, 2003 2:27:59 AM]

<hr />
Sander Marechal<small>[Lone Wolves][Hearts for GNOME][E-mail][Forum FAQ]</small>

Ok, I see my mistake. Ok well I''ve fixed the entire Select portion. I''ll post build #10 in a day or so and see what problems still exist. Thanks.
Damn... Tripod dropped my site stating that it volated it''s rules. So it is down for now... for now please email me at: raproductions@hotmail.com if you wish to have the source/binary.

Thanks.

This topic is closed to new replies.

Advertisement