使用分支限界求解有约束最短路径问题
题目描述
用分支定界算法求以下问题:
某公司于乙城市的销售点急需一批成品,该公司成品生产基地在甲城市。
甲城市与乙城市之间共有 n 座城市,互相以公路连通。甲城市、乙城市以及其它各城市之间的公路连通情况及每段公路的长度由矩阵M1 给出。
每段公路均由地方政府收取不同额度的养路费等费用,具体数额由矩阵M2 给出。
请给出在需付养路费总额不超过 1500 的情况下,该公司货车运送其产品从甲城市到乙城市的最短运送路线。
具体数据参见文件:
M1.txt: 各城市之间的公路连通情况及每段公路的长度矩阵(有向图); 甲城市为城市Num.1,乙城市为城市Num.50。
M2.txt: 每段公路收取的费用矩阵(非对称)。
求解思路
- 利用 dijkstra 算法计算每个点到终点的最短距离和最小花费,D[i]表示节点 i 和终点之间的最短距离,C[i] 表示节点 i 和终点之间的最短距离
- 设定初始最短距离 minDist= 9999,初始化队列为[(node = 0,dist = 0 ,cost = 0)],node为节点序号,dist为展开到节点时走过的总距离,cost为展开到节点时的总 cost
- 从队列中取出一个节点 n 进行展开,对于每个可能被展开的节点 m ,首先进行剪枝操作,如果 dist + m1[n][m] + D[m] > minDist (下界大于当前最短距离)或者 cost + m2[n][m] + C[m] >1500(花费的下界超标),则剪掉节点 m
- 如果 m = end 并且 dist+m1[n][m] + D[m] <minDIst , 说明找到一个当前最优路径,更新最短距离 minDist = dist
- 对剩余的节点按照距离下界进行升序排序之后放入队列,优先展开下界最小的节点
- 重复步骤 3-5,直到队列为空,算法停止后得到的 minDist 为最优解
伪代码
minDist = 9999
maxCost = 1500
queue = [(node = 0, dist = 0, cost = 0)]
allNode = [0,1,.....50]
en = 50
D = dijkstra(transpose(m1))
C = dijkstra(transpose(m2))
while(!isEmpty(queue))
{
(n,dist,cost) = queue.pop()
nodeList = allNode.delete(n)
for(m in nodeList){
if(m1[n][m]+dist+D[m] > minDist or cost+m2[n][m]+C[m] > maxCost){
nodeList.delete(m)
continue
}
if(m == en and dist+m1[n][m]+D[m] < minDist)
minDist = dist+m1[n][m]+D[m]
}
sort(nodeList,by = dist+m1[n][m]+D[m])
for(m in nodeList){
queue.push((node = m, dist = dist+m1[n][m]+D[m], cost = cost+m2[n][m]+C[m]))
}
}
print minDist