Python 模拟退火算法(SA)求解多目标高次函数的帕累托前沿

系列文章目录

 


 

文章目录

目录

系列文章目录

文章目录

前言

一、模型的建立

二、算法的步骤

三、代码的实现

四、运行的结果

总结


 

 


前言

        我前面的博客用NSGA-II算法求解了多目标高次函数的帕累托前沿,本文打算用模拟退火算法求解同样的问题。

        相关论文提到,模拟退火算法是一种全局优化算法,用于在大规模解空间中寻找极值。相较于其他常见的优化算法,模拟退火算法具有较好的全局发现能力,并且可以逃离局部最优解。

        这是因为模拟退火算法具有一定的随机性和概率性,在搜索过程中可能会以一定概率接受劣解,从而避免陷入局部最优解。而遗传算法通常采用选择、交叉、变异等操作来进化个体,并不能保证每一次进化都是优化的,有可能会导致个体陷入局部最优解而不能再继续前进。另外,模拟退火算法可以通过不断减小温度来控制搜索的范围,并逐渐靠近全局最优解,因此也能够避免过早地收敛于局部最优解。

        总之,模拟退火算法相比遗传算法更加灵活和鲁棒,具有一定的随机性和概率性,从而能够避免陷入局部最优解,取得更优的最优解。因此我们在研究求解多目标规划问题的时候,不得不了解一下模拟退火算法。       


 

一、模型的建立

        研究的模型为:min(y1=eq?x%5E%7B2%7D,xeq?%5Cin[0,10]), min(y2=eq?%282-x%29%5E%7B2%7D,xeq?%5Cin[0,10])。 即求解两个目标函数最小值的问题。

二、算法的步骤

        2.1 首先设置了一些参数,例如自变量取值范围、目标函数个数、初始温度、最小温度、降温速率、每个温度下的迭代次数等。然后定义了一个自变量的类,其中包含了计算目标函数值的方法。

        2.2 定义了一个Individual类,用于表示种群中的每个个体。在这个类中,我们用self.x来表示该个体的自变量,用self.objs来表示该个体对应的目标函数值。

        2.3 在接下来的simulated_annealing函数中,首先初始化种群。我们通过随机数生成初始个体,并将这些个体放入pop列表中。

        2.4 在每个温度下进行迭代。每次迭代中,我们对pop列表中的每个个体进行处理,产生一个新的个体,并计算其对应的目标函数值。然后,根据一定的概率,我们要么接受新的个体,要么保留原有的个体。如果接受新的个体,则从pop列表中删除当前个体,并加入新的个体;同时,若新的个体比当前的全局最优解更好,我们还需要更新best_pop列表。相反,如果保留原有的个体,则不进行任何操作。

        2.5 我们进入下一个温度。为了降低温度,我们将当前的温度乘以alpha,其中alpha为降温速率。

        2.6 当温度降至最小值T_min时,模拟退火算法结束。我们输出所有的不可支配解(即帕累托前沿)到控制台,并在坐标系上以红色点的形式标出这些解。

        2.7 最后,我们通过散点图将所有不可支配解在坐标系中进行可视化展示。其中灰色点表示所有的解,红色点表示帕累托前沿的解。(但是模拟退火算法求出的帕累托解往往只有几个或者一个,很难形成遗传算法那种优美的帕累托前沿曲线)。

三、代码的实现

        代码如下:

import math
import random
import copy
import matplotlib.pyplot as plt

#设置参数
x_range = (-10, 10) #自变量取值范围
num_obj = 2 #目标函数个数
T_init = 50 #初始温度
T_min = 1e-6 #最小温度
alpha = 0.99 #降温速率
L = 100 #每个温度下的迭代次数

#定义自变量的类
class Individual:
    def __init__(self, x):
        self.x = x
        self.objs = [None] * num_obj

    #计算目标函数的值
    def evaluate(self):
        self.objs[0] = self.x * self.x
        # self.objs[0] = (5 - self.x) ** 2
        self.objs[1] = (2 - self.x) ** 2

#模拟退火
def simulated_annealing():
    global T_init, T_min, alpha, L, x_range, num_obj

    #初始化种群
    init_x = random.uniform(*x_range)
    pop = [Individual(init_x) for _ in range(L)]

    #计算目标函数初始值
    for ind in pop:
        ind.evaluate()

    #记录全局最优解
    best_pop = copy.deepcopy(pop)

    #开始模拟退火
    T = T_init
    while T > T_min:
        for i in range(L):
            #生成新解
            new_x = pop[i].x + random.uniform(-1, 1) * (x_range[1] - x_range[0])
            new_x = max(x_range[0], min(x_range[1], new_x))
            new_ind = Individual(new_x)
            new_ind.evaluate()

            #接受新解
            if new_ind.objs[0] < pop[i].objs[0] or (new_ind.objs[0] == pop[i].objs[0] and new_ind.objs[1] < pop[i].objs[1]):
                pop[i] = copy.deepcopy(new_ind)
                #更新全局最优解
                if new_ind.objs[0] < best_pop[0].objs[0] or (new_ind.objs[0] == best_pop[0].objs[0] and new_ind.objs[1] < best_pop[0].objs[1]):
                    best_pop = [copy.deepcopy(new_ind)]

            #接受差解
            else:
                delta_e = abs(new_ind.objs[0] - pop[i].objs[0]) + abs(new_ind.objs[1] - pop[i].objs[1])
                p_accept = math.exp(-delta_e / T)
                if random.random() < p_accept:
                    pop[i] = copy.deepcopy(new_ind)

        #降温
        T *= alpha

    #输出最优解集合
    pareto_front = set()
    for ind in best_pop:
        pareto_front.add(ind)

    print("Pareto front:")
    for ind in pareto_front:
        print(f"x={ind.x:.4f}, y1={ind.objs[0]:.4f}, y2={ind.objs[1]:.4f}")

    #可视化
    plt.scatter([ind.objs[0] for ind in best_pop], [ind.objs[1] for ind in best_pop], c='gray', alpha=0.5)
    plt.scatter([ind.objs[0] for ind in pareto_front], [ind.objs[1] for ind in pareto_front], c='r')
    plt.xlabel('Objective 1')
    plt.ylabel('Objective 2')
    plt.show()

if __name__ == "__main__":
    print("加入我的qq群,大家一起讨论管理、规划类问题的算法\n群里我会不定期上传一些我自己和其他大神的算法源码\n群号为:808756207")
    #运行模拟退火算法
    simulated_annealing()

 

四、运行的结果

        结果未传。

 


 

总结

        模拟退火算法在通常情况的运行速度都比遗传算法快,在调整好初始温度、最小温度、降温速率等参数的情况下,较之遗传算法也比较容易跳出局部最优解,面向全局搜索我们想要的答案。

 

你可能感兴趣的:(Python,数据分析,项目管理算法,python,模拟退火算法,机器学习,numpy,算法)