物资配送路径问题(一)
来源:互联网 发布:编程员工资 编辑:程序博客网 时间:2024/04/28 14:05
这篇文章是一个研究生数模的作业,研究了一下感觉挺有意思的,所以准备拿来好好研究一下,借此写几篇博文,记载。
----20140605
首先,这里第一篇我会基于该题目本身来进行基本的设计和研究。参考过一两篇所谓答案,感觉看上去不知所云,希望我能用最简单的语言成功描述这个问题。下面是这个题目:
某物流中心拥有一支货运车队,每台货运车辆的载重量(吨)相同、平均速度(千米/小时)相同,该物流中心用这样的车为若干个客户配送物资,物流中心与客户以及客户与客户之间的公路里程(千米)为已知。每天,各客户所需物资的重量(吨)均已知,并且每个客户所需物资的重量都小于一台货运车辆的载重量,所有送货车辆都从物流中心出发,最后回到物流中心。物流中心每天的配送方案应当包括:当天出动多少台车?行驶路径如何?由此形成的当天总运行里程是多少?一个合格的配送方案要求送货车辆必须在一定的时间范围内到达客户处,早到达将产生等待损失,迟到达将予以一定的惩罚;而一个好的配送方案还应该给出使配送费用最小或总运行里程最短的车辆调度方案。
〔算例〕载重量为 8 吨、平均速度为 50千米/小时 的送货车辆从物流中心(0)出发,为编号是 1,2,…,8 的8个客户配送物资。某日,第个客户所需物资的重量为吨(),在第个客户处卸货时间为小时,第个客户要求送货车辆到达的时间范围 由表1给出。物流中心与各客户以及各客户间的公路里程(单位:千米)由表2给出。问当日如何安排送货车辆(包括出动车辆的台数以及每一台车辆的具体行驶路径)才能使总运行里程最短。
表1 物资配送任务及其要求
客户
1
2
3
4
5
6
7
8
(吨)
2
1.5
4.5
3
1.5
4
2.5
3
(小时)
1
2
1
3
2
2.5
3
0.8
[1, 4]
[4, 6]
[1, 2]
[4, 7]
[3, 5.5]
[2, 5]
[5, 8]
[1.5, 4]
表2 点对之间的公路里程(千米)
0
1
2
3
4
5
6
7
8
0
0
40
60
75
90
200
100
160
80
1
40
0
65
40
100
50
75
110
100
2
60
65
0
75
100
100
75
75
75
3
75
40
75
0
100
50
90
90
150
4
90
100
100
100
0
100
75
75
100
5
200
50
100
50
100
0
70
90
75
6
100
75
75
90
75
70
0
70
100
7
160
110
75
90
75
90
70
0
100
8
80
100
75
150
100
75
100
100
0
很显然这是一个基于最短路径的问题。
在第一步,显然应该获得关于所有节点之间的最短路径矩阵。最初我根据网上的若干文章选择使用了Dijkstra算法以获得关于物流中心,也就是0节点的最短路径数组。当然针对算例也能得到不错的配送方案,但是对于比较复杂的路线肯定无法满足需要,因此我还是重选了Floyd算法来处理这个问题(另一个原因是因为这个算法更好写)。这里我把两个算法写成的java函数放到下面
//Floyd算法,返回一个类,这个类包含两个二维数组public Result floyd(int[][] g) {int n = g.length;int[][] dis = new int[n][n];//距离矩阵int[][] path = new int[n][n];//path矩阵for (int q = 0; q < n; q++) {for (int w = 0; w < n; w++) {dis[q][w] = g[q][w];path[q][w] = -1;}}//数组初始化完成for (int k = 0; k < n; k++) {for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {if (dis[i][j] > dis[i][k] + dis[k][j]) {dis[i][j] = dis[i][k] + dis[k][j];path[i][j] = k;}}}}Result rs = new Result();rs.dis = dis;rs.path = path;return rs;}
//每次只会计算start这一行,结果包含两个二维数组和一个数组public Result dijsktra(int[][] weight, int start) {// 接受一个有向图的权重矩阵,和一个起点编号start(从0编号,顶点存在数组中)// 返回一个int[] 数组,表示从start到它的最短路径长度int n = weight.length; // 顶点个数int[] shortPath = new int[n]; // 存放从start到其他各点的最短路径int[] visited = new int[n]; // 标记当前该顶点的最短路径是否已经求出,1表示已求出int[] pathM = new int[n];for (int i = 0; i < pathM.length; i++) {pathM[i]= -1;}Result rs = new Result();// 初始化,第一个顶点求出shortPath[start] = 0;visited[start] = 1;for (int count = 1; count <= n - 1; count++) // 要加入n-1个顶点{int k = -1; // 选出一个距离初始顶点start最近的未标记顶点int dmin = 1000;for (int i = 0; i < n; i++) {if (visited[i] == 0 && weight[start][i] < dmin) {dmin = weight[start][i];k = i;}}// 将新选出的顶点标记为已求出最短路径,且到start的最短路径就是dminshortPath[k] = dmin;visited[k] = 1;// 以k为中间点想,修正从start到未访问各点的距离for (int i = 0; i < n; i++) {if (visited[i] == 0&& weight[start][k] + weight[k][i] < weight[start][i]) {weight[start][i] = weight[start][k] + weight[k][i];pathM[i] = k;}}}rs.pathM = pathM;//path矩阵rs.dist = shortPath;//改行的dist数组rs.resultM = weight;//修改过start行的距离矩阵return rs;}
得到基础的两个矩阵之后。第一步就算是结束了。
但是接下来选择多少运送车辆和每辆车的运送路径就成了关键的问题。
1.根据车辆载重构造可能的运送线路集合;
2.根据最短线路规则制定行车线路;
3.根据时间规则,构造可能的节点顺序。
想到这里,问题似乎就陷入了死胡同,首先,三个条件的交叉点不一定存在。第二,没有一个条件可以作为评分标准。第三,用程序写这个就更不好写了。
既然一次性搞定有问题,那么就一步步来把。
- 物资配送路径问题(一)
- 最后一公里极速配送(一)
- 物资调度(dfs)
- 物资系统存在的问题!
- 单配送物流算法(简化为旅行商问题)
- 购物配送系统的问题
- nyoj1249 物资调度(dp)
- C语言文件路径问题(一)
- 欧拉路径(一笔画问题)
- 配送中心(Distribution center)
- zzuoj--10401--物资调度(dfs)
- nyoj 1249 物资调度(DP)
- NYOJ 1249 物资调度(DFS+剪枝)
- NYOJ 1249 物资调度(DFS+剪枝)
- 最后一公里极速配送(二)
- 最后一公里极速配送(三)
- 最后一公里极速配送(四)
- java路径问题(一)——getClass().getResourceAsStream()
- 自定义jquery 常用方法。
- utf8 和unicode关系
- c++ builder firemonkey 实现填充椭圆
- 开心的金明
- 特殊符号☎▶
- 物资配送路径问题(一)
- Android机顶盒取网卡的Mac地址
- ant + findbugs 安装及实现静态代码检查,并生成HTML检查报告
- 缘聚缘散,皆是缘
- tomcat启动报错,找不到对应的 queue,从而引发内存泄漏
- \u Unicode和汉字转化
- eclipse 中的html 中的中文都是乱码
- 毕业5年决定人的一生-- 大家千万不要错过这篇文章
- 深入理解Java内存模型(二)——重排序