예제 #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
파일: CC.cs 프로젝트: franklzt/DataStruct
 // depth-first search for an EdgeWeightedGraph
 private void dfs(EdgeWeightedGraph G, int v) {
     marked[v] = true;
     id[v] = count;
     size[count]++;
     for (Edge e : G.adj(v)) {
         int w = e.other(v);
         if (!marked[w]) {
             dfs(G, w);
         }
     }
 }
예제 #3
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;
 }
예제 #4
0
 // scan vertex v
 private void scan(EdgeWeightedGraph G, int v) {
     marked[v] = true;
     for (Edge e : G.adj(v)) {
         int w = e.other(v);
         if (marked[w]) continue;         // v-w is obsolete edge
         if (e.weight() < distTo[w]) {
             distTo[w] = e.weight();
             edgeTo[w] = e;
             if (pq.contains(w)) pq.decreaseKey(w, distTo[w]);
             else                pq.insert(w, distTo[w]);
         }
     }
 }
예제 #5
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;
 }
예제 #6
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;
    }