NSGA2遗传算法多目标优化 三维视图 寻优多个函数(函数类型见图二类型),出图为三维红色为帕列托(图一), 带最终结果图(图三)
最近在研究多目标优化问题,发现NSGA2遗传算法是个非常强大的工具,今天就来跟大家分享一下如何用NSGA2遗传算法实现对多个函数的寻优,并绘制出炫酷的三维帕累托图。
NSGA2遗传算法简介
NSGA2(Non - dominated Sorting Genetic Algorithm II)是一种高效的多目标遗传算法。它通过非支配排序和拥挤度计算,能够快速地找到一组帕累托最优解。简单来说,非支配排序就是将种群中的个体按照它们之间的支配关系进行分层,而拥挤度则用于保持种群的多样性,避免算法过早收敛。
寻优多个函数
我们要寻优的函数类型参考图二(这里假设函数形式为$f1(x,y,z)$,$f2(x,y,z)$,$f_3(x,y,z)$,具体函数形式需根据实际图二确定)。在Python中,我们可以这样定义函数(示例函数,仅为演示结构):
import numpy as np def f1(x, y, z): return x ** 2 + y ** 2 + z ** 2 def f2(x, y, z): return np.sin(x) + np.cos(y) + np.tan(z) def f3(x, y, z): return np.exp(-x) + np.exp(-y) + np.exp(-z)NSGA2算法实现
这里我们借助pymoo库来实现NSGA2算法,pymoo库提供了丰富的多目标优化算法实现,使用起来非常方便。
from pymoo.algorithms.moo.nsga2 import NSGA2 from pymoo.factory import get_problem from pymoo.optimize import minimize from pymoo.util.plotting import plot class MyProblem(get_problem("Elementwise")): def __init__(self): super().__init__(n_var=3, n_obj=3, n_constr=0, xl=-5, xu=5) def _evaluate(self, x, out, *args, **kwargs): out["F"] = np.column_stack([f1(x[:, 0], x[:, 1], x[:, 2]), f2(x[:, 0], x[:, 1], x[:, 2]), f3(x[:, 0], x[:, 1], x[:, 2])]) algorithm = NSGA2(pop_size=100) problem = MyProblem() res = minimize(problem, algorithm, ('n_gen', 200), seed=1, save_history=True, verbose=True)在上述代码中,我们首先定义了一个自定义问题MyProblem,它继承自pymoo库的Elementwise问题类。在_evaluate方法中,我们计算每个个体对应的多个目标函数值。然后,我们选择NSGA2算法,并设置种群大小为100,进化代数为200,对问题进行求解。
绘制三维帕累托图
得到最优解后,我们就可以绘制三维帕累托图了。同样使用pymoo库的绘图功能:
import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D fig = plt.figure() ax = fig.add_subplot(111, projection='3d') F = res.F ax.scatter(F[:, 0], F[:, 1], F[:, 2], c='r') ax.set_xlabel('Objective 1') ax.set_ylabel('Objective 2') ax.set_zlabel('Objective 3') plt.show()上述代码创建了一个三维坐标轴,并将NSGA2算法得到的帕累托最优解以红色散点的形式绘制在三维空间中。这样我们就得到了图一所示的三维红色帕累托图。
最终结果图(图三)
最终结果图(图三)通常会展示算法在进化过程中的一些关键指标,比如每一代的最优解分布情况,或者收敛情况等。我们可以通过保存每一代的最优解,并绘制相关曲线来展示。
history = res.history gen = [] obj1_best = [] obj2_best = [] obj3_best = [] for algo in history: gen.append(algo.n_gen) F = algo.pop.get("F") best_index = np.argmin(F[:, 0]) obj1_best.append(F[best_index, 0]) obj2_best.append(F[best_index, 1]) obj3_best.append(F[best_index, 2]) fig, axs = plt.subplots(3, 1, figsize=(8, 10)) axs[0].plot(gen, obj1_best) axs[0].set_ylabel('Best Obj1') axs[1].plot(gen, obj2_best) axs[1].set_ylabel('Best Obj2') axs[2].plot(gen, obj3_best) axs[2].set_ylabel('Best Obj3') axs[2].set_xlabel('Generation') plt.show()这段代码遍历算法进化历史,记录每一代的最优目标函数值,并绘制出三个目标函数最优值随代数变化的曲线,这就可以作为最终结果图(图三),直观地展示算法的收敛过程。
通过以上步骤,我们就利用NSGA2遗传算法完成了多目标优化,并绘制出了三维帕累托图和最终结果图,希望对大家在多目标优化问题的研究上有所帮助!
以上代码和分析基于示例假设,实际应用中需根据图二真实函数形式进行调整。