001 
002 
003 
004 
005 
006 
007 
008 
009 
010 
011 
012 
013 
014 
015 
016 
017 
018 
019 
020 
021 
022 
023 
024 
025 
026 
027 
028 
029 
030 
031 
032 
033 
034 
035 
036 
037 
038 
039 
040 
041 
042 
043 
044 
045 
046 
047 
048 
049 
050 
051 
052 
053 
054 
055 
056 
057 
058 
059 
060 
061 
062 
063 
064 
065 
066 
067 
068 
069 
070 
071 
072 
073 
074 
075 
076 
077 
078 
079 
080 
081 
082 
083 
084 
085 
086 
087 
088 
089 
090 
091 
092 
093 
094 
095 
096 
097 
098 
099 
100 
101 
102 
103 
104 
105 
106 
107 
108 
109 
110 
111 
112 
113 
114 
115 
116 
117 
118 
119 
120 
121 
122 
123 
124 
125 
126 
127 
128 
129 
130 
131 
132 
133 
134 
135 
136 
137 
138 
139 
140 
141 
142 
143 
144 
145 
146 
147 
148 
149 
150 
151 
152 
153 
154 
155 
156 
 | 
// Exercise 4.2.39 (Solution published at http://algs4.cs.princeton.edu/)
package algs42;
import stdlib.*;
import algs13.Queue;
/* ***********************************************************************
 *  Compilation:  javac TopologicalQueue.java
 *  Execution:    java TopologicalQueue V E F
 *  Dependencies: Queue.java
 *
 *  Compute topological ordering of a DAG using queue-based algorithm.
 *  Runs in O(E + V) time.
 *
 *
 *************************************************************************/
public class XTopologicalQueue {
  private final Queue<Integer> order;     // vertices in topological order
  private final int[] indegree;           // indegree[v] = indegree of vertex v
  private final int[] rank;               // rank[v] = order where vertex v appers in order
  private int count;                // for computing the ranks
  public XTopologicalQueue(Digraph G) {
    indegree = new int[G.V()];
    rank = new int[G.V()];
    order = new Queue<>();
    // compute indegrees
    for (int v = 0; v < G.V(); v++) {
      for (int w : G.adj(v)) {
        indegree[w]++;
      }
    }
    // initialize queue to contain all vertices with indegree = 0
    Queue<Integer> queue = new Queue<>();
    for (int v = 0; v < G.V(); v++)
      if (indegree[v] == 0) queue.enqueue(v);
    while (!queue.isEmpty()) {
      int v = queue.dequeue();
      order.enqueue(v);
      rank[v] = count++;
      for (int w : G.adj(v)) {
        indegree[w]--;
        if (indegree[w] == 0) queue.enqueue(w);
      }
    }
  }
  // is G a directed acyclic graph?
  public boolean isDAG() {
    for (int element : indegree)
      if (element != 0) return false;
    return true;
  }
  // the vertices in topological order (assuming G is a DAG)
  public Iterable<Integer> order() {
    return order;
  }
  // the rank of vertex v in topological order
  public int rank(int v) {
    return rank[v];
  }
  // certify that digraph is acyclic
  private boolean check(Digraph G) {
    // digraph is acyclic
    if (isDAG()) {
      // check that ranks are a permutation of 0 to V-1
      boolean[] found = new boolean[G.V()];
      for (int i = 0; i < G.V(); i++) {
        found[rank(i)] = true;
      }
      for (int i = 0; i < G.V(); i++) {
        if (!found[i]) {
          System.err.println("No vertex with rank " + i);
          return false;
        }
      }
      // check that ranks provide a valid toplogical order
      for (int v = 0; v < G.V(); v++) {
        for (int w : G.adj(v)) {
          if (rank(v) > rank(w)) {
            System.err.format("%d-%d: rank(%d) = %d, rank(%d) = %d\n",
                v, w, v, rank(v), w, rank(w));
            return false;
          }
        }
      }
      // check that order() is consistent with rank()
      int r = 0;
      for (int v : order()) {
        if (rank(v) != r) {
          System.err.println("order() and rank() inconsistent");
          return false;
        }
        r++;
      }
    }
    return true;
  }
  public static void main(String[] args) {
    args = new String[] { "10", "20", "2" };
    // create random DAG with V vertices and E edges; then add F random edges
    int V = Integer.parseInt(args[0]);
    int E = Integer.parseInt(args[1]);
    int F = Integer.parseInt(args[2]);
    Digraph G = new Digraph(V);
    int[] vertices = new int[V];
    for (int i = 0; i < V; i++) vertices[i] = i;
    StdRandom.shuffle(vertices);
    for (int i = 0; i < E; i++) {
      int v, w;
      do {
        v = StdRandom.uniform(V);
        w = StdRandom.uniform(V);
      } while (v >= w);
      G.addEdge(vertices[v], vertices[w]);
    }
    // add F extra edges
    for (int i = 0; i < F; i++) {
      int v = (int) (Math.random() * V);
      int w = (int) (Math.random() * V);
      G.addEdge(v, w);
    }
    StdOut.println(G);
    // find a directed cycle
    XTopologicalQueue topological = new XTopologicalQueue(G);
    if (!topological.isDAG()) {
      StdOut.println("Not a DAG");
    }
    // or give topologial sort
    else {
      StdOut.print("Topological order: ");
      for (int v : topological.order()) {
        StdOut.print(v + " ");
      }
      StdOut.println();
    }
  }
}
 |