Java Prim算法实现

时间:2018-12-17 20:50:39

标签: java graph-theory prims-algorithm

我正在尝试在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地图中使用此算法来查找两点之间的最短直线路径。当我尝试前两个示例时,我认为我的算法是正确的,因此我将其应用于实际问题,但是结果不正确,因此我从互联网上选择了一个随机图,并将其传递给我的算法,以查看它是否真正起作用,出来没有。 预先谢谢您,请帮忙。

0 个答案:

没有答案