Multi-objective optimization is the simultaneous optimization of multiple objective functions that are in a trade-off relationship. In the case of single-objective optimization, there is one optimal solution, but in the case of multi-objective optimization, there is not always one optimal solution. The optimal solution in multi-objective optimization is called ** Pareto optimal solution **. A diagram of the Pareto optimal solution is shown below.
platypus platypus seems to be one of the libraries for multipurpose optimization. Specifically, it seems that many methods such as NSGA-II, NSGA-III, MOEA / D, IBEA, Epsilon-MOEA, SPEA2, GDE3, OMOPSO, SMPSO, Epsilon-NSGA-II can be used.
Install with pip to use it.
pip install platypus-opt
Platypus also provides test questions. This time, let's use a test question called DTLZ2.
from platypus import NSGAII, Problem, Real, nondominated, Integer
import matplotlib.pyplot as plt
from platypus.problems import DTLZ2
def main():
#problem,Set the algorithm,Search execution
problem = DTLZ2(2)
algorithm = NSGAII(problem, population_size=100)
algorithm.run(10000)
#Extract non-inferiority
nondominated_solutions = nondominated(algorithm.result)
#Draw graph
plt.scatter([s.objectives[0] for s in nondominated_solutions if s.feasible],
[s.objectives[1] for s in nondominated_solutions if s.feasible])
plt.show()
if __name__ == '__main__':
main()
The result of optimizing as a two-purpose problem as DTLZ2 (2) is as follows. It was confirmed that the Pareto optimal solution was obtained.
I tried to optimize it as a 3 purpose problem as DTLZ2 (3).
Platypus also allows you to optimize your own problems. First, let's set the objective function. This time, we will optimize the two-variable two-purpose minimization problem. The following two are the objective functions.
f(x)=2x_1^2+x_2^2
g(x)=-x_1^2-2x_2^2
#Objective function setting
def objective(vars):
x1 = int(vars[0])
x2 = int(vars[1])
return [2*(x1**2) + x2**2, -x1**2 -2*(x2**2)]
After setting the objective function, let's set the search. You can set the problem with Problem (number of variables, number of objective functions).
#2 variables 2 problem of purpose
problem = Problem(2, 2)
problem.directions [:] = Problem.MINIMIZE sets it as a minimization problem. If you want to make it a maximization problem, you can set it with Problem.MAXIMIZE. If you want to mix minimization and maximization, you can set it for each objective variable. For example, problem.directions [:] = [Problem.MINIMIZE, Problem.MAXIMIZE].
#Set minimize or maximize
problem.directions[:] = Problem.MINIMIZE
Next, let's set the coefficient of determination. This time, both $ x_1 $ and $ x_2 $ are integers, and the range is $ 0 \ leq x_1 \ leq100 $ and $ 0 \ leq x_2 \ leq50 $. This time, the coefficient of determination is an integer, but if you want to handle it as a real number, you can change Integer to Real.
#Set the range of decision variables
int1 = Integer(0, 100)
int2 = Integer(0, 50)
problem.types[:] = [int1, int2]
The above code can be summarized as follows.
def main():
#2 variables 2 problem of purpose
problem = Problem(2, 2)
#Set minimize or maximize
problem.directions[:] = Problem.MINIMIZE
#Set the range of decision variables
int1 = Integer(0, 100)
int2 = Integer(0, 50)
problem.types[:] = [int1, int2]
problem.function = objective
#Set the algorithm,Search execution
algorithm = NSGAII(problem, population_size=50)
algorithm.run(1000)
The following results were obtained. It is not a smooth curve like DTLZ2 (), but I was able to obtain a Pareto optimal solution.
By the way, you can add the information of Pareto optimal solution to DataFrame by adding the following code.
df = pd.DataFrame(columns=("x1", "x2", "f1", "f2"))
for i in range(len(nondominated_solutions)):
df.loc[i, "x1"] = int1.decode(nondominated_solutions[i].variables[0])
df.loc[i, "x2"] = int2.decode(nondominated_solutions[i].variables[1])
df.loc[i, "f1"] = nondominated_solutions[i].objectives[0]
df.loc[i, "f2"] = nondominated_solutions[i].objectives[1]
df.to_csv("NSGAII.csv")
Platypus - Multiobjective Optimization in Python
Recommended Posts