我发现了一些有趣的Project Euler问题(81-83)。它们都是"找到最短路径的变体"通过这个方阵。我将使用Djikstra的最短路径算法一次解决所有这些问题。它们每个都有自己奇怪的变化,但都可以用各种边缘设置建模(有些问题只能移动"向右和向下"其他问题是"上/下/左/右&#34 ;)
无论如何,我以为我已经写了一个光滑的方式来概括边缘构造,使用"模式列表"为给定节点指定哪些相邻节点可以创建边缘。此代码的片段如下:
def makeGraph(fn="smallMatrix.txt", modes = [(0,1), (0,-1), (-1,0), (1,0)]):
for row in range(0, len(network)):
for col in range(0, len(network[row])):
#create edges
edgesFromNewNode = []
for mode in modes:
try:
#newEdge = ( edgeLength, (destination row, col) )
newEdge = ( network[row+mode[0]][col+mode[1]], ( row+mode[0] , col+mode[1] ) )
edgesFromNewNode.append(newEdge)
except IndexError:
pass
edgeCatalog[(row, col)] = edgesFromNewNode
所以我无法理解为什么节点(0,0)(左上角节点)有四条边 - 它应该只有两个有效的(1,0)和(0,1)。然后我意识到,当我将模式掩码应用到(0,0)时,我会得到像(0,-1)和(-1,0)这样的东西,其中AREN&#T; T索引错误 - 它们是'说使用列表的末尾。
在处理row = 0或col = 0时,我可以用一堆粗略的if-then-else案例来解决这个问题,但是它很糟糕。我希望有更多的pythonic方法。有什么建议?
答案 0 :(得分:1)
通常说网格大小为 m 行 n 列,您可以从单元格移动到任何有效的相邻单元格。然后您可以使用方向数组(类似于你的模式)
dx[4]={0,-1,0,1} // movement in rows
dy[4]={-1,0,1,0} // movement in columns
现在假设您在 x,y 的单元格中,并且您想要转到其有效的相邻单元格
int valid(int i,int j)
{
if(i>=0&&i<m&&j>=0&&j<n)return 1;
return 0;
}
for(i=0;i<4;i++)
{
new_x=dx[i]+x;
new_y=dy[i]+y;
if( valid(new_x,new_y) )
{
/* new_x,new_y is valid adjacent cell
do whatever you want to process with it */
}
}
我认为这种方式更干净。
答案 1 :(得分:1)
明确。以下变体并不比try... except IndexError:
if 0 <= row+mode[0] < len(network):
if 0 <= col+mode[1] < len(network[row]):
newEdge = (...)
edgesFromNewNode.append(newEdge)