模拟退火+Gurobi 解决 旅行家问题TSP

本文探讨了使用模拟退火算法解决旅行商问题(TSP),并通过与Gurobi求解器的对比展示了解决方案的有效性和效率。

模拟退火算法,顾名思义,模拟晶体退火过程。晶体在加热后固体化为液态,内部原子运动加剧,会离开原有位置向四周扩散。此时慢慢进行退火冷却使其重新固化,粒子往往会停留在比原先能量低得多的位置上,本质上也是通过随机性跳出局部最优。

本文尝试用模拟退火算法对TSP问题(travelling salesman problem)进行求解,并与Gurobi求解器进行对比。

Ω


TSP:旅行推销员问题


旅行推销员是一个非常经典的NP-Hard问题,即在多项式时间内也无法验证解的正确性。问题大意非常简单,就是有个城市,两两之间距离已知,有个salesman从某个城市出发希望能够游历其他每座城市一遍,同时最后回到出发城市,重度强迫症患者的他希望设计出一条满足上述要求的最短路线。

如果你是他的朋友,你会如何劝退他,请写一篇不少于200词的感化信。(100)

✦ 初始化城市坐标和距离矩阵

可以通过随机生成或者加载之前生成的坐标来初始化

import numpy as np
import random as rd

# 随机生成城市坐标
loc = np.zeros([100, 2])
for i in range(len(loc)):
    loc[i] = (rd.random() * 100, rd.random() * 100)
np.save("loc.npy", loc) # 保存生成坐标

# 导入之前城市坐标
# loc=np.load("loc.npy")

num = len(loc)
# 多一列方便处理回到原城市的约束
dist = np.zeros([num, num + 1])

# 计算距离矩阵
for i in range(num):
    for j in range(i + 1, num):
        dist[i, j] = dist[j, i] = np.linalg.norm(loc[i] - loc[j])
dist[:, num] = dist[:, 0]
✦ 贪心求初始解

TSP问题的解基本不需要编码,包含所有城市一个全排列的列表就可以作为可行解的编码。我这里规定了0号作为起点和终点。

用贪心算法构造初始解,即从起点城市开始每次选择离当前城市最近的且还未访问过的城市作为下一个目的地。在城市数较少时贪心结果几乎就是最优解,城市数大了就嘻嘻。

# 贪心求初始解
path=[0]
isVisited=[False]*num
isVisited[0]=True
crt=0
sum_d=0
for i in range(num):
    idx=np.argsort(dist[crt])
    for j in idx:
        if j!=num and not isVisited[j] and j!=crt:
            path.append(j)
            sum_d+=dist[crt,j]
            isVisited[j]=True
            crt=j
            break
path.append(0)
sum_d
好的,关于Gurobi和MATLAB的使用教程,我可以为您提供一些基本的指导。 首先,您需要安装MATLAB和Gurobi软件。Gurobi提供了一个免费的学术许可证,可以在其官方网站上申请。安装好Gurobi后,您需要将其与MATLAB连接起来。您可以通过在MATLAB命令窗口中输入以下命令来测试是否成功连接: ``` gurobi_test() ``` 如果您看到一些关于Gurobi的信息,那么就说明连接成功了。 接下来,您可以使用YALMIP来建模和求解TSP问题。YALMIP是一个MATLAB工具箱,可以帮助您轻松地建模各种优化问题。以下是一个使用YALMIP和Gurobi求解TSP问题的示例代码: ```matlab % 生成TSP问题的数据 n = 5; % 城市数量 x = randn(n,1); y = randn(n,1); % 定义变量 u = sdpvar(n,1); v = binvar(n,n); % 定义目标函数 obj = sum(sum(v.*repmat(sqrt((x-x').^2+(y-y').^2),1,1))); % 添加约束条件 con = [sum(v,2)==1, sum(v,1)==1, u(1)==1, 2<=u<=n+1]; for i = 2:n con = [con, 2 <= u(i) <= n+1, u(i) <= u(find(v(i,:))) + (n-2)*(1-v(i,:)))]; end % 求解问题 ops = sdpsettings('solver','gurobi'); sol = optimize(con,obj,ops); % 输出结果 if sol.problem == 0 disp('Optimal solution found'); disp(value(obj)); else disp('Error'); end ``` 上述代码中,我们首先生成了一个包含5个城市的TSP问题的数据,然后定义了变量和目标函数。接下来,我们添加了约束条件来确保每个城市只能被访问一次,并且每个城市都必须在一条路径中出现。最后,我们使用Gurobi求解了该问题,并输出了最优解。 希望这个简单的示例可以帮助您入门Gurobi和MATLAB的使用。如果您需要更多的帮助,请随时联系我。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值