Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maximization isted of minimization #211

Closed
GrzegorzGiniewicz opened this issue Jun 16, 2017 · 14 comments
Closed

Maximization isted of minimization #211

GrzegorzGiniewicz opened this issue Jun 16, 2017 · 14 comments

Comments

@GrzegorzGiniewicz
Copy link

Hi.

i have problem with minimization of ackley benchmark function. I cant achieve minimization.

im using

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

Im loking for help on stackoveflow. There is my code. Link:

https://stackoverflow.com/questions/44576799/minimize-a-function-using-deap

@fmder
Copy link
Member

fmder commented Jun 16, 2017

You must use axis=0 when registering numpy stats operators. It should get you a better insight. Otherwise, your code look fine to me and there is no bug on that aspect in DEAP.

@fmder fmder closed this as completed Jun 16, 2017
@GrzegorzGiniewicz
Copy link
Author

GrzegorzGiniewicz commented Jun 17, 2017

I used axis = 0 but it doesn't help. I need to use SelRoulette for my program but it still going for maximization, no matter if i put in weights 1.0 or -1.0 or use FitnessMin or FitnessMax. When i use SelTournament, tournsize = 3 i can change weights and it's maximization for 1.0 and minimization for -1.0. Why it doesnt work with SelRoulette ? What can i do to achive minimization and use SelRoulette? @fmder

@fmder
Copy link
Member

fmder commented Jun 17, 2017 via email

@GrzegorzGiniewicz
Copy link
Author

GrzegorzGiniewicz commented Jun 17, 2017

Thanks for quick answer and sorry for trouble.

@fmder
Copy link
Member

fmder commented Jun 17, 2017

Maybe you can try #87, if it works you could propose a pull request.

@fmder fmder reopened this Jun 17, 2017
@GrzegorzGiniewicz
Copy link
Author

GrzegorzGiniewicz commented Jun 17, 2017

I've changed selection for SelBest but i cant set k= 20 [like this: (toolbox.register("select", tools.selBest, k=20) ] im geting error: "selBest" got multiple values for keyword argument 'k'. And still its maximizing, even with :
creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
creator.create("Individual", list, typecode='d', fitness=creator.FitnessMin)

I understand that k is for the number of individuals to select.
Without k parametr in selection it works but still maximizing.

import random
import numpy
from deap import algorithms
from deap import base
from deap import creator
from deap import tools
from deap import benchmarks
from random import Random
from time import time
import math

toolbox = base.Toolbox()  
ind = 5
IND_SIZE = ind

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

toolbox.register("expr", random.sample, range(IND_SIZE), IND_SIZE,)

toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.expr)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)

toolbox.register("mate", tools.cxTwoPoint)
toolbox.register("mutate", tools.mutGaussian, mu=0.2, sigma=0.2, indpb=0.1)
toolbox.register("select", tools.selBest)  #k parameter doesnt work
toolbox.register("evaluate", benchmarks.ackley)


def main():
prng=None
best=None

if prng is None:
    prng = Random()
    prng.seed(time())

random.seed(prng)
pop = toolbox.population(n=100)

stats = tools.Statistics(lambda ind: ind.fitness.values)
stats.register("best", numpy.mean, axis=0)

algorithms.eaSimple(pop, toolbox, 0.9, 0.2, 100, stats=stats)

return pop, best

pop,best= main()

@fmder
Copy link
Member

fmder commented Jun 17, 2017

In eaSimple, selection is made to replace the whole population with k=len(population).

@fmder
Copy link
Member

fmder commented Jun 17, 2017

If you want to customize selection with multiple operators I'd say you should copy the content of eaSimple in your own script and replace the selection part, you'll be able to get exactly what you want really easily. The content of eaSimple is no more than 30 lines of code.

@GrzegorzGiniewicz
Copy link
Author

GrzegorzGiniewicz commented Jun 17, 2017

ok i changed k for 20 but still it's maximizing. How i can achive minimization ? @fmder

import random
import numpy
import operator
from deap import algorithms
from deap import base
from deap import creator
from deap import tools
from deap import gp
from deap import benchmarks
from random import Random
from time import time
import math
 
 
def varAnd(population, toolbox, cxpb, mutpb):
 
 
    offspring = [toolbox.clone(ind) for ind in population]
# Apply crossover and mutation on the offspring
    for i in range(1, len(offspring), 2):
        if random.random() < cxpb:
            offspring[i - 1], offspring[i] = toolbox.mate(offspring[i - 1], offspring[i])
            del offspring[i - 1].fitness.values, offspring[i].fitness.values
 
    for i in range(len(offspring)):
        if random.random() < mutpb:
            offspring[i], = toolbox.mutate(offspring[i])
            del offspring[i].fitness.values
 
    return offspring
 
 
def eaSimple(population, toolbox, cxpb, mutpb, ngen, stats=None, halloffame=None, verbose=__debug__):
 
    logbook = tools.Logbook()
    logbook.header = ['gen', 'nevals'] + (stats.fields if stats else [])
 
# Evaluate the individuals with an invalid fitness
    invalid_ind = [ind for ind in population if not ind.fitness.valid]
    fitnesses = toolbox.map(toolbox.evaluate, invalid_ind)
    for ind, fit in zip(invalid_ind, fitnesses):
        ind.fitness.values = fit
 
    if halloffame is not None:
        halloffame.update(population)
 
    record = stats.compile(population) if stats else {}
    logbook.record(gen=0, nevals=len(invalid_ind), **record)
    if verbose:
        print logbook.stream
 
# Begin the generational process
    for gen in range(1, ngen + 1):
# Select the next generation individuals
        offspring = tools.selBest(population, k=20)
# Vary the pool of individuals
        offspring = varAnd(offspring, toolbox, cxpb, mutpb)
# Evaluate the individuals with an invalid fitness
        invalid_ind = [ind for ind in offspring if not ind.fitness.valid]
        fitnesses = toolbox.map(toolbox.evaluate, invalid_ind)
        for ind, fit in zip(invalid_ind, fitnesses):
            ind.fitness.values = fit
# Update the hall of fame with the generated individuals
        if halloffame is not None:
            halloffame.update(offspring)
# Replace the current population by the offspring
        population[:] = offspring
# Append the current generation statistics to the logbook
        record = stats.compile(population) if stats else {}
        logbook.record(gen=gen, nevals=len(invalid_ind), **record)
        if verbose:
            print logbook.stream
 
    return population, logbook
 
 
 
def main():
 
    toolbox = base.Toolbox()  
    ind = 5
    IND_SIZE = ind
 
    creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
    creator.create("Individual", list, typecode='d', fitness=creator.FitnessMin)
 
    toolbox.register("expr", random.sample, range(IND_SIZE), IND_SIZE)
 
    toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.expr)
    toolbox.register("population", tools.initRepeat, list, toolbox.individual)
 
    toolbox.register("mate", tools.cxTwoPoint)
    toolbox.register("mutate", tools.mutGaussian, mu=0.2, sigma=0.2, indpb=0.1)
    #toolbox.register("select", tools.selBest)
    toolbox.register("evaluate", benchmarks.ackley)
 
 
 
    prng=None
    best=None
 
    if prng is None:
        prng = Random()
        prng.seed(time())
       
    random.seed(prng)
    pop = toolbox.population(n=100)
 
    stats = tools.Statistics(lambda ind: ind.fitness.values)
    stats.register("best", numpy.mean, axis=0)
 
    eaSimple(pop, toolbox, 0.9, 0.2, 100, stats=stats)
 
#verbose=False
 
    return pop, best
 
pop,best= main()

@fmder
Copy link
Member

fmder commented Jun 17, 2017

How do you see that it is maximizing?

@GrzegorzGiniewicz
Copy link
Author

GrzegorzGiniewicz commented Jun 17, 2017

im printing results :
https://pastebin.com/XmSeegsV
best sholud be coming to 0

Its wird that its not working, when i use selTournament it's fine . Buy i rly need selBest

@fmder
Copy link
Member

fmder commented Jun 17, 2017

I just tested your script. I just saw that the "best" you are printing is the average of all fitnesses. What you really should look for is the min value. Add those lines to your script

stats.register("min", numpy.min, axis=0)
stats.register("max", numpy.max, axis=0)
stats.register("avg", numpy.average, axis=0)

You'll see that the min value starts around 7 or so and goes to 0 in about 5 to 10 generations. Why does it go up again? It is because of the And variation operator and your high crossover and mutation rate. The evaluation is done after variation and before selection thus you might modify the best individuals. However by using a hall of fame you will still capture it.

With high crossover rate it is possible for the max value to go up and the min value to go down averaging the optimisation result over the entire population, exactly what you are observing. Essentially you should just check for the min value.

@fmder fmder closed this as completed Jun 17, 2017
@GrzegorzGiniewicz
Copy link
Author

Thank you very much for help and patiance.

@fmder
Copy link
Member

fmder commented Jun 17, 2017 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants