Enforcing Percentage (Genes Must Sum to 1)
The values I'm trying to optimize are percentages, such that the sum of all genes should be exactly 1. Is there a way to enfoce this in PyGAD?
I can keep each gene individually bound [0, 1] with the gene_space hyperparameter, but I haven't yet managed to apply the "sum" constrain.
From the sequencing in the algorithm, would a custom function called on_generation perhaps be able to handle this? I couldn't yet crack that but I think it might be a solution.
This is not yet a supported feature in PyGAD but I am working on finding a way to apply conditions between some individual genes (e.g. a gene must satisfy a condition like gene1<gene2+gene3) and also across all genes.
At the current moment, there are some things that might help you.
- An easy way, as you suggested, is to check the values of all genes in the population in either the
on_mutation()or theon_generation()callback functions. There, you handle the gene values in case the sum exceeds 1. You can access to the population through thepopulationproperty. - I do not know if this is applicable to your case but you may split the 0-1 range across your genes in
gene_spaceso that you are confident that the sum will be 1. - Implement your own mutation function because mutation is what changes the genes' values. But this would need some effort.
I'll try handling it using on_generation() then!
Just one follow up question which I couldn't get from the docs, besides "stop" what is the expected return from on_generation()? i.e. should it try to modify the ga_instance in place or should it return a new ga_instance?
The return value from the on_generation() function is optional. You are not asked to return anything.
For your case, you can just overwrite the population property.
def on_generation(ga_instance):
ga_instance.population = ...
Caution: In case you returned "stop", then the algorithm will stop without going through the remaining generations.