ahmedfgad / GeneticAlgorithmPython

Source code of PyGAD, a Python 3 library for building the genetic algorithm and training machine learning algorithms (Keras & PyTorch).
https://pygad.readthedocs.io
BSD 3-Clause "New" or "Revised" License
1.85k stars 462 forks source link

Wrong number of arguments exceptions for fitness functions with 2 required parameters #112

Open jack89roberts opened 2 years ago

jack89roberts commented 2 years ago

I'm trying pygad (2.16.3) for the first time , and have found the check for the number of arguments of the fitness function to be overly sensitive, e.g. I would like to be able to pass fitness functions of the following types:

Class instance functions:

import pygad

class Fitness:
    def fitness(self, x, idx):
        return sum(x)

foo = Fitness()

ga_instance = pygad.GA(
    num_generations=10,
    num_parents_mating=5,
    fitness_func=foo.fitness,
    sol_per_pop=10,
    num_genes=5,
)

Incorrectly triggers an error that fitness requires 3 parameters, since f.fit.__code__.co_argcount returns 3 (including self). Checking with signature instead could be an alternative:

from inspect import signature
len(signature(f.fit).parameters)
>>> 2

Functions with additional parameters that have default values:

import pygad

def fitness(x, idx, y=3):
    return sum(x)

ga_instance = pygad.GA(
    num_generations=10,
    num_parents_mating=5,
    fitness_func=fitness,
    sol_per_pop=10,
    num_genes=5,
)

Also triggers an error, but fitness can be called with 2 parameters as required. Unsure of a workaround for this one.

Is there any reason why pygad couldn't use either of these fitness functions? I'd especially like to be able to use a function of a class instance for one of my projects.

jack89roberts commented 2 years ago

I just found #92 , which has a fix for the class case.