矩形从左上角到右下角找最短路
题目: 如下图: 从起点出发,只能想右或者向下走,然后走到终点。。方框里面的数值代表代价,我们要找一条代价比较小的路径。。怎样做呢? 快去想想。。
分析:
动态规划走起 i 代表行, j 代表列,我们走一步,累加一步,然后进行选择。
下面分情况:
当 i = 0 (也就是第一行): 我们如果走这条路,每走一步,路径累加。所有就有下式子:
m[0][j] = m[0][j-1] + m[0][j] 就是路径的累加
当 j = 0 (也就是第一列):我们从这条路走,每走一步,也进行累加
m[i][0] = m[i-1][0] + m[i][0]
当i != 0 并且 j != 0 时, 我们就要找从上面下来走这里好,还是从左边过来走这里好? 显然是谁小,找谁。。这样代价就小呀,如下式:
m[i][j] = max(m[i-1][j] , m[i][j-1]) + m[i][j]
打印路径: 我们刚才每就按一个点,我们都会标记此点的计算是从哪个方向来的(上或者左)。。现在打印路径,我们从右下边的那个元素开始,如果标记向上,我们就先上,向左,我们就向左。。直至到起点。。
代码实现:
def short_path(mat):
    i = len(mat)    # 行数
    j = len(mat[0])  # 列数
    # 建立一个标志矩阵  代表着我们当前往哪里走
    sign = [[None for k in range(j)] for m in range(i)]
    sign[0][0] = '起点'
    for k in range(1, j):
        mat[0][k] += mat[0][k-1]
        sign[0][k] = '向左'
    for m in range(1, i):
        mat[m][0] += mat[m-1][0]
        sign[m][0] = '向上'
    for k in range(1, j):
        for m in range(1, i):
            temp = min(mat[m-1][k], mat[m][k-1])
            if temp == mat[m-1][k]:
                sign[m][k] = '向上'
            if temp == mat[m][k-1]:
                sign[m][k] = '向左'
            mat[m][k] += temp
    for item in sign:
        print(item)
    return mat, sign
def print_path(sign):
    path = []
    i = len(sign) -1
    j = len(sign[0])-1
    while i > 0 and j > 0:
        if sign[i][j] == '向左':
            j -= 1
            path.append('向左')
        if sign[i][j] == '向上':
            i -= 1
            path.append('向上')
    path.append('起点')
    return path
if __name__ == '__main__':
    matrix = [[2, 3, 1, 4, 4],
              [2, 1, 4, 5, 3],
              [3, 0, 2, 3, 6],
              [4, 3, 2, 0, 8],
              [4, 2, 0, 2, 1]]
    mat, sign = short_path(matrix)
    # 打印路径
    path = print_path(sign)
    print("从终点会起点的路径:", path)  输出结果:
我们在按照打印的路径画出来

京公网安备 11010502036488号