用障碍探索网格

时间:2012-07-19 07:21:54

标签: c algorithm

我需要一种机器人算法来探索带障碍物的n * n网格(如果你愿意,可以使用迷宫)。目标是探索所有没有障碍物的广场,避开带障碍物的广场。诀窍是障碍物迫使机器人改变其路径,使其错过障碍物后面可能的自由方格。我可以懒惰地增加/减少机器人的x / y坐标,让机器人在四个方向中的任何一个方向上移动,以防没有障碍物,并且机器人可以穿过预先看到的路径(如果需要)以便到达其他自由方格。当所有自由方格至少满足一次时,算法应该终止。

任何简单的懒惰/有效方法吗?非常感谢伪代码

3 个答案:

答案 0 :(得分:1)

保留一份未探明的邻居名单。一个聪明的启发式方法,可以使用下一个访问列表中的字段来使其在必要时更有效。

伪代码(使用堆栈跟踪导致DFS的未探测邻居):

// init
Cell first_cell;
CellStack stack;
stack.push(first_cell);

while(!stack.isEmpty()) {
    Cell currentCell = stack.pop();
    currentCell.markVisisted();
    for(neighbor in currentCell.getNeighbors()) {
        stack.push(neighbor);
    }
}

答案 1 :(得分:1)

我认为问题可以从Traveling Salesman Problem减少,因此是NP - Hard,因此您不太可能找到能够以最佳和最有效的方式解决问题的多项式解决方案。

但是,您可能希望对TSP采用heuristics and approximations的一些内容,我相信它们也可以适应这个问题,因为问题似乎首先对TSP非常接近

修改

如果找不到最短路径并且您想要任何路径,那么维护访问集的简单DFS可以做到。在DFS的步骤中,您将从递归中返回 - 您移动到之前的方块,这样一来,如果有一条通向所有方块的路径,机器人将确保探索所有方块。

DFS的伪代码:

search(path,visited,current):
   visited.add(current) 
   for each square s adjacent to current:
      if (s is an obstacle): //cannot go to a square which is an obstacle
         continue
      if (s is not in visited): //no point to go to a node that was already visited
         path.add(s) //go to s
         search(path,visited,current) //recursively visit all squares accesable form s
         //step back from s to current, so you can visit the next neighbor of current.
         path.add(current)

使用search([source],{},source)

进行调用

请注意,可以在for each步骤之前使用优化启发式算法 - 启发式只是重新排序节点的迭代顺序。

答案 2 :(得分:0)

我认为问题解决的最佳方式是递归(转到最近的免费单元格)。使用以下额外的启发式:使用最少的自由邻居(更喜欢存根)转到最近的空闲单元格。

伪代码:

// init:
for (cell in all_cells) {
    cell.weight = calc_neighbors_number(cell);
}

path = [];

void calc_path(cell)
{
    cell.visited = true;
    path.push_back(cell);
    preferred_cell = null;
    for (cell in cell.neighbors)
        if (cell.visited) {
            continue;
        }
        if (preferred_cell == null || preferred_cell.weight > cell.weight)
           preferred_cell = cell;
    }
    if (preferred_cell != null) {
        calc_path(preferred_cell);
    }
}

// Start algotithm:
calc_path(start);