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

Provide "warm start" population #44

Closed
hyumo opened this issue Mar 18, 2020 · 7 comments
Closed

Provide "warm start" population #44

hyumo opened this issue Mar 18, 2020 · 7 comments

Comments

@hyumo
Copy link

hyumo commented Mar 18, 2020

I am curious if there's a way to provide initial input values to the algorithm so that the search would be quicker?

I am not quite familiar with those genetic algorithms, correct me if I am wrong in this.

@blankjul
Copy link
Collaborator

Yes, you can pre-define the initial population (this is how it would be called in evolutionary computation).

If you just know the design values:

import numpy as np

from pymoo.algorithms.so_genetic_algorithm import GA
from pymoo.factory import get_problem
from pymoo.optimize import minimize

problem = get_problem("sphere")

X = np.random.random((500, problem.n_var))

algorithm = GA(sampling=X)

res = minimize(problem,
               algorithm,
               seed=1,
               verbose=False)

print("Best solution found: \nX = %s\nF = %s" % (res.X, res.F))

If you like to provide pre-evaluated solutions:

import numpy as np

from pymoo.algorithms.so_genetic_algorithm import GA
from pymoo.factory import get_problem
from pymoo.model.evaluator import Evaluator
from pymoo.model.population import Population
from pymoo.optimize import minimize

problem = get_problem("sphere")

X = np.random.random((500, problem.n_var))

pop = Population(len(X))
pop.set("X", X)
Evaluator().eval(problem, pop)

algorithm = GA(sampling=pop)

res = minimize(problem,
               algorithm,
               seed=1,
               verbose=False)

print("Best solution found: \nX = %s\nF = %s" % (res.X, res.F))

Hope this answers your question.

@hyumo
Copy link
Author

hyumo commented Mar 18, 2020

Yes! Thanks for your quick respond. And thanks for this awesome library.

@hyumo hyumo closed this as completed Mar 18, 2020
@hyumo hyumo reopened this Jun 24, 2020
@hyumo
Copy link
Author

hyumo commented Jun 24, 2020

Sorry to reopen this issue, I am having some issues trying to set an initial x value. I am curious what would the "500" (population) be in the MOEA/D algo. I am using elementwise evaluation and I got the following error. I was able to run NSGA3 by setting it to the same as the population size. Thanks for your help.

Traceback (most recent call last):
  File "test.py", line 216, in <module>
    res = minimize(problem,
  File "d:\Anaconda3\envs\pymoo\lib\site-packages\pymoo\optimize.py", line 76, in minimize
    res = algorithm.solve()
  File "d:\Anaconda3\envs\pymoo\lib\site-packages\pymoo\model\algorithm.py", line 208, in solve
    self._solve(self.problem)
  File "d:\Anaconda3\envs\pymoo\lib\site-packages\pymoo\model\algorithm.py", line 289, in _solve
    self.next()
  File "d:\Anaconda3\envs\pymoo\lib\site-packages\pymoo\model\algorithm.py", line 260, in next
    self._next()
  File "d:\Anaconda3\envs\pymoo\lib\site-packages\pymoo\algorithms\moead.py", line 102, in _next
    off = crossover.do(self.problem, pop, parents[None, :])
  File "d:\Anaconda3\envs\pymoo\lib\site-packages\pymoo\model\crossover.py", line 50, in do
    X = pop.get("X")[parents.T].copy()
IndexError: index 3 is out of bounds for axis 0 with size 1

@blankjul
Copy link
Collaborator

The 500 was just randomly picked. However, for MOEAD the Population object or NumPy array must be equal to the number of reference directions.

import numpy as np

from pymoo.algorithms.moead import MOEAD
from pymoo.factory import get_reference_directions, DTLZ1
from pymoo.model.evaluator import Evaluator
from pymoo.model.population import Population
from pymoo.optimize import minimize
from pymoo.visualization.scatter import Scatter

problem = DTLZ1()

ref_dirs = get_reference_directions("das-dennis", 3, n_partitions=12)
X = np.random.random((len(ref_dirs), problem.n_var))

pop = Population(len(X))
pop.set("X", X)
Evaluator().eval(problem, pop)

algorithm = MOEAD(ref_dirs, sampling=pop)

res = minimize(problem,
               algorithm,
               seed=1,
               verbose=True)

Scatter().add(res.F).show()

Does this work for you? Elementwise evaluation shall not make any difference.

@hyumo
Copy link
Author

hyumo commented Jun 25, 2020

Thanks for your help!

I switched to using len(ref_dirs), however, I am still getting similar errors.

I can try to reference a default problem and see if I implemented my own problem correctly, but it seems to be working fine if I remove the sampling argument.

My own problem has:

  • 19 variables
  • 2 objectives
  • over 1000 constraints

Here's what I am doing:

    # Reference direction
    ref_dirs = get_reference_directions("das-dennis", 2, n_partitions=12)
    # Generate initial condition
    x = np.full((len(ref_dirs), problem.n_var), 20)

    pop = Population(len(x))
    pop.set("X", x)
    Evaluator().eval(problem, pop)

    algorithm = MOEAD(
        ref_dirs,
        decomposition="pbi",
        prob_neighbor_mating=0.95,
        sampling=pop
    )

    termination = get_termination("n_gen", 20)   

    res = minimize(problem,
               algorithm,
               termination,
               save_history=True,
               verbose=True)
Setting number of neighbours to population size: 13
====================================================================================================
n_gen |  n_eval |   cv (min)   |   cv (avg)   |  n_nds  | delta_ideal  | delta_nadir  |   delta_f
====================================================================================================
    1 |       0 |  0.146588718 |  0.146588718 |       1 |            - |            - |            -
Traceback (most recent call last):
  File "limerock2.py", line 239, in <module>
    res = minimize(problem,
  File "d:\Anaconda3\envs\pymoo\lib\site-packages\pymoo\optimize.py", line 76, in minimize
    res = algorithm.solve()
  File "d:\Anaconda3\envs\pymoo\lib\site-packages\pymoo\model\algorithm.py", line 208, in solve
    self._solve(self.problem)
  File "d:\Anaconda3\envs\pymoo\lib\site-packages\pymoo\model\algorithm.py", line 289, in _solve
    self.next()
  File "d:\Anaconda3\envs\pymoo\lib\site-packages\pymoo\model\algorithm.py", line 260, in next
    self._next()
  File "d:\Anaconda3\envs\pymoo\lib\site-packages\pymoo\algorithms\moead.py", line 102, in _next
    off = crossover.do(self.problem, pop, parents[None, :])
  File "d:\Anaconda3\envs\pymoo\lib\site-packages\pymoo\model\crossover.py", line 50, in do
    X = pop.get("X")[parents.T].copy()
IndexError: index 6 is out of bounds for axis 0 with size 1

@blankjul
Copy link
Collaborator

I just debugged it. And your initial population is NOT supposed to have duplicates. Because a duplicate elimination happens the population becomes a single individual which fails. If you pass instead of X equals to 20 random values it should work.

import numpy as np

from pymoo.algorithms.moead import MOEAD
from pymoo.factory import get_reference_directions, DTLZ1, get_termination
from pymoo.model.evaluator import Evaluator
from pymoo.model.population import Population
from pymoo.optimize import minimize

problem = DTLZ1(n_obj=2)

# Reference direction
ref_dirs = get_reference_directions("das-dennis", 2, n_partitions=12)
x = np.random.random((len(ref_dirs), problem.n_var))

pop = Population(len(x))
pop.set("X", x)
Evaluator().eval(problem, pop)

algorithm = MOEAD(
    ref_dirs,
    decomposition="pbi",
    prob_neighbor_mating=0.95,
    sampling=pop
)

termination = get_termination("n_gen", 20)

res = minimize(problem,
           algorithm,
           termination,
           save_history=True,
           verbose=True)

@hyumo
Copy link
Author

hyumo commented Jun 25, 2020

hmm, ok, that's good to know. Thanks a lot for your help, I've added some randomness to 20 and it seems to be working fine now.

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