问题81: https://projecteuler.net/problem=81 tldr:只需在matrix.txt(一个包含80×80矩阵的文本文件)中向右和向下移动,即可找到从左上到右下的最小路径和
这看起来像是一个加权边无环图中的最短路径问题,我将dijkstra算法应用于它。我试过的一些测试用例得到了正确的答案,但我得到了问题的错误答案
编辑:出于某种原因,当我在代码中添加注释时,它会将其格式设置为粗体,并破坏代码的格式设置,所以我将把它们放在这里
评论:
ar包含数组,sp是包含所有最短路径的备忘录 u[0]是数字,u[1]=i,u[2]=j Q是一个优先级队列,每个元素都有(值,位置x,位置y) sp是一个dict,它存储到(值、位置x、位置y)的最短路径 S存储我们已知最短路径的项目(值、位置x、位置y)
我的代码:
import numpy as np
def readfile(filename):
file = open(filename,"r")
ar=np.zeros((80,80))
sp={}
for i in range(80):
l=file.readline()
line=l.split(',')
for j in range(80):
ar[i][j]=int(line[j])
sp[(int(line[j]),i,j)]=10000000
return ar,sp
def extract_min():
min_n,i,j=100000,-1,-1
for n in Q:
if n[0]<min_n:
min_n=n[0]
i=n[1]
j=n[2]
return min_n,i,j
def adj(u):
try: a,i,j=(ar[u[1]][u[2]+1],u[1],u[2]+1)
except:a,i,j=-1,-1,-1
try: b,k,m=(ar[u[1]+1][u[2]],u[1]+1,u[2])
except:b,k,m=-1,-1,-1
return ((a,i,j),(b,k,m))
def relax(u,v):
if sp[v]>sp[u]+v[0]:
sp[v]=sp[u]+v[0]
parent[v]=u
def dijkstra():
Q.append(source)
S=[]
while len(Q)!=0:
u=extract_min()
Q.remove(u)
S.append(u)
for v in adj(u):
if v not in Q and v not in S and v[0]!=-1:
relax(u,v)
Q.append(v)
ar,sp=readfile("p081_matrix.txt")
source=(ar[0][0],0,0)
dest=(ar[79][79],79,79)
sp[source]=source[0]
Q=[]
parent={}
dijkstra()
print(sp[dest])
这个问题不需要复杂的树搜索。答案可以在单个过程中迭代计算
下面是一个简单的解决方案,它从上到下、从左到右遍历矩阵的单元格,累加总和,并根据上面和左边单元格的计算值选择最小的一个。第一行和第一列是无条件求和,因为没有备用路径可通过
随着循环的进行,R保持到前一行中每个位置的最小和路径。在上述示例中,R将按如下方式进行:
最后一行的最后一个值就是答案
注意,这种方法可以很容易地调整为使用行迭代器作为输入。这样,它将非常节省内存,因为它只需要保存2行数据即可处理输入文件
您还可以使用一种简单的递归方法,通过计算右下角单元格左上方单元格的和路径来获得结果。即使使用记忆,这也比上面的迭代解决方案慢60倍。这是一种有趣的概念方法:
更新
正如我所评论的,我不认为Dijkstra的算法是最好的方法,但我已经更新了您的代码,使其能够工作。我在修改的行中添加了注释。这些变化有两种类型:
更正后的代码:
不同的解决方案
使用路径信息发布不同的解决方案
相关问题 更多 >
编程相关推荐