用棋盘构建邻接图(用于dijkstra)

时间:2017-06-02 18:33:33

标签: algorithm matrix graph-algorithm dijkstra adjacency-matrix

我遇到了一个问题,我想在我的作业中添加一些小功能,结果对我来说是压倒性的(在没有上下文的情况下阅读大胆的句子)。

我的程序中有大约35个项目的列表,其中包含我应该使用的地图的相关信息。它可以包含以下元素:

  • "墙"它的坐标(X,Y)在dijkstra中应该有100的重量。
  • "树"用绳索(X,Y),重量3

我有一个像棋盘一样的10x10地图,这意味着100个瓷砖和35个项目。 "没有什么"在列表中表示dijkstra中的权重1(表示正常路线)

为了使dijkstra工作并能够找到两个图块之间的最短路径,我必须构建一个邻接图。 我的问题是,如何定义瓷砖"周围"当前的磁贴,如果我只有那个列表?

只有" +"形状的相邻瓷砖;它们之间的图中有边缘,但我每次都必须检查列表中是否有内容?

如果你能指出一个包含代码示例的来源,那么问题上的任何领导都会非常感激。我只看到非常混乱的代码与很多" if-elseif-elseif ..."解决这个问题。

感谢您的时间!

编辑:我最终使用了@kraskevich建议的方式,并且效果非常好,但所有答案和建议都非常有用,非常感谢大家!

2 个答案:

答案 0 :(得分:2)

您并不需要构建图表。只需创建一个10x10表并将相应项的权重放入其中:

board = 10x10 array filled with 1
for item in list:
    if item is a tree:
         board[item.row][item.column] = 3
    else if item is a wall:
         board[item.row][item.column] = 100

之后,您可以将坐标对(row, col)视为顶点,并在处理图块时更新4个相邻单元格的距离。就是这样。当然,您还可以创建一个包含100个顶点的图形,并从图块中明确地将边缘添加到所有4个相邻单元格(权重是边缘图块末端的权重)并使用标准实现。

迭代相邻单元格最方便的方法如下:

delta_rows = [-1, 1, 0, 0]
delta_cols = [0, 0, -1, 1]
...
for direction = 0 .. 3
     new_row = row + delta_rows[direction]
     new_col = col + delta_cols[direction]
     if is_valid(new_row, new_col)
          // do something

答案 1 :(得分:1)

基于这个通用图形界面实现Dijkstra应该是直截了当的:

interface Graph<T> {
  Iterable<T> adjacentNodes(T node);
  double getDistance(T node, T adjacent);
}

所以我们现在需要做的就是填写你的案例:

class Field {
  final int x;
  final int y;
  int value = 1;
  Field (int x, int y) {
    this.x = x;
    this.y = y;
  }
}

class ChessboardGraph implements Graph<Field> {
  Field[][] board = new Filed[10][10];

  ChessboardGraph(List<Entry> list) {
    for (int x = 0; x < 10; x++) {
      for (int y = 0; y < 10; y++) {
        board[x][y] = new Field(x, y);
      }
    }
    for (Entry e: list) {
      board[e.x][e.y].value = e.value == TREE ? 3 : 100;
    }
  }

  Iterable<Field> adjacentNodes(Field node) {
    ArrayList result = new ArrayList<>();
    int x = node.x;
    int y = node.y;
    if (x > 0) {
      if (y > 0) {
        result.add(board[x - 1][y - 1]);
      }
      if (y < 9) {
        result.add(board[x - 1][y + 1]);
      }
    }
    if (x < 9) {
      if (y > 0) {
        result.add(board[x + 1][y - 1]);
      }
      if (y < 9) {
        result.add(board[x + 1][y + 1]);
      }
    }
  }

  double getDistance(Field node, Field adjacent) {
    assert Math.abs(node.x - adjacent.x) + Math.abs(node.y - adjacent.y) == 1;
    return board[adjacent.x][adjacent.y];
  }
}