动态规划-多段图问题的python实现方法
matlab用了俩月,python刚学没几天,肯定有很多需要改进的地方,欢迎大家批评指正。
(这是为了完成作业写了两天才写出来的)
问题描述
多段图G=(V,E)是一个有向图。它具有如下特性:图中的节点被划分成k≥2个不相交的集合V_i,1≤i≤k,其中V_i和V_k分别只有一个节点s(源点)和t(汇点)。图中所有的边<u,v>均具有如下性质:若u∈V_i,则v∈V_(i+1),1≤i<k-1,且每条边<u,v>均附有成本c(u,v)。从s到t的一条路径成本是这条路径上边的成本和。多段图问题是求由s到t的最小成本路径。每个集合V_i定义图中的一段。由于E的约束,每条从s到t的路径都是从第1段开始,在第k段终止。下图所示为一个5段图
算法流程
多段图的向后处理算法:首先从V_1出发,计算s到V_2每个节点的成本并记录,用BCOST(i,j)表示第i个集合的结点j到源点s的最小成本。那么:BCOST(1,1)=0;BCOST(2,2)=min{BCOST(1,1)+c(1,2)}=9,同理:BCOST(2,3)=7;BCOST(2,4)=3;BCOST(2,5)=2;
再计算第三个集合:
BCOST(3,6)=min{BCOST(2,2)+c(2,6),BCOST(2,3)+c(3,6)},同理:BCOST(3,7)=11;BCOST(3,8)=10。
第四集合:
BCOST(4,9)=min{BCOST(3,6)+c(6,9),BCOST(3,7)+c(7,9)}= 15,同理:BCOST(4,10)=14;BCOST(4,11)=16。
第五集合:
BCOST(5,12)=min{BCOST(4,9)+c(9,12),BCOST(4,10)+C(10,12), BCOST(4,11)+c(11,12)}=16。
由此得出s到t的最小成本路径为16。
代码实现
# 多段图的向后处理算法
ddt = dict() # 定义多段图的线段成本为空字典
point = []
while 1:
inf = input('请输入边信息:(点a 点b 成本)(输入0结束)')
if inf == '0':
break
else:
str1 = inf.split(' ', 2)[0]
str2 = inf.split(' ', 2)[1]
int3 = int(inf.split(' ', 2)[2])
point.append(int(str1))
point.append(int(str2))
str4 = 'c('+str1+','+str2+')'
ddt[str4] = int3 # 通过循环将输入值存储在字典中
s = input('请输入起点:') # 定义起点
t = input('请输入终点:') # 定义终点
Vnum = int(input('请输入中间集合的数量(不包含起点和终点):')) #定义集合
V = [[s]]
for item in range(1, Vnum + 1):
p = input('请输入中间第'+str(item)+'阶段的点:')
P = p.split(' ')
V.append(P)
V.append([t])
Bcost = {'(1,1)': 0} # 定义成本集合
path = {} # 存储路径
pa = {} # 存储最小路径
for i in range(1, Vnum + 2): # 通过循环计算每个集合的每个节点到起点的最小成本
VV1 = V[i][:]
for j in VV1:
key = '('+str(i+1)+','+j+')'
interim = []
VV2 = V[i-1][:]
for z in VV2:
key2 = '('+str(i)+','+z+')'
B = Bcost.get(key2)
c = 'c('+z+','+j+')'
cost = ddt.get(c, 'None')
if cost != 'None':
value = int(B) + int(cost)
interim.append(value)
path[str(value)] = z
Bcost[key] = min(interim)
pa[j] = path.get(str(Bcost[key]))
pathlist = [t]
interim2 = t
for x in range(Vnum): # 计算最小路径节点
interim2 = pa.get(interim2)
pathlist.append(interim2)
pathlist.append(s)
pathlist = pathlist[::-1]
print('从', s, '到', t, '的最小路径为:', pathlist) #结果输出
mincost = (Bcost.get(key))
print('从', s, '到', t, '的最小成本为:', mincost) #结果输出
注意:输入时数字之间用空格隔开,程序才能将其分割并保存。