通过lua中的2d数组迭代

时间:2013-07-21 15:23:49

标签: lua multidimensional-array

我正在开始一些lua脚本,似乎陷入了一个简单的问题。

我实际上正在尝试实现Floyd-Warschall算法来计算图形的每个顶点之间的所有最短路径(http://en.wikipedia.org/wiki/Floyd - Warshall_algorithm,以简要解释算法)。它最初是用python编写的(这里是代码https://gist.github.com/DavidCain/4032399)。我的版本有点不同,为了使它适合我的主要代码,但它基本上是相同的。

这是我的评论代码。每次运行它,我都会“尝试索引字段”? (零值)“(我觉得解决方案很简单,但我似乎无法将手指放在上面。任何帮助都会受到赞赏):

function adj(bodies) --returns, from a 1d array of vertices called "bodies", a square adjacency matrix (a matrix of size number_of_vertices x number_of_vertices that tells, with a ones, if vertices are connected, or with 'infs' if they are not connected)
    n = table.getn(bodies)
    dist = {}
    for _,i in pairs(bodies) do
        dist[i] = {}
        for _,j in pairs(bodies) do
            if i == j then
                dist[i][j] = 0
            end
            if areConnected(i,j) == true then --areConnected is another function I wrote to see if, well, two particular vertices are actually connected. If they are, distance is 1, if not, distance is inf.
                dist[i][j] = 1
            else dist[i][j] = math.huge
            end
        end
    end
    return adjMatrix
end

function PhysicsDebugDraw:fw(adjMatrix) --I pass adjMatrix to this function

d = adjMatrix 

    for _,k in pairs(d) do
        for _,i in pairs(d) do
            for _,j in pairs(d) do
                d[i][j] = math.min(d[i][j], d[i][k] + d[k][j]) -- the problem is here I suspect...
            end
        end
    end
    return d
end

1 个答案:

答案 0 :(得分:1)

您没有显示adjMatrix的结构或其布局的实际外观,但是从查看三重嵌套循环来看,它的用法可能不正确。

请注意变量kij

for _,k in pairs(d) do
  for _,i in pairs(d) do
    for _,j in pairs(d) do
      d[i][j] = math.min(d[i][j], d[i][k] + d[k][j])
    end
  end
end

不是 adjMatrix的键,而是该对的值部分。记住pairs会在每次迭代时返回键后跟值。但是,使用作为密钥,您可以访问adjMatrix内容的最内层循环。

如果没有看到adjMatrix的实际结构,就很难推荐正确迭代它的解决方案。但让kij保持key部分是一个合理的开始。

for k in pairs(d) do
  for i in pairs(d) do
    for j in pairs(d) do
      d[i][j] = math.min(d[i][j], d[i][k] + d[k][j])
    end
  end
end

请注意,如果您的adjMatrix使用数字作为键并且连续(不会跳过任何数字),则可以使用#adjMatrix代替pairs(adjMatrix)

编辑:在查看您的python版本后,我做了以下观察:

  • adj返回一个方形矩阵。那就是它的宽度==高度
  • "空"细胞表示为无穷大
  • 转换为adj后表(或python dict)行和列是连续的
  • fw制作一个"浅" g
  • 的副本

假设上面的不变量是真的(如果他们不是,请告诉我),那么以下内容将是lua中更忠实的翻译:

function shallow_copy(g)
  local h = {}
  for k, v in pairs(g) do
    h[k] = v
    end
  return h
  end

--[[
eg.
g = {
        {0, 3, 8, math.huge, -4},
        {math.huge, 0, math.huge, 1, 7},
        {math.huge, 4, 0, math.huge, math.huge},
        {2, math.huge, -5, 0, math.huge},
        {math.huge, math.huge, math.huge, 6, 0},
    }
--]]
function fw(g)
  local d = shallow_copy(g)
  for k = 1, #d do
    for i = 1, #d do
      for j = 1, #d do
        d[i][j] = math.min(d[i][j], d[i][k] + d[k][j])
        end
        end
        end

  return d
  end

您可以假装end关键字不可见。 :P