Closed hyumo closed 4 years ago
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.
Yes! Thanks for your quick respond. And thanks for this awesome library.
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
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.
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:
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
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)
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.
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.