-
-
Notifications
You must be signed in to change notification settings - Fork 489
Can't use a method as fitness function #69
-
I need my fitness function to have a state, for that reason I need to use a method instead of a function in the fitness_func parameter.
The problem is, PyGAD won't accept a method as fitness function.
This happens because PyGAD verifies how many arguments a function have and together with "self" argument a method as fitnees function would have 3 arguments. PyGAD won't let any fitness_func with number of arguments different than 2.
Shouldn't this be changed in the lib?
Does someone know a way around this while this feature isn't provided?
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 1 -
👀 1
Replies: 3 comments 2 replies
-
I am having a similar issue. Trying to encapsulate all GA in a Class and global variables are not good design pattern.
e.g.
class MyGA:
def fitness_func(self, solution, sol_idx): ...
def on_generation(self, ga_instance): ...
so then I tried using functools.partial and still no
Traceback (most recent call last): File "C:\python\PyGadCNNADNet.py", line 57, in <module> myga = GadADNN() File "C:\python\PyGadCNNADNet.py", line 37, in __init__ self.ga_instance = GA(num_generations=10, num_parents_mating=2, initial_population=self.population_vectors.copy(), fitness_func=partial(self.fitness_func, self=self), mutation_percent_genes=0.1, parent_selection_type="sss", crossover_type="single_point", mutation_type="random", keep_parents=-1, on_generation=partial(self.on_generation, self=self)) File "C:\Users\foxx0\AppData\Local\Programs\Python\Python310\lib\site-packages\pygad\pygad.py", line 638, in __init__ if (fitness_func.__code__.co_argcount == 2): AttributeError: 'functools.partial' object has no attribute '__code__'. Did you mean: '__call__'?
so then I tried using functools.partialmethod and still no.
Traceback (most recent call last): File "C:\python\PyGadCNNADNet.py", line 57, in <module> myga = GadADNN() File "C:\python\PyGadCNNADNet.py", line 37, in __init__ self.ga_instance = GA(num_generations=10, num_parents_mating=2, initial_population=self.population_vectors.copy(), fitness_func=partialmethod(self.fitness_func, self=self), mutation_percent_genes=0.1, parent_selection_type="sss", crossover_type="single_point", mutation_type="random", keep_parents=-1, on_generation=partialmethod(self.on_generation, self=self)) File "C:\Users\foxx0\AppData\Local\Programs\Python\Python310\lib\site-packages\pygad\pygad.py", line 645, in __init__ raise TypeError("The value assigned to the fitness_func parameter is expected to be of type function but ({fitness_func_type}) found.".format(fitness_func_type=type(fitness_func))) TypeError: The value assigned to the fitness_func parameter is expected to be of type function but (<class 'functools.partialmethod'>) found.
workaround is to remove the argument count checks entirely in pygad.py line 638.
image
and lines 742
image
In fact actually there are 2 open PR to address this issue. Can we merge one of them and move forward already?
#99
#92
Beta Was this translation helpful? Give feedback.
All reactions
-
I am facing a similar issue, and posted it as Issue Request #138, with a proposed code patch. It allows for PyGAD GA class constructor to accept my class instance reference as a new parameter, and then delivering it to callback methods within my class. If the reference is set to None, then a function may be assumed, else it should call a method with the provisioned reference. I also like PR #92 proposed solution, either one would work for me. Currently, I am using my own patched code with latest Version 2.18.1.
Another issue I encountered is with on_crossover and on_mutation callbacks not being called if crossover_type or mutation_type are set to None, respectively. I need for my callbacks to be invoked regardless of type being set to None or not. I need to make adjustments for each solution just before the mutation operation, even when no crossover is required. The zip uploaded code monkeypatch solves this problem.
Beta Was this translation helpful? Give feedback.
All reactions
-
I uploaded pull request #143 which fixes both of my issues. Proposed changes are against PyGAD v2.18.1. I have been testing my implementation with these changes and so far it works well with methods as callbacks.
Beta Was this translation helpful? Give feedback.
All reactions
-
This is now supported. The fitness or any callback can accept a function or a method.
Beta Was this translation helpful? Give feedback.
All reactions
-
Great!
Beta Was this translation helpful? Give feedback.