基于多段图问题的动态规划算法设计-python

目录

算法描述

1.伪代码

2.代码思路

源代码

复杂度分析

程序的运行结果及截图

总结与改进


算法描述

1.伪代码

MultiStageGraph(G, k, n, p[]) {     
//输入 n 个结点的 k 段图,假设顶点按段的顺序编号     
//E(G)是边集,p[1,2,…,k]是最小成本路径     
    new cost[n];     
    new d[n];     
    cost[0] = 0;     
    for i = 1 upto n-1 do {     
        cost[i] = ∞;     
        while (任意<i, r>∈E(G)) {     
            if (c(i, r) + cost[r] < cost[i]) {     
                cost[i] = c(i, r) + cost[r];     
                d[i] = r;     
            }     
        }     
}     
p[0] = 0;     
p[k-1] = n;     
for i = 0 to k - 1 do {     
    p[i] = d[p[i]];     
}     
}   

2.代码思路

       通过动态规划的方式,逐步计算每个节点的最小成本,并最终得到最小成本路径。首先对节点的成本进行初始化,然后通过遍历每个节点,计算出每个节点的最小成本。最后输出最小代价和计算得到的最小成本路径。

源代码

def MultiStageGraph(G, k, n, p):
    """
    计算 n 个结点的 k 段图中的最小成本路径

    Args:
    G (list): 边集,每个元素是一个三元组 (起点, 终点, 成本)
    k (int): 图的段数
    n (int): 结点个数
    p (list): 用于存储最小成本路径的列表,长度为 k

    Returns:
    无返回值,最小成本路径存储在参数 p 中
    """
    cost = [0] * n  # 存储每个节点的最小成本
    d = [-1] * n      # 存储对应最小成本路径的前一个节点
    cost[0] = 0       # 起始节点的成本为 0

    # 计算每个节点的最小成本
    for i in range(1, n):
        cost[i] = float('inf')  # 初始化成本为无穷大
        for edge in G:
            if edge[1] == i:  # 只考虑终点在当前结点的边
                r = edge[0]     # 起点
                if edge[2] + cost[r] < cost[i]:  # 如果经过当前边到达终点的成本更小
                    cost[i] = edge[2] + cost[r]   # 更新最小成本
                    d[i] = r  # 记录对应最小成本路径的前一个节点

    print("最小代价为:", cost[n-1])

    # 计算最小成本路径
    p[0] = 0
    p[k-1] = n-1
    for i in range(k - 2, 0, -1):
        p[i] = d[p[i+1]]

# 用户输入
n = int(input("请输入节点数n:"))
k = int(input("请输入段数k:"))
edge_num=int(input("请输入边数:"))   
G = []
print("输入边(起点 终点 成本)")
for _ in range(edge_num):
    edge = tuple(map(int, input().split()))
    G.append(edge)

p = [0] * k

# 调用算法并输出结果
MultiStageGraph(G, k, n, p)
print("路径为:",p)

复杂度分析

时间复杂度取决于节点数 n、段数 k 和边数 m。

初始化 cost 和 d 列表的时间复杂度为 O(n)。

计算每个节点的最小成本的时间复杂度为 O(m*n),因为对于每个节点,都需要考虑每条边。

计算最小成本路径的时间复杂度为 O(k),因为只需遍历段数次。

因此,总体时间复杂度为 O(m*n + k)。

空间复杂度方面,主要是存储了两个长度为 n 的列表 cost 和 d,以及一个长度为 k 的列表 p,因此空间复杂度为 O(n + k)。

程序的运行结果及截图

测试数据:
0 1 9
0 2 7
0 3 3
0 4 2
1 5 4
1 6 2
1 7 1
2 5 2
2 6 7
3 7 11
4 6 11
4 7 8
5 8 6
5 9 5
6 8 4
6 9 3
7 9 5
7 10 6
8 11 4
9 11 2
10 11 99

总结与改进

实现了多段图中的最小成本路径计算算法。通过动态规划的方式,逐步计算每个节点的最小成本,并最终得到最小成本路径。首先对节点的成本进行初始化,然后通过遍历每个节点,计算出每个节点的最小成本。最后输出最小代价和计算得到的最小成本路径。

但是,在该算法中,如果多段图有两条或两条以上的最短路径(代价相同,路径不同),那么该算法只能给出一条,修改时,需要把路径p设置成一个多维列表,储存多个最短路径,还要把d设置成多维变量,以储存到达i结点的代价相同的n个前置结点,仍然复杂。

因此,设计如下通过深度优先搜索,可以找到所有的最短路径,以下是代码和结果。

def MultiStageGraph(G, k, n, p):
    """
    计算 n 个结点的 k 段图中的最小成本路径

    Args:
    G (list): 边集,每个元素是一个三元组 (起点, 终点, 成本)
    k (int): 图的段数
    n (int): 结点个数
    p (list): 用于存储最小成本路径的列表

    Returns:
    无返回值,最小成本路径存储在参数 p 中
    """
    cost = [0] * n  # 存储每个节点的最小成本
    cost[0] = 0  # 起始节点的成本为 0

    # 计算每个节点的最小成本和路径数量
    for i in range(1, n):
        cost[i] = float('inf')  # 初始化成本为无穷大
        for edge in G:
            if edge[1] == i:  # 只考虑终点在当前结点的边
                r = edge[0]  # 起点
                if edge[2] + cost[r] < cost[i]:  # 如果经过当前边到达终点的成本更小
                    cost[i] = edge[2] + cost[r]  # 更新最小成本

    print("最小代价为:", cost[n-1])

    # 使用深度优先搜索找到所有的最短路径
    def dfs(u, path):
        if u == 0:
            p.append(path[::-1])
            return
        for edge in G:
            if edge[1] == u and cost[u] == cost[edge[0]] + edge[2]:
                dfs(edge[0], path + [edge[0]])

  
    dfs(n-1, [n-1])

    print("最小成本路径为:", p)

# 用户输入
n = int(input("请输入节点数n:"))
k = int(input("请输入段数k:"))
edge_num = int(input("请输入边数:"))
G = []
print("输入边(起点 终点 成本)")
for _ in range(edge_num):
    edge = tuple(map(int, input().split()))
    G.append(edge)

p = []

# 调用算法并输出结果
MultiStageGraph(G, k, n, p)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值