在多级网格中测试相邻单元

时间:2012-06-22 19:54:40

标签: algorithm data-structures recursion gis

我正在设计一种算法来测试网格上的单元格是否相邻。 问题是细胞不在平面网格上。它们位于多级网格上,如下图所示。

Level 1 (Top Level)
| - - - - - |
| A | B | C |
| - - - - - |
| D | E | F |
| - - - - - |
| G | H | I |
| - - - - - |


Level 2
| -Block A- | -Block B- |
| 1 | 2 | 3 | 1 | 2 | 3 |
| - - - - - | - - - - - |
| 4 | 5 | 6 | 4 | 5 | 6 |   ...
| - - - - - | - - - - - |
| 7 | 8 | 9 | 7 | 8 | 9 |
| - - - - - | - - - - - |
| -Block D- | -Block E- |
| 1 | 2 | 3 | 1 | 2 | 3 |
| - - - - - | - - - - - |
| 4 | 5 | 6 | 4 | 5 | 6 |   ...
| - - - - - | - - - - - |
| 7 | 8 | 9 | 7 | 8 | 9 |
| - - - - - | - - - - - |
      .           .
      .           .
      .           .

此图表根据我的实际需要进行了简化,但概念是相同的。有一个顶层区块,其中有许多单元格(级别1)。每个块进一步细分为更多的单元格(级别2)。对于我的项目,这些单元格进一步细分为3级,4级和5级,但我们只是坚持这个问题的两个级别。

我正在以“A8,A9,B7,D3”的形式接收我的功能输入。这是一个单元格ID列表,其中每个单元格ID都具有格式(级别1标识)(级别2标识)。

让我们首先比较两个单元格A8和A9。这很容易,因为它们处于同一块。

private static RelativePosition getRelativePositionInTheSameBlock(String v1, String v2) {
    RelativePosition relativePosition;

    if( v1-v2 == -1 ) {
        relativePosition = RelativePosition.LEFT_OF;
    }
    else if (v1-v2 == 1) {
        relativePosition = RelativePosition.RIGHT_OF;
    }
    else if (v1-v2 == -BLOCK_WIDTH) {
        relativePosition = RelativePosition.TOP_OF;
    }
    else if (v1-v2 == BLOCK_WIDTH) {
        relativePosition = RelativePosition.BOTTOM_OF;
    }
    else {
        relativePosition = RelativePosition.NOT_ADJACENT;
    }
    return relativePosition;
}

A9-B7比较可以通过检查A是否是BLOCK_WIDTH的倍数以及B是否是(A-BLOCK_WIDTH + 1)来完成。 如果A / B对是3-1,6-4或9-7,为了更好的可读性,或者只是天真地检查。

对于B7 - D3,它们不相邻但D3与A9相邻,所以我可以进行与上述类似的邻接测试。

远离细节,专注于大局。这真的是最好的方法吗?请记住以下几点:

  • 我实际上有5个级别而不是2级,所以我可能会得到一个像“A8A1A,A8A1B,B1A2A,B1A2B”的列表。
  • 添加要比较的新单元格仍需要我比较之前的所有其他单元格(看起来我能为此步骤做的最好 是O(n))
  • 细胞不是所有3x3块,它们就是我的例子。它们可以是具有不同M和N的MxN块 不同层次。
  • 在我上面的当前实现中,如果单元格位于相同的块中,我有单独的函数来检查邻接,如果它们在 将水平相邻的块分开或者它们是分开的 垂直相邻的块。这意味着我必须知道这个位置 在我调用其中一个之前,当前级别的两个块 下面一层的功能。

判断为不同级别的不同边缘情况处理多个函数并具有5级嵌套if语句的复杂性。我想知道另一种设计是否更合适。也许是一个更加递归的解决方案,使用其他数据结构,或者可能将整个多级网格映射到单级网格(我的快速计算为我提供了大约700,000个原子单元ID)。即使我走这条路线,从多层次到单层面的映射本身也是一项非常重要的任务。

3 个答案:

答案 0 :(得分:0)

计算并比较最低级别的绝对x和y坐标。

对于示例(假设A {1}} = 0,B代表1,...... int index0 = 0 ... 8):

index1

一般来说,给定

int x = (index0 % 3) * 3 + index1 % 3;
int y = (index0 / 3) * 3 + index1 / 3;

答案 1 :(得分:0)

  
      
  • 我实际上有5个级别而不是2级,所以我可能会得到一个像“A8A1A,A8A1B,B1A2A,B1A2B”的列表。
  •   
  • 添加一个要比较的新单元格仍然需要我比较之前的所有其他单元格(看起来我能为此步骤做的最好的是   为O(n))
  •   
  • 细胞不是所有3x3块,它们就是我的例子。它们可以是具有不同M和N的MxN块   水平。
  •   

我没有看到这些点的问题:如果一个单元格在最高级别不相邻,那么我们可以在那里停止计算,我们不必在较低级别计算邻接。如果只有五个级别,那么你最多可以进行五次邻接计算,这应该没问题。

  
      
  • 在我上面的当前实现中,如果单元格位于相同的块中,如果它们位于单独的水平相邻块中,或者它们位于单独的垂直相邻块中,则我有单独的函数来检查邻接。这意味着在我为下面的图层调用其中一个函数之前,我必须知道当前级别的两个块的位置。
  •   

你应该尝试重写这个。应该只有两种方法:一种计算两个单元是否相邻,另一种计算两个单元是否在给定级别相邻:

  • RelativePosition isAdjacent(String cell1, String cell2);
  • RelativePosition isAdjacentAtLevel(String cell1, String cell2, int level);

方法isAdjacent为每个级别调用方法isAdjacentAtLevel。我不确定cell1cell2是否始终包含所有级别的信息,但isAdjacent可以分析给定的单元格字符串并相应地调用相应的级别邻接检查。当两个单元格在特定级别不相邻时,则不需要检查所有更深层次。

方法isAdjacentAtLevel应该:查找给定级别的 M N ,从cell1和{{1}中提取信息给定级别并执行邻接计算。每个级别的计算应该相同,因为每个级别本身具有相同的块结构。

答案 2 :(得分:0)

您可以使用空间填充曲线,例如peano曲线或z morton曲线。