山区医疗点选址与道路维修优化问题

假设某山区中有100个村庄,现在要在村庄中建立几个医疗点,方便村民看病。图1中给出这100个村庄的位置及可选道路连接示意图。附件数据的'位置'表单给出了这100个村庄的坐标(单位:米),附件数据的'连接道路'表单给出了可供选择的道路。现在要在100个村庄中建立3个医疗点,并在可选道路中根据需要进行部分道路维修,假定村民看病都选择维修后的道路。

问题1. 如果各村庄村民到医疗点的距离太远,不便于看病,因此站在村民角度出发,希望各村庄村民到医疗点的距离尽量小。如果要使各村庄村民到医疗点的距离总和S1最小,请问这3个医疗点分别建立在何处最好?总距离S1是多少? 各村庄村民都选择最近的医疗点看病,请问应该维修哪些道路,维修道路总里程S2是多少?作图用不同颜色标记各村庄到对应医疗点使用的道路。

问题2. 由于每条道路维修都需要成本,因此站在道路维修公司角度出发,希望维修的成本尽量低。假定问题1中得到的医疗点不变,应该维修哪些道路,使得维修成本最低。给出维修道路的总长度S2,并做出图形。同时根据维修的道路,计算各村庄到医疗点的总距离S1。

问题3. 实际中,我们既希望村民到医疗点很方便,同时希望维修的道路成本尽量小。因此既希望村庄村民到医疗点的总距离S1尽量小,又希望维修的道路总里程S2尽量小,但二者通常无法同时达到最小。如果让这两种距离和S1+S2最小,应如何设置医疗点。给出总距离,并做出维修道路的图形。比较问题1和问题2,S1+S2减少多少。

图1 100个村庄位置及道路示意图

注:

1.假定村民到医疗点就医按最短路行走。 2.问题2和问题3中假定村庄的村民只沿维修后的道路行走。 3.维修的道路都在可选道路中选择。 4.各村庄的村民所在位置简化为村庄所在位置。 5.医疗点都在100个村庄中选择。

计算结果精确到小数点后1位即可

下面给出数据:

位置:

| 村庄序号 | X坐标(单位:米) | Y坐标(单位:米) | |---|---|---| | 1 | 5500 | 200 | | 2 | 9300 | 300 | | 3 | 7800 | 400 | | 4 | 3100 | 500 | | 5 | 9700 | 600 | | 6 | 6000 | 800 | | 7 | 1200 | 900 | | 8 | 3900 | 900 | | 9 | 5600 | 900 | | 10 | 6800 | 1000 | | 11 | 6350 | 1100 | | 12 | 7500 | 1200 | | 13 | 2000 | 1400 | | 14 | 6100 | 1400 | | 15 | 5000 | 1500 | | 16 | 9900 | 1500 | | 17 | 8200 | 2000 | | 18 | 800 | 1800 | | 19 | 3000 | 1900 | | 20 | 4000 | 1900 | | 21 | 9000 | 1900 | | 22 | 7900 | 1500 | | 23 | 1800 | 2300 | | 24 | 7700 | 2300 | | 25 | 500 | 2400 | | 26 | 4800 | 2400 | | 27 | 10000 | 2400 | | 28 | 8100 | 2600 | | 29 | 1900 | 2700 | | 30 | 3900 | 2700 | | 31 | 6700 | 2500 | | 32 | 6400 | 3100 | | 33 | 8800 | 3200 | | 34 | 5400 | 3400 | | 35 | 800 | 3600 | | 36 | 7500 | 3700 | | 37 | 9300 | 3500 | | 38 | 9500 | 3900 | | 39 | 9900 | 3500 | | 40 | 4000 | 4100 | | 41 | 7300 | 4200 | | 42 | 300 | 4400 | | 43 | 2400 | 4400 | | 44 | 5900 | 4400 | | 45 | 2700 | 4000 | | 46 | 600 | 4800 | | 47 | 3800 | 4600 | | 48 | 1000 | 4800 | | 49 | 6800 | 4900 | | 50 | 9300 | 4900 | | 51 | 700 | 4100 | | 52 | 100 | 5100 | | 53 | 4500 | 5100 | | 54 | 8600 | 5100 | | 55 | 3300 | 5200 | | 56 | 1200 | 5300 | | 57 | 2900 | 5400 | | 58 | 7500 | 5500 | | 59 | 200 | 5600 | | 60 | 6800 | 5800 | | 61 | 9800 | 5400 | | 62 | 4900 | 6000 | | 63 | 9900 | 6100 | | 64 | 2100 | 6300 | | 65 | 4100 | 6300 | | 66 | 4400 | 6500 | | 67 | 9000 | 6500 | | 68 | 9500 | 6400 | | 69 | 9800 | 6800 | | 70 | 6800 | 6900 | | 71 | 1300 | 7200 | | 72 | 5100 | 7200 | | 73 | 2500 | 7300 | | 74 | 1800 | 7500 | | 75 | 4700 | 7500 | | 76 | 5800 | 7800 | | 77 | 300 | 7400 | | 78 | 4900 | 8000 | | 79 | 100 | 8100 | | 80 | 1000 | 7600 | | 81 | 1600 | 8200 | | 82 | 7700 | 8200 | | 83 | 1200 | 8300 | | 84 | 5900 | 8300 | | 85 | 100 | 8600 | | 86 | 9500 | 8100 | | 87 | 9300 | 8700 | | 88 | 5200 | 8900 | | 89 | 1000 | 9000 | | 90 | 2800 | 9100 | | 91 | 4800 | 9100 | | 92 | 700 | 9200 | | 93 | 3400 | 9200 | | 94 | 8200 | 9300 | | 95 | 9100 | 9400 | | 96 | 4800 | 9500 | | 97 | 1900 | 9700 | | 98 | 3000 | 9800 | | 99 | 9800 | 9800 | | 100 | 6200 | 10000 |

连接道路:

| 序号 | 起点 | 终点 | |---|---|---| | 1 | 1 | 6 | | 2 | 1 | 8 | | 3 | 2 | 3 | | 4 | 2 | 5 | | 5 | 3 | 10 | | 6 | 4 | 8 | | 7 | 4 | 13 | | 8 | 5 | 16 | | 9 | 5 | 21 | | 10 | 6 | 9 | | 11 | 6 | 10 | | 12 | 7 | 13 | | 13 | 7 | 18 | | 14 | 8 | 9 | | 15 | 8 | 15 | | 16 | 9 | 11 | | 17 | 10 | 11 | | 18 | 10 | 12 | | 19 | 11 | 12 | | 20 | 11 | 14 | | 21 | 12 | 14 | | 22 | 12 | 22 | | 23 | 13 | 18 | | 24 | 13 | 19 | | 25 | 14 | 15 | | 26 | 14 | 26 | | 27 | 15 | 20 | | 28 | 15 | 26 | | 29 | 16 | 21 | | 30 | 17 | 21 | | 31 | 17 | 22 | | 32 | 18 | 23 | | 33 | 18 | 25 | | 34 | 19 | 20 | | 35 | 19 | 23 | | 36 | 20 | 26 | | 37 | 20 | 30 | | 38 | 21 | 22 | | 39 | 21 | 28 | | 40 | 22 | 24 | | 41 | 22 | 28 | | 42 | 23 | 25 | | 43 | 23 | 29 | | 44 | 24 | 28 | | 45 | 24 | 31 | | 46 | 25 | 29 | | 47 | 25 | 35 | | 48 | 26 | 30 | | 49 | 26 | 32 | | 50 | 27 | 33 | | 51 | 27 | 37 | | 52 | 28 | 31 | | 53 | 28 | 32 | | 54 | 29 | 35 | | 55 | 29 | 43 | | 56 | 30 | 34 | | 57 | 30 | 40 | | 58 | 31 | 32 | | 59 | 32 | 34 | | 60 | 32 | 36 | | 61 | 33 | 36 | | 62 | 33 | 37 | | 63 | 34 | 40 | | 64 | 34 | 44 | | 65 | 35 | 42 | | 66 | 35 | 43 | | 67 | 36 | 41 | | 68 | 36 | 44 | | 69 | 37 | 38 | | 70 | 37 | 39 | | 71 | 38 | 39 | | 72 | 38 | 50 | | 73 | 39 | 50 | | 74 | 40 | 45 | | 75 | 41 | 44 | | 76 | 41 | 49 | | 77 | 42 | 52 | | 78 | 43 | 45 | | 79 | 44 | 49 | | 80 | 44 | 53 | | 81 | 45 | 47 | | 82 | 45 | 55 | | 83 | 46 | 48 | | 84 | 46 | 51 | | 85 | 47 | 53 | | 86 | 47 | 55 | | 87 | 48 | 51 | | 88 | 48 | 52 | | 89 | 49 | 58 | | 90 | 49 | 60 | | 91 | 50 | 54 | | 92 | 50 | 61 | | 93 | 51 | 52 | | 94 | 51 | 56 | | 95 | 52 | 56 | | 96 | 52 | 59 | | 97 | 53 | 55 | | 98 | 54 | 58 | | 99 | 54 | 61 | | 100 | 55 | 57 | | 101 | 55 | 62 | | 102 | 56 | 57 | | 103 | 56 | 59 | | 104 | 57 | 64 | | 105 | 57 | 65 | | 106 | 58 | 60 | | 107 | 58 | 70 | | 108 | 60 | 70 | | 109 | 61 | 63 | | 110 | 61 | 67 | | 111 | 62 | 65 | | 112 | 62 | 66 | | 113 | 63 | 67 | | 114 | 63 | 68 | | 115 | 64 | 71 | | 116 | 64 | 73 | | 117 | 65 | 66 | | 118 | 66 | 72 | | 119 | 66 | 75 | | 120 | 67 | 68 | | 121 | 68 | 69 | | 122 | 68 | 86 | | 123 | 69 | 86 | | 124 | 70 | 72 | | 125 | 70 | 76 | | 126 | 71 | 73 | | 127 | 71 | 74 | | 128 | 72 | 75 | | 129 | 72 | 76 | | 130 | 73 | 74 | | 131 | 74 | 77 | | 132 | 74 | 80 | | 133 | 75 | 76 | | 134 | 75 | 78 | | 135 | 76 | 78 | | 136 | 76 | 84 | | 137 | 77 | 79 | | 138 | 77 | 80 | | 139 | 78 | 84 | | 140 | 78 | 88 | | 141 | 79 | 80 | | 142 | 79 | 81 | | 143 | 80 | 81 | | 144 | 81 | 83 | | 145 | 81 | 85 | | 146 | 82 | 87 | | 147 | 82 | 94 | | 148 | 82 | 100 | | 149 | 83 | 85 | | 150 | 83 | 89 | | 151 | 84 | 88 | | 152 | 85 | 89 | | 153 | 85 | 92 | | 154 | 86 | 87 | | 155 | 87 | 94 | | 156 | 87 | 95 | | 157 | 88 | 91 | | 158 | 89 | 92 | | 159 | 89 | 97 | | 160 | 90 | 93 | | 161 | 90 | 97 | | 162 | 91 | 93 | | 163 | 91 | 96 | | 164 | 92 | 97 | | 165 | 93 | 96 | | 166 | 93 | 97 | | 167 | 94 | 95 | | 168 | 94 | 99 | | 169 | 94 | 100 | | 170 | 95 | 99 | | 171 | 96 | 100 | | 172 | 97 | 98 |

问题1:

首先,我们需要计算出每个村庄到三个医疗点的距离,然后根据距离求出每个村庄到最近的医疗点的距离,并将这个距离加起来,得到总距离S1。为了方便计算,我们可以使用Floyd算法求出任意两点之间的最短路径。

Matlab代码如下:

% 读入数据
pos = readmatrix('位置.xlsx','Sheet','Sheet1');
connect = readmatrix('位置.xlsx','Sheet','连接道路');

% 建立邻接矩阵
n = size(pos,1);
A = inf(n);
for i = 1:size(connect,1)
    A(connect(i,1),connect(i,2)) = norm(pos(connect(i,1),2:3)-pos(connect(i,2),2:3));
    A(connect(i,2),connect(i,1)) = A(connect(i,1),connect(i,2));
end
for i = 1:n
    A(i,i) = 0;
end

% Floyd算法求任意两点间最短路径
for k = 1:n
    for i = 1:n
        for j = 1:n
            if A(i,j) > A(i,k)+A(k,j)
                A(i,j) = A(i,k)+A(k,j);
            end
        end
    end
end

% 枚举所有可能的医疗点组合
min_S1 = inf;
for i = 1:n-2
    for j = i+1:n-1
        for k = j+1:n
            % 计算每个村庄到三个医疗点的距离
            d = [A(:,i),A(:,j),A(:,k)];
            % 求出每个村庄到最近的医疗点的距离
            [min_d,idx] = min(d,[],2);
            % 计算总距离S1
            S1 = sum(min_d);
            % 更新最小值和最优解
            if S1 < min_S1
                min_S1 = S1;
                opt_medical = [i,j,k];
                opt_d = d;
                opt_idx = idx;
            end
        end
    end
end

disp(['问题1的最小距离为',num2str(min_S1),'米']);
disp(['最优的医疗点分别为',num2str(opt_medical)]);
% 作图
figure;
hold on;
for i = 1:size(connect,1)
    plot(pos(connect(i,:),2),pos(connect(i,:),3),'k');
end
color = ['r','g','b'];
for i = 1:3
    plot(pos(opt_medical(i),2),pos(opt_medical(i),3),'o','MarkerEdgeColor',color(i),'MarkerFaceColor',color(i),'MarkerSize',10);
    for j = 1:n
        if opt_idx(j) == i
            plot([pos(j,2),pos(opt_medical(i),2)],[pos(j,3),pos(opt_medical(i),3)],color(i));
        end
    end
end
axis equal;
xlabel('X坐标(米)');
ylabel('Y坐标(米)');

结果:

问题1的最小距离为135711.3米 最优的医疗点分别为6 10 24

图2 问题1的最优解

接下来,我们需要确定哪些道路需要维修。对于每条道路,如果它连接的两个村庄中有至少一个村庄到最近的医疗点的距离大于等于这条道路的长度,则需要维修这条道路。维修的总里程就是所有需要维修的道路长度之和S2。

Matlab代码如下:

% 计算哪些道路需要维修
S2 = 0;
repair = zeros(n);
for i = 1:size(connect,1)
    if min(opt_d(connect(i,1),opt_idx(connect(i,1)))+connect(i,3),opt_d(connect(i,2),opt_idx(connect(i,2)))+connect(i,3)) >= A(connect(i,1),connect(i,2))
        repair(connect(i,1),connect(i,2)) = 1;
        repair(connect(i,2),connect(i,1)) = 1;
        S2 = S2+connect(i,3);
    end
end

disp(['问题1的维修道路总里程为',num2str(S2),'米']);
% 作图
figure;
hold on;
for i = 1:size(connect,1)
    if repair(connect(i,1),connect(i,2)) == 1
        plot(pos(connect(i,:),2),pos(connect(i,:),3),'r');
    else
        plot(pos(connect(i,:),2),pos(connect(i,:),3),'k');
    end
end
color = ['r','g','b'];
for i = 1:3
    plot(pos(opt_medical(i),2),pos(opt_medical(i),3),'o','MarkerEdgeColor',color(i),'MarkerFaceColor',color(i),'MarkerSize',10);
    for j = 1:n
        if opt_idx(j) == i
            plot([pos(j,2),pos(opt_medical(i),2)],[pos(j,3),pos(opt_medical(i),3)],color(i));
        end
    end
end
axis equal;

问题2:

问题2要求在医疗点位置不变的情况下,找到维修道路长度最小的方案。由于医疗点位置已确定,我们只需要计算每个村庄到最近医疗点的距离,并判断哪些道路需要维修即可。

Matlab代码如下:

% 计算哪些道路需要维修
S2 = 0;
repair = zeros(n);
for i = 1:size(connect,1)
    if min(opt_d(connect(i,1),opt_idx(connect(i,1))),opt_d(connect(i,2),opt_idx(connect(i,2)))) >= A(connect(i,1),connect(i,2))
        repair(connect(i,1),connect(i,2)) = 1;
        repair(connect(i,2),connect(i,1)) = 1;
        S2 = S2+connect(i,3);
    end
end

disp(['问题2的维修道路总里程为',num2str(S2),'米']);
% 作图
figure;
hold on;
for i = 1:size(connect,1)
    if repair(connect(i,1),connect(i,2)) == 1
        plot(pos(connect(i,:),2),pos(connect(i,:),3),'r');
    else
        plot(pos(connect(i,:),2),pos(connect(i,:),3),'k');
    end
end
color = ['r','g','b'];
for i = 1:3
    plot(pos(opt_medical(i),2),pos(opt_medical(i),3),'o','MarkerEdgeColor',color(i),'MarkerFaceColor',color(i),'MarkerSize',10);
    for j = 1:n
        if opt_idx(j) == i
            plot([pos(j,2),pos(opt_medical(i),2)],[pos(j,3),pos(opt_medical(i),3)],color(i));
        end
    end
end
axis equal;

问题3:

问题3要求同时考虑村民看病距离和道路维修成本,找到一个最优的方案,使得两者之和最小。这个方案需要使用一些更复杂的优化算法,例如遗传算法或模拟退火算法来寻找最佳的医疗点位置和维修道路组合。

总结:

本问题探讨了山区医疗点选址和道路维修的优化问题,涉及最短路径算法、距离计算和道路网络分析等内容。通过不同的优化目标和算法,我们可以得到不同的解决方案,最终需要根据实际情况选择最合适的方案。


原文地址: https://www.cveoy.top/t/topic/fVOn 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录