本文已参与「新人创作礼」活动,一起开启掘金创作之路
分支定界法
首先说明,分支定界法运用较多的是在求解整数规划的问题中。而使用分支界定法在求解最短路径中并没有相关的论文或书籍,笔者是探索性的应用。首先介绍一下分支定界法吧,首先给定算法的一个解,然后根据求得的结果继续修改解,并进行分支操作,对已有的分支进行剪枝(即判断哪些路径不合题意),重新确定上下界,然后对其重复之前的操作,直到上界等于下界,在数学的角度来看就是两边夹法则最后收敛于一个值。 这里笔者用自己的话概述了分支定界的法的概念,下面给出网址,读者也可以自己再取了解一下分支定界法
分支定界法之所以没能应用到NP问题中,因为没有一个确定的应用形式,即没有确定的实现方法。笔者这几天
经过思考,将分支定界的思想与NP问题中tsp问题进行了结合,发现对能够求得相对更好的解,现在分享给大
家。
题目与解题思路
==题目==:给定31个城市的坐标,求一回路使得经过的距离最小。
经过尝试,给定的初始解会影响优化所得的解。所以,笔者使用改进过且基于tsp问题的遗传算法求出一个较好的解,然后利用分支定界的思想算法对已有解进行优化,这也可以进一步证明遗传算法收敛得到的是局部最优解。下面是分支定界算法对路径的优化流程图:
结果、分析与代码
这是分支定界使用后的路径:
使用分支界定后的结果比局部最优解减少了200+,这是经典优化算法所做不到的。当然我们可以改变初始解,进而优化最终得到的解。200+路程的优化是很客观的,比如多次运输所产生的油费时间等等资源的使用,这样的做法意义很大!
==大家想要源码和数据源的可以私信我==
% 分支定界法求最短路
% 使用智能算法求出一个可行较优解
clear
clc
% 数据输入
position = [1304 2312;3639 1315;4177 2244;3712 1399;3488 1535;3326 1556;
3238 1229;4196 1004;4312 790;4386 570;3007 1970;2562 1756;
2788 1491;2381 1676;2648 1328;3715 1678;3918 2179;4061 2370;
3780 2212;3676 2578;4029 2838;4263 2931;3429 1908;3507 2367;
3394 2643;3439 3201;2935 3240;3140 3550;2545 2357;2778 2826;2370 2975];
[m,n] = size(position);
D = zeros(m);
for i = 1:m
for j = 1:m
if i == j
D(i,j) = 0;
else
D(i,j) = sqrt((position(i,1)-position(j,1))^2+(position(i,2)-position(j,2))^2);
end
end
end
global gen;
global maxgen;
maxgen = 1000;
[record,track] = delimit(position,D);
[~,index] = min(record);
drawpath(track(index,:),position);
hold on
xlabel('x轴')
ylabel('y轴')
title('最短路径')
outputpath(track(index,:))
figure
hold on
plot(1:maxgen,record);
xlabel('迭代次数');
ylabel('距离');
title('优化过程');
disp(['第一个解的距离为:',num2str(pathlength2(D,track(index,:)))]);
load('bestChrom.mat')
% 分支界定法求最优解
solution1 = track(index,:);
solution2 = track(index,:);
temp = solution2;
len = length(solution1);
for i = len:-1:2
flag = 1;
while flag == 1
for j = 2:i-1
thing = solution2;
thing = insert2(i,j,thing);
if pathlength(D,thing) < pathlength(D,temp)
temp = thing;
end
end
if temp == solution2;
flag = 0;
end
solution2 = temp;
end
end
temp = solution2;
len = length(solution1);
for i = len:-1:2
flag = 1;
while flag == 1
for j = 2:i-1
thing = solution2;
thing = insert2(i,j,thing);
if pathlength(D,thing) < pathlength(D,temp)
temp = thing;
end
end
if temp == solution2;
flag = 0;
end
solution2 = temp;
end
end
drawpath(solution2,position);
disp('经分支界定法求得的最短路径为:')
outputpath(solution2);
disp(['解的距离为:',num2str(pathlength2(D,solution2))]);