长江水污染数学建模期末作业.docx
《长江水污染数学建模期末作业.docx》由会员分享,可在线阅读,更多相关《长江水污染数学建模期末作业.docx(38页珍藏版)》请在冰豆网上搜索。
长江水污染数学建模期末作业
2010年数学建模
机电工程学院08机械
上课时间周五下午一二节
组员:
陈燕毫200800840009
郭玉柱200800840038
张千里200800840224
最优线路设计的数学模型
一.问题的重述和分析
最优线路设计
某货运公司,仓库地点见图1中的红色小圆圈,某送货员需将一批货物从仓库送至城市内各目的地。
76个位置的坐标见表3,编号为1的点是出发点,编号2-76的点是目的地,散点图见图1:
红色*号的是编号2-41目的地。
蓝色*号是剩下的目的地。
1.如果76个位置之间的任意连线都是通路,请设计送货线路,使送货距离最短,并用画图的方式展示所求结果。
2.如果相互通路信息如图2所示,请设计送货线路,使送货距离最短,并用画图的方式展示所求结果。
3.在第2问的基础上,如果每次最多带40个目的地货物,而且排序在前面的目的地必须优先送货,请设计送货路线,使送货距离最短,并用画图的方式展示所求结果。
4.如果要求算法在普通PC上求结果不超过两分钟,请给出你的算法代码。
图一送货示意图
图二相互联系信息
序号
X坐标
Y坐标
1
3600
2300
2
3100
3300
3
4700
5750
4
5400
5750
5
5608
7103
6
4493
7102
7
3600
6950
8
3100
7250
9
4700
8450
10
5400
8450
11
5610
10053
12
4492
10052
13
3600
10800
14
3100
10950
15
4700
11650
16
5400
11650
17
6650
10800
18
7300
10950
19
7300
7250
20
6650
6950
21
7300
3300
22
6650
2300
23
5400
1600
24
8350
2300
25
7850
3300
26
9450
5750
27
10150
5750
28
10358
7103
29
9243
7102
30
8350
6950
31
7850
7250
32
9450
8450
33
10150
8450
34
10360
10053
35
9242
10052
36
8350
10800
37
7850
10950
38
9450
11650
39
10150
11650
40
11400
10800
41
12050
10950
42
12050
7250
43
11400
6950
44
12050
3300
45
11400
2300
46
10150
1600
47
13100
2300
48
12600
3300
49
14200
5750
50
14900
5750
51
15108
7103
52
13993
7102
53
13100
6950
54
12600
7250
55
14200
8450
56
14900
8450
57
15110
10053
58
13992
10052
59
13100
10800
60
12600
10950
61
14200
11650
62
14900
11650
63
16150
10800
64
16800
10950
65
16800
7250
66
16150
6950
67
16800
3300
68
16150
2300
69
14900
1600
70
19800
800
71
19800
10000
72
19800
11900
73
19800
12200
74
200
12200
75
200
1100
76
200
800
表三:
坐标信息
二、模型的分析
最短路问题是最重要的最优化问题之一,也是图论研究中的一个经典算法问题。
最短路问题在现实生活和生产中有着广泛的应用。
例如各种管道的铺设,线路的安排,厂区的选择和布局,设备的更新等。
它还经常被作为一种基本工具,用于解决其他的最优化问题以及预测和决策问题。
历史上曾经出现过各种各样的最短路问题,例如上世纪60年代中国数学家管梅谷提出的“中国邮递员问题”,还有数学家Hamilton在1859年提出的“环球航行”问题,“旅行售货员问题”。
该问题要求设计三种不同情况下的最短送货线路。
实质是在满足题目要求的可以遍历所有76点的通路中通过数学建模求解出最短的一条。
问题一给定一个点,要求从该点开始,遍历所有其余75个点,并选择出距离最短的路线,其中题目中给定的76个点之中的任意两个点都可以形成通路。
题目二与题目一得区别在于,题目二中的每个点只与有限个剩余点之间可以形成通路。
题目三中规定每次送货时最多只能携带40个目的地的货物,并且排序在前面的目的地必须优先送货。
三、模型假设和符号说明
(1)规定题目中所用的的点用符号i(i=1,2,3,….)来表示。
用d(i,j)表示第i和第j个点之间的距离。
当i,j两个点之间连通时,则两点之间的距离即为两点间的实际距离;当两点不连通时,则距离为无穷大。
(2)为求解最短距离的通路,从i=1的点出发,从剩余的75个点中间选择距离最近的一点,记该距离为S1。
然后从该点出发,按上述方法寻找下一个最短距离,记为s2。
依次进行,求得S3,S4,S5,…,S75。
则最短距离为S1+S2+S3+…+S75,记为SUM。
则SUM为所求。
(3)假设任意两点之间的通路都为直线。
(4)在求解过程中,从i点执行之后,访问第i+1点时,不考虑i+1点之后的点对i+1点的选择。
四、模型的建立和求解
(一)问题1.如果76个位置之间的任意连线都是通路,请设计送货线路,使送货距离最短,并用画图的方式展示所求结果。
从i=1的点也就是第一个点,寻找与之距离最近的下一个点,记该距离为S1。
然后寻找与该点距离最近的下一个点,求得距离S2,依照此步骤,求得S3,S4,…,S75。
具体方法:
首先建立一个表示第i点到任一点之间距离的矩阵,记为B(i,j)。
然后从第一个点开始,依次遍历其余75个点取与第一个点距离最小的点k,并把第k点的横坐标保存在x矩阵,把纵坐标保存在y矩阵,同时把其它点与第一个点的距离置无穷大。
然后从第k个点开始依次遍历剩余75个点则最短距离SUM即为SUM=S1+S2+S3+….+S75。
求解该问题的算法如下,
用Matlab软件的该最短路径如下:
基本路径为:
1-2-23-22-21-25-24-46-45-44-48-47-69-68-67-50-49-52-53-54-42-43-28-29-30-31-19-20-5-6-7-8-9-10-11-12-13-14-15-16-17-18-37-36-35-34-40-41-60-59-58-57-63-64-62-61-55-56-52-51-66-65-71-72-73-39-38-32-33-27-26-43-75-76-74-70。
最短距离为1.3719e+005。
模型分析:
根据以上方法求得的Matlab图形,可以看出路径存在交叉,明显不构成欧拉回路,因此此算法求得的路径并非最短,有待改进。
由上图可以看出,对最短路径影响较大的点是位于边缘上的第70-76点。
模型改进:
方法一:
可以通过适当修改路径,当到达边缘附近的点时,由边缘点距离较近的点直接访问边缘上的点,然后从该边缘点继续向下执行。
基本路径大致与原图相似。
方法改进后最短路径为1.0053e+005。
方法二:
可以通过对所有的点分布图进行分区。
如可以对整个图分成若干区,运输路径先将第一区所有点访问完之后,再进入下一区,依次遍历所有的点。
这种方法可以有效缩小边缘点对最短路径的影响。
把所有点分成7个区之后,效果可见下图:
基本路径大致为由第1点开始依次顺序执行到76点。
最短路径为1.4835e+005。
路径变大的原因可能是分区不合适。
(二)如果相互通路信息如图2所示,请设计送货线路,使送货距离最短,并用画图的方式展示所求结果
每个点与有限个点连通。
首先建立一个表示第i个点到第j个点是否有通路的矩阵。
例如第一行c={1,2,22,23,75,76}表示第一个点与第2、22、23、75、76之间有通路,依旧采用与问题一相同的方法,分别比较第1个点与第2、22、23、75、76点之间的距离,取最小值,如22点,然后从22点依次比较与22点有通路的点,取得与其距离最短的点。
按照同样的方法直到所有点都比较完毕,构成一个循环回路。
用Matlab绘制的图形如下:
模型分析:
由Matlab图形可以观察到,图形由第一点开始遍历执行到第55点时,出现了死点,即与第55点有通路的所有点都已经遍历。
第55点找不到下一点。
分析其原因可能是只考虑最短路径,没有考虑第i点的选择对以后点选择的影响。
模型改进:
方法一:
可以采用分区的方法,根据死点的位置进行合理的分区,可以有效避免死点的出现,但是这种方法用程序实现比较困难,因此这种方法并非一种实际的方法。
方法二:
分析死点出现的原因,主要是由于采用“贪心法”时对路径的选择不考虑可持续性。
因此,在“贪心法”的基本框架下,可以采用设置优先访问权的办法,即到达死点附近时优先访问死点!
此外,考虑到问题一中边缘点对最短路径的影响,在设置死点优先访问权的同时,也对边缘点设置优先访问权。
用Matlab绘制的图形如下:
此时的访问顺序:
1-2-23-22-21-25-24-46-45-44-48-47-69-68-70-67-50-51-66-65-56-55-52-49-53-54-42-43-27-28-33-32-29-26-30-31-19-20-4-3-6-5-10-9-7-8-12-11-17-18-37-36-35-34-40-41-60-59-58-57-63-64-71-72-73-62-61-39-38-16-15-74-75-76。
改进后路径距离为:
1.3725e+005
(三)在第2问的基础上,如果每次最多带40个目的地货物,而且排序在前面的目的地必须优先送货,请设计送货路线,使送货距离最短,并用画图的方式展示所求结果。
按照题目要求,每次最多携带40个目的地的货物,即1-40点的目的地。
为了实现此路径,可采用问题一的改进方法,即采用分区的方法,将前40个点列在第一区,其余的点放在第二区。
首先由1点出发,依旧采用“贪心法”,依次遍历前40个点后,回到出发点,获得最小路径。
然后,再由原点携带剩余36个点的货物,依次遍历剩余36个点,再次得到一个最小路径。
最终,将两次最小路径求和,便得到总的最小路径。
用Matlab绘制图形如下:
分步路径一:
分步路径二:
分步路径组合:
模型分析:
在程序编写过程中出现多处死点,在程序编写过程中有较大困难,可以通过下面的方法对算法进行改进。
在原题假设基础上,再添加如下假设:
1、路径由原点出发到达下一点时,不考虑原点与此点的通路限制。
2、由最终一点返回原点时,忽略通路限制,直接返回原点。
3、在Matlab绘图过程中,如出现死点,则在死点附近一点设置对死点的优先访问权。
改进之后,不再出现死点,并且得到的路径较优。
模型改进:
依旧可以采用分区和设置优先路径的方法对模型进行改进。
但是程序编写有较大难度。
还可以采用其它求解最短路径的方法。
结束语:
本次模型的建立采用的主要方法是“贪心法”和图论中关于求解最短路径的方法。
模型建立时首先采用依次寻找最近点的贪心法,但是此方法存在较大的不足。
这种方法只考虑下一点的选择,而忽略下一点后其它点对此点选择的影响,这也是造成第二,三问中出现死点的原因。
针对此问题,对模型进行了适当的改进,方法主要是分区和设置优先访问路径。
参考书目:
《数学建模的实践》高教版
《应用运筹学》浙江大学出版社
《图论简明教程》清华大学出版社
《图论及其应用》高教版
《图论》北京理工大学出版社
《中国大学生数学建模竞赛》高教版
《matlab与数学建模基础教程》高教版
《matlab绘图基础》
附录
注:
由于问题要求不同,有些程序根据要求进行了相应修改,可能有重复现象。
其中fun_create_b(),fun_shorway()是问题二三均调用到的子程序,fun_check(),fun_modify_all_b()是问题二中使用到的子程序。
问题一原代码
functiony=fun1(c)
%此程序由坐标阵a生成距离阵b,经过路径选择生成%最小路径图
a=[3600,2300;3100,3300;4700,5750;5400,5750;5608,7103;4493,7102;3600,6950;3100,7250;4700,8450;5400,8450;5610,10053;4492,10052;3600,10800;3100,10950;4700,11650;5400,11650;6650,10800;7300,10950;7300,7250;6650,6950;7300,3300;6650,2300;5400,1600;8350,2300;7850,3300;9450,5750;10150,5750;10358,7103;9243,7102;8350,6950;7850,7250;9450,8450;10150,8450;10360,10053;9242,10052;8350,10800;7850,10950;9450,11650;10150,11650;11400,10800;12050,10950;12050,7250;11400,6950;12050,3300;11400,2300;10150,1600;13100,2300;12600,3300;14200,5750;14900,5750;15108,7103;13993,7102;13100,6950;12600,7250;14200,8450;14900,8450;15110,10053;13992,10052;13100,10800;12600,10950;14200,11650;14900,11650;16150,10800;16800,10950;16800,7250;
16150,6950;16800,3300;16150,2300;14900,1600;
19800,800;19800,10000;19800,11900;19800,12200;200,12200;200,1100;200,800]
b=zeros(76);
fori=1:
76
forj=i:
76
b(i,j)=((a(i,1)-a(j,1))^2+(a(i,2)-a(j,2))^2)^0.5;
b(j,i)=b(i,j);
b(i,i)=inf;
end
end
n=1;
k=1;
sum1=0;
temp=zeros(1,76);
x=zeros(1,76);
y=zeros(1,76);
fori=1:
75
temp(1,i)=inf;
forj=1:
76
iftemp(1,i)>b(k,j)
temp(1,i)=b(k,j)
n=j;
end
iftemp(1,i)>b(j,k)
temp=b(j,k)
n=j;
end
end
sum1=sum1+temp(1,i)
x(i)=a(n,1);
y(i)=a(n,2);
form=1:
76
b(m,k)=inf;%
b(k,m)=inf;
end
k=n;
end
plot(x,y)
改进方法一
functiony=gaijin(c)
%设置路径权限
a=[3600,2300;3100,3300;。
。
。
。
200,1100;200,800]注:
方框中坐标省略
b=zeros(76);
fori=1:
76
forj=i:
76
b(i,j)=((a(i,1)-a(j,1))^2+(a(i,2)-a(j,2))^2)^0.5;
b(j,i)=b(i,j);
b(i,i)=inf;
end
end
n=1;
k=1;
sum1=0;
temp=zeros(1,76);
x=zeros(1,76);
y=zeros(1,76);
x
(1)=a(1,1);
y
(1)=a(1,2);
fori=1:
75
ifk==14
n=74;
elseifk==62
n=73;
elseifk==67
n=70;
elseifk==35
n=38;
elseifk==59
n=61;
elsetemp(1,i)=inf;
forj=1:
1:
76
iftemp(1,i)>b(k,j)
temp(1,i)=b(k,j)
n=j;
end
iftemp(1,i)>b(j,k)
temp=b(j,k)
n=j;
end
end
end
sum1=sum1+temp(1,i)
x(i+1)=a(n,1);
y(i+1)=a(n,2);
form=1:
76
b(m,k)=inf;%
b(k,m)=inf;
end
k=n
end
plot(x,y)
改进方法二
%此程序对矩阵b进行分块求最短路径
function[xx,yy]=fun_rem_a(d)
lentt=0;
sum=0;
a=[3600,2300;3100,3300;…..200,1100;200,800]注:
方框中坐标省略
xx=zeros(1,lentt);
yy=zeros(1,lentt);
d=17
b=fun_create_b(a,d);
[x,y,sum1]=fun_shorway(a,b);
fori=1:
d
xx(i)=x(i);
yy(i)=y(i);
end
fori=1:
length(a)-d+1
a(i,1)=a(i+d-1,1);
a(i,2)=a(i+d-1,2);
end
sum=sum+sum1
lentt=lentt+d;
d=7
b=fun_create_b(a,d);
[x,y,sum1]=fun_shorway(a,b);
fori=1:
d
xx(lentt+i-1)=x(i);
yy(lentt+i-1)=y(i);
end
fori=1:
length(a)-d+1
a(i,1)=a(i+d-1,1);
a(i,2)=a(i+d-1,2);
end
sum=sum+sum1
lentt=lentt+d;
d=15
b=fun_create_b(a,d);
[x,y,sum1]=fun_shorway(a,b);
fori=1:
d
xx(lentt+i-1)=x(i);
yy(lentt+i-1)=y(i);
end
fori=1:
length(a)-d+1
a(i,1)=a(i+d-1,1);
a(i,2)=a(i+d-1,2);
end
sum=sum+sum1
lentt=lentt+d;
d=9
b=fun_create_b(a,d);
[x,y,sum1]=fun_shorway(a,b);
fori=1:
d
xx(lentt+i-1)=x(i);
yy(lentt+i-1)=y(i);
end
fori=1:
length(a)-d+1
a(i,1)=a(i+d-1,1);
a(i,2)=a(i+d-1,2);
end
sum=sum+sum1
lentt=lentt+d;
d=19
b=fun_create_b(a,d);
[x,y,sum1]=fun_shorway(a,b);
fori=1:
d
xx(lentt+i-1)=x(i);
yy(lentt+i-1)=y(i);
end
fori=1:
length(a)-d+1
a(i,1)=a(i+d-1,1);
a(i,2)=a(i+d-1,2);
end
sum=sum+sum1
lentt=lentt+d;
d=8
b=fun_create_b(a,d);
[x,y,sum1]=fun_shorway(a,b);
fori=1:
d
xx(lentt+i-1)=x(i);
yy(lentt+i-1)=y(i);
end
fori=1:
length(a)-d+1
a(i,1)=a(i+d-1,1);
a(i,2)=a(i+d-1,2);
end
sum=sum+sum1
lentt=lentt+d;
d=7
b=fun_create_b(a,d);
[x,y,sum1]=fun_shorway(a,b);
fori=1:
d
xx(lentt+i-1)=x(i);
yy(lentt+i-1)=y(i);
end
fori=1:
length(a)-d+1
a(i,1)=a(i+d-1,1);
a(i,2)=a(i+d-1,2);
end
lentt=lentt+d;
sum=sum+sum1
plot(xx,yy);
end
子程序1
function[b]=fun_create_b(a,d)
%此程序由矩阵a生成距离阵b,在问题一二三中均有使用,%此处作为独立函数写出,方便运算过程中主程序调用
len=d
b=zeros(len);
fori=1:
len
forj=i:
len
b(i,j)=((a(i,1)-a(j,1))^2+(a(i,2)-a(j,2))^2)^0.5;
b(j,i)=b(i,j);
b(i,i)=inf;
end
end
b=fun_all(1,b);
end
子程序2
function[x,y,sum1]=fun_shorway(a,b)
%此程序由矩阵a及相应的距离阵b,求出最短路径,并输出%图形
%此处作为独立函数写出,方便运算过程中主程序调用
lent=length(b)%定义lent记录矩阵b的长度
n=1;%定义变量n记录每个点的最短距离点
k=1;%定义变量k作为路径寻找中的指示器
sum1=0;%定义路径长度记录器sum1
x=zeros(1,lent);%定义行矩阵x记录路径中每个%点的横坐标
y=zeros(1,lent);%定义行矩阵y记录路径中每个点的纵
%坐标
x(1,1)=a(1,1)%定义起始点横坐标
y(1,1)=a(1,2)%定义起始点纵坐标
fori=1:
(lent-1)
replace=inf;%定义replace作为寻%找最近距离点的暂存器