最短路径代价MCP算法(做了小改动,不仅能输出最小权值,而且能输出路径)

要学习别人的算法和思考如何修改算法–牢记!

一、关于MCP算法

在这里插入图片描述如上图,给定一个矩阵,和一个位置(m,n)怎么找到其到(0,0)的最短路径代价,可以看出 (0, 0) –> (0, 1) –> (1, 2) –> (2, 2)。这个时候路径的最短代价 8 (1 + 2 + 2 + 3)。那么编程如何实现?
借用下面公式:minCost(m, n) = min (minCost(m-1, n-1), minCost(m-1, n), minCost(m, n-1)) + cost[m][n]
那么代码用递归实现如下:

R = 3
C = 3
import sys 
def minCost(cost, m, n): 
    if (n < 0 or m < 0): 
        return sys.maxsize 
    elif (m == 0 and n == 0): 
        return cost[m][n] 
    else: 
        return cost[m][n] + min( minCost(cost, m-1, n-1), 
                                minCost(cost, m-1, n), 
                                minCost(cost, m, n-1) ) 
def min(x, y, z): 
    if (x < y): 
        return x if (x < z) else z 
    else: 
        return y if (y < z) else z 

cost= [ [1, 2, 3], 
        [4, 8, 2], 
        [1, 5, 3] ] 
print(minCost(cost, 2, 2)) 
输出值为:8

二、如何输出路径和权重?

上面代码输出的最短路径代价,那么我想得到路径怎么办?其实很改动和简单,代码如下:

# 最小代价路径(加权)MCP算法
R = 3
C = 3
import sys 
def minCost(cost,m, n): 
    if (n < 0 or m < 0): 
        return sys.maxsize 
    elif (m ==0 and n == 0):
        return cost[m][n] 
    else: #这里使用了技巧,输出的不在是最小权值,而是由权值和路径(r,c)组成的一个字符串
        return str(cost[m][n])+str(m)+str(n)+" "+min( str(minCost(cost, m-1, n-1)), 
                                str(minCost(cost,m-1, n)), 
                                str(minCost(cost, m, n-1)))
def parser(path,sx,sy):#解译路径和权组成的字符串
    pathdict={}
    pathList=path.strip().split()[::-1]
    pathList=path.split()[::-1]
    for i,e in enumerate(pathList):
        if i==0:
            pathdict[(sx,sy)]=e ####这里注意的是如果用权值作为字典的key,
			#如果权值相同那么就会出现问题(python3 dict 根据key 去重)
            continue
        pathdict[(eval(e[1]),eval(e[2]))]=e[0]
    return pathdict
def min(x, y, z): 
    if (x < y): 
        return x if (x < z) else z 
    else: 
        return y if (y < z) else z  
# 
cost= [ [1, 2, 3,4], 
        [4, 8, 2,5], 
        [1, 5, 3,2] ] 
path=minCost(cost, 2, 1)
print(parser(path,0,0))
输出:{(0, 0): '1', (1, 0): '4', (2, 0): '1', (2, 1): '5'}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值