动态规划-多段图问题的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)  #结果输出

在这里插入图片描述

注意:输入时数字之间用空格隔开,程序才能将其分割并保存。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值