DEAP / deap

Distributed Evolutionary Algorithms in Python
http://deap.readthedocs.org/
GNU Lesser General Public License v3.0
5.77k stars 1.12k forks source link

Bounded search space (e.g. Branin function) #417

Closed a-z-e-r-i-l-a closed 4 years ago

a-z-e-r-i-l-a commented 4 years ago

Hi

I was looking for an example in you repository similar to the following problem but was rather lost and did not finally see a case in which the search space bounds are defined in a multidimensional setting for genetic algorithm. For example, let's say I want to optimize the so called Branin function defined in a 2 dimensional input space:

def Branin ( x ):
      y = (x[1] - (5.1 / (4 * np.pi ** 2)) * x[0] ** 2 + 5 * x[0] / np.pi - 6) ** 2
      y += 10 * (1 - 1 / (8 * np.pi)) * np.cos(x[0]) + 10
      return y

in which the two dimensional input x has the following bounds: first dimension bounded between -5 and 10, while second dimension is bounded between 0 to 15.

bounds = [[-5, 10], 
                 [0, 15]],

If there is a similar example in this repo that I have missed I would be glad if anyone shares a link to it. In addition, if this issue is not closed immediately, I would also still be able to clarify if there was any doubt left for me regarding the code.

Thanks.

fmder commented 4 years ago

What about this one:

a-z-e-r-i-l-a commented 4 years ago

@fmder Hi François, I was still unable to use it for the Branin function. Here's what I changed in the example you mentioned:


def Branin ( x ):
      y = (x[1] - (5.1 / (4 * np.pi ** 2)) * x[0] ** 2 + 5 * x[0] / np.pi - 6) ** 2
      y += 10 * (1 - 1 / (8 * np.pi)) * np.cos(x[0]) + 10
      return y

creator.create("FitnessMin", base.Fitness, weights=(-1.0, -1.0))
creator.create("Individual", array.array, typecode='d', fitness=creator.FitnessMin)

toolbox = base.Toolbox()

# Attribute generator
toolbox.register("attr_float", random.uniform, -5, 5)

# Structure initializers
toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_float, 3)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)

def checkBounds(min, max):
    def decorator(func):
        def wrappper(*args, **kargs):
            offspring = func(*args, **kargs)
            for child in offspring:
                for i in range(len(child)):
                    if child[i] > max:
                        child[i] = max
                    elif child[i] < min:
                        child[i] = min
            return offspring
        return wrappper
    return decorator

toolbox.register("evaluate", Branin)   #<<<<<<<<<<<<<<< Changed line 
toolbox.register("mate", tools.cxBlend, alpha=1.5)
toolbox.register("mutate", tools.mutGaussian, mu=0, sigma=3, indpb=0.3)
toolbox.register("select", tools.selNSGA2)

toolbox.decorate("mate", checkBounds(-5, 5))
toolbox.decorate("mutate", checkBounds(-5, 5)) 

def main():
    random.seed(64)

    MU, LAMBDA = 50, 100
    pop = toolbox.population(n=MU)
    hof = tools.ParetoFront()
    stats = tools.Statistics(lambda ind: ind.fitness.values)
    stats.register("avg", numpy.mean, axis=0)
    stats.register("std", numpy.std, axis=0)
    stats.register("min", numpy.min, axis=0)
    stats.register("max", numpy.max, axis=0)

    algorithms.eaMuPlusLambda(pop, toolbox, mu=MU, lambda_=LAMBDA, 
                              cxpb=0.5, mutpb=0.2, ngen=150, 
                              stats=stats, halloffame=hof)

    return pop, stats, hof

For the bounds since the example was for a one dimensional problem, I was also unsure how to define it for the two dimensional Branin. Thanks.