赞
踩
自来水管道铺设问题
在村村通自来水工程实施过程中,从保证供水质量以及设备维护方便角度出发,某地区需要建设一个中心供水站,8个一级供水站和30个二级供水站,各级供水站的位置坐标如表1所示,其中类型A表示中心供水站,类型V代表一级供水站,类型P为二级供水站。图是各级供水站的地理位置图。
现在要将中心供水站A处的自来水通过管道输送到一级供水站和二级供水站。按照设计要求,从中心站A铺设到一级供水站的管道为I型管道,从一级供水站出发铺设到二级供水站的管道为II型管道。
自来水管道铺设技术要求如下:
请结合上述管道铺设要求,建立数学模型,解决以下问题:
从中心供水站A出发,自来水管道应该如何铺设才能使管道的总里程最少?以图形给出铺设方案,并给出I型管道和II型管道总里程数。
首先,我们需要明确问题的目标:从中心供水站A出发,铺设自来水管道到一级供水站和二级供水站,使得管道的总里程最少。同时,需要遵循特定的铺设规则,如中心供水站只能与一级供水站连接,一级供水站可以与二级供水站连接等。
原始数据:
原始数据散点图:
一级管道最小生成树图和总距离图:
总最小生成树图和总最小距离:
- clc;
- clear;
- close all;
-
- A=[26 31;
- 5 33;8 9;10 24;17 23;20 10;25 47;35 42;41 31]; %8个一级供水站V
- B=[5 33;8 9;10 24;17 23;20 10;25 47;35 42;41 31;
- 24 30;21 29;22 30;24 32;37 33;38 33;37 36;20 13;13 46;16 39;21 39;29 38;29 44;36 44;16 46;22 44;40 44;42 40;21 41;17 51;7 34;17 34; %30个二级供水站P
- 26 16;9 16;12 17;9 19;2 1;25 25;33 21;40 24];
- C=[26 31; %1个中心供水站A
- 5 33;8 9;10 24;17 23;20 10;25 47;35 42;41 31; %8个一级供水站V
- 24 30;21 29;22 30;24 32;37 33;38 33;37 36;20 13;13 46;16 39;21 39;29 38;29 44;36 44;16 46;22 44;40 44;42 40;21 41;17 51;7 34;17 34; %30个二级供水站P
- 26 16;9 16;12 17;9 19;2 1;25 25;33 21;40 24];
- m=length(A); %m=9
- n=length(B); %n=38
- a=zeros(39); %带权邻接矩阵
- b=zeros(39); %无权邻接矩阵
-
- for i=1:m
- for j=i+1:m
- a(i,j)=sqrt(sum((A(i,:)-A(j,:)).^2)); %中心与一级,一级之间距离
- if i>1
- a(j,i)=sqrt(sum((A(i,:)-A(j,:)).^2)); %一级供水站之间距离
- end
- end
- end
-
- for i=1:n
- for j=i+1:n
- a(i+1,j+1)=sqrt(sum((B(i,:)-B(j,:)).^2)); %一级与二级,二级之间距离
- if i>8
- a(j+1,i+1)=sqrt(sum((B(i,:)-B(j,:)).^2)); %二级供水站之间距离
- end
- end
- end
-
- total=0; % 管道总里程数
- a(find(a==0))=inf; % prim算法
- result=[];p=1;tb=2:length(a);
- while length(result)~=length(a)-1
- temp=a(p,tb);temp=temp(:);
- d=min(temp);
- total=total+d;
- [jb,kb]=find(a(p,tb)==d);
- j=p(jb(1));k=tb(kb(1));
- b(j,k)=1;
- b(k,j)=1;
- result=[result,[j;k;d]];p=[p,k];tb(find(tb==k))=[];
- end
-
- % 输出一级管道的距离
- disp('一级管道的距离:');
- % 初始化一级管道总距离
- total_one_level = 0;
- for i = 1:m
- for j = i+1:m
- if b(i, j) == 1
- distance = a(i, j);
- fprintf('从一级供水站 %d 到一级供水站 %d 的距离为 %.2f\n', i, j, distance);
- % 累加一级管道的距离
- total_one_level = total_one_level + distance;
- end
- end
- end
-
- fprintf('一级管道总距离为 %.2f\n', total_one_level);
-
- result
- total
-
- % 以下为绘图部分,请将此部分放在合适的地方
- A1=[26]; % 中心供水站x坐标
- A2=[31]; % 中心供水站y坐标
-
- V1=[5 8 10 17 20 25 35 41]; % 一级供水站x坐标
- V2=[33 9 24 23 10 47 42 31]; % 一级供水站y坐标
-
- P1=[24 21 22 24 37 38 37 20 13 16 21 29 29 36 16 22 40 42 21 17 7 17 26 9 12 9 2 25 33 40]; % 二级供水站x坐标
- P2=[30 29 30 32 33 33 36 13 46 39 39 38 44 44 46 44 44 40 41 51 34 34 16 16 17 19 1 25 21 24]; % 二级供水站y坐标
-
- % 画线路图
- scatter(A1,A2,'bo') % 中心供水站位置
- hold on;
- scatter(V1,V2,'k*') % 一级供水站位置
- hold on;
- scatter(P1,P2,'b.') % 二级供水站位置
- hold on;
-
- xlabel('x')
- ylabel('y')
- gplot(b,C,'r-')
- hleg=legend('中心供水站','一级供水站','二级供水站','管道','location','northeastoutside');
通过本次实验,知道并应用了Prim算法:
普利姆(Prim)算法求最小生成树,也就是在包含n个顶点的连通图中,找出只有(n-1)条边包含所有n个顶点的连通子图,也就是所谓的极小连通子图
设G=(V,E)是连通网,T=(U,D)是最小生成树,V,U是顶点集合,E,D是边的集合,若从顶点u开始构造最小生成树,则从集合V中取出顶点u放入集合U中,标记顶点v的visited[u]=1,若集合U中顶点ui与集合V-U中的顶点vj之间存在边,则寻找这些边中权值最小的边,但不能构成回路,将顶点vj加入集合U中,将边(ui,vj)加入集合D中,标记visited[vj]=1。重复上述步骤,直到U与V相等,即所有顶点都被标记为访问过,此时D中有n-1条边。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。