从方形矩阵组成边

时间:2015-01-02 15:44:04

标签: python algorithm graph

我发现了一些有趣的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方法。有什么建议?

2 个答案:

答案 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)