Problems with a custom generator with NSGA-II

52 views
Skip to first unread message

Alberto Tonda

unread,
Nov 10, 2016, 10:01:46 AM11/10/16
to Inspyred
Dear all,

I am experimenting with a custom generator for NSGA-II, but I have some weird error when I try to pass it some arguments with a dictionary. This is the basic example of NSGA-II, for which my generator makes no sense, but I am able to reproduce the error:

from random import Random
from time import time
import inspyred

def nsga2generate(random, args) :

        phenotype_len = args.get("phenotype_len", 3)

        # extract random number in 1,400
        individual_size = random.randint(1,400)
        individual = [0] * individual_size
        for i in range(0, individual_size) : individual[i] = random.randint(1, phenotype_len)
        return individual

def main(prng=None, display=False):
    if prng is None:
        prng = Random()
        prng.seed(time())

    args = dict()
    args["phenotype_len"] = 10

    problem = inspyred.benchmarks.Kursawe(3)
    ea = inspyred.ec.emo.NSGA2(prng)
    ea.variator = [inspyred.ec.variators.blend_crossover,
                   inspyred.ec.variators.gaussian_mutation]
    ea.terminator = inspyred.ec.terminators.generation_termination
    final_pop = ea.evolve(generator=nsga2generate(prng, args),
                          #generator=nsga2generate
                          evaluator=problem.evaluator,
                          pop_size=100,
                          maximize=problem.maximize,
                          bounder=problem.bounder,
                          max_generations=80)

    if display:
        final_arc = ea.archive
        print('Best Solutions: \n')
        for f in final_arc:
            print(f)
        import pylab
        x = []
        y = []
        for f in final_arc:
            x.append(f.fitness[0])
            y.append(f.fitness[1])
        pylab.scatter(x, y, color='b')
        pylab.savefig('{0} Example ({1}).pdf'.format(ea.__class__.__name__,
                                                     problem.__class__.__name__),
                      format='pdf')
        pylab.show()
    return ea

if __name__ == '__main__':
    main(display=True)

If I just pass the generator with 

generator=nsga2generate

everything works properly. However, with the current code, I get:

Traceback (most recent call last):
  File "sample-nsga-ii.py", line 53, in <module>
    main(display=True)
  File "sample-nsga-ii.py", line 32, in main
    max_generations=80)
  File "/usr/local/lib/python3.5/dist-packages/inspyred/ec/emo.py", line 147, in evolve
    return ec.EvolutionaryComputation.evolve(self, generator, evaluator, pop_size, seeds, maximize, bounder, **args)
  File "/usr/local/lib/python3.5/dist-packages/inspyred/ec/ec.py", line 430, in evolve
    cs = generator(random=self._random, args=self._kwargs)
TypeError: 'list' object is not callable

There is clearly something I am missing. Can you help me?

Thank you for your time.

Aaron Garrett

unread,
Nov 10, 2016, 10:34:38 AM11/10/16
to Inspyred
When you pass that generator into the args, you're calling it (by passing the prng and args parameters). That means you're setting generator to the RESULT of the function call, which is a list. You just need to pass the function name as the generator like you have commented out. 

If I've misunderstood your question, let me know.

Alberto Tonda

unread,
Nov 10, 2016, 10:35:49 AM11/10/16
to insp...@googlegroups.com
I see! But then, how do you pass the arguments to the generator? 

--
You received this message because you are subscribed to a topic in the Google Groups "Inspyred" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/inspyred/mKwNHVAyRfk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to inspyred+unsubscribe@googlegroups.com.
To post to this group, send email to insp...@googlegroups.com.
Visit this group at https://groups.google.com/group/inspyred.
For more options, visit https://groups.google.com/d/optout.



--
Alberto Tonda

Aaron Garrett

unread,
Nov 10, 2016, 10:37:12 AM11/10/16
to Inspyred
After reading your message again, I think I understand what your real question is. You probably want to know how to pass the dictionary stuff to your custom generator. You do that by putting those values in the arguments to the evolve function call.


    final_pop = ea.evolve(generator=nsga2generate,
                          evaluator=problem.evaluator,
                          pop_size=100,
                          maximize=problem.maximize,
                          bounder=problem.bounder,
                          max_generations=80,
                          phenotype_len=10)

Those are automatically collected and put into the args dictionary that is passed to bounder. You can consult it exactly as you are doing right now.


On Thursday, November 10, 2016 at 9:01:46 AM UTC-6, Alberto Tonda wrote:

Aaron Garrett

unread,
Nov 10, 2016, 10:38:15 AM11/10/16
to Inspyred
Ha! You ninja'd me on that reply. Or am I a mind reader?...


On Thursday, November 10, 2016 at 9:01:46 AM UTC-6, Alberto Tonda wrote:

Alberto Tonda

unread,
Nov 10, 2016, 10:40:00 AM11/10/16
to insp...@googlegroups.com
Excellent! Thanks a lot, I completely missed that.

PS: both. I am a ninja, and you're a mind reader ;-)

--
You received this message because you are subscribed to a topic in the Google Groups "Inspyred" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/inspyred/mKwNHVAyRfk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to inspyred+unsubscribe@googlegroups.com.
To post to this group, send email to insp...@googlegroups.com.
Visit this group at https://groups.google.com/group/inspyred.
For more options, visit https://groups.google.com/d/optout.



--
Alberto Tonda
Reply all
Reply to author
Forward
0 new messages