文章目录
参考模型
以上海到广州为例,在公路与铁路的混合运输网中共选取28个城市,查阅数据得到各点之间的路程,同时查阅到运输成本的计算公式以及公路运输和铁路运输的速度,逐渐深入的方式建立了三个模型并且求解。
本次模型解答分为三个阶段:
1.公路运输阶段,在这个阶段中我们只考虑两地之间的公路运输,讨论两地之间的最短路径问题。
2.混合运输阶段,在这个阶段我们将铁路网络和公路网络混合考虑,讨论成本最优的运输路径。
3.有时间约束下的混合运输阶段,在这个阶段中我们添加了时间约束条件,讨论在满足条件下的最优成本的运输路径。
模型求解
第一阶段——只考虑单一的公路运输(Dijkstra算法)
这个模型的求解可以参照前一篇博客
C语言实现Dijkstra算法(求解两点之间最短路径问题)
第二阶段——考虑铁路网络和公路网络(最优成本)
建立模型
类似于阶段1的求解思路,结合我国铁路网络并不是在任何两个城市之间都能对汽车进行铁路运输的现状,我们只在阶段1选取的城市中筛选出了9个铁路运输枢纽,并在网上查阅相邻城市的铁路距离和成本计算公式:==
铁路:(16.8+(0.0845+0.033)×运输的公里数)×重量
公路:0.35×运输的公里数×重量==
出于对算法简便性的考虑,我们结合上述公式,用Excel将铁路-公路距离矩阵转化为铁路公路成本矩阵,而涉及到相邻城市既有铁路又有公路的情况下,以成本较低的铁路运输作为该路线的运输成本,这样得到铁路-公路运输成本的矩阵后,只需将该矩阵替换阶段1的最短路径矩阵,即可用与阶段1相同的算法得到上海-广州的铁路公路混合运输的最小成本运输方案。
所以这个阶段就是把原先的距离变量换算为两地之间的运输成本问题,把最短路径变为最优成本,依旧使用Dijkstra算法
所用数据
根据以上计算公式可求得两地之间的运输成本
代码实现
只需要将第一阶段的C语言实现Dijkstra算法(求解两点之间最短路径问题)代码中的矩阵变成这个矩阵即可
第三阶段——在时间约束条件下的最短路径问题(分枝定界法+Dijkstra算法)
建立模型
在实际情况中,公司会要求在一个固定时间内将产品运输到目的地,这时候就会产生一个在时间约束条件下的查找最优路径问题。在这里,我们通过网上查询资料假设出公路运输的时速为75km/h,铁路运输的时速为50km/h,且忽略由铁路和公路进行交换时所损耗的时间。
所用数据
这里不仅需要两地之间的运输成本的数据,还需要两地之间运输所需的时间
通过模型假设中的运输速度可以算出两地之间的运输所需时间
代码实现
程序框图
流程图解释
- 首先利用Dijkstra算法分别计算出各点至终点的最小成本和最短耗时,分别存入shortestpath[N]与minestcost[N]两个一维数组当中,且将一开始最短耗时路径所需的成本作为初始时的上界minPath,最小成本路径的耗时作为可行解costOfMinpath的初始值。
- 之后进行初步的判断,若最小成本的耗时costOfMinpath已经满足了约束条件,则算法直接结束并输出最小成本的路径;若最小耗时路径都不满足约束条件,则算法结束,输出“因约束条件太小,程序无解”。
- 在两次判断都完成之后开始执行分支定界法来搜索符合条件的最优路径。首先建立存放“活”节点的栈p,利用栈来实现深度遍历。这里的活节点是指在遍历该节点的字节点时能够发现符合约束的可行解。(其余的变量在变量表格中已经给出)
- 起始点如栈,开始进入循环,首先确定该次循环的父节点为活节点栈中最顶部的节点,之后开始遍历该父节点下没有被遍历过的字节点i,若父节点现有成本消耗nowpath+path[pnow ][i]>minPath或者时间消耗nowcost+cost[pnow][i]>bound则该子节点不满足条件,开始遍历下一个子节点;若字节点满足条件,则判断该字节点是否为终点,若该子节点为终点,则该次遍历获得一条符合条件的最优成本路径,更新minPath和costOfMinPath,并同时更新nowpath与nowcost,且将此次遍历完所得可行解的路径存入最优解finalroad栈中;若该子节点并非终点,则子节点入栈,且标志位tag值为1,表示该父节点为活节点,同时子节点入栈,is[i]=1表示该子节点已被标注,更新现有成本nowpath和现有时间损耗nowcost。
- 找到可行的子节点或遍历完该父节点的所有子节点之后跳出该父节点循环,判断标志位tag是否为0,若为0则表示该父节点为死节点,找不到符合条件的子节点,则该父节点弹出活节点栈p,并再次更新nowpath与nowcost,同时将该节点标志位is置零;若tag=1表示该父节点为活节点,保留在栈中。最后将tag更新为0,将本次找到的子节点作为下次遍历的父节点,实现深度遍历。最后,当活节点栈p为空时表示已搜索了所有节点的可行路径,跳出循环,程序结束,最后输出finalroad中存储的节点路径。
程序代码
#include <iostream>
#include <stack>
#define N 28//城市个数
#define MAX 100000//两节点之间无路径的时候的最大值
using namespace std;
double minPath; // 记录最短路径长度
double costOfMinPath; // 记录最短路径的花费
double shortesetpath[N];//记录各城市到终点的最短路程
double minestcost[N];//记录各城市到终点的最小花费
double path[N][N]={
{0, 34.265, 40.535, 100000, 79.52, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},
{34.265, 0, 29.575, 37.135, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},
{40.535, 29.575, 0, 19.845, 100000, 77.49, 37.715, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},
{100000, 37.135, 19.845, 0, 42.42, 100000, 57.435, 100000, 96.81, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},
{79.52, 100000, 100000, 42.42, 0, 100000, 85.47, 100000, 95.55, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},
{100000, 100000, 77.49, 100000, 100000, 0, 100000, 100000, 100000, 50.295, 58.275, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},
{100000, 100000, 37.715, 57.453, 85.47, 100000, 0, 40.81, 100000, 33.775, 100000, 100000, 100000, 100000, 53.5775, 42.885, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},
{100000, 100000, 100000, 100000, 100000, 100000, 40.81, 0, 45.395, 100000, 100000, 100000, 100000, 100000, 100000, 70.595, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 45.395, 0, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 111.405, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},
{100000, 100000, 100000, 100000, 100000, 50.295, 33.775, 100000, 100000, 0, 100000, 42.105, 100000, 100000, 100000, 122.675, 163.765, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},
{100000, 100000, 100000, 100000, 100000, 58.275, 100000, 100000, 100000, 100000, 0, 100000, 50.4, 100000, 55.755, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 42.105, 100000, 0, 100000, 100000, 36.33, 93.205, 134.295, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 50.4, 100000, 0, 45.5, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 84.7, 100000, 100000},
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 45.5, 0, 33.72, 147.105, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 66.033, 100000, 100000, 100000},
{100000, 100000, 100000, 100000, 100000, 100000, 53.5775, 100000, 100000, 100000, 55.755, 36.33, 100000, 33.72, 0, 38.655, 100000, 98.875, 118.3, 100000, 151.935, 194.25, 100000, 100000, 100000, 100000, 100000, 100000},
{100000, 100000, 100000, 100000, 100000, 100000, 42.885, 70.595, 100000, 122.675, 100000, 93.205, 100000, 147.105, 38.655, 0, 63, 100000, 29.015, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 109.155, 100000},
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 111.405, 163.765, 100000, 134.295, 100000, 100000, 100000, 63, 0, 100000, 100000, 63.7, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 98.875, 100000, 100000, 0, 138.565, 100000, 66.675, 100000, 100000, 139.23, 100000, 100000, 100000, 100000},
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 118.3, 29.015, 100000, 138.565, 0, 96.915, 132.51, 113.68, 100000, 100000, 100000, 100000, 100000, 100000},
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 63.7, 100000, 96.915, 0, 100000, 136.255, 115.29, 100000, 100000, 100000, 100000, 100000},
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 151.935, 100000, 100000, 66.675, 132.51, 100000, 0, 100000, 100000, 86.415, 100000, 100000, 100000, 146.51},
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 194.25, 100000, 100000, 100000, 113.68, 136.255, 100000, 0, 55.195, 100000, 100000, 100000, 127.575, 135.835},
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 115.29, 100000, 55.195, 0, 100000, 100000, 100000, 116.795, 100000},
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 139.23, 100000, 100000, 86.415, 100000, 100000, 0, 111.195, 100000, 100000, 128.66},
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 66.033, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 111.195, 0, 121.03, 100000, 99.8725},
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 84.7, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 121.03, 0, 100000, 100000},
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 109.155, 100000, 100000, 100000, 100000, 100000, 127.575, 116.795, 100000, 100000, 100000, 0, 34.705},
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 146.51, 135.835, 100000, 128.66, 99.8725, 100000, 34.705, 0}
};//路径矩阵
double cost[N][N]={
{0, 1.30533333333333, 4.04, 100000, 3.02933333333333, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},//1
{1.30533333333333, 0, 1.12666666666667, 1.41466666666667, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},//2
{4.04, 1.12666666666667, 0, 0.756, 100000, 2.952, 3.56, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},//3
{100000, 1.41466666666667, 0.756, 0, 1.616, 100000, 2.188, 100000, 3.688, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},//4
{3.02933, 100000, 100000, 1.616, 0, 100000, 3.256, 100000, 3.64, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},//5
{100000, 100000, 2.952, 100000, 100000, 0, 100000, 100000, 100000, 1.916, 2.22, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},//6
{100000, 100000, 3.56, 2.188, 3.256, 100000, 0, 1.55466666666667, 100000, 1.28666666666667, 100000, 100000, 100000, 100000, 6.26, 4.44, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},//7
{100000, 100000, 100000, 100000, 100000, 100000, 1.55466666666667, 0, 1.72933333333333, 100000, 100000, 100000, 100000, 100000, 100000, 2.68933333333333, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},//8
{100000, 100000, 100000, 3.688, 3.64, 100000, 100000, 1.72933333333333, 0, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 4.244, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},//9
{100000, 100000, 100000, 100000, 100000, 1.916, 1.28666666666667, 100000, 100000, 0, 100000, 1.604, 100000, 100000, 100000, 4.67333333333333, 6.23866666666667, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},//10
{100000, 100000, 100000, 100000, 100000, 2.22, 100000, 100000, 100000, 100000, 0, 100000, 1.92, 100000, 2.124, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},//11
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 1.604, 100000, 0, 100000, 100000, 1.384, 3.55066666666667, 5.116, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},//12
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 1.92, 100000, 0, 1.73333333333333, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 3.22666666666667, 100000, 100000},//13
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 1.73333333333333, 0, 2.88, 5.604, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 8.38, 100000, 100000, 100000},//14
{100000, 100000, 100000, 100000, 100000, 100000, 6.26, 100000, 100000, 100000, 2.124, 1.384, 100000, 2.88, 0, 3.72, 100000, 3.76666666666667, 4.50666666666667, 100000, 5.788, 7.4, 100000, 100000, 100000, 100000, 100000, 100000},//15
{100000, 100000, 100000, 100000, 100000, 100000, 4.44, 2.68933333333333, 100000, 4.67333333333333, 100000, 3.55066666666667, 100000, 5.604, 3.72, 0, 2.4, 100000, 1.10533333333333, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 15.72, 100000},//16
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 4.244, 6.23866666666667, 100000, 5.116, 100000, 100000, 100000, 2.4, 0, 100000, 100000, 2.42666666666667, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000},//17
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 3.76666666666667, 100000, 100000, 0, 5.27866666666667, 100000, 2.54, 100000, 100000, 5.304, 100000, 100000, 100000, 100000},//18
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 4.50666666666667, 1.10533333333333, 100000, 5.27866666666667, 0, 3.692, 5.048, 4.33066666666667, 100000, 100000, 100000, 100000, 100000, 100000},//19
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 2.42666666666667, 100000, 3.692, 0, 100000, 5.19066666666667, 4.392, 100000, 100000, 100000, 100000, 100000},//20
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 5.788, 100000, 100000, 2.54, 5.048, 100000, 0, 100000, 100000, 3.292, 100000, 100000, 100000, 5.58133333333333},//21
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 7.4, 100000, 100000, 100000, 4.33066666666667, 5.19066666666667, 100000, 0, 2.10266666666667, 100000, 100000, 100000, 4.86, 5.17466666666667},//22
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 4.392, 100000, 2.10266666666667, 0, 100000, 100000, 100000, 4.44933333333333, 100000},//23
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 5.304, 100000, 100000, 3.292, 100000, 100000, 0, 4.236, 100000, 100000, 4.90133333333333},//24
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 8.38, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 4.236, 0, 4.61066666666667, 100000, 14.14},//25
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 3.22666666666667, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 4.61066666666667, 0, 100000, 100000},//26
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 15.72, 100000, 100000, 100000, 100000, 100000, 4.86, 4.44933333333333, 100000, 100000, 100000, 0, 2.94},//27
{100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 100000, 5.58133333333333, 5.17466666666667, 100000, 4.90133333333333, 14.14, 100000, 2.94, 0}//28
};//消耗天数矩阵
std::stack<int> finalroad;
int finalroad2[N];
void Difindpath();//算出最短路径
int findpathwithboundary(double bound);//算出有约束条件的最短路径
void Difindcost();//算出最小耗时
void showpath(int i);//展示最短路径
//*终点*到每个节点的最短路径
void Difindpath(){
int is[N];//确认该节点是否选用
double distance[N];//各点最短路径
double destination=0;
int road[N];//上一节点
for(int h=0;h<N;h++){
distance[h]=MAX;//初始化各点最短路径,除终点外其余都为最大路径
is[h]=0;
}
distance[N-1]=0;
//最多进行N-1次循环
for(int k=1;k<N;k++){
int max=100000;//路径最大值
int u=N-1;//u为已经找到最短路径的节点,初始状态都为终点N-1
for(int i=N-1;i>=0;i--){
if(is[i]==0 && distance[i]<max){
u=i;
max=distance[i];
}
}
is[u]=1;
//找出一点后更新其余点的最短路径
for(int y=N-1;y>=0;y--){
if(is[y]==0 && distance[u]+path[u][y]<distance[y]){
distance[y]=distance[u]+path[u][y];
road[y]=u;
}
}
}
for(int j=0;j<N;j++){
shortesetpath[j]=distance[j];//赋值给最短路程
finalroad2[j]=road[j];
}
int k1=0;
int next;
while(k1!=N-1){
next=road[k1];
destination=destination+cost[k1][next];
k1=next;
}//遍历出最短路程的耗时
costOfMinPath=destination;//最短路消耗的时间
cout<<"最小成本所消耗的时间为:"<<costOfMinPath<<endl;
}
//*终点*到各个节点的最短耗时
void Difindcost(){
int is[N];//确认该节点是否选用
double distance[N];//各点最短耗时
double destination=0;
int road[N];//上一节点
for(int h=0;h<N;h++){
distance[h]=MAX;//初始化各点最短路径,除终点外其余都为最大路径
is[h]=0;
}
distance[N-1]=0;
//最多进行N-1次循环
for(int k=1;k<N;k++){
int max=100000;//路径最大值
int u=N-1;//u为已经找到最短路径的节点,初始状态都为终点N-1
for(int i=N-1;i>=0;i--){
if(is[i]==0 && distance[i]<max){
u=i;
max=distance[i];
}
}
is[u]=1;
//找出一点后更新其余点的最短耗时
for(int y=N-1;y>=0;y--){
if(is[y]==0 && distance[u]+cost[u][y]<distance[y]){
distance[y]=distance[u]+cost[u][y];
road[y]=u;
}
}
}
for(int j=0;j<N;j++){
minestcost[j]=distance[j];//赋值给最短消耗时间
}
int k1=0;
int next;
while(k1!=N-1){
next=road[k1];
destination=destination+path[k1][next];
k1=next;
}//遍历出耗时最短的路程
minPath=destination;//最短耗时(可行解)的路程作为上界
cout<<"最短时间路径所消耗的成本为:"<<minPath<<endl;
/*int k=0;
while(k!=N-1){
int k1;
k1=k+1;
cout<<k1<<"->";
k=road[k];
}
//cout<<N<<' '<<"路径为"<<shortesetpath[0]<<"耗时为"<<costOfMinPath<<endl;*/
}
//分支定界法确定符合条件的最优解
int findpathwithboundary(double bound){
int is[N];//判断节点是否已经被遍历
int pnow;//现在检索的节点
double nowpath=0;
double nowcost=0;
int lastout=-1;//确定弹出的节点
int tag=0;//标识位,看是否找到下一个节点
std::stack<int> p;//利用栈实现深度优先遍历
p.push(0);//起点入栈
for(int i1=0;i1<N;i1++)
is[i1]=0;
is[0]=1;//赋初值,起点被遍历过
if(costOfMinPath<bound)
{
return 1;//所选择的最短路径符合条件
}
if(minestcost[0]>bound)
return 2;
while(!p.empty())//栈非空说明需继续遍历
{
pnow=p.top();
//cout<<1<<endl;
for(int i=0;i<N;i++){
if(is[i]==1||i<=lastout)//已经遍历过的节点
continue;
if(path[pnow][i]<MAX)//pnow与i节点之间有路
{
if(nowpath+shortesetpath[i]>=minPath||nowcost+minestcost[i]>bound)//没有当前解好或者不满足条件
continue;
if(nowpath+path[pnow][i]>=minPath||nowcost+cost[pnow][i]>bound)//不满足条件
continue;
if(i==N-1)//pnow为终点,已找到一条最短路径
{
minPath=nowpath+path[pnow][i];
costOfMinPath=nowcost+cost[pnow][i];
nowpath=minPath;//回溯
nowcost=costOfMinPath;
p.push(i);//押回栈中,下一步检索
finalroad=p;//返回该路径
break;
}
else//找到下一节点
{
tag=1;
nowpath=nowpath+path[pnow][i];
nowcost=nowcost+cost[pnow][i];
p.push(i);//下一个城市选中,压入栈中
lastout=-1;
is[i]=1;//节点这次已经被遍历
break;
}
}
}
if(tag==0)//该次遍历没有得到下一节点
{
lastout=p.top();//弹出顶部节点
p.pop();//移除顶部节点
if(p.empty())//栈为空则退出循环
break;
pnow=p.top();//查询顶部节点
is[lastout]=0;
nowpath=nowpath-path[pnow][lastout];
nowcost=nowcost-cost[pnow][lastout];//该节点之前的道路不再计算
}
tag=0;//循环最后令标志位为零
}
return 0;//最短路径做出了改变
}
void showpath(int i){
if(i==1)//直接输出最短路径结果
{
int k=0;
while(k!=N-1){
int k1;
k1=k+1;
cout<<k1<<"->";
k=finalroad2[k];
}
cout<<N<<' '<<"成本为"<<shortesetpath[0]<<"耗时为"<<costOfMinPath<<endl;
}
if(i==0)//输出改变条件后的最短路径
{
while(finalroad.size()!=1){
int pnow,pout;
pnow=finalroad.top();
finalroad.pop();
pout=pnow+1;
cout<<pout<<"<-";
}
cout<<1<<' '<<"路径为"<<minPath<<"耗时为"<<costOfMinPath<<endl;
}
if(i==2)
{
cout<<"约束太小不能达成目标"<<endl;
}
}
int main(){
Difindcost();
Difindpath();//初始化数组
/*double bound;
std::cout<<"请输入时间限制:";
std::cin>>bound;*/
double bound;
//输出遍历完后的数组
cout<<"各地到终点的最小成本为:"<<endl;
for(int i=0;i<N;i++)
cout<<shortesetpath[i]<<" ";
cout<<endl;
cout<<"各地到终点的最短时间为:"<<endl;
for(int j=0;j<N;j++)
cout<<minestcost[j]<<" ";
cout<<endl;
cout<<"请输入时间限制:";
cin>>bound;
int tag;//标志位
tag=findpathwithboundary(bound);
showpath(tag);
//cout<<minPath;
//cout<<costOfMinPath;
system("pause");
return 0;
}
结果分析
本次测试输入约束bound为28h,可获得结果:
28<-27<-16<-8<-7<-4<-2<-1 路径为384.1耗时为27.812
对比结果可得此结果为该模型中满足输入约束条件的最优路径
同时我将最短时间路程所消耗的成本和最小成本路程所消耗的时间都输出了出来
程序实现界面如下图所示
在地图上标出:
其中红色的路线是模型三选取的在时间约束条件下的最优成本路径