AForge.NET

  :: AForge.NET Framework :: Articles :: Forums ::

Genetic trouble...

Forum to discuss AForge.NET Framework, its features, API, how-tos, etc.

Genetic trouble...

Postby Blue Ninja » Fri Feb 10, 2012 1:06 am

Hi there,

I'm trying to use the Genetics classes for a project, and I've run into trouble. I'm pretty sure I've read and understand the documentation and the theory, but maybe I'm missing something.

The problems I'm having have to do with the Population's FitnessMax and BestChromosome properties. I did find that those are not calculated until either Migration or Selection is performed, which explained why they didn't seem correct after the initial population was created. Since Evaluate had been called on each new chromosome, I'd assumed that these functions would work initially.

However, even after several RunEpoch calls, these values don't seem right. In my FitnessFunction class, I exclude chromosomes that fail at their task. I'd tried assigning them a value of 0, and then even tried -1, but was still getting odd results - but then I found a forum post here where it was mentioned that these values must always be > 0. So, I replaced that value with Double.Epsilon, and I'm getting closer. That should probably be in the documentation.

However, I still seem to be getting some impossible results. I have an NUnit test set up to try solving the problem, and show some debug output. Everytime the FitnessFunction is called, if the chromosome is viable, I spit out its value to the console. When the series of RunEpoch calls is done, the BestChromosome returns a value that did *not* make the cut in the FitnessFunction, and should therefore have a fitness value of Double.Epsilon. However, the value returned for the chromosome is much higher - one that was only output by the FitnessFunction for a *different* chromosome.

It looks as if the values are getting mixed up somewhere. I've looked through the AForge.Genetic DLL to better understand what's happening in there, but haven't found an explanation for what I'm seeing. No off-by-one indexes, no apparent calls to Mutate() that aren't followed by Evaluate(), etc.

Does anyone have any insight into what I might be missing? I know it's tough without being able to see the code, and I've been doing this long enough not to be so pompous at to believe it couldn't possibly be something obvious that I screwed up. Any thoughts would be appreciated!
Blue Ninja
 
Posts: 4
Joined: Thu Feb 09, 2012 10:47 pm

Re: Genetic trouble...

Postby andrew.kirillov » Fri Feb 10, 2012 10:12 am

Hello,

Blue Ninja wrote: I found a forum post here where it was mentioned that these values must always be > 0. So, I replaced that value with Double.Epsilon, and I'm getting closer. That should probably be in the documentation.

This is actually there - in documentation.

To narrow down the problem, I would try one of four genetic samples provided with the framework. Try to see of those provide any issues related to the way how fitness and best chromosome are calculated. If there is similar issue, then we can have a look at it and fix. If samples work fine, then there might be an issue in your application.
With best regards,
Andrew


Interested in supporting AForge.NET Framework?
User avatar
andrew.kirillov
Site Admin, AForge.NET Developer
 
Posts: 2827
Joined: Fri Jan 23, 2009 9:12 am
Location: UK

Re: Genetic trouble...

Postby Blue Ninja » Thu Mar 01, 2012 9:58 pm

My apologies on the long delay, I must have missed the notification email from your reply. Thanks for getting back to me quickly.

I've still been experiencing oddities, and have done a lot of head scratching. Perhaps the simplest way to determine what's going on is to see if you can explain to me why Population.BestChromosome.Fitness and Population.FitnessMax would be different. For example, the following code:

Code: Select all
   Console.WriteLine("    Fitness: " & _Population.FitnessMax & " (" & _Population.BestChromosome.Fitness & ")")
   Console.WriteLine("           : " & Eval.Evaluate(_Population.BestChromosome))


Produces the following output:

Code: Select all
    Fitness: 0.911111111111111 (0.911111111111111)
           : 4.94065645841247E-324


In the example above, "Eval" is the fitness evaluation function passed to the Population constructor. The value 4.94065645841247E-324 is Double.Epsilon, the lowest value above zero, which I use when a chromosome completely fails to achieve the desired goal, which should exclude it from possibly being the BestChromosome.

I then tried outputting the chromosome sequence from the evaluation function anytime the value was >= .91, thus giving me a long list of chromosomes that had that high a value during the RunEpoch loop. At the end of RunEpoch, I looked for the chromosome returned as BestChromosome in that list, and it had at no point been assigned the value in question.

It looks like there is something out of sync with Population.BestChromosome, Population.FitnessMax, and the actual fitness value returned for the chromosome in question. I haven't been able to figure out what I might be doing to explain these results, but it certainly may be due to user error instead of a bug. I'd sure appreciate any help you can offer, and I'll provide you with whatever additional information you need to do so.

Thanks for your time.
Blue Ninja
 
Posts: 4
Joined: Thu Feb 09, 2012 10:47 pm

Re: Genetic trouble...

Postby Blue Ninja » Fri Mar 02, 2012 3:08 am

Update: I may be on the trail of part of the problem - when overriding the ChromosomeBase.Clone() method, I'm unable to set the value of Fitness, because the underlying protected field has the same name as the property, and differs only by case. As such, no case-insensitive languages can inherit that class properly. I'll try changing that and re-building the source, but it's probably something that should be changed in the library, no?

Also, I think I've tracked down why the results have been weird. Buried in the innards of my derived chromosome class are a few reference-type members. The Clone() and CreateNew() methods didn't take this into account for all members, so there were a few cases where changing a property of one chromosome also changed that property of another, which had already had Evaluate() called, thus changing the values for the next time I called Evaluate() to compare, and showing unexpected results.

I think those are the only two problems, but I have more testing to do. The reference types was definitely not a bug, but a usage problem - my fault. However, the inability to access the protected "fitness" member due to the identical read-only property name is requiring me to build a custom version from source. I'd like to hear your feedback on that issue.

Thanks again!
Blue Ninja
 
Posts: 4
Joined: Thu Feb 09, 2012 10:47 pm

Re: Genetic trouble...

Postby andrew.kirillov » Fri Mar 02, 2012 9:22 am

Blue Ninja wrote:However, the inability to access the protected "fitness" member due to the identical read-only property name is requiring me to build a custom version from source. I'd like to hear your feedback on that issue.

We can fix that. But I must admit that there are many places in the framework where field name differs from property name only in casing. However those are mostly private fields. But we can fix the protected stuff. You may put an issue in tracking system ...

Those language which don’t care about casing is just pain in the ass.
With best regards,
Andrew


Interested in supporting AForge.NET Framework?
User avatar
andrew.kirillov
Site Admin, AForge.NET Developer
 
Posts: 2827
Joined: Fri Jan 23, 2009 9:12 am
Location: UK

Re: Genetic trouble...

Postby Blue Ninja » Fri Mar 02, 2012 4:36 pm

Yes, I'm sure that's the case in a lot of places. I know the issue of case sensitivity, like many other aspects of individual programming languages, is something of an ideological holy war - both sides have their merits, but programmers tend to fall along one extreme or another. Far be it from me to stir that pot 'o trouble! But since the library is likely to be used from both kinds of languages, it's probably better in this instance to accommodate them all.

I appreciate your quick feedback on the matter! Thanks again for your valuable contribution to the community with this library.
Blue Ninja
 
Posts: 4
Joined: Thu Feb 09, 2012 10:47 pm




Return to AForge.NET Framework

cron