送货路线设计问题 _数学建模_优化
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
送货路线设计问题
现今社会网络越来越普及,网购已成为一种常见的消费方式,随之物流行业也渐渐兴盛,每个送货员需要以最快的速度及时将货物送达,而且他们往往一人送多个地方,请设计方案使其耗时最少。
现有一快递公司,库房在图1中的O点,一送货员需将货物送至城市内多处,请设计送货方案,使所用时间最少。
该地形图的示意图见图1,各点连通信息见表3,假定送货员只能沿这些连通线路行走,而不能走其它任何路线。
各件货物的相关信息见表1,50个位置点的坐标见表2。
假定送货员最大载重50公斤,所带货物最大体积1立方米。
送货员的平均速度为24公里/小时。
假定每件货物交接花费3分钟,为简化起见,同一地点有多件货物也简单按照每件3分钟交接计算。
现在送货员要将100件货物送到50个地点。
请完成以下问题。
1. 若将1~30号货物送到指定地点并返回。
设计最快完成路线与方式。
给出结果。
要求标出送货线路。
2. 假定该送货员从早上8点上班开始送货,要将1~30号货物的送达时间不能超过指定时间,请设计最快完成路线与方式。
要求标出送货线路。
3. 若不需要考虑所有货物送达时间限制(包括前30件货物),现在要将100件货物全部送到指定地点并返回。
设计最快完成路线与方式。
要求标出送货线路,给出送完所有快件的时间。
由于受重量和体积限制,送货员可中途返回取货。
可不考虑中午休息时间。
以上各问尽可能给出模型与算法。
图1 快递公司送货地点示意图
O点为快递公司地点,O点坐标(11000,8250),单位:米
表1 各货物号信息表
货物号送达地点重量(公斤) 体积(立方米) 不超过时间
1 13 2.500.03169:00
2 18 0.500.03549:00
3 31 1.180.02409:30
4 26 1.560.035012:00
5 21 2.150.030512:00
6 14 1.720.010012:00
7 17 1.380.010912:00
8 23 1.400.042612:00
9 32 0.700.048112:00
10 38 1.330.021910:15
11 45 1.100.02879:30
12 43 0.950.022810:15
13 39 2.560.059512:00
14 45 2.280.03019:30
15 42 2.850.019010:15
16 43 1.700.078210:15
17 32 0.250.041212:00
表2 50个位置点的坐标
表3 相互到达信息
快递公司送货策略
一摘要:
本文是关于快递公司送货策略的优化设计问题,即在给定送货地点和给定设计规范的条件下,确定所需业务员人数,每个业务员的运行线路,总的运行公里数,以及费用最省的策略。
本文主要从最短路经和费用最省两个角度解决该问题,建立了两个数据模型。
模型一:利用“图”的知识,将送货点抽象为“图”中是顶点,由于街道和坐标轴平行,即任意两顶点之间都有路。
在此模型中,将两点之间的路线权值赋为这两点横纵坐标之和。
如A(x1,y1),B(x2,y2)两点,则权值为D=|x2-x1|+|y2-y1|。
并利用计算机程序对以上结果进行了校核。
模型二:根据题意,建立动态规划的数学模型。
然后用动态规划的知识求得最优化结果。
根据所建立的两个数学模型,对满足设计要求的送货策略和费用最省策略进行了模拟,在有标尺的坐标系中得到了能够反映运送最佳路线的模拟图。
最后,对设计规范的合理性进行了充分和必要的论证。
二关键词:
快递公司送货最优化图模型多目标动态规划TSP模型
三问题重述:
在快递公司送货策略中,确定业务员人数和各自的行走路线是本题的关键。
这个问题可以描述为:一中心仓库(或配送调度中心) 拥有最大负重为25kg 的业务员m 人, 负责对30个客户进行货物分送工作, 客户i 的快件量为已知 , 求满足需求的路程最短的人员行驶路径,且使用尽量少的人数,并满足以下条件:
1) 每条送快件的路径上各个客户的需求量之和不超过个人最大负重。
2) 每个客户的需求必须满足, 且只能由一个人送货.
3)每个业务员每天平均工作时间不超过6小时,在每个送货点停留的时间为10分钟,途中速度为25km/h 。
4)为了计算方便,我们将快件一律用重量来衡量,平均每天收到总重量为184.5千克。
表一为题中所给的数据:
表一
处于实际情况的考虑, 本研究中对人的最大行程不加限制.本论文试图从最优化的角度,建立起满足设计要求的送货的数学模型,借助于计算机的高速运算与逻辑判断能力,求出满足题意要求的结果。
四 问题分析:
从公司总部配出一个人,到任意未配送的送货点,然后将这个人配到最近的未服务的送货点范围之内的邻居,并使送货时间小于6小时,各送货点总重量不超过25kg 。
继续上述指派,直到各点总重量超过25kg ,或者送货时间大于6小时。
最后业务员返回总部,记录得到的可行行程(即路线)。
对另一个业务员重复上述安排,直到没有未服务的送货点。
对得到的可行的行程安排解中的每一条路径,求解一个旅行商问题,决定访问指派给每一条行程的业务员的顺序,最小化运输总距离。
得到可行解的行程安排解后退出。
根据题意的要求,每个人的工作时间不超过6小时,且必须从早上9点钟开始派送,到当天17点之前(即在8小时之内)派送完毕。
且8255.184=⎥
⎥
⎤
⎢⎢⎡kg kg ,故至少需要8条路线。
表二列出了题中任意两配送点间的距离。
表二:任意两点间的距离矩阵
因为距离是对称的,即从送货点i到送货点j的距离等于从j到i的距离。
记作:dij.
表三给出了客户的需求,为了完成送快递的任务,每个人在工作时间范围内,可以承担两条甚至更多的线路。
表中给出了送货点序号,送货点编号,快件量T,以及送货点的直角坐标。
表三
序号送货点快件量T 坐标(km)序号送货点快件量T 坐标(km)
x y x Y
1 1 8 3
2 16 16 3.5 2 16
2 2 8.2 1 5 17 17 5.8 6 18
3 3 6 5
4 18 18 7.
5 11 17
4 4 5.
5 4 7 19 19 7.8 15 12
5 6 3 0 8 20 15 3.4 19 9
6 5 4.5 3 11 21 32 6.2 22 5
五 模型假设:
(1)街道方向均平行于坐标轴,且在该前提下,业务员可以任意选择路线。
(2)无塞车现象,即业务员送快递途中不受任何外界因素影响,且业务员的休息时间不包
括在最大工作时间6个小时内。
(3)业务员人数不限制。
(4)每个业务员的路线一旦确定,便不再更改。
(5)每个业务员送快递是独立的,每人之间互不影响。
(6)业务员到某送货点后必须把该送货点的快件送完。
(7)每个业务员每天的工作时间不超过6个小时。
(8)业务员回到快递公司后停留一个小时。
六 主要符号说明:
Ti :序号为i 的送货点的快件重量 (xi ,yi )序号为i 的送货点的坐标 M 重:业务员送货总重载费用 M 空:业务员送货总空载费用 M 总:业务员送货总费用 N :业务员送货的总次数 m :业务员人数
mj :第j 个业务员送货的次数
⎩⎨
⎧=的送货点没有送快件,业务员在序号为
的送货点送快件业务员在序号为
i 0i ,1ai 1,k i 0k i bi ⎧=⎨⎩第条路线选择序号为的送货点是最远点
,第条路线选择序号为的送货点不是最远点
七 模型建立与求解: 7.1问题一模型
本模型考虑用多目标动态规划求解。
由于问题一中只要求给出一个合理的方案,且未涉及到业务员工资问题,故只要满足条件——业务员的工作时间上限是6个小时以及每条路线的最大载重量不大于25kg 即可,本模型中追加两个目标——路程最短和人员最少。
可以通过以下两种方法实现:(1)每一个行程的第一个送货点是距离总部最近的未服务的送货点。
用这种方法,即可得到一组运行路线,总的运行公里数,以及总费用。
(2)每一个行程的第一个送货点是距离总部最远的未服务的送货点。
然后以该点为基准,选择距它最近的点,加上约束条件,也可得到一组数据。
然后比较两组结果,通过函数拟合即可得到最优化结果。
本模型中以满足需求的路程最短的人员行驶路径,且使用尽量少的人数,即
N
30
k 1i 1
min (2*bi*(xi+yi))==∑∑ 且 minm
约束条件为:
① 时间约束:∑∑==≤++mj
1
j 30
16)6125)(2(i ai yi xi
② 载重量约束:
25*≤ai Ti
方法一:每一个行程的第一个送货点是距离总部最近的未服务的送货点。
第一条行程中访问了节点0-1-3-4-5-0,是因为1距离原点最近,因此由1出发,3是距离1点最近的点,而且两处快件量之和为14kg ,小于每个人最大负重量,可以继续指配。
接着,4是距离3最近的点,而且三处快件量之和为19.5kg ,仍小于25kg,还可以继续指配。
在剩下的未服务送货点中,5距离4最近(其实距离4最近的点有2,5,6,7四个点,然后考虑该点需求的快件量,将其从大到小依次排列,快件量需求大者优先,但超过25kg 上限的点舍去。
这里2,7被舍去,故选择了5)总快件量之和为24kg 。
再继续扩充,发现就会超出“25kg ”这个上限,因此选择返回,所以0-1-3-4-5就为第一条路线所含有的送货点。
用该算法得到的各路线为:
(1)
0 1 3 4 5 0
(2)1 2 6 7 13 0 (3)9 8 12 10 0
(4)0 16 17 20 14 15 23 0 (5)0 11 22 32 19 0 (6)0 27 26 0
(7)0 18 24 25 0 (8)0 29 28 30 0
现在0-1-3-4-5这四个送货点之间的最优访问路径安排就是一个典型的单回路问题。
可以通过单回路运输模型-TSP 模型求解。
一般而言,比较简单的启发式算法求解TSP 模型求解有最邻近法和最近插入法两种。
由RosenkrantzStearns 等人在1977年提出的最近插入法,
能够比最近邻点法,取得更满意的解。
由于0-1-3-0 已经先构成了一个子回路,现在要将节点4 插入,但是客户4有三个位置可以插入,现在分析将客户4插入到哪里比较合适: 1.插入到(0,1)间,C 总= 7+4+5+1+4+9=30。
2.插入到(1,3)间,C 总=5+6+4+9=24。
3.插入到(3,0)间,C 总=5+4+4+11=24。
比较上述三种情况的增量,插入到(3,0)间和(1,3)间增量最小,考虑到下一节点插入时路程最小问题,所以应当将4插入到送货点3和总部0之间。
接下来,用同样的方法,将5插到4和0之间,能使该条路线总路程最小,该路线总路程为32km ,历时1.9467h 。
结果子回路为T={0-1-3-4-5-0}.因为街道平行于坐标轴方向,所以它就是最优化路线。
第二条行程这中,由于所剩下节点中,2距离0点最近,因此由2出发,就可以找到最近点13,接着是7,然后6.这样,第二条优化路线0-2-13-7-6-0就确定了。
用这种方法,依次可确定以下剩余六条路线。
得到总的送货路线为: (1)
1 3 4 5 0
(2)0 2 13 7 6 0 (3)0 10 12 8 9 0
(4)0 16 17 20 14 15 23 0 (5)0 19 11 32 22 0 (6)0 18 24 25 (7)0 27 26 0 (8)0 29 30 28
7 2 27(21,13)3.7067 22 76
8 3 29(25,16)4.8400 18.3 96
合计30 28.2699 184.5 506
改进前和改进后的路程,时间比较如下:
然后,根据所经历的时间进行划分,确定运送人数。
在工作时间小于6小时的前提下,最终
只需要六名运输员,第一条线路和第二条线路有一人完成,第三条和第七条线路由一人完成,则各运输员到达各站点时间的情况如下:
路径为:
方法二:每一个行程的第一个送货点是距离总部最远的未服务的送货点。
分析方法如一:
得到的路径为:
(1)************(2)0 26 27 8 0
(3)0 24 25 14 9 0
(4)0 18 17 20 16 6 0
(5)0 32 22 11 10 0 (6)0 19 13 7 0 (7)0 12 4 3 0 (8)
0 5 2 1 0
同方法一,用最近插入法修改路径可以得到更优的解,改进后的路径为:
(1) 0 28 30 29 23 15 0
(2) 0 26 27 8 0
(3) 0 24 25 14 9 0 (4)***********(5) 0 11 32 22 10 0 (6) 0 19 13 7 0 (7) 0 4 12 3 0 (8) 0 2 5 1 0 改
进前后路程和时间的比较如下:
然后,根据所经历的时间进行划分,确定运送人数。
在工作时间小于6小时的前提下,最终只需要五名运输员,第三条线路和第八条线路由一人完成第四条线路和第七条线路由一人完成,第五条线路和第六条线路由一人完成,则各运输员到达各站点时间的情况如下:
路线站点编
号
到各站点时
间
出发时
间
路线
站点编
号
到各站点时
间
出发时间
1 28 10:46
9:00 5
11 9:48
9:00 30 11:11 32 10:15
29 11:33 22 10:39
23 12:05 10 11:06
15 12:34
6 19 13:55
12:50
2 26 10:29
9:00
13 14:31
27 10:51 7 14:53
8 11:47
7
4 13:36
13:10
3 2
4 10:22
9:00
12 14:12
25 10:44 3 14:48
14 11:11
8
2 13:48
13:34 9 11:45 5 14:07
4 20 9:50
9:00
1 14:39 18 10:17
17 10:41
16 11:07
6 11:41
路径图为:
由上面得图表知改进后的方法二的路线的总的距离为480km,时间为24.1997;比改进后的
方法一的距离短,时间短,所以若是只考虑时间和路程,改进后的方法二为最优解。
7.2 问题二模型
问题二中由于业务员所得的费用是最主要的,业务员安排、路线选择都是为了总费用的最小化提供条件,所以应首先考虑路费,之后再考虑业务员的安排。
为了使总能够费用最少,总的思路是先送货给离快递公司最近切块间最重的送货点,以此类推,在保证时间、载重量有限的前提下,沿途把快递送完,最终让业务员最远点空载返回。
根据这一思路,全部路线业务员的重载费用可表示为:
∑=+
=
30
1
Ti 3
M
i
yi
xi)(
重
从上式可以看出,业务员的重载费用是恒定的,又由于总费用为重载与空载费用之和,所以总费用的确定就可以转化为满足一定条件下的各路线的最远点的选择问题。
某路线业务员经过的路径选择应遵循以下原则:一是,近者优先原则。
某业务员最近起始送货点的选择直接关系到费用的多少,所以该业务员在沿途往送货终点站中应尽量把较近点的快件送完,不让下一条路线再把较近点作为起始送货站。
二是,不走冤枉路原则。
一方面,离原点(快递公司)较远的送货点坐标应分别大于离原点较近送货点的坐标,在各个坐标上均不走回头路,即按图(a)中的①②路线前进,而不按③路线前进:
图(a)业务员行走路线约定
另一方面,由于在路途相等的条件下,重载费用要比空载费用大得多,因此,尽量让业务员空载行走。
三是,坐标贴近原则。
在同一条路线中,离原点较近送货点的坐标仅次于较远点的坐标。
四是,路线较少原则。
路线多,一方面,相对最远点的选择多,跑的空路多,费用就多;另一方面,过分地强调短暂效益,出动路线多,会引起业务员的反感,不利于以后的人员控制。
根据上述分析及基本假设,业务员送货的费用可以表示如下:
重载费用:
∑=+=30
1Ti 3M i yi xi )(重
空载费用:
∑∑==+=N
130
1
2M k i yi xi bi )(空
总费用:
空重总M M M +=
应该满足以下要求:
① 时间约束:∑∑==≤++++mj
1
j 30
16)613020(i ai yi xi yi xi
② 载重量约束: 25*≤ai Ti
③ 路线约束:
1111----≤≤i i i i i i i i y a y a x a x a 且
根据路线约束条件③以及表二知:送货点1(3,2)、2(1,5)首先必须作为某路线的最近起始送货点,再结合时间约束条件①、载重量约束条件②以及上述分析的有关内容,依次选出各路线的次近点,并做统筹兼顾,一直到满足约束条件的最大值为止。
随后又选出6(0,8)、9(10,2)、10(14,0)、16(2,16)、22(21,0)、15(19,9)、25(15,14)为某条路线的最近点,分别确定次近点等,最后确定各路线如图(b )所示:
第一条路线:
第二条路线:
第三条路线:
第四条路线:
第五条路线:
第六条路线:
第七条路线:
第八条路线:
第九条路线:
图(b)业务员行走路线
根据上面确定的路线,把个业务员所经过的送货点数、最近点、所用时间、总载重量进行归纳,并用C++编程求出各业务员送货所得费用以及总费用,如下表:
根据时间约束,最少要8个业务员送快件,其中把路线1和2合并,让业务员A执行任务,其余的分别由其他7个业务员送货。
同时,为了便于统筹业务员,可以得出各业务员到各送货点的时间(各业务员的出发时间为0)以及各路线从快递公司出发的参考时间(从9:00开始工作)。
第一个人:0-1-3-8-13-0和0-2-4-7-14-0
第二个人:0-6-5-20-18-30-0
第三个人:0-9-12-19-0
第四个人:0-10-11-32-23-0
第五个人:0-16-17-24-28-0
第六个人:0-22-29-0
第七个人:0-15-27-0
第八个人:0-25-26-0
根据上述分析,得到各路线的行走路线如下图所示:
若根据问题一的求解方法,可得以下8条路线:
第一条路线:
返回线
快递公司1(3,2)3(5,4)4(4,7)5(3,11)
出发线
第二条路线:
第三条路线:
第四条路线:
第五条路线:
第六条路线:
第七条路线:
第八条路线:
图(b)业务员行走路线
根据上面确定的路线,把个业务员所经过的送货点数、最近点、所用时间、总载重量进行归
合并则有以下人员分配:
第一个人:0-1-3-4-5-0和0-19-25-24-0
第二个人:0-2-13-7-6-0和0-10-12-8-9-0
第三个人:0-16-17-20-14-0
第四个人:0-22-32-23-15-11-0
第五个人:0-18-26-28-0
第六个人;0-27-29-30-0
八模型评价
1、模型的优点:
(1)模型系统的给出了业务员的调配方案,便于指导工作实践。
(2)模型简单明了,容易理解与灵活应用。
(3)模型的方法和思想对其他类型也适合,易于推广到其他领域。
(4)本模型方便、直观,易于在计算机上实现和推广。
2、模型的缺点:
(1)模型给出的约束条件可能也有不太现实的。
(2)对街道的方向,客户的快件量的假设有待进一步改进。
3、模型的推广
(1)本模型不但适合于快递公司送货问题,还是用于一般的送货以及运输问题,只需要稍微改动模型即可。
(2)模型方便、直观,可以实现计算机模拟。
(3)建模的方法和思想可以推广到其他类型,如车辆调度问题等。
参考文献:
[1]:姜启源、谢金星、叶俊编,数学模型-3版,北京,高等教育出版社,2003.8
[2]:吴建国、汪名杰、李虎军、刘仁云编,数学建模案例精编-1版,北京,中国水利水电
出版社,2005.5
[3]:唐焕文、贺明峰编,数学模型引论-3版,北京,高等教育出版社,2005.3
注释:C++源码
求解路线及其相关内容:
问题一之方法一:
#include<iostream>
#include<fstream>
#include<cmath>
#define max 1000
using namespace std;
struct ver{
int x;
int y;
int num;
float weight;
};
bool visited[31];
ver v[31];
int next1(){
int k,min=max,tag=0;
float w;
for(int i=1;i<31;i++){
if(visited[i]==false&&v[i].x+v[i].y<min){
min=v[i].x+v[i].y;
k=i;
w=v[i].weight;
tag=1;
}
if(visited[i]==false&&v[i].x+v[i].y==min&&v[i].weight>w){
k=i;
w=v[i].weight;
tag=1;
}
}
if(tag)return k;
else return 0;
}
int next2(int k,float w){
int min=max,tag=0,m,i;
for(i=1;i<31;i++){
if(visited[i]==false&&fabs(v[k].x-v[i].x)+fabs(v[k].y-v[i].y)<min&&w+v[i].weight<=25){ min=fabs(v[k].x-v[i].x)+fabs(v[k].y-v[i].y);
m=i;
tag=1;
}
if(visited[i]==false&&fabs(v[k].x-v[i].x)+fabs(v[k].y-v[i].y)==min&&w+v[i].weight<=25& &v[i].weight>v[m].weight){
m=i;tag=1;
}
}
if(tag)return m;
else return 0;
}
void way(){
int k;
float w;
k=next1();
while(k!=0){
float time;
int num_of_station=0,distance,tag;
visited[k]=true;
w=v[k].weight;
distance=v[k].x+v[k].y;
time=(v[k].x+v[k].y)/25.0;
cout<<'0'<<"->"<<v[k].num<<"->";
tag=next2(k,w);
while(tag!=0){
num_of_station++;
visited[tag]=true;
cout<<v[tag].num<<"->";
w=w+v[tag].weight;
time=time+(fabs(v[k].x-v[tag].x)+fabs(v[k].y-v[tag].y))/25.0;
if(time+(v[tag].x+v[tag].y)/25.0+(num_of_station+1)/6.0<=6){
distance=distance+fabs(v[k].x-v[tag].x)+fabs(v[k].y-v[tag].y);
k=tag;
tag=next2(tag,w);
}else{
time=time-(fabs(v[k].x-v[tag].x)+fabs(v[k].y-v[tag].y))/25.0;
break;
}
}
time=time+(v[k].x+v[k].y)/35.0+(num_of_station+1)/6.0;
distance=distance+v[k].x+v[k].y;
cout<<'0'<<" "<<time<<" "<<distance<<"km "<<w<<endl;
k=next1();
}
}
int main(){
int i;
ifstream infile("1.txt");
cout<<"各站点的坐标及相关信息是:"<<endl;
for(i=0;i<31;i++){
visited[i]=false;
infile>>v[i].num>>v[i].x>>v[i].y>>v[i].weight;
cout<<v[i].num<<"("<<v[i].x<<","<<v[i].y<<"):"<<v[i].weight<<'\t';
}
cout<<endl;
cout<<"\n各条送快递的线路"<<" "<<"所用时间"<<" "<<"该线路总路程"<<endl;
way();
return 0;
}
问题一之方法二:
#include<iostream>
#include<fstream>
#include<cmath>
#define max 1000
using namespace std;
struct ver{
int x;
int y;
int num;
float weight;
};
bool visited[31];
ver v[31];
int next1(){
int k,max1,tag=0;
float w;
for(int i=1;i<31;i++){
if(visited[i]==false&&v[i].x+v[i].y>max1){
max1=v[i].x+v[i].y;
k=i;
w=v[i].weight;
tag=1;
}
if(visited[i]==false&&v[i].x+v[i].y==max1&&v[i].weight<w){
k=i;
w=v[i].weight;
tag=1;
}
}
if(tag)return k;
else return 0;
}
int next2(int k,float w){
int min=max,tag=0,m,i;
for(i=1;i<31;i++){
if(visited[i]==false&&fabs(v[k].x-v[i].x)+fabs(v[k].y-v[i].y)<min&&w+v[i].weight<=25){ min=fabs(v[k].x-v[i].x)+fabs(v[k].y-v[i].y);
m=i;
tag=1;
}
if(visited[i]==false&&fabs(v[k].x-v[i].x)+fabs(v[k].y-v[i].y)==min&&w+v[i].weight<=25& &v[i].weight<v[m].weight){
m=i;tag=1;
}
}
if(tag)return m;
else return 0;
}
void way(){
int k;
float w;
k=next1();
while(k!=0){
float time;
int num_of_station=0,distance,tag;
visited[k]=true;
w=v[k].weight;
distance=v[k].x+v[k].y;
time=(v[k].x+v[k].y)/25.0;
cout<<'0'<<"->"<<v[k].num<<"->";
tag=next2(k,w);
while(tag!=0){
num_of_station++;
visited[tag]=true;
cout<<v[tag].num<<"->";
w=w+v[tag].weight;
time=time+(fabs(v[k].x-v[tag].x)+fabs(v[k].y-v[tag].y))/25.0;
if(time+(v[tag].x+v[tag].y)/25.0+(num_of_station+1)/6.0<=6){
distance=distance+fabs(v[k].x-v[tag].x)+fabs(v[k].y-v[tag].y);
k=tag;
tag=next2(tag,w);
}else{
time=time-(fabs(v[k].x-v[tag].x)+fabs(v[k].y-v[tag].y))/25.0;
break;
}
}
time=time+(v[k].x+v[k].y)/25.0+(num_of_station+1)/6.0;
distance=distance+v[k].x+v[k].y;
cout<<'0'<<" "<<time<<" "<<distance<<"km "<<w<<endl;
k=next1();
}
}
int main(){
int i;
ifstream infile("1.txt");
cout<<"各站点的坐标及相关信息是:"<<endl;
for(i=0;i<31;i++){
visited[i]=false;
infile>>v[i].num>>v[i].x>>v[i].y>>v[i].weight;
cout<<v[i].num<<"("<<v[i].x<<","<<v[i].y<<"):"<<v[i].weight<<'\t';
}
cout<<endl;
cout<<"\n各条送快递的线路"<<" "<<"所用时间"<<" "<<"该线路总路程"<<endl;
way();
return 0;
}
问题二:
#include<iostream>
#include<fstream>
#include<cmath>
#define M 1000
using namespace std;
struct node{
int x;
int y;
int num;
float weight;
};
node v[31];
int mindis[31];
bool vd[31];
void create(ifstream &in,int n){
int i;
for(i=0;i<n;i++){
vd[i]=false;
in>>v[i].num>>v[i].x>>v[i].y>>v[i].weight;
cout<<v[i].num<<"("<<v[i].x<<","<<v[i].y<<") "<<v[i].weight<<'\t';
}
}
int d(node a,node b){
return (abs(a.x-b.x)+abs(a.y-b.y));
}
void dis(){
int i,j;
for(i=0;i<31;i++){
cout<<v[i].num<<"到各点的距离:\n";
for(j=0;j<31;j++)
cout<<d(v[i],v[j])<<" ";
cout<<endl<<endl;
}
}
int next1()
int k,min=M,tag=0;
float w;
for(int i=1;i<31;i++)
{
if(vd[i]==false&&d(v[0],v[i])<min)
{ min=d(v[0],v[i]);
k=i;
w=v[i].weight;
tag=1;
}
if(vd[i]==false&&d(v[0],v[i])==min&&v[i].weight>w)
{ k=i;
w=v[i].weight;
tag=1;
}
}
if(tag) return k;
else return 0;
}
int next2(int k,float w)
{
int min=M,tag=0,m,i;
for(i=1;i<31;i++)
{
if(vd[i]==false&&d(v[k],v[i])<min&&w+v[i].weight<=25&&v[i].x>v[k].x&&v[i].y>v[k].y) {
min=d(v[k],v[i]);
m=i;
tag=1;
}
if(vd[i]==false&&d(v[k],v[i])==min&&w+v[i].weight<=25&&v[i].weight>v[m].weight&& v[i].x>v[k].x&&v[i].y>v[k].y)
{
m=i;tag=1;
}
}
if(tag) return m;
else return 0;
}
void way()
{
int k;
float w;
k=next1();
while(k!=0)
{
float time,money;
int num_of_station=0,distance,tag;
vd[k]=true;
w=v[k].weight;
distance=v[k].x+v[k].y;
money=3.0*w*distance;
time=(v[k].x+v[k].y)/20.0;
cout<<'0'<<"->"<<v[k].num<<"->";
tag=next2(k,w);
while(tag!=0)
{
num_of_station++;
vd[tag]=true;
cout<<v[tag].num<<"->";
w=w+v[tag].weight;
time=time+(d(v[k],v[tag]))/20.0;
if(time+(v[tag].x+v[tag].y)/20.0+(num_of_station+1)/6.0<=6){
distance=distance+d(v[k],v[tag]);
money=money+3.0*distance*v[tag].weight;
k=tag;
tag=next2(tag,w);
}
else {
time=time-(fabs(v[k].x-v[tag].x)+fabs(v[k].y-v[tag].y))/20.0;
break;}
}
time=time+(v[k].x+v[k].y)/30.0+(num_of_station+1)/6.0;
distance=distance+v[k].x+v[k].y;
money=money+(v[k].x+v[k].y)*2.0;
cout<<'0'<<" "<<time<<" "<<distance<<"km"<<" "<<money<<" "<<w<<endl;
k=next1();
}
}
int main(){
ifstream infile("1.txt");
create(infile,31);
cout<<endl<<endl;
way();
system("PAUSE");
return 0;
}。