二维数组中最小路径和的Python实现
问题:已知随机生成的二维数组数据,例如
[ [7,8,4,1],
[5,6,3,2],
[4,3,5,9],
[6,8,1,4]]
查找从左上端到右下角的最小路径和和路径,注意路径只能向右和项下走,一直走到最右下角为止。
算法运用动态规划,遍历整个数组,直到右下角为止。需要两个辅助数组,一个记录最小和的数据,一个记录最小和的路径。
以下是用Python实现的代码,用turtle实现效果。
import random
import turtle
import time
#产生数据的二维表格,以5维为例,随机产生的数据范围,可修改为任意。
import random
import turtle
import time
#产生数据的二维表格
X_Y = 5
NUM_MIN = 1
NUM_MAX = 20
my_numb_lists=[]
dp_array = [[0 for j in range(X_Y) ] for i in range(X_Y)]
dp_dir_array = [[0 for j in range(X_Y) ] for i in range(X_Y)]
for i in range(X_Y):
my_numb_lists.append([])
for j in range(X_Y):
my_numb_lists[i].append(random.randint(NUM_MIN,NUM_MAX))
print(my_numb_lists)
#利用海龟,绘制GUI图形
turtle.screensize(1000,800,'pink')
turtle.hideturtle()
turtle.speed(8)
turtle.right(0)
for i in range(X_Y+1):
turtle.penup()
turtle.goto(-200,200-i*100)
turtle.pendown()
turtle.forward(100*X_Y)
turtle.right(90)
for i in range(X_Y+1):
turtle.penup()
turtle.goto(-200+i*100,200)
turtle.pendown()
turtle.forward(100*X_Y)
def fresh_display():
for i in range(X_Y):
for j in range(X_Y):
turtle.penup()
turtle.goto(-150+j*100,150-i*100)
if dp_dir_array[i][j] == 0:
turtle.pencolor("Black")
turtle.write(my_numb_lists[i][j],align="center", font=("Courier", 20, "bold"))
else:
turtle.pencolor("Blue")
turtle.write(my_numb_lists[i][j],align="center", font=("Courier", 20, "bold"))
fresh_display()
#动态规划解决最小路径问题
for i in range(X_Y):
for j in range(X_Y):
if i==0 and j==0:
dp_array[0][0] = my_numb_lists[0][0]
elif i == 0:
dp_array[0][j] = dp_array[0][j-1]+my_numb_lists[0][j]
elif j == 0:
dp_array[i][0] = dp_array[i-1][0]+my_numb_lists[i][0]
else:
a_b_i = dp_array[i-1][j]
a_b_j = dp_array[i][j-1]
if a_b_i <= a_b_j:
dp_array[i][j] = a_b_i + my_numb_lists[i][j]
# dp_array[i][j-1] = 0
else:
dp_array[i][j] = a_b_j + my_numb_lists[i][j]
# dp_array[i-1][j] = 0
print(dp_array)
#产生最小路径的轨迹(非0)
ii,jj = X_Y-1,X_Y-1
dp_dir_array[0][0] = 1
dp_dir_array[X_Y-1][X_Y-1] = 1
while ii or jj :
if jj == 0 :
dp_dir_array[ii][jj] = 1
ii-=1
continue
elif ii == 0:
dp_dir_array[ii][jj] = 1
jj-=1
continue
if dp_array[ii][jj] - my_numb_lists[ii][jj] == dp_array[ii][jj-1]:
dp_dir_array[ii][jj-1] = 1
jj-=1
else:
dp_dir_array[ii-1][jj] = 1
ii-=1
print(dp_dir_array)
fresh_display()
turtle.done()在这里插入代码片
下图为实现的效果
![在这里插入图片描述](https://img-blog.csdnimg.cn/481a9130170e42a49b3bba87d599454b.png#pic_center
python控制台的输出:
[[11, 4, 8, 5, 17], [19, 11, 19, 1, 18], [20, 1, 2, 8, 6], [9, 13, 2, 18, 19], [10, 5, 4, 3, 18]]
[[11, 15, 23, 28, 45], [30, 26, 42, 29, 47], [50, 27, 29, 37, 43], [59, 40, 31, 49, 62], [69, 45, 35, 38, 56]]
[[1, 1, 0, 0, 0], [0, 1, 0, 0, 0], [0, 1, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 1, 1]]
最小路径和即为蓝色的数字相加11+4+11+1+2+2+4+3+18 = 56