Lua(trAInsported):尝试实现Wavefront算法,但不起作用

我正在尝试实现波前算法,但该函数存在问题,该函数会生成具有特定渐变的地图。

我尝试了以下几种不同版本的代码,但没有一个起作用。

如果尚未更改梯度,则应将算法(目标)的起点设置为1,然后增加每个邻居的梯度上的该点(类似于每个波前算法)。

originXoriginY是目标,应该从中开始算法。 mapMatrix是全局变量

mapMatrix看起来像这样:

0 0 0 0 0 0 0
0 0 N 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 N 0 0 N 0 N
N N 0 0 N 0 0 
0 0 0 0 0 0 0

(对于铁轨为0,对于障碍物为N(无))

预期的输出示例:

7 6 5 4 3 4 5
6 5 N 3 2 3 4
5 4 3 2 1 2 3
6 5 4 3 2 3 3
7 N 5 4 N 4 N
N N 6 5 N 5 6 
9 8 7 6 7 6 7

以下面的代码为例:

function pathFinder(originX,originY)
    northDir = originY - 1
    eastDir = originX + 1
    southDir = originY + 1
    westDir = originX - 1

    if northDir > 0 and mapMatrix[originX][northDir] == 0 then 
        mapMatrix[originX][northDir] = mapMatrix[originX][originY] + 1
        pathFinder(originX,northDir)

    end
    if eastDir <= 7 and mapMatrix[eastDir][originY] == 0 then 
        mapMatrix[eastDir][originY] = mapMatrix[originX][originY] + 1
        pathFinder(eastDir,originY)

    end
    if southDir <= 7 and mapMatrix[originX][southDir] == 0 then 
        mapMatrix[originX][southDir] = mapMatrix[originX][originY] + 1
        pathFinder(originX,southDir)

    end
    if westDir > 0 and mapMatrix[westDir][originY] == 0 then 
        mapMatrix[westDir][originY] = mapMatrix[originX][originY] + 1
        pathFinder(westDir,originY)
    end
end

我得到这个mapMatrix

0 0 0 0 3 4 5
0 0 N 0 2 10 6
0 0 0 0 1 9 7
0 0 0 0 0 0 8
0 N 0 0 N 0 N
N N 0 0 N 0 0 
0 0 0 0 0 0 0

如果我切换if语句,它将产生不同版本的mapMatrix

完成northDirlocal后,输出如下所示:编辑

33 24 23 22 3 4 5
32 25 N 21 2 11 6
31 26 27 20 1 10 7
30 29 28 19 20 9 8
31 N 29 18 N 10 N
N N 30 17 N 11 12
33 32 31 16 15 14 13

如果需要更多代码或信息,我很乐意提供帮助

dunhuangheisha 回答:Lua(trAInsported):尝试实现Wavefront算法,但不起作用

您的代码根本是错误的。在第一次检查中递归调用pathFinder时,它只会朝那个方向前进,直到出现任何障碍,然后才朝下一个方向前进,依此类推。


BFS实际上是一个非常简单的算法。可以轻松地在队列上迭代地实现它,而无需进行以下任何递归:

  1. 将初始节点放入队列;
  2. 从队列中弹出第一个节点并对其进行处理;
  3. 将未处理的相邻节点推送到队列的末尾;
  4. 如果队列不为空,请转到步骤2。

在Lua的矩形矩阵上,可以用大约两三行来实现:

function gradient(matrix,originX,originY)
    -- Create queue and put origin position and initial value to it.
    local queue = { { originX,originY,1 } }

    repeat
        -- Pop first position and value from the queue.
        local x,y,value = unpack(table.remove(queue,1))

        -- Mark this position in the matrix.
        matrix[y][x] = value

        -- Check position to the top.
        if y > 1 and matrix[y - 1][x] == 0 then
            -- If it is not already processed,push it to the queue.
            table.insert(queue,{ x,y - 1,value + 1 })
        end

        -- Check position on the left.
        if x > 1 and matrix[y][x - 1] == 0 then
            table.insert(queue,{ x - 1,value + 1 })
        end

        -- Check position to the bottom.
        if y < #matrix and matrix[y + 1][x] == 0 then
            table.insert(queue,y + 1,value + 1 })
        end

        -- Check position on the right.
        if x < #matrix[y] and matrix[y][x + 1] == 0 then
            table.insert(queue,{ x + 1,value + 1 })
        end

    -- Repeat,until queue is not empty.
    until #queue == 0
end

-- Just helper function to print a matrix.
function printMatrix(matrix)
    for _,row in pairs(matrix) do
        for _,value in pairs(row) do
            io.write(string.format("%2s",value))
        end
        io.write('\n')
    end
end

local mapMatrix = {
    {   0,},{   0,'N',{ 'N',}

gradient(mapMatrix,5,3)
printMatrix(mapMatrix)

--[[
Produces:
 7 6 5 4 3 4 5
 6 5 N 3 2 3 4
 5 4 3 2 1 2 3
 6 5 4 3 2 3 4
 7 N 5 4 N 4 N
 N N 6 5 N 5 6
 9 8 7 6 7 6 7
]]

这是一个完整的脚本,可以在控制台中运行。


但是,尽管出于说明目的,此代码非常简单,但效率不是很高。每次从队列中删除第一个项目都会导致其余项目的重新索引。对于生产代码,您应该为队列实现一个链表或类似的东西。

本文链接:https://www.f2er.com/3110649.html

大家都在问