以编程方式查找距离一定距离的所有瓷砖

时间:2013-06-19 04:01:09

标签: objective-c algorithm graph-algorithm

我正在寻找一种更好的方法来创建距离起点一定距离的点阵列。路上可能存在障碍,这是无法通行的。

x x x o x x x x
x x o o o x x x
x o o o o o x x
o o o A o o o x
x o B B o o x x
x x x x o x x x
x x x x x x x x

x - 空// A - 开始// B - 障碍物// o - 距离> = 3

所以我当前的实现使用递归,基本上搜索每个方向,直到达到3的距离。它看起来像这样:

- (NSArray *) findTiles:(CGPoint)position for:(int)area;
{
    // Holding array
    NSMutableArray *array = [NSMutableArray array];

    CGPoint p = ccp(position.x - 1, position.y);
    if ( [self isValidTile:p] && area != 0 )
        if ( ![self isOccupiedTile:p] )
            [array addObjectsFromArray: [self findMoveTiles:p for:area - 1]];

    p = ccp(position.x, position.y - 1);
    if ( [self isValidTile:p] && area != 0 )
        if ( ![self isOccupiedTile:p] )
            [array addObjectsFromArray: [self findMoveTiles:p for:area - 1]];

    p = ccp(position.x + 1, position.y);
    if ( [self isValidTile:p] && area != 0 )
        if ( ![self isOccupiedTile:p] )
            [array addObjectsFromArray: [self findMoveTiles:p for:area - 1]];

    p = ccp(position.x, position.y + 1);
    if ( [self isValidTile:p] && area != 0 )
        if ( ![self isOccupiedTile:p] )
            [array addObjectsFromArray: [self findMoveTiles:p for:area - 1]];

    // Add ourself only if we are empty
    if ( [self isValidTile:position] && ![self isOccupiedTile:position])
        if ( ![array containsObject:[NSValue valueWithCGPoint:position]] )
            [array addObject:[NSValue valueWithCGPoint:position]];

    return [NSArray arrayWithArray:array];
}

有没有人有更快的方法呢?这种方法很好,但是大面积的速度非常慢。返回的数组也有许多重复的坐标作为containsObject:似乎不起作用。

PS - 不确定图算法是否适用于此(我会说它确实如此)

3 个答案:

答案 0 :(得分:0)

我认为这可能是一个解决方案。不确定

**Quadrant**


       |
   II  |    I
       |
-------A---------
       |
  III  |   IV
       |


       |
   II  |
       |
-------A

**Rotate right**
|
|    II
|
A---------

**Rotate right**
A---------
|
|   II
|
  1. 编写一个逻辑,用于以A为象限的中心找到第四象限的路线。
  2. 编写逻辑以将您的点阵列分成4个象限,以A为中心即(0,0)。确保2个象限中没有轴线。因此,一旦隔离区的一侧必须放置一系列区块。
  3. 将每个象限传递给logic 1进行处理并找到路径长度数组。确保旋转矩阵,原点将到达左上角。
  4. 根据象限,您可以计算方向。

答案 1 :(得分:0)

这是BFS的典型应用。我不知道Objective-C,但是,你提到了递归,通常是DFS。 BFS的典型实现使用queue

您可以在每个单元格上有一个标记,一旦您访问它就会设置该标记,如果设置了标记,则不会再次访问该单元格。这样可以防止任何重复的细胞。

访问标志不会阻止查找所有单元格,因为BFS保证找到到任何单元格的最短路径,因为它首先访问所有单元格距离1,然后距离2,然后距离3等,从开始,因此,它总是会在更长的路径之前找到更短的路径。这与DFS(使用访问标志)相反,DFS首先搜索尽可能长的路径,因此即使存在长度为2的路径,它也可以将单元格标记为长度3路径上的访问,从而跳过它可以获得的未访问的单元格来自那个牢房。

答案 2 :(得分:0)

一段时间后回到这里,

我意识到正常的BFS实际上并不起作用,因为没有办法告诉你从根节点走了多远。

我实现了一个带有堆栈的BFS,所以它类似于dfs