数学建模运输问题.docx
《数学建模运输问题.docx》由会员分享,可在线阅读,更多相关《数学建模运输问题.docx(22页珍藏版)》请在冰豆网上搜索。
数学建模运输问题
华东交通大学数学建模2012年第一次模拟训练题
所属学校:
华东交通大学(ECJTU)
参赛队员:
胡志远、周少华、蔡汉林、段亚光、
李斌、邱小秧、周邓副、孙燕青
指导老师:
朱旭生(博士)
摘要:
本文的运输问题是一个比较复杂的问题,大多数问题都集中在最短路径的求解问题上,问题特点是随机性比较强。
根据不同建模类型
针对问题一,我们直接采用Dijkstra算法(包括lingo程序和手算验证),将问题转化为线性规划模型求解得出当运送员在给第二个客户卸货完成的时,若要他先给客户10送货,此时尽可能短的行使路线为:
,总行程85公里。
针对问题二,我们首先利用prim算法求解得到一棵最小生成树:
再采用Dijkstra算法求得客户2返回提货点的最短线路为
故可得到一条理想的回路是:
后来考虑到模型的推广性,将问题看作是哈密顿回路的问题,建立相应的线性规划模型求解,最终找到一条满足条件的较理想的的货车送货的行车路线:
。
针对问题三,我们首先直接利用问题二得一辆车的最优回路,以货车容量为限定条件,建立相应的规划模型并设计一个简单的寻路算法,最终可为公司确定合理的一号运输方案:
两辆车全程总和为295公里(见正文);然后建立线性规划模型得出二号运输方案:
两辆车全程总和为290公里(见正文);
针对问题四,
一、问题分析
对问题
(一)的分析就是求指定两点间的最短路径问题,对此我们可以采用dijkstra算法可以很简单的算出答案,由此延伸一下我们可以推广到可找出第二个客户到任何一个客户的的最短路径,为此我们也将找出此类题目的一般lingo算法。
对问题
(二)的分析,由提货点出发再返回到提货点,而且这条路径必须是相对而言最短的,显然这个问题是在模型中找出一条最短的哈密尔顿回路的问题,建立相应的线性规划模型就能最终找到一条满足条件的较理想的的结果
对问题(三)的分析,这个问题主要是要把9个客户(1好客户为提货点)分成两个集合,然后依次构建出两个完整的最短的汉密尔顿回路。
对问题(四)的分析
关键字:
Dijkstra算法,prim算法,哈密顿回路
二、模型假设
1、任何两个客户之间的路径长度都是固定的,不存在临时出发状况例如绕道,改道的情况。
2、不考虑任何现实状况中的实际情况,一切按照题目的数据进行求解。
三、符号说明
表示从第i个客户到第j个客户的路线距离
表示第i个客户到第j个客户的0-1变量
(注:
其他变量在模型中定义)
四、模型的建立与求解
问题一、
模型一:
直接求解:
为了简化问题我们用dijistra算法直接求解,然后用表格法简化其操作步骤:
1
2
3
4
5
6
7
8
9
10
A
50
30*
infi
35
50
infi
60
infi
Infi
B
50
45
35*
50
80
55
infi
90
C
50
45*
50
45
55
90
D
50
50
45*
55
85
90
F
50*
50
55
85
90
G
50*
55
85
90
H
55*
85
90
I
65*
90
J
85*
由上表我们显然可以得到一条最短路径:
2→3→8→9→10(且最短路径为85)
同样从上表格中我们不但可以找出客户2到客户10的最短路径同样可以找出客户到其他任何客户位置的最短路径列表如下:
2→1(最短路径为50)
2→3(最短路径为30)
2→3→4(最短路径为45)
2→5(最短路径为35)
2→6(最短路径为50)
2→5→7(最短路径为45)
2→3→8(最短路径为55
2→3→8→9(最短路径为65)
模型二:
编写出lingo的算法求解:
定义
是由
点出发至终点
的最短路程,由最优化原理可得
这是一个函数方程,用LINGO可以很方便的解决。
model:
data:
n=10;
enddata
sets:
points/1..n/:
F;!
10个客户点;
roads(points,points)/
1,2
2,32,52,62,8
3,43,63,73,83,10
4,54,64,74,84,94,10
5,65,75,85,10
6,76,86,9
7,87,97,10
8,9
9,10
/:
D,P;
endsets
data:
D=
50
30355060
1530502560
453055204065
60103055
255535
304560
10
20;
enddata
F(n)=0;
@for(points(i)|i#lt#n:
F(i)=@min(roads(i,j):
D(i,j)+F(j));
);
!
显然,如果P(i,j)=1,则点i到点n的最短路径的第一步是i-->j,否则就不是。
由此,我们就可方便的确定出最短路径;
@for(roads(i,j):
P(i,j)=@if(F(i)#eq#D(i,j)+F(j),1,0)
);
End
摘入Lingo的部分显示结果:
P(1,2)1.000000
P(2,3)1.000000
P(2,5)0.000000
P(2,6)0.000000
P(2,8)0.000000
P(3,4)0.000000
P(3,6)0.000000
P(3,7)0.000000
P(3,8)1.000000
P(3,10)0.000000
P(4,5)0.000000
P(4,6)0.000000
P(4,7)0.000000
P(4,8)1.000000
P(4,9)0.000000
P(4,10)0.000000
P(5,6)0.000000
P(5,7)0.000000
P(5,8)0.000000
P(5,10)1.000000
P(6,7)0.000000
P(6,8)0.000000
P(6,9)1.000000
P(7,8)1.000000
P(7,9)0.000000
P(7,10)1.000000
P(8,9)1.000000
P(9,10)1.000000
由p(i,j)是否等于1来确定路径,可得路径为2->3,3->8,8->9,9->10.为85
模型结果对比:
由第一个结果对比第二个模型的算法结果相同,可知这个lingo算法模型是正确的,以后若遇到类似求某点到其他各点的最短路径问题都可选用lingo的算法求解
问题二
很明显运输公司分别要对10个客户供货,必须访问每个客户,但问题要求我们建立相应模型寻找一条尽可能短的行车路线,首先不考虑送货员把10个客户所需的货送完货后不返回提货点的情形,利用求最小生成树的prim算法结合题中所给的邻接矩阵,很快可以得到以下一棵最小生成树:
V1→V5→V7→V6→V3→V4→V8→V9→V10→V2
以上路线的总行程为175公里,充分利用问题一所建的模型
(1),很快就可以求得
(客户2)返回
(提货点)的最线路是
行程50公里(,我们有理由相信这样构成的回路实际上也是最短回路:
V1→V5→V7→V6→V3→V4→V8→V9→V10→V2→V1
总行程为225公里。
这种寻路方法并不比其他方法差而且它的速度也很快,只是它局限于顶点数较少的情形,一旦顶点数扩大实现起来难度就会大大提高,而且它的不易推广,因此我们有必要对此问题深入研究,进而建立起一个数学模型以适应顶点数变化,使它能够具有较好的推广性,应用到现实生活中去来实现以不变应万变的现象。
模型的推广
变量说明
表示从第i个客户到第j个客户的路线距离
表示第i个客户到第j个客户的0-1变量
根据对问题的分析,我们首先引入一些0-1整数变量:
其题目目标就是使
为最小。
这里有两个明显的必须满足的条件:
访问客户i后必须要有一个即将访问的确切客户;访问客户j前必须要有一个刚刚访问过的确切客户。
用下面的两组约束分别实现上面的两个条件。
这里,我们将添加一种在原模型上附加充分的约束条件以避免产生子巡回的方法。
把额外变量
附加到问题中。
可把这些变量看作是连续的(虽然这些变量在最优解中取普通的整数值)。
现在附加下面形式的约束条件
。
为了证明该约束条件有预期的效果,必须证明:
(1)任何含子巡回的路线都不满足该约束条件;
(2)全部巡回都满足该约束条件。
首先证明
(1),用反证法。
假设还存在子巡回,也就是说至少有两个子巡回。
那么至少存在一个子巡回中不含客户1。
把该子巡回记为
,则必有
把这k个式子相加,有
,矛盾!
故假设不正确,结论
(1)得证。
下面证明
(2),采用构造法。
对于任意的总巡回
,可取
访问客户i的顺序数,取值范围为
。
因此,
。
下面来证明总巡回满足该约束条件。
(ⅰ)总巡回上的边
(ⅱ)非总巡回上的边
从而结论
(2)得证。
这样我们把TSP转化成了一个混合整数线性规划问题。
显然,当客户个数较大(大于30)时,该混合整数线性规划问题的规模会很大,从而给求解带来很大问题。
TSP已被证明是NP难问题,目前还没有发现多项式时间的算法。
对于小规模问题,我们求解这个混合整数线性规划问题的方式还是有效的。
以下是linggo算法:
MODEL:
SETS:
CUSTOMERS/1..10/:
U;
LINK(CUSTOMERS,CUSTOMERS):
DIST,X;
ENDSETS
DATA:
DIST=
05010000040251000003010000050100000
5003010000035501000006010000100000
1000003001510000030502510000060
4010000150453055204065
251510000045060103010000055
1000005030306002555351000000
301000005010000010250304560
100000602520305530010100000
2010000010000040100000152545020
352010452010000060100000300;
ENDDATA
N=@SIZE(CUSTOMERS);
MIN=@SUM(LINK:
DIST*X);
@FOR(CUSTOMERS(K):
@SUM(CUSTOMERS(I)|I#NE#K:
X(I,K))=1;