分支定界法--NP(tsp)问题中的应用

分支界定法--NP问题中的应用

分支定界法

首先说明,分支定界法运用较多的是在求解整数规划的问题中。而使用分支界定法在求解最短路径中并没有相关的论文或书籍,笔者是探索性的应用。首先介绍一下分支定界法吧,首先给定算法的一个解,然后根据求得的结果继续修改解,并进行分支操作,对已有的分支进行剪枝(即判断哪些路径不合题意),重新确定上下界,然后对其重复之前的操作,直到上界等于下界,在数学的角度来看就是两边夹法则最后收敛于一个值。
这里笔者用自己的话概述了分支定界的法的概念,下面给出网址,读者也可以自己再取了解一下分支定界法

   分支定界法之所以没能应用到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))]);

猜你喜欢

转载自blog.csdn.net/wlfyok/article/details/108018089