加强Floyd算法和找零问题贪婪算法求解Python代码实现

加强Floyd算法,使得该算法能够求出最短路径本身,而不仅仅是它们的长度。

算法设计思想

  • 所有路径都由两条路径构成: 一条从 v i v_i vi v k v_k vk的路径,路径中每个中间顶点的编号都不大于 k − 1 k-1 k1; 一条从 v k v_k vk v j v_j vj的路径,路径中每个中间顶点的编号也都不大于 k − 1 k-1 k1

  • 设路径长度为 d d d 得到以下递推式, 当 k ≥ 1 , d i j ( 0 ) = w i j 时 , d i j ( k ) = m i n { d i j ( k − 1 ) , d i k ( k − 1 ) + d k j ( k − 1 ) } 当k\geq 1, d_{ij}^{(0)}=w_{ij}时, d_{ij}^{(k)} = min\begin{Bmatrix} d_{ij}^{(k-1)}, d_{ik}^{(k-1)} + d_{kj}^{(k-1)} \end{Bmatrix} k1,dij(0)=wijdij(k)=min{dij(k1),dik(k1)+dkj(k1)}

  • 同理路径本身也可以得到与上面相同的公式

具体步骤描述

  • 初始化邻接矩阵

  • 通过邻接矩阵来初始化路径矩阵

  • k k k 从 0 开始循环

  • 遍历邻接矩阵,按照公式处理邻接矩阵和路径矩阵

  • 当 k ≥ 1 , d i j ( 0 ) = w i j 时 , d i j ( k ) = m i n { d i j ( k − 1 ) , d i k ( k − 1 ) + d k j ( k − 1 ) } 当k\geq 1, d_{ij}^{(0)}=w_{ij}时, d_{ij}^{(k)} = min\begin{Bmatrix} d_{ij}^{(k-1)}, d_{ik}^{(k-1)} + d_{kj}^{(k-1)} \end{Bmatrix} k1,dij(0)=wijdij(k)=min{dij(k1),dik(k1)+dkj(k1)}

  • 将两个矩阵返回,即得到最短路径的长度以及最短路径本身

实现源码

import numpy as np

# 初始化邻接矩阵
W = [
    [0, np.inf, 3, np.inf, np.inf],
    [2, 0, np.inf, np.inf, 5],
    [np.inf, 7, 0, 1, np.inf],
    [6, np.inf, np.inf, 0, 11],
    [np.inf, np.inf, np.inf, np.inf, np.inf],
]

S = []

# 初始化路径矩阵
for i in range(len(W)):
    S.append([chr(97 + i) for j in range(len(W))])


def Floyd(W, S):
    D = W
    for k in range(len(W)):
        for i in range(len(W)):
            for j in range(len(W)):
                if D[i][j] > D[i][k] + D[k][j]:
                    S[i][j] = S[i][k] + S[k][j]
                    D[i][j] = D[i][k] + D[k][j]
                # 给路径矩阵添上路径终点结点
                if k == len(W) - 1:
                    S[i][j] += S[j][0][0]
    return np.array(D), np.
array(S)


W, S = Floyd(W, S)
print("3190608027 黄文焕")
print(W)
print(S)

运行结果截图

在这里插入图片描述

为找零问题写一个贪婪算法的伪代码,它以金额n和硬币的面额d1>d2>…>dm作为输入。

算法设计思想

  • 将 n 和 d1 相除,商为硬币个数,再 n 取余 d1 赋值给 n,循环下去,直到 dm

具体步骤描述

  • 输入 n 以及从大到小排列的币值

  • 循环处理 li 中的币值,n / li[index],n = n % li[index]

  • 将结果保存在字典 d 中,

  • 返回结果字典 d

实现源码

print("3190608027 黄文焕")
n = int(input("请输入n: "))
li = list(map(int, input("请从大到小输入币值: ").split()))
d = dict()
index = 0

while index < len(li):
    m = int(n / li[index])
    d[li[index]] = m
    n = n % li[index]
    index += 1
print(d)

运行结果截图

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鞠杉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值