【问题标题】:How to store neighbours of a cell in a gird into a priority queue如何将网格中单元格的邻居存储到优先级队列中
【发布时间】:2020-08-15 13:51:17
【问题描述】:

假设我有一个 4 x 4 的网格,所以有 16 个单元格。每个单元格包含一个介于 1,5 之间的值。例如。

     0 1 2 3
     _ _ _ _
0 - |2|1|3|2|
1 - |1|3|5|1|
2 - |5|2|1|4|
3 - |2|4|2|1|

现在我知道我需要使用 Dijkstra 算法。此外,为了优化这一点,我需要使用优先级队列。

我的目标是找到每个单元格到目的地的最短总和。源在网格和目标上也可以是随机的。 (即不总是从左上到右下)。

我使用过使用相邻矩阵的图表。但是,使用此网格创建相邻矩阵是否明智?即将所有非邻居的字段设置为无穷大。将信元插入优先级队列的最充分方法是什么?会是 {(row,col), distance} 吗?

根据我的理解澄清一下,优先级队列将存储最佳路径?所以细胞和累积距离。因为,Dijstra 的算法使用 BFS,在这种情况下,它将搜索所有邻居的最短距离。

【问题讨论】:

  • 将 BFS 使用的常规队列替换为优先级队列的哪一部分让您感到困扰?
  • @Andreas - 所以如果我有一个起始单元格,比如说 (1,1),我如何将它存储到优先级队列中,使得值为 (1,1),它们的关键是距离。我不确定如何将元组插入优先级队列。我希望 {(1,1), 0} 用于第一个索引,并在执行 BFS 后为下一个单元格说 {(1,2),2}
  • 所以创建一个有 3 个字段的类,在距离上设置为Comparable,然后插入优先级队列。我没有看到问题。
  • @Andreas 为什么我们需要创建一个类?对不起,如果这听起来很愚蠢
  • 因为要存储3个值的对象到优先级队列中,并且需要对象的优先级比较实现,所以最简单的实现方法就是为此目的创建一个类,并且使距离场成为对象的自然顺序。您还打算如何存储 {(1,2),2} 值?

标签: java algorithm data-structures priority-queue dijkstra


【解决方案1】:

使“节点”成为一个具有 3 个字段(行、列、距离)并实现 Comparable 的类。然后使用使用PriorityQueue<Node>:

import java.util.PriorityQueue;

class Main {

    public static void main(String[] args) {
        PriorityQueue<Node> pq = new PriorityQueue<>();
        pq.add(new Node(2, 3, 12));
        pq.add(new Node(0, 9, 1));
        pq.add(new Node(4, 0, 8));

        System.out.println(pq.poll().getDistance()); //prints 1
    }
}

class Node  implements Comparable<Node>{

    private final int row, col, distance;

    public Node(int row, int col, int value) {
        this.row = row;
        this.col = col;
        distance = value;
    }

    int getDistance() {
        return distance;
    }

    @Override
    public int compareTo(Node other) {
        return Integer.compare(distance, other.distance);
    }
}

或者将Comperator 设置为优先级队列,这样Node 就不必实现Comparable:

import java.util.PriorityQueue;

class Main {

    public static void main(String[] args) {
        PriorityQueue<Node> pq = new PriorityQueue<>(Node::compare);
        pq.add(new Node(2, 3, 12));
        pq.add(new Node(0, 9, 1));
        pq.add(new Node(4, 0, 8));

        System.out.println(pq.poll().getDistance()); //prints 1
    }
}

class Node{

    private final int row, col, distance;

    public Node(int row, int col, int value) {
        this.row = row;
        this.col = col;
        distance = value;
    }

    int getDistance() {
        return distance;
    }

    public static int compare(Node o1, Node o2) {
        return Integer.compare(o1.getDistance(), o2.getDistance());
    }
}

您还可以使用 lambda 表达式来设置比较器:

PriorityQueue&lt;Node&gt; pq = new PriorityQueue&lt;&gt;((o1,o2)-&gt;Integer.compare(o1.getDistance(), o2.getDistance()));

所有三个选项都有效。

【讨论】:

  • “设置合作者” 你的意思是“给Comparator”吗?
  • @C0der 谢谢!一个比另一个更好吗?
猜你喜欢
  • 2022-08-20
  • 1970-01-01
  • 2016-04-26
  • 2011-12-20
  • 2014-12-14
  • 1970-01-01
  • 2023-04-04
  • 2018-06-24
  • 1970-01-01
相关资源
最近更新 更多