예제 #1
0
    private IndexMinPQ<Double> pq;    // priority queue of vertices

    /**
     * Computes a shortest-paths tree from the source vertex {@code s} to every
     * other vertex in the edge-weighted graph {@code G}.
     *
     * @param  G the edge-weighted digraph
     * @param  s the source vertex
     * @throws IllegalArgumentException if an edge weight is negative
     * @throws IllegalArgumentException unless {@code 0 <= s < V}
     */
    public DijkstraUndirectedSP(EdgeWeightedGraph G, int s) {
        for (Edge e : G.edges()) {
            if (e.weight() < 0)
                throw new IllegalArgumentException("edge " + e + " has negative weight");
        }

        distTo = new double[G.V()];
        edgeTo = new Edge[G.V()];

        validateVertex(s);

        for (int v = 0; v < G.V(); v++)
            distTo[v] = Double.POSITIVE_INFINITY;
        distTo[s] = 0.0;

        // relax vertices in order of distance from s
        pq = new IndexMinPQ<Double>(G.V());
        pq.insert(s, distTo[s]);
        while (!pq.isEmpty()) {
            int v = pq.delMin();
            for (Edge e : G.adj(v))
                relax(e, v);
        }

        // check optimality conditions
        assert check(G, s);
    }
예제 #2
0
    private double weight;                      // weight of MST

    /**
     * Compute a minimum spanning tree (or forest) of an edge-weighted graph.
     * @param G the edge-weighted graph
     */
    public BoruvkaMST(EdgeWeightedGraph G) {
        UF uf = new UF(G.V());

        // repeat at most log V times or until we have V-1 edges
        for (int t = 1; t < G.V() && mst.size() < G.V() - 1; t = t + t) {

            // foreach tree in forest, find closest edge
            // if edge weights are equal, ties are broken in favor of first edge in G.edges()
            Edge[] closest = new Edge[G.V()];
            for (Edge e : G.edges()) {
                int v = e.either(), w = e.other(v);
                int i = uf.find(v), j = uf.find(w);
                if (i == j) continue;   // same tree
                if (closest[i] == null || less(e, closest[i])) closest[i] = e;
                if (closest[j] == null || less(e, closest[j])) closest[j] = e;
            }

            // add newly discovered edges to MST
            for (int i = 0; i < G.V(); i++) {
                Edge e = closest[i];
                if (e != null) {
                    int v = e.either(), w = e.other(v);
                    // don't add the same edge twice
                    if (!uf.connected(v, w)) {
                        mst.add(e);
                        weight += e.weight();
                        uf.union(v, w);
                    }
                }
            }
        }

        // check optimality conditions
        assert check(G);
    }
예제 #3
0
    // check optimality conditions (takes time proportional to E V lg* V)
    private boolean check(EdgeWeightedGraph G) {

        // check weight
        double totalWeight = 0.0;
        for (Edge e : edges()) {
            totalWeight += e.weight();
        }
        if (Math.abs(totalWeight - weight()) > FLOATING_POINT_EPSILON) {
            System.err.printf("Weight of edges does not equal weight(): %f vs. %f\n", totalWeight, 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 : G.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()) {

            // all edges in MST except e
            uf = new UF(G.V());
            for (Edge f : edges()) {
                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;
    }
예제 #4
0
    private MinPQ<Edge> pq;      // edges with one endpoint in tree

    /**
     * Compute a minimum spanning tree (or forest) of an edge-weighted graph.
     * @param G the edge-weighted graph
     */
    public LazyPrimMST(EdgeWeightedGraph G) {
        mst = new Queue<Edge>();
        pq = new MinPQ<Edge>();
        marked = new boolean[G.V()];
        for (int v = 0; v < G.V(); v++)     // run Prim from all vertices to
            if (!marked[v]) prim(G, v);     // get a minimum spanning forest

        // check optimality conditions
        assert check(G);
    }
예제 #5
0
파일: CC.cs 프로젝트: franklzt/DataStruct
 /**
  * Computes the connected components of the edge-weighted graph {@code G}.
  *
  * @param G the edge-weighted graph
  */
 public CC(EdgeWeightedGraph G) {
     marked = new boolean[G.V()];
     id = new int[G.V()];
     size = new int[G.V()];
     for (int v = 0; v < G.V(); v++) {
         if (!marked[v]) {
             dfs(G, v);
             count++;
         }
     }
 }
예제 #6
0
 /**
  * Initializes a new edge-weighted graph that is a deep copy of {@code G}.
  *
  * @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);
         }
     }
 }
예제 #7
0
 /**
  * Contracts the edges incidents on the vertices {@code s} and {@code t} of
  * the given edge-weighted graph.
  * 
  * @param G the edge-weighted graph
  * @param s the vertex {@code s}
  * @param t the vertex {@code t}
  * @return a new edge-weighted graph for which the edges incidents on the
  *         vertices {@code s} and {@code t} were contracted
  */
 private EdgeWeightedGraph contractEdge(EdgeWeightedGraph G, int s, int t) {
     EdgeWeightedGraph H = new EdgeWeightedGraph(G.V());
     for (int v = 0; v < G.V(); v++) {
         for (Edge e : G.adj(v)) {
             int w = e.other(v);
             if (v == s && w == t || v == t && w == s) continue;
             if (v < w) {
                 if (w == t)      H.addEdge(new Edge(v, s, e.weight()));
                 else if (v == t) H.addEdge(new Edge(w, s, e.weight()));
                 else             H.addEdge(new Edge(v, w, e.weight()));
             }
         }
     }
     return H;
 }
예제 #8
0
 /**
  * Computes a minimum cut of the edge-weighted graph. Precisely, it computes
  * the lightest of the cuts-of-the-phase which yields the desired minimum
  * cut.
  * 
  * @param G the edge-weighted graph
  * @param a the starting vertex
  */
 private void minCut(EdgeWeightedGraph G, int a) {
     UF uf = new UF(G.V());
     boolean[] marked = new boolean[G.V()];
     cut = new boolean[G.V()];
     CutPhase cp = new CutPhase(0.0, a, a);
     for (int v = G.V(); v > 1; v--) {
         cp = minCutPhase(G, marked, cp);
         if (cp.weight < weight) {
             weight = cp.weight;
             makeCut(cp.t, uf);
         }
         G = contractEdge(G, cp.s, cp.t);
         marked[cp.t] = true;
         uf.union(cp.s, cp.t);
     }
 }
예제 #9
0
    // check optimality conditions:
    // (i) for all edges e = v-w:            distTo[w] <= distTo[v] + e.weight()
    // (ii) for all edge e = v-w on the SPT: distTo[w] == distTo[v] + e.weight()
    private boolean check(EdgeWeightedGraph G, int s) {

        // check that edge weights are nonnegative
        for (Edge e : G.edges()) {
            if (e.weight() < 0) {
                System.err.println("negative edge weight detected");
                return false;
            }
        }

        // check that distTo[v] and edgeTo[v] are consistent
        if (distTo[s] != 0.0 || edgeTo[s] != null) {
            System.err.println("distTo[s] and edgeTo[s] inconsistent");
            return false;
        }
        for (int v = 0; v < G.V(); v++) {
            if (v == s) continue;
            if (edgeTo[v] == null && distTo[v] != Double.POSITIVE_INFINITY) {
                System.err.println("distTo[] and edgeTo[] inconsistent");
                return false;
            }
        }

        // check that all edges e = v-w satisfy distTo[w] <= distTo[v] + e.weight()
        for (int v = 0; v < G.V(); v++) {
            for (Edge e : G.adj(v)) {
                int w = e.other(v);
                if (distTo[v] + e.weight() < distTo[w]) {
                    System.err.println("edge " + e + " not relaxed");
                    return false;
                }
            }
        }

        // check that all edges e = v-w on SPT satisfy distTo[w] == distTo[v] + e.weight()
        for (int w = 0; w < G.V(); w++) {
            if (edgeTo[w] == null) continue;
            Edge e = edgeTo[w];
            if (w != e.either() && w != e.other(e.either())) return false;
            int v = e.other(w);
            if (distTo[v] + e.weight() != distTo[w]) {
                System.err.println("edge " + e + " on shortest path not tight");
                return false;
            }
        }
        return true;
    }
예제 #10
0
 /**
  * Returns the cut-of-the-phase. The cut-of-the-phase is a minimum s-t-cut
  * in the current graph, where {@code s} and {@code t} are the two vertices
  * added last in the phase. This algorithm is known in the literature as
  * <em>maximum adjacency search</em> or <em>maximum cardinality search</em>.
  * 
  * @param G the edge-weighted graph
  * @param marked the array of contracted vertices, where {@code marked[v]}
  *            is {@code true} if the vertex {@code v} was already
  *            contracted; or {@code false} otherwise
  * @param cp the previous cut-of-the-phase
  * @return the cut-of-the-phase
  */
 private CutPhase minCutPhase(EdgeWeightedGraph G, boolean[] marked, CutPhase cp) {
     IndexMaxPQ<Double> pq = new IndexMaxPQ<Double>(G.V());
     for (int v = 0; v < G.V(); v++) {
         if (v != cp.s && !marked[v]) pq.insert(v, 0.0);
     }
     pq.insert(cp.s, Double.POSITIVE_INFINITY);
     while (!pq.isEmpty()) {
         int v = pq.delMax();
         cp.s = cp.t;
         cp.t = v;
         for (Edge e : G.adj(v)) {
             int w = e.other(v);
             if (pq.contains(w)) pq.increaseKey(w, pq.keyOf(w) + e.weight());
         }
     }
     cp.weight = 0.0;
     for (Edge e : G.adj(cp.t)) {
         cp.weight += e.weight();
     }
     return cp;
 }
예제 #11
0
    /**
     * Checks optimality conditions.
     * 
     * @param G the edge-weighted graph
     * @return {@code true} if optimality conditions are fine
     */
    private boolean check(EdgeWeightedGraph G) {

        // compute min st-cut for all pairs s and t
        // shortcut: s must appear on one side of global mincut,
        // so it suffices to try all pairs s-v for some fixed s
        double value = Double.POSITIVE_INFINITY;
        for (int s = 0, t = 1; t < G.V(); t++) {
            FlowNetwork F = new FlowNetwork(G.V());
            for (Edge e : G.edges()) {
                int v = e.either(), w = e.other(v);
                F.addEdge(new FlowEdge(v, w, e.weight()));
                F.addEdge(new FlowEdge(w, v, e.weight()));
            }
            FordFulkerson maxflow = new FordFulkerson(F, s, t);
            value = Math.min(value, maxflow.value());
        }
        if (Math.abs(weight - value) > FLOATING_POINT_EPSILON) {
            System.err.println("Min cut weight = " + weight + " , max flow value = " + value);
            return false;
        }
        return true;
    }
예제 #12
0
    private Queue<Edge> mst = new Queue<Edge>();  // edges in MST

    /**
     * Compute a minimum spanning tree (or forest) of an edge-weighted graph.
     * @param G the edge-weighted graph
     */
    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);
    }
예제 #13
0
    /**
     * Compute a minimum spanning tree (or forest) of an edge-weighted graph.
     * @param G the edge-weighted graph
     */
    public PrimMST(EdgeWeightedGraph G) {
        edgeTo = new Edge[G.V()];
        distTo = new double[G.V()];
        marked = new boolean[G.V()];
        pq = new IndexMinPQ<Double>(G.V());
        for (int v = 0; v < G.V(); v++)
            distTo[v] = Double.POSITIVE_INFINITY;

        for (int v = 0; v < G.V(); v++)      // run from each vertex to find
            if (!marked[v]) prim(G, v);      // minimum spanning forest

        // check optimality conditions
        assert check(G);
    }
예제 #14
0
 /**
  * Computes a minimum cut of an edge-weighted graph.
  * 
  * @param G the edge-weighted graph
  * @throws IllegalArgumentException if the number of vertices of {@code G}
  *             is less than {@code 2} or if anny edge weight is negative
  */
 public GlobalMincut(EdgeWeightedGraph G) {
     V = G.V();
     validate(G);
     minCut(G, 0);
     assert check(G);
 }
예제 #15
0
 /**
  * Validates the edge-weighted graph.
  * 
  * @param G the edge-weighted graph
  * @throws IllegalArgumentException if the number of vertices of {@code G}
  *             is less than {@code 2} or if any edge weight is negative
  */
 private void validate(EdgeWeightedGraph G) {
     if (G.V() < 2) throw new IllegalArgumentException("number of vertices of G is less than 2");
     for (Edge e : G.edges()) {
         if (e.weight() < 0) throw new IllegalArgumentException("edge " + e + " has negative weight");
     }
 }