我正在尝试在Java中实现prim的算法,在某些情况下,我的算法似乎会产生正确的结果,而在其他情况下,我的算法似乎会产生错误或部分正确的结果,而我找不到原因,这是我的代码:< / p>
节点类
public class Node implements Comparable<Node>{
private double cost;
private int dest;
private int source;
private Node next;
public Node(double cost, int dest,int source) {
this.cost = cost;
this.dest = dest;
this.source = source;
}
public Node() {
}
public double getCost() {
return cost;
}
public void setCost(double cost) {
this.cost = cost;
}
public int getDest() {
return dest;
}
public void setDest(int dest) {
this.dest = dest;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public int getSource() {
return source;
}
public void setSource(int source) {
this.source = source;
}
public int compareTo(Node node) {
if(this.cost> node.getCost())
return 1;
else if (this.cost<node.getCost())
return -1;
else
return 0;
}
}
链接列表类:
public class LinkedList {
private Node first;
private Node last;
private int counter;
public LinkedList() {
}
public Node getFirst() {
return first;
}
public Node getLast() {
return last;
}
public int getCounter() {
return counter;
}
public Object getFirstNode() {
if(counter == 0)
return null;
else
return first;
}
public Object getLastNode() {
if(counter ==0)
return null;
else
return last;
}
public void addLast(double cost,int dest,int source) {
if (counter == 0) {
first = last = new Node(cost,dest,source);
}
else {
Node temp = new Node(cost,dest,source);
last.setNext(temp);
last = temp;
}
counter++;
}
public void addFirst(double cost,int dest,int source) {
if (counter == 0) {
first = last = new Node(cost,dest,source);
}
else {
Node temp = new Node(cost,dest,source);
temp.setNext(first);
first = temp;
}
counter++;
}
}
严格算法类:
public class Prim {
private double[][] t;
private LinkedList[] list;
private PriorityQueue heap = new PriorityQueue<Node>();
public Prim(int vertex) {
t = new double[vertex][3];
list = new LinkedList[vertex];
for (int i = 0; i < vertex; i++) {
list[i] = new LinkedList();
}
for (int i = 0; i < vertex; i++) {
t[i][1] = Integer.MAX_VALUE;
}
}
public void MST(int start) {
t[start - 1][0] = 1;
t[start - 1][1] = 0;
t[start - 1][2] = 0;
Node node = list[start - 1].getFirst();
// vertex-1
while (node != null) {
t[node.getDest() - 1][1] = node.getCost();
t[node.getDest() - 1][2] = node.getSource();
// vertex - 1
node = node.getNext();
}
// debug
for (int i = 0; i < t.length; i++) {
System.out.println('\n');
for (int j = 0; j < t[i].length; j++) {
System.out.print(t[i][j] + " ");
}
}
System.out.println('\n');
while (heap.peek() != null) {
Node minNode = (Node) heap.poll();
if (t[minNode.getDest() - 1][0] != 1 && minNode.getCost() <= t[minNode.getDest() - 1][1]) {
t[minNode.getDest() - 1][0] = 1;
Node adjacent = list[minNode.getDest() - 1].getFirst();
while (adjacent != null ) {
if (t[adjacent.getDest() - 1][0] != 1 && (adjacent.getCost()<t[adjacent.getDest() - 1][1])) {
t[adjacent.getDest() - 1][1] = adjacent.getCost();
t[adjacent.getDest() - 1][2] = adjacent.getSource();
}
adjacent = adjacent.getNext();
}
}
}
}
public void addNode(int index, int cost, int dest) {
list[index - 1].addLast(cost, dest, index);
heap.add(new Node(cost, dest, index));
}
public PriorityQueue getHeap() {
return heap;
}
public void setHeap(PriorityQueue heap) {
this.heap = heap;
}
public double[][] getT() {
return t;
}
public void setT(double[][] t) {
this.t = t;
}
}
在驱动程序类中:
Prim prim = new Prim(4);
prim.addNode(1, 5, 2);
prim.addNode(1, 4, 4);
prim.addNode(2, 5, 1);
prim.addNode(2, 3, 3);
prim.addNode(2, 2, 4);
prim.addNode(3, 3, 2);
prim.addNode(3, 6, 4);
prim.addNode(4, 4, 1);
prim.addNode(4, 6, 3);
prim.addNode(4, 2, 2);
prim.MST(4);
如果使用prim.getT()打印表t并遍历2d数组,则会生成正确的结果:(k:已知,d成本,p路径或移动的节点)。请注意,由于该图是有向的,因此必须说:prim.addNode(1,5,2)其中1是源,2是目的地,5成本,并且:prim.addNode(2,5,1)其中2来源,1个费用和5个目的地。
k d p
1 0 0
1 2 4
1 3 2
1 4 1
Prim prim = new Prim(7);
prim.addNode(1, 2, 2);
prim.addNode(1, 1, 4);
prim.addNode(1, 4, 3);
prim.addNode(2, 2, 1);
prim.addNode(2, 3, 4);
prim.addNode(2, 10, 6);
prim.addNode(3, 4, 1);
prim.addNode(3, 2, 4);
prim.addNode(3, 5, 6);
prim.addNode(4, 1, 1);
prim.addNode(4, 3, 2);
prim.addNode(4, 2 ,3);
prim.addNode(4, 7, 5);
prim.addNode(4, 8, 6);
prim.addNode(4, 4, 7);
prim.addNode(5, 10, 2);
prim.addNode(5, 7, 4);
prim.addNode(5, 6, 7);
prim.addNode(6, 5, 3);
prim.addNode(6, 8, 4);
prim.addNode(6, 1, 7);
prim.addNode(7, 4, 4);
prim.addNode(7, 6, 5);
prim.addNode(7, 1, 6);
prim.MST(4);
在打印表格时也会产生适当的结果:
1 1 4
1 2 1
1 2 4
1 0 0
1 6 7
1 1 7
1 4 4
但是,如果我创建以下图形:
Prim prim = new Prim(6);
prim.addNode(1, 4, 2);
prim.addNode(1, 5, 6);
prim.addNode(1, 3, 4);
prim.addNode(2, 4, 1);
prim.addNode(2, 3, 3);
prim.addNode(2, 4, 4);
prim.addNode(2, 4, 5);
prim.addNode(3, 3, 2);
prim.addNode(3, 2, 4);
prim.addNode(4, 2, 3);
prim.addNode(4, 4, 2);
prim.addNode(4, 3 ,1);
prim.addNode(4, 3, 5);
prim.addNode(5, 3, 4);
prim.addNode(5, 4, 2);
prim.addNode(5, 1, 6);
prim.addNode(6, 5, 1);
prim.addNode(6, 1, 5);
prim.MST(4);
我得到以下结果:
1 3 4
1 3 3
1 2 4
1 0 0
1 1 6
1 2147483647 0
换句话说,最后两行是错误的,如果它有助于链接到互联网上最后一张图片,则为http://users.monash.edu/~lloyd/tilde/CSC2/CSE2304/Notes/17MST2.shtml
基本上,我将顶点存储在一系列链接列表中。数组中的第一个索引包含与第一个顶点相邻的所有节点的链表,依此类推。每个节点具有以下数据成员:
1-费用,来源与目的地之间的距离;
2-源,即顶点;
3-目标或目标节点。
表t
有3列,第一列是节点是否已知,第二列是成本,第三列是源节点的路径或数量。
起始基本上是我要从该无向图中的哪个节点开始。
最后,我想补充一点,我实际上是在Google地图中使用此算法来查找两点之间的最短直线路径。当我尝试前两个示例时,我认为我的算法是正确的,因此我将其应用于实际问题,但是结果不正确,因此我从互联网上选择了一个随机图,并将其传递给我的算法,以查看它是否真正起作用,出来没有。
预先谢谢您,请帮忙。