【数模】选址问题 7个居民点中建设银行(多目标,NP-Hard)

选址问题

现准备在7个居民点中设置一银行,路线与距离如下图,问设在哪个点,可使最大服务距离最小?若设两个点呢?

在这里插入图片描述

在matlab中把图给画出来
s = [1 2 2 3 3 3 4 5 6];
t = [2 3 6 4 6 7 7 6 7];
weights = [3 2 1.5 6 2.5 4 3 1.5 1.8];
G = graph(s,t,weights);
plot(G,'EdgeLabel',G.Edges.Weight,"EdgeLabelColor",'r')

在这里插入图片描述

算出每个点到其他点的最小加权距离

总共有7个节点,算出每个点到其他点最短加权路径之和,最终得到一个对称的矩阵,其中每个点表示i到j的距离。

% 总共有7个节点
% 算出每个点到其他点最短加权路径之和
% 最终得到一个对称的矩阵,其中每个点表示i到j的距离
D=zeros(7,7);
for i=1:7
    for j=1:7
        [ ~,D(i,j)] = shortestpath(G,i,j);
    end
end

在这里插入图片描述

计算每个点作为银行建设点的最大服务距离
% 看看哪个覆盖范围最大
[m,index]=min(max(D'))

在这里插入图片描述

最后结果是6号点,最大服务距离为4.8

第二问

第二问要求建两个银行,主要思想就是,把所有建银行的可能情况都列出来,然后计算,每个点到这两个银行距离的最小值作为该点到银行的距离,之后把这些距离的最大值作为该店建银行的最大服务距离,最后找到这些最大服务距离的最小值即可得到结果。

列出所有的选两个点的情况
% 第二问
% 列出所有的选两个点的情况
tp=zeros(21,11);
tt=1;
for i=1:7
    for j=i+1:7
        tp(tt,1)=i;
        tp(tt,2)=j;
        tt=tt+1;
    end
end
点1点2
12
13
14
15
16
17
23
24
25
26
27
34
35
36
37
45
46
47
56
57
67
D2=zeros(7,1);
for i=1:length(tp)
    for j=1:7
        [ ~,temp1] = shortestpath(G,j,tp(i,1));
        [ ~,temp2] = shortestpath(G,j,tp(i,2));
        tp(i,j+2) = min([temp1 temp2]);
    end
end
tp(:,10) = sum(tp(:,3:9),2);
tp(:,11) = max(tp(:,3:9),[],2);
% [m,index]=min(tp(:,11))
% 因为会有多个最小的,故用find函数找
res=tp(find(tp(:,11)==min(tp(:,11))),1:2)

在这里插入图片描述

最终结果是在2、4或者2、7建银行。

变题

这个题目是让我们求设在哪个点,可使最大服务距离最小,其实,如果把问题改成设在哪个点,可使其他点离银行的总距离最小

思路

思路其实很简单,就是在之前的基础上,把每个点到银行的距离加起来,然后找到建银行距离总和最小的点。

变题第一问
最后看看哪个点的路径之和最小
[m,index]=min(sum(D))

在这里插入图片描述

最后结果也是6号点,距离其他点的总距离是16.6

变题第二问
D2=zeros(7,1);
for i=1:length(tp)
    for j=1:7
        [ ~,temp1] = shortestpath(G,j,tp(i,1));
        [ ~,temp2] = shortestpath(G,j,tp(i,2));
        tp(i,j+2) = min([temp1 temp2]);
    end
end
tp(:,10) = sum(tp(:,3:9),2);
tp(:,11) = max(tp(:,3:9),[],2);
% [m,index]=min(tp(:,11))
% 因为会有多个最小的,故用find函数找
res=tp(find(tp(:,11)==min(tp(:,11))),1:2)
res2=tp(find(tp(:,10)==min(tp(:,10))),1:2)

在这里插入图片描述

最后结果是在4、6建银行会让总距离最小。

结语

由此可见,让最大服务距离最小的时候不一定总距离会最小。

下表是问题2的总结果

第一个点第二个点点1距银行的距离点2距银行的距离点3距银行的距离点4距银行的距离点5距银行的距离点6距银行的距离点7距银行的距离距离之和最大距离
120026.331.53.316.16.3
13020642.5418.56
14035064.5321.56
150346.301.53.318.16.3
1601.52.54.81.501.812.14.8
1703433.31.8015.14
23300631.53.316.86
24302031.5312.53
253026.301.53.316.16.3
263024.81.501.813.14.8
27302331.5012.53
34520042.5316.55
35520601.53.317.86
364.51.504.81.501.814.14.8
3752033.31.8015.15
45634001.5317.56
464.51.52.501.501.811.84.5
476.33.3403.31.8018.76.3
564.51.52.54.8001.815.14.8
57634301.5017.56
674.51.52.531.500134.5
  • 16
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是多目标选址问题NSGA2的MATLAB主函数示例代码: 假设我们要解决一个多目标选址问题目标是最小化三个目标函数:1)设施建设成本,2)服务范围内的客户数量,和3)服务范围内的设施数量。 我们的问题是在一个二维平面上选择最佳位置来建设设施,每个位置都有一个成本、一个客户数量和一个设施数量。我们可以使用以下函数来生成初始种群: ```matlab function pop = generate_population(popsize, nvar, lbound, ubound) % 生成初始种群 pop = lbound + rand(popsize, nvar).*(ubound-lbound); end ``` 接下来,我们定义一个包含三个目标函数的评估函数: ```matlab function [f1, f2, f3] = evaluate(x) % 评估函数 % x - 种群矩阵,每一行代表一个个体,每一列代表一维变量 % f1 - 第一个目标函数的值 % f2 - 第二个目标函数的值 % f3 - 第三个目标函数的值 % 计算第一个目标函数的值(总成本) f1 = sum(x(:,1)); % 计算第二个目标函数的值(服务范围内的客户数量) f2 = 0; for i = 1:size(x,1) count = 0; for j = 1:size(x,1) if norm(x(i,:)-x(j,:)) <= 5 % 服务范围为5 count = count + x(j,2); end end f2 = f2 + count; end % 计算第三个目标函数的值(服务范围内的设施数量) f3 = 0; for i = 1:size(x,1) count = 0; for j = 1:size(x,1) if norm(x(i,:)-x(j,:)) <= 5 % 服务范围为5 count = count + x(j,3); end end f3 = f3 + count; end end ``` 然后,我们定义一个将二维坐标向量和设施数量向量转换为种群矩阵的函数: ```matlab function pop = vector_to_population(vector, nvar) % 将二维坐标向量和设施数量向量转换为种群矩阵 pop = []; for i = 1:length(vector) pop(i,:) = [vector(i,1), vector(i,2), vector(i,3)]; end pop = unique(pop, 'rows'); % 去重 pop = pop(1:min(size(pop,1),nvar),:); % 限制种群大小 end ``` 接下来,我们可以使用以下代码来运行NSGA2算法: ```matlab % 参数设置 popsize = 50; % 种群大小 ngen = 100; % 运行的迭代次数 nvar = 3; % 变量的数量 nobj = 3; % 目标函数的数量 lbound = [0, 0, 0]; % 变量的下界 ubound = [100, 100, 100]; % 变量的上界 pcross = 0.8; % 交叉概率 pmut = 0.1; % 变异概率 eta_c = 10; % 交叉分布索引 eta_m = 10; % 变异分布索引 % 生成初始种群 pop = generate_population(popsize, nvar, lbound, ubound); for i = 1:ngen % 评估种群适应度 f = zeros(size(pop,1), nobj); for j = 1:size(pop,1) [f(j,1), f(j,2), f(j,3)] = evaluate(pop(j,:)); end % 运行NSGA-II算法 [pop, front] = nsga2(pop, nobj, nvar, 0, 1, popsize, pcross, pmut, eta_c, eta_m, lbound, ubound); % 输出当前迭代的最优解 fprintf('Iteration: %d\n', i); fprintf('Best solution: %.2f, %.2f, %.2f\n', front(1,1), front(1,2), front(1,3)); end % 将最终的种群转换为二维坐标向量和设施数量向量 result = []; for i = 1:size(front,1) result = [result; front(i,:)]; end result = unique(result, 'rows'); % 去重 result = result(1:min(size(result,1),nvar),:); % 限制种群大小 % 输出最终的解 fprintf('Final solution: %.2f, %.2f, %.2f\n', result(1,1), result(1,2), result(1,3)); ``` 在此示例,我们使用了一个简单的二维选址问题来演示NSGA2算法的实现过程。您可以根据自己的问题需求更改评估函数、初始种群生成函数和参数设置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值