【问题标题】:Implementation of Prim's AlgorithmPrim算法的实现
【发布时间】:2010-10-20 11:10:12
【问题描述】:

对于我的 CS 课程,我需要在 Java 中实现 Prim 算法,但我遇到了优先队列步骤的问题。我有优先队列方面的经验,并且了解它们通常可以正常工作,但我在执行特定步骤时遇到了问题。

Prim(G,w,r)
  For each u in V[G]
    do key[u] ← ∞ 
       π[u] ← NIL  
  key[r] ← 0
  Q ← V[G]  
  While Q ≠ Ø
    do u ← EXTRACT-MIN(Q)
       for each v in Adj[u]
            if v is in Q and w(u,v) < key[v]
                 then π[v] ← u
                       key[v] ← w(u,v)

我创建了一个 Node 类,其中包含键值(我假设它是连接到节点的最轻的边缘)和父节点。我的问题是我不明白将节点添加到优先级队列中。当父节点设置为 NIL 并将键设置为 ∞ 时,将所有节点添加到优先级队列对我来说没有意义。

【问题讨论】:

    标签: java algorithm priority-queue prims-algorithm


    【解决方案1】:

    您不必担心将所有节点添加到优先级队列中,即使它们具有无限键;它们最终会在伪代码的最后一行被 DECREASE_KEY 降低。无论如何你都需要这个操作,所以没有理由不简化你的生活并一次性插入它们。

    我只看到您的伪代码存在一个问题,即它在断开连接的图表上会表现得很奇怪。

    【讨论】:

      【解决方案2】:

      在您问题的伪代码中,key[u]π[u] 是一组值,它们将代表算法完成时G 的最小生成树。这些值在算法开始时分别初始化为NIL,表示尚未将顶点添加到 MST。下一步设置根元素 (key[r] ← 0)。

      优先级队列Q 是独立于keyπ 的数据结构。 Q 应该使用原始图 G 中的所有顶点进行初始化,不是 key 和 π 中的值。请注意,除了每个顶点的最亮边和父节点之外,您还需要更多信息,因为您需要知道与从 Q 提取的每个顶点相邻的所有顶点。

      【讨论】:

        【解决方案3】:

        如果你不想使用 PriorityQueue,here 是我在 Java 中的 Heap 实现。你可以将 PriorityQueue 替换为 MinHeap。

        package algo2;
        
        import java.io.DataInputStream;
        import java.io.InputStream;
        import java.util.HashMap;
        import java.util.Map;
        import java.util.PriorityQueue;
        
        public class Prims {
        
        private static final class GNode implements Comparable<GNode> {
            // unique id of the node
            int id;
        
            // map of child nodes and their respective distance from current node 'id'
            Map<GNode, Integer> children = new HashMap<GNode, Integer>();
        
            // used in future computation, to store minimal/optimal updated distance
            int distFromParent=0;
        
            public GNode(int i) {
                this.id=i;
            }
        
            @Override
            public int compareTo(GNode o) {
                return this.distFromParent-o.distFromParent;
            }
        
            @Override
            public String toString() {
                return "GNode [id=" + id + ", distFromParent=" + distFromParent
                        + "]";
            }
        }
        
        static long findLengthOfMST(GNode[] nodes) {
            PriorityQueue<GNode> pq = new PriorityQueue<GNode>();
            boolean[] visited = new boolean[nodes.length];
            boolean[] exited = new boolean[nodes.length];
            pq.add(nodes[1]);
            visited[1] = true;
            long sum = 0;
            int count = 0;
            while (pq.size() > 0) {
                GNode o = pq.poll();
                if (!exited[o.id]) {
                    for (GNode n : o.children.keySet()) {
                        if (exited[n.id]) {
                            continue;
                        }
                        if (visited[n.id]) {
                            if (n.distFromParent >= o.children.get(n)) {
                                n.distFromParent = o.children.get(n);
                            }
                        } else {
                            visited[n.id] = true;
                            n.distFromParent = o.children.get(n);
                            pq.add(n);
                        }
                    }
                    sum += o.distFromParent;
                    exited[o.id] = true;
                    count++;
                }
                if (pq.size() == 0) {
                    for (int i = 1; i < nodes.length; i++) {
                        if (!exited[i]) {
                            pq.add(nodes[i]);
                        }
                    }
                }
            }
            System.out.println(count);
            return sum;
        }
        
        public static void main(String[] args) {
            StdIn s = new StdIn(System.in);
            int V = s.nextInt();
            int E = s.nextInt();
            GNode[] nodes = new GNode[V+1];
            for (int i = 0; i < E; i++) {
                int u = s.nextInt();
                int v = s.nextInt();
                GNode un = nodes[u];
                GNode vn = nodes[v];
                if (un == null) {
                    un = new GNode(u);
                    nodes[u] = un;
                }
                if (vn == null) {
                    vn = new GNode(v);
                    nodes[v] = vn;
                }
        
                int w = s.nextInt();
                un.children.put(vn, w);
                vn.children.put(un, w);
            }
            long len = findLengthOfMST(nodes);
            System.out.println(len);
        }
        
        private static class StdIn {
            final private int BUFFER_SIZE = 1 << 17;
            private DataInputStream din;
            private byte[] buffer;
            private int bufferPointer, bytesRead;
            public StdIn(InputStream in) {
            din = new DataInputStream(in);
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
            }
            public int nextInt() {int ret = 0;byte c = read();while (c <= ' ')c = read();boolean neg = c == '-';if (neg)c=read();do{ret=ret*10+c-'0';c = read();} while (c>' ');if(neg)return -ret;return ret;}
            private void fillBuffer(){try{bytesRead=din.read(buffer,bufferPointer=0,BUFFER_SIZE);}catch(Exception e) {}if(bytesRead==-1)buffer[0]=-1;}
            private byte read(){if(bufferPointer == bytesRead)fillBuffer();return buffer[bufferPointer++];}
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多