GeneticAlgorithmPython icon indicating copy to clipboard operation
GeneticAlgorithmPython copied to clipboard

gene_space with condition between genes

Open GregBueno opened this issue 4 years ago • 3 comments

Hi @ahmedfgad, First, you did an excellent project, congratulations!

Secondly I have a question, my problem has a peculiar condition in gene generation, the sum of two genes must be in range (0,1) like: 0<sum(variable1+variable2)<1

How can I implement ?

My gen space: [{'low': 0, 'high': 1.0}, {'low': 0, 'high': 1.0}, {'low': 0, 'high': 3.5}, {'low': 0, 'high': 4.0}]

The first and second parameters must be within the range and the sum of the two parameters must be between 0 and 1

Thank you

GregBueno avatar Apr 01 '21 06:04 GregBueno

Hi @GregBueno,

Thank you 👍

Please note that I tried to cover as many general cases as possible in PyGAD.

For your request, this is not supported but you can do it with little efforts.

One way is to restrict the values of the 2 genes between 0 and 1: {'low': 0, 'high': 1.0}. This way, the sum of the 2 genes will not exceed 1.0. But this limits the gene values to just the 0.0-0.5 range.

If you want to use the full range 0.0-1.0 while making sure the sum does not exceed 1.0, then do the following:

  1. Allow the first gene to take a value from the range 0.0-1.0.
  2. Implement the on_mutation() callback function which is called after the mutation is applied.
  3. Inside on_mutation(), loop through the solutions, return the value of the first gene, subtract its value from 1.0, and override the value of the second gene by this result.

Here is an example: The solution may have 4 genes and you want the sum of the first 2 genes to be 1.0. [0.7, 0.6, 2, 3]

  • The sum of the first 2 genes is 0.7+0.6=1.4. This is not accepted.
  • Inside the on_mutation() function, subtract 0.7 from 1.0 to get 1.0-0.7=0.3.
  • Override the second gene value by 0.3.

I hope you can find any of these options helpful.

Please let me know if I can help in any way.

ahmedfgad avatar Apr 01 '21 13:04 ahmedfgad

Saw this issue and I'm in a similar boat, although with a different twist.

So it's safe to assume that the on_mutation() method is where new genes get created, and you could add some custom logic to ensure the new sets of genes meet certain criteria?

In my situation, I'm using 2 genes that represent a range of numbers, and that range must be incremented up, not down. So for example, if the first gene is 50, than the second gene must be greater than 50, so that my effective range ends up being something like 50 and 100, it can't be 50 and 30, type thing. So I could work in some logic to tweak the genes that need tweaking in on_mutation()?

I guess too, how would one work in the gene_space parameters for this, so that the upper range number stays within the gene_space range for that gene?

THANKS! Great work!

UPDATE

I think I may have answered my own question here. What I plan to do is:

  1. Create my own initial population, making use of the logic I want for the genes
  2. Then using the on_mutation() callback method, basically do the same thing, run the new population through the logic function to make sure all the genes follow the correct pattern.

I'm going to work on this this weekend as I'm still a bit unclear as to HOW I'm going to do this, but I have an idea or two. Thanks!

windowshopr avatar Jul 23 '21 22:07 windowshopr

  • penalize the fitness function if the selected parameter does not make sense e.g) variable1+variable2>1 -> return some large negative fitness value

  • or override below methods. new function will filter out invalid parameter combinations. on_start, on_crossover, on_mutation

miroblog avatar Dec 15 '23 18:12 miroblog