Project-Platypus / Platypus

A Free and Open Source Python Library for Multiobjective Optimization
GNU General Public License v3.0
570 stars 153 forks source link

Can we use initial conditions to run platypus? #20

Closed ivan-marroquin closed 7 years ago

ivan-marroquin commented 7 years ago

Hi,

Is there a way to use initial conditions to run NSGA II or any other MOEA algorithm in platypus?

Thanks,

Ivan

dhadka commented 7 years ago

Yes, they all should allow you to set initial conditions. For example, if you want to set the initial population, supply your own Generator to the constructor. The generator creates the initial population. By default it uses RandomGenerator:


class RandomGenerator(Generator):
    def __init__(self):
        super(RandomGenerator, self).__init__()

    def generate(self, problem):
        solution = Solution(problem)
        solution.variables = [x.rand() for x in problem.types]
        return solution

But, you can create your own Generator that returns a specific population of solutions.

ivan-marroquin commented 7 years ago

Thanks for the clarification. If you don't mind, could you review my own generator?

I have this Python code:

def inverse_desired_value_third_layer(w): return [-(w[0] - np.log(np.exp(w[0]) + np.exp(w[1]) + np.exp(w[2]))), np.exp(w[1]), np.exp(w[2])]

problem= Problem(3, 3)

if (np.max(np.abs(weights_third_layer)) + np.max(np.abs(third_layer_bias))) > 1: limits= np.max(np.abs(weights_third_layer)) + np.max(np.abs(third_layer_bias)) else: limits= 1.

problem.types[0]= Real(0, limits) problem.types[1]= Real(-limits, 0) problem.types[2]= Real(-limits, 0) problem.function= inverse_desired_value_third_layer algorithm= NSGAII(problem, population_size= 100, variator= SBX())

Also, I have the following initial values for w: w[0]= -0.5503, w[1]= -0.6505, w[2]= 0.3471

The generator to add to the Python code is as follows: from platypus.operators import Generator

class MyGenerator(Generator): def init(self): super(MyGenerator, self).init()

def generate(self, problem):
    solution = Solution(problem)
    solution.variables = [ [-0.5503, -0.6505, 0.3471] for _ in problem.types]
    return solution

and finally, I call the NSGA II algorithm

algorithm= NSGAII(problem, population_size= 100, generator= MyGenerator, variator= SBX())

ivan-marroquin commented 7 years ago

Thanks a lot for taking the time to review the code. Unfortunately, I get this error message:

TypeError: generate() missing 1 required positional argument: 'problem'

It is a bit strange. The generate function is called with (self, problem).

I noticed that the generate function makes use of Solution, so I added this line to my code: from platypus.core import Solution

Ivan

ivan-marroquin commented 7 years ago

playing a bit with the code, I did the following:

class MyGenerator(Generator): def init(self): super(MyGenerator, self).init() def generate(self, problem): solution= Solution(problem) solution.variables= [ w0 for _ in problem.types] return solution

algorithm= NSGAII(problem, population_size= 100, generator= MyGenerator(), variator= SBX())

Note that w0 contains the initial conditions: an array with 3 elements. Also, the call "generator= MyGenerator()" fixed the previous error message.

Unfortunately, I get the new error message : ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Any ideas?

ivan-marroquin commented 7 years ago

The core.py gives the error:

File "C:\Anaconda3\lib\site-packages\platypus-0.1-py3.6.egg\platypus\core.py", line 451, in compare if o1 < o2:

It seems that there is a conflict in the way the solution.variables is made with respect to what the core.py is expecting as input

dhadka commented 7 years ago

When calling


    solution.variables = [ w0 for _ in problem.types ]

You're creating an array of arrays, e.g.:

    [[-0.5503, -0.6505, 0.3471], [-0.5503, -0.6505, 0.3471], [-0.5503, -0.6505, 0.3471]]

I believe instead you want to do:


    solution.variables = w0

    # or equivalently

    solution.variables = [-0.5503, -0.6505, 0.3471]

Note that for a population_size of 100, this will initialize the population with 100 identical solutions. You may want to inject other random solutions into the population as well.

ivan-marroquin commented 7 years ago

Thanks for all!