目录
- 一、采用DE求解 TSP
 - 二、 旅行商问题
 - 2.1 实际例子:求解 6 个城市的 TSP
 - 2.2 ==**求解该问题的代码**==
 - 2.3 代码运行过程截屏
 - 2.4 代码运行结果截屏(后续和其他算法进行对比)
 
- 三、 ==如何修改代码?==
 - 3.1 减少城市坐标,如下:
 - 3.2 增加城市坐标,如下:
 
- 四、 差分进化算法 (Differential Evolution, DE) 原理
 - 4.1 DE算法定义
 - 4.2 DE的基本思想
 - 4.3 DE的工作原理
 - 4.4 DE的参数
 - 4.5 DE的优缺点
 - 4.5.1 优点
 - 4.5.2 缺点
 
- 4.6 DE的应用场景
 
一、采用DE求解 TSP
求解代码在文中,后续会出其他算法求解TSP问题,你们参加数学建模竞赛只需要会改代码即可。
用来对比此专栏的
遗传算法(GA算法)求解实例—旅行商问题 (TSP)
粒子群算法(PSO算法)求解实例—旅行商问题 (TSP)
模拟退火算法(SA算法)求解实例—旅行商问题 (TSP)
蚁群算法(ACO算法)求解实例—旅行商问题 (TSP)
禁忌搜索算法(TS算法)求解实例—旅行商问题 (TSP)
注意每次运行算法得到的结果可能不太一样。
我知道大家对原理性的东西不感兴趣,我把原理性的东西放在后面,大家如果需要写数模论文可以拿去,但是记得需要改一改,要不然查重过不去。
二、 旅行商问题
2.1 实际例子:求解 6 个城市的 TSP
假设有 6 个城市,其坐标如下:
| 城市 | X 坐标 | Y 坐标 | 
|---|---|---|
| 0 | 10 | 20 | 
| 1 | 30 | 40 | 
| 2 | 20 | 10 | 
| 3 | 40 | 30 | 
| 4 | 10 | 10 | 
| 5 | 50 | 20 | 
目标是找到一个经过所有城市且总距离最短的路径。
2.2 求解该问题的代码
import numpy as np
import random
# 定义城市坐标
cities = np.array([
    [10, 20],
    [30, 40],
    [20, 10],
    [40, 30],
    [10, 10],
    [50, 20]
])
# 计算两城市之间的欧几里得距离
def calculate_distance(city1, city2):
    return np.sqrt(np.sum((city1 - city2) ** 2))
# 计算总旅行距离
def total_distance(path):
    distance = 0
    for i in range(len(path) - 1):
        distance += calculate_distance(cities[path[i]], cities[path[i + 1]])
    distance += calculate_distance(cities[path[-1]], cities[path[0]])  # 回到起点
    return distance
# 差分变异操作
def differential_mutation(population, F=0.8):
    size = len(population)
    mutant_population = []
    for i in range(size):
        # 随机选择三个不同的个体
        indices = list(range(size))
        indices.remove(i)
        a, b, c = random.sample(indices, 3)
        # 获取个体的路径
        path_a, path_b, path_c = population[a], population[b], population[c]
        # 生成变异向量 (通过交换生成一个新路径)
        mutant_path = path_a.copy()
        for j in range(len(mutant_path)):
            if random.random() < F:
                # 确保新路径中不出现重复的城市
                if path_b[j] not in mutant_path:
                    mutant_path[j] = path_b[j]
                elif path_c[j] not in mutant_path:
                    mutant_path[j] = path_c[j]
        mutant_population.append(mutant_path)
    return mutant_population
# 差分进化算法主函数
def differential_evolution(cities, pop_size=20, max_iter=500, F=0.8, CR=0.7):
    num_cities = len(cities)
    # 初始化种群(每个个体是一个随机的城市排列)
    population = [list(np.random.permutation(num_cities)) for _ in range(pop_size)]
    # 初始化最优解
    best_solution = population[0]
    best_distance = total_distance(best_solution)
    for iteration in range(max_iter):
        # 差分变异
        mutant_population = differential_mutation(population, F)
        # 交叉与选择
        for i in range(pop_size):
            trial_path = population[i].copy()
            for j in range(num_cities):
                if random.random() < CR:
                    # 采用变异路径的值
                    trial_path[j] = mutant_population[i][j]
            # 修正路径,确保所有城市均被唯一访问
            missing_cities = list(set(range(num_cities)) - set(trial_path))
            for j in range(num_cities):
                if trial_path.count(trial_path[j]) > 1:  # 如果有重复的城市
                    trial_path[j] = missing_cities.pop()  # 替换为缺失的城市
            # 计算试验路径的总距离
            trial_distance = total_distance(trial_path)
            # 选择操作
            if trial_distance < total_distance(population[i]):
                population[i] = trial_path
            # 更新全局最优解
            if trial_distance < best_distance:
                best_solution = trial_path
                best_distance = trial_distance
        print(f"Iteration {iteration + 1}: Best distance = {best_distance:.2f}")
    return best_solution, best_distance
# 运行差分进化算法
best_path, best_distance = differential_evolution(cities)
print("Best path:", best_path)
print("Best distance:", best_distance)
 
2.3 代码运行过程截屏

2.4 代码运行结果截屏(后续和其他算法进行对比)

三、 如何修改代码?
这一部分是重中之重,大家参加数学建模肯定是想跑出自己的结果,所以大家只需要把自己遇到的数学问题,抽象成TSP问题,然后修改代码的城市坐标,然后运行即可。
# 定义城市坐标
cities = np.array([
    [10, 20],
    [30, 40],
    [20, 10],
    [40, 30],
    [10, 10],
    [50, 20]
])
 
3.1 减少城市坐标,如下:
# 定义城市坐标
cities = np.array([
    [10, 20],
    [30, 40],
    [20, 10],
    [40, 30]
])
 
3.2 增加城市坐标,如下:
# 定义城市坐标
cities = np.array([
    [10, 20],
    [30, 40],
    [20, 10],
    [40, 30],
    [30, 40],
    [20, 10],
    [10, 10],
    [50, 20]
])
 
四、 差分进化算法 (Differential Evolution, DE) 原理
4.1 DE算法定义
差分进化算法 (Differential Evolution, DE) 是一种基于种群的全局优化算法,由 Storn 和 Price 在 1995 年提出。DE 主要用于连续优化问题,但也可以通过适当的修改和适配用于离散问题,如旅行商问题 (TSP)。差分进化算法通过对种群中个体的差分变异、交叉和选择操作,不断逼近问题的最优解。DE 因其简单、高效和全局搜索能力强而受到广泛应用。
4.2 DE的基本思想
差分进化算法的核心思想是通过模拟自然界中的进化过程,对种群中的个体进行变异和选择,以迭代地逼近最优解。算法在每一代中,对种群中的每个个体生成一个“变异个体”,并通过交叉操作形成“试验个体”,然后通过选择操作决定是否用试验个体替换当前个体。
4.3 DE的工作原理
-  
初始化种群:
- 随机生成一个包含多个个体(解)的初始种群,通常个体数量为 
pop_size。每个个体表示问题解空间中的一个可能解。 
 - 随机生成一个包含多个个体(解)的初始种群,通常个体数量为 
 -  
变异操作:
- 对于种群中的每个个体 
X_i,生成一个变异个体V_i。变异是通过随机选择三个不同的个体X_a、X_b和X_c,按如下公式进行:
V i = X a + F ⋅ ( X b − X c ) V_i = X_a + F \cdot (X_b - X_c) Vi=Xa+F⋅(Xb−Xc)
其中:F是变异因子,通常取值在[0, 2]之间,用于控制差分向量的缩放,影响变异的幅度。
 
 - 对于种群中的每个个体 
 -  
交叉操作:
- 将当前个体 
X_i与其对应的变异个体V_i进行交叉操作,生成一个“试验个体”U_i。交叉操作采用以下公式:
U i , j = { V i , j , if rand ( 0 , 1 ) < C R or j = j r a n d X i , j , otherwise U_{i,j} = \begin{cases} V_{i,j}, & \text{if } \text{rand}(0, 1) < CR \text{ or } j = j_{rand} \\ X_{i,j}, & \text{otherwise} \end{cases} Ui,j={Vi,j,Xi,j,if rand(0,1)<CR or j=jrandotherwise
其中:CR是交叉概率(交叉率),决定变异个体的分量保留到试验个体中的概率。j_{rand}是一个随机选择的索引,确保至少一个基因来自变异个体V_i。
 
 - 将当前个体 
 -  
选择操作:
- 选择操作用于决定是否用试验个体 
U_i替换当前个体X_i。若U_i的适应度(即目标函数值)优于X_i,则用U_i替换X_i:
X i = { U i , if f ( U i ) ≤ f ( X i ) X i , otherwise X_i = \begin{cases} U_i, & \text{if } f(U_i) \leq f(X_i) \\ X_i, & \text{otherwise} \end{cases} Xi={Ui,Xi,if f(Ui)≤f(Xi)otherwise 
 - 选择操作用于决定是否用试验个体 
 -  
迭代和终止:
- 重复步骤 2-4,直到满足终止条件(如达到最大迭代次数或找到满意解)。
 
 
4.4 DE的参数
- 种群大小 (
pop_size):通常为解空间维度的 5 到 10 倍。较大的种群规模可以提高算法的全局搜索能力,但计算开销也会增加。 - 变异因子 (
F):控制差分变异的幅度。通常取值在[0.5, 1.0]之间。较大的F值可能会导致更大的变异,增强全局搜索能力,但可能降低收敛速度。 - 交叉概率 (
CR):控制交叉操作的概率。通常取值在[0, 1]之间。较高的CR值会使得个体与变异个体有更多基因交换,增加种群多样性。 - 最大迭代次数 (
max_iter):算法运行的最大迭代次数,决定了算法的终止条件。 
4.5 DE的优缺点
4.5.1 优点
- 全局搜索能力强:DE 算法通过差分变异和选择操作,能够有效避免陷入局部最优解,具有较强的全局搜索能力。
 - 参数少且易于设置:DE 算法的参数相对较少,通常只有种群大小、变异因子和交叉概率,易于理解和调整。
 - 简单易实现:DE 算法的结构简单,易于实现和应用于各种优化问题。
 - 适应性强:DE 算法可以处理复杂的非线性、多模态优化问题,适用于连续优化和某些离散优化问题。
 
4.5.2 缺点
- 适用于连续优化问题:DE 算法主要用于连续优化问题,在离散优化问题中需要进行适配和修改。
 - 收敛速度较慢:在某些复杂问题中,DE 算法的收敛速度可能较慢,需要较多的迭代次数。
 - 依赖参数设置:虽然 DE 的参数少,但性能仍然对参数选择较为敏感,需根据具体问题进行调整。
 
4.6 DE的应用场景
- 函数优化:解决复杂数学函数的最小化或最大化问题。
 - 工程优化:如结构设计优化、机器学习模型的参数优化、能源分配优化等。
 - 机器学习:用于优化神经网络的权重、支持向量机的参数选择等。
 - 组合优化问题:经过适当修改,DE 算法可用于求解旅行商问题 (TSP)、路径规划问题等。
 



















