系列文章目录



文章目录


目录

系列文章目录

文章目录

前言

一、模型的建立

二、算法的步骤

三、代码的实现

四、运行的结果

总结



前言

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

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

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

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


一、模型的建立

        研究的模型为:min(y1=python 多目标跟踪评价 gts ts文件怎样做 python多目标优化算法_python,xpython 多目标跟踪评价 gts ts文件怎样做 python多目标优化算法_模拟退火算法_02[0,10]), min(y2=python 多目标跟踪评价 gts ts文件怎样做 python多目标优化算法_python_03,xpython 多目标跟踪评价 gts ts文件怎样做 python多目标优化算法_模拟退火算法_02[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

'''
求 使得y=x^2和y=(2-x)^2的y值最小的x值
'''

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

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

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


pop = [Individual(random.uniform(*x_range)) for _ in range(L)]
pop_original=copy.deepcopy(pop) # 深拷贝一份儿原始数据
# 模拟退火
def simulated_annealing():
    global T_init, T_min, alpha, L, x_range, num_obj

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

    # 开始模拟退火
    T = T_init
    while T > T_min:
        fitness=0
        for i in range(L):
            fitness+=1/(pop[i].objs[0]+pop[i].objs[1])
            # 生成新解
            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] and new_ind.objs[1] < pop[i].objs[1]:
                pop[i] = 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)
        fitness_all.append(fitness)

        # 降温
        T *= alpha


if __name__ == "__main__":
    # 运行模拟退火算法
    simulated_annealing()
    for ind in pop:
        print(f"x={ind.x:.4f}, y1={ind.objs[0]:.4f}, y2={ind.objs[1]:.4f}")
    # 可视化
    plt.scatter([ind.objs[0] for ind in pop_original], [ind.objs[1] for ind in pop_original], c='gray',alpha=0.5)
    plt.scatter([ind.objs[0] for ind in pop], [ind.objs[1] for ind in pop], c='red', alpha=1)
    plt.xlabel('Objective 1')
    plt.ylabel('Objective 2')
    plt.show()
    plt.plot(fitness_all, c='green',alpha=0.5)
    plt.show()

四、运行的结果

        

python 多目标跟踪评价 gts ts文件怎样做 python多目标优化算法_python_05

python 多目标跟踪评价 gts ts文件怎样做 python多目标优化算法_numpy_06


总结

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