// check optimality conditions (takes time proportional to E V lg* V) private boolean check(EdgeWeightedGraph G) { // check total weight double total = 0.0; for (Edge e : edges()) { total += e.weight(); } double EPSILON = 1E-12; if (Math.abs(total - weight()) > EPSILON) { System.err.printf("Weight of edges does not equal weight(): %f vs. %f\n", total, weight()); return false; } // check that it is acyclic UF uf = new UF(G.V()); for (Edge e : edges()) { int v = e.either(), w = e.other(v); if (uf.connected(v, w)) { System.err.println("Not a forest"); return false; } uf.union(v, w); } // check that it is a spanning forest for (Edge e : edges()) { int v = e.either(), w = e.other(v); if (!uf.connected(v, w)) { System.err.println("Not a spanning forest"); return false; } } // check that it is a minimal spanning forest (cut optimality conditions) for (Edge e : edges()) { int v = e.either(), w = e.other(v); // all edges in MST except e uf = new UF(G.V()); for (Edge f : mst) { int x = f.either(), y = f.other(x); if (f != e) uf.union(x, y); } // check that e is min weight edge in crossing cut for (Edge f : G.edges()) { int x = f.either(), y = f.other(x); if (!uf.connected(x, y)) { if (f.weight() < e.weight()) { System.err.println("Edge " + f + " violates cut optimality conditions"); return false; } } } } return true; }
public PrimMST(EdgeWeightedGraph G) { edgeTo = new Edge[G.V()]; distTo = new double[G.V()]; marked = new boolean[G.V()]; for (int v = 0; v < G.V(); v++) distTo[v] = Double.POSITIVE_INFINITY; pq = new IndexMinPQ<Double>(G.V()); distTo[0] = 0.0; pq.insert(0, 0.0); // Initialize pq with 0, weight 0. while (!pq.isEmpty()) visit(G, pq.delMin()); // Add closest vertex to tree. }
/** * Initializes a new edge-weighted graph that is a deep copy of <tt>G</tt>. * * @param G the edge-weighted graph to copy */ public EdgeWeightedGraph(EdgeWeightedGraph G) { this(G.V()); this.E = G.E(); for (int v = 0; v < G.V(); v++) { // reverse so that adjacency list is in same order as original Stack<Edge> reverse = new Stack<Edge>(); for (Edge e : G.adj[v]) { reverse.push(e); } for (Edge e : reverse) { adj[v].add(e); } } }
public KruskalMST(EdgeWeightedGraph G) { mst = new Queue<Edge>(); MaxPQ<Edge> pq = new MaxPQ<Edge>(); for (Edge e : G.edges()) pq.insert(e); // 将所有的边进入优先队列,按照权重升序排列 UF uf = new UF(G.V()); // 构建union-find对象 while (!pq.isEmpty() && mst.size() < G.V() - 1) { Edge e = pq.delMax(); // 从pq得到权重最小的边和他的顶点 int v = e.either(), w = e.other(v); if (uf.connected(v, w)) continue; // 忽略失效的边,两个顶点已经在生成树中了 uf.union(v, w); // 否则将两者合并,在一个树中,顶点 mst.enqueue(e); // 将边添加到最小生成树中 } }
public MyPrimMST(EdgeWeightedGraph G) { this.G = G; pq = new IndexMinPQ<Double>(G.V()); disTo = new double[G.V()]; edges = new Bag<Edge>(); for (int i = 0; i < G.V(); ++i) disTo[i] = Double.POSITIVE_INFINITY; edgeTo = new int[G.V()]; marked = new boolean[G.V()]; disTo[0] = 0.0; visit(0); while (!pq.isEmpty()) { int v = pq.delMin(); weight += disTo[v]; edges.add(new Edge(v, edgeTo[v], disTo[v])); visit(v); } }
KruskalMST(EdgeWeightedGraph G) { MinPQ<Edge> pq = new MinPQ<Edge>(); // we dont need to pass a new comparator let it // follow the natural ordering of edges double temp_wt = 0; for (Edge e : G.edges()) pq.insert(e); UF set = new UF(G.V()); while (!pq.isEmpty() && mst.size() < (G.V() - 1)) { Edge e = pq.delMin(); int v = e.either(); int w = e.other(v); if (!set.connected(v, w)) { set.union(v, w); mst.add(e); temp_wt += e.weight(); } } this.weight = temp_wt; }
private void visit(EdgeWeightedGraph G, int v) { // Mark v and add to pq all edges from v to unmarked vertices. marked[v] = true; for (Edge e : G.adj(v)) { if (!marked[e.other(v)]) { pq.insert(e); } } }
public KruskalMST(EdgeWeightedGraph g) { mst = new Queue<Edge>(); MinPQ<Edge> pq = new MinPQ<Edge>(); for (Edge e : g.edges()) { pq.insert(e); } UnionFind uf = new UnionFind(g.vertices()); while (!pq.isEmpty() && mst.size() < g.vertices() - 1) { Edge e = pq.delMin(); int v = e.either(), w = e.other(v); if (uf.connected(v, w)) continue; // -- would form a cycle uf.union(v, w); mst.enqueue(e); } }
public void visit(int v) { marked[v] = true; for (Edge e : G.adj(v)) { int w = e.other(v); if (marked[w]) continue; if (disTo[w] > e.weight()) { disTo[w] = e.weight(); if (!pq.contains(w)) { pq.insert(w, e.weight()); } else pq.changeKey(w, e.weight()); edgeTo[w] = v; } } }
// Kruskal's algorithm public KruskalMST(EdgeWeightedGraph G) { // more efficient to build heap by passing array of edges MinPQ<Edge> pq = new MinPQ<Edge>(); for (Edge e : G.edges()) { pq.insert(e); } // run greedy algorithm UF uf = new UF(G.V()); while (!pq.isEmpty() && mst.size() < G.V() - 1) { Edge e = pq.delMin(); int v = e.either(); int w = e.other(v); if (!uf.connected(v, w)) { // v-w does not create a cycle uf.union(v, w); // merge v and w components mst.enqueue(e); // add edge e to mst weight += e.weight(); } } // check optimality conditions assert check(G); }
/** * Dado un grafo no dirigido y con pesos, ejecuta el algoritmo de Kruskal para la obtención del su * árbol de cobertura mínima. * * @param G Grafo no dirigido con pesos al cual se le deesea obtener su arbol de cobertura mínima. */ public void minimumSpanningTree(EdgeWeightedGraph G) // By Kruskal's algorithm { LinkedList<Edge> mst = new LinkedList<>(); MinPQ<Edge> pq = new MinPQ<>(G.E()); for (Edge edge : G.edges()) // Bag<Edge> != Comparator<Edge> :c pq.insert(edge); UF uf = new UF(G.V()); while (!pq.isEmpty() && mst.size() < G.V() - 1) { Edge edge = pq.delMin(); int v = edge.either(), w = edge.other(v); if (!uf.connected(v, w)) { uf.union(v, w); mst.add(edge); } } System.out.println(""); for (Edge edge : mst) System.out.println(edge); }
private void visit(EdgeWeightedGraph G, int v) // Add v to tree; update data structures. { marked[v] = true; for (Edge e : G.adj(v)) { int w = e.other(v); if (marked[w]) continue; // v-w is ineligible. if (e.weight() < distTo[w]) // Edge e is new best connection from tree to w. { edgeTo[w] = e; distTo[w] = e.weight(); if (pq.contains(w)) pq.change(w, distTo[w]); else pq.insert(w, distTo[w]); } } }
public LazyPrimMST(EdgeWeightedGraph G) { pq = new PriorityQueue<>(Collections.reverseOrder()); marked = new boolean[G.V()]; mst = new LinkedList<>(); visit(G, 0); while (!pq.isEmpty()) { Edge e = pq.poll(); int v = e.either(); int w = e.other(v); if (marked[v] && marked[w]) continue; mst.offer(e); if (!marked[v]) visit(G, v); if (!marked[w]) visit(G, w); } }
public static void main(String[] args) { EdgeWeightedGraph ewg = new EdgeWeightedGraph(Integer.parseInt(args[0])); ewg.addEdge(new Edge(0, 1, 10)); ewg.addEdge(new Edge(1, 2, 11)); ewg.addEdge(new Edge(2, 3, 12)); ewg.addEdge(new Edge(3, 4, 13)); ewg.addEdge(new Edge(4, 5, 14)); ewg.addEdge(new Edge(5, 6, 21)); ewg.addEdge(new Edge(6, 7, 22)); ewg.addEdge(new Edge(7, 8, 23)); ewg.addEdge(new Edge(8, 9, 24)); ewg.addEdge(new Edge(9, 0, 25)); int count = 0; for (Edge e : ewg.edges()) { StdOut.println(count + " => " + e); count++; } }
public LazyPrimMST(EdgeWeightedGraph G) { pq = new MinPQ<Edge>(); marked = new boolean[G.V()]; mst = new Queue<Edge>(); visit(G, 0); // assumes G is connected (see ex. 4.3.22) while (!pq.isEmpty()) { Edge e = pq.delMin(); // Get lowest-weight from pq. int v = e.either(); int w = e.other(v); if (marked[v] && marked[w]) { continue; // Skip if ineligible } mst.enqueue(e); // Add edge to tree if (!marked[v]) { // Add vertex to tree (either v or w). visit(G, v); } if (!marked[w]) { visit(G, w); } } }
private void visit(EdgeWeightedGraph G, int v) { marked[v] = true; for (Edge e : G.adj(v)) { if (!marked[e.other(v)]) pq.offer(e); } }