我正在为大学使用Dijkstra算法,使用PriorityQueue来存储我的图形的剩余顶点,按最短遍历距离排序。 我使用的比较器:
class DistanceComparator implements Comparator<Integer> {
int[] dist;
public DistanceComparator(int[] d) {
dist = d;
}
@Override
public int compare(Integer i, Integer j)
{
if((dist[i]-dist[j]) < 0) {
return -1;
}
if((dist[i]-dist[j]) > 0) {
return 1;
}
return 0;
}
}
现在我面临的问题是距离正在变化,因此我的队列的比较器需要经常更新。
static PriorityQueue<Integer> refreshQueue(int[] d) {
Comparator<Integer> comp = new DistanceComparator(d);
PriorityQueue<Integer> q = new PriorityQueue<Integer>(adj.length, comp);
for(int i = 0; i < adj.length; i++) {
q.add(i);
}
return q;
}
这样可以解决问题,但它也会使所需的运行时O(num Edges*log(num Vertices))
紧张。
我怎样才能消除每次调整比较器的需要?
答案 0 :(得分:2)
在Java中实现Dijkstra算法的传统方法是创建一个包含节点和距离的单独类:
class Dist implements Comparable<Dist> {
final int vertex;
final int distance;
public int compareTo(Dist other) {
return Integer.compare(distance, other.distance);
}
}
并将那些放入您的优先级队列。
您最终会得到反映次优路径的过时Dist
个对象,但只有在您已经看到“最佳”路径之后,才会忽略您已经从中取出的顶点优先队列。
基本上,不要更改Comparator
:更改要比较的对象。