Exemple #1
0
  /**
   * Determines whether the digraph <tt>G</tt> has a topological order and, if so, finds such a
   * topological order.
   *
   * @param G the digraph
   */
  public TopologicalX(Digraph G) {
    // compute indegrees
    int[] indegree = new int[G.V()];
    for (int v = 0; v < G.V(); v++) {
      for (int w : G.adj(v)) {
        indegree[w]++;
      }
    }

    // initialize
    rank = new int[G.V()];
    order = new Queue<Integer>();
    int count = 0;

    // initialize queue to contain all vertices with indegree = 0
    Queue<Integer> queue = new Queue<Integer>();
    for (int v = 0; v < G.V(); v++) if (indegree[v] == 0) queue.enqueue(v);

    for (int j = 0; !queue.isEmpty(); j++) {
      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);
      }
    }

    // there is a directed cycle in subgraph of vertices with indegree >= 1.
    if (count != G.V()) {
      order = null;
    }

    assert check(G);
  }
Exemple #2
0
  private int[] path(Iterable<Integer> v, Iterable<Integer> w) {
    boolean isWithin = true;
    for (int i : v) {
      if (i < 0 || i > G.V() - 1) isWithin = false;
    }
    for (int i : w) {
      if (i < 0 || i > G.V() - 1) isWithin = false;
    }
    if (!isWithin) throw new IndexOutOfBoundsException("Arguments not within [0, V-1]");

    SAPPath vPath = new SAPPath(G, v);
    SAPPath wPath = new SAPPath(G, w);
    int[] distV = vPath.breath();
    int[] distW = wPath.breath();
    int sap = INFINITY;
    int distVW = INFINITY;
    int ancestor = INFINITY;
    for (int i = 0; i < G.V(); i++) {
      if (distV[i] != INFINITY && distW[i] != INFINITY) {
        distVW = distV[i] + distW[i];
        if (distVW < sap) {
          sap = distVW;
          ancestor = i;
        }
      }
    }
    int[] p = {sap, ancestor};
    return p;
  }
  /**
   * Computes the vertices reachable from the source vertex <tt>s</tt> in the digraph <tt>G</tt>.
   *
   * @param G the digraph
   * @param s the source vertex
   */
  public NonrecursiveDirectedDFS(Digraph G, int s) {
    marked = new boolean[G.V()];

    // to be able to iterate over each adjacency list, keeping track of which
    // vertex in each adjacency list needs to be explored next
    Iterator<Integer>[] adj = (Iterator<Integer>[]) new Iterator[G.V()];
    for (int v = 0; v < G.V(); v++) adj[v] = G.adj(v).iterator();

    // depth-first search using an explicit stack
    Stack<Integer> stack = new Stack<Integer>();
    marked[s] = true;
    stack.push(s);
    while (!stack.isEmpty()) {
      int v = stack.peek();
      if (adj[v].hasNext()) {
        int w = adj[v].next();
        // StdOut.printf("check %d\n", w);
        if (!marked[w]) {
          // discovered vertex w for the first time
          marked[w] = true;
          // edgeTo[w] = v;
          stack.push(w);
          // StdOut.printf("dfs(%d)\n", w);
        }
      } else {
        // StdOut.printf("%d done\n", v);
        stack.pop();
      }
    }
  }
Exemple #4
0
  /**
   * Ejecuta una caminata aleatoria sobre un grafo dirigido. Imprime por pantalla la cantidad de
   * pasos que dio antes de visitar todos los nodos del grafo.
   *
   * @param G Grafo dirigido sobre el cual se desea realizar la caminata aleatoria.
   */
  public void randomWalk(Digraph G) {
    int cont = 0;

    if (G.V() == 0) return;

    boolean[] viewed = new boolean[G.V()];
    int node = 0;
    viewed[node] = true;
    while (!this.allTrue(viewed)) {
      if (G.outdegree(node) == 0) {
        System.out.println("Encontrado un nodo sin salida");
        System.out.println("Cantidad de pasos dados en el Random Walk : " + cont);
        return;
      }

      int visited = this.getRandomNode(G.adj(node), G.outdegree(node));
      System.out.println(node + " -> " + visited);
      viewed[visited] = true;

      cont++;
      node = visited;
    }

    System.out.println("Cantidad de pasos dados en el Random Walk : " + cont);
  }
Exemple #5
0
 public BreadthFirstDirectedPaths(Digraph G, int s) {
   marked = new boolean[G.V()];
   distTo = new int[G.V()];
   edgeTo = new int[G.V()];
   for (int v = 0; v < G.V(); v++) distTo[v] = INFINITY;
   this.s = s;
   bfs(G, s);
 }
 /**
  * Determines a depth-first order for the digraph <tt>G</tt>.
  *
  * @param G the digraph
  */
 public DepthFirstOrder(Digraph G) {
   pre = new int[G.V()];
   post = new int[G.V()];
   postorder = new Queue<Integer>();
   preorder = new Queue<Integer>();
   marked = new boolean[G.V()];
   for (int v = 0; v < G.V(); v++) if (!marked[v]) dfs(G, v);
 }
 // does the id[] array contain the strongly connected components?
 private boolean check(Digraph G) {
   TransitiveClosure tc = new TransitiveClosure(G);
   for (int v = 0; v < G.V(); v++) {
     for (int w = 0; w < G.V(); w++) {
       if (stronglyConnected(v, w) != (tc.reachable(v, w) && tc.reachable(w, v))) return false;
     }
   }
   return true;
 }
 public KosarajuSCC(Digraph G) {
   marked = new boolean[G.V()];
   id = new int[G.V()];
   DepthFirstOrder order = new DepthFirstOrder(G.reverse());
   for (int s : order.reverse())
     if (!marked[s]) {
       dfs(G, s);
       count++;
     }
 }
Exemple #9
0
 DepthFirstOrder(Digraph G) {
   marked = new boolean[G.V()];
   pre = new LinkedList<Integer>();
   post = new LinkedList<Integer>();
   reversePost = new Stack<Integer>();
   for (int v = 0; v < G.V(); v++) {
     if (!marked[v]) {
       dfs(G, v);
     }
   }
 }
Exemple #10
0
 /** Copy constructor. */
 public Digraph(Digraph 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<Integer> reverse = new Stack<Integer>();
     for (int w : G.adj[v]) {
       reverse.push(w);
     }
     for (int w : reverse) {
       adj[v].add(w);
     }
   }
 }
  /**
   * Computes the strong components of the digraph <tt>G</tt>.
   *
   * @param G the digraph
   */
  public GabowSCC(Digraph G) {
    marked = new boolean[G.V()];
    stack1 = new Stack<Integer>();
    stack2 = new Stack<Integer>();
    id = new int[G.V()];
    preorder = new int[G.V()];
    for (int v = 0; v < G.V(); v++) id[v] = -1;

    for (int v = 0; v < G.V(); v++) {
      if (!marked[v]) dfs(G, v);
    }

    // check that id[] gives strong components
    assert check(G);
  }
Exemple #12
0
  /** Unit tests the <tt>DepthFirstOrder</tt> data type. */
  public static void main(String[] args) {
    In in = new In(args[0]);
    Digraph G = new Digraph(in);

    DepthFirstOrder dfs = new DepthFirstOrder(G);
    StdOut.println("   v  pre post");
    StdOut.println("--------------");
    for (int v = 0; v < G.V(); v++) {
      StdOut.printf("%4d %4d %4d\n", v, dfs.pre(v), dfs.post(v));
    }

    StdOut.print("Preorder:  ");
    for (int v : dfs.pre()) {
      StdOut.print(v + " ");
    }
    StdOut.println();

    StdOut.print("Postorder: ");
    for (int v : dfs.post()) {
      StdOut.print(v + " ");
    }
    StdOut.println();

    StdOut.print("Reverse postorder: ");
    for (int v : dfs.reversePost()) {
      StdOut.print(v + " ");
    }
    StdOut.println();
  }
  /** Unit tests the <tt>GabowSCC</tt> data type. */
  public static void main(String[] args) {
    In in = new In(args[0]);
    Digraph G = new Digraph(in);
    GabowSCC scc = new GabowSCC(G);

    // number of connected components
    int M = scc.count();
    StdOut.println(M + " components");

    // compute list of vertices in each strong component
    Queue<Integer>[] components = (Queue<Integer>[]) new Queue[M];
    for (int i = 0; i < M; i++) {
      components[i] = new Queue<Integer>();
    }
    for (int v = 0; v < G.V(); v++) {
      components[scc.id(v)].enqueue(v);
    }

    // print results
    for (int i = 0; i < M; i++) {
      for (int v : components[i]) {
        StdOut.print(v + " ");
      }
      StdOut.println();
    }
  }
Exemple #14
0
  /** Test client. */
  public static void main(String[] args) {
    In in = new In(args[0]);
    Digraph G = new Digraph(in);
    StdOut.println(G);

    StdOut.println();
    for (int v = 0; v < G.V(); v++) for (int w : G.adj(v)) StdOut.println(v + "->" + w);
  }
 /** Unit tests the <tt>NonrecursiveDirectedDFS</tt> data type. */
 public static void main(String[] args) {
   In in = new In(args[0]);
   Digraph G = new Digraph(in);
   int s = Integer.parseInt(args[1]);
   NonrecursiveDirectedDFS dfs = new NonrecursiveDirectedDFS(G, s);
   for (int v = 0; v < G.V(); v++) if (dfs.marked(v)) StdOut.print(v + " ");
   StdOut.println();
 }
  public KosarajuSCC(Digraph G) {

    // compute reverse postorder of reverse graph
    DepthFirstOrder dfs = new DepthFirstOrder(G.reverse());

    // run DFS on G, using reverse postorder to guide calculation
    marked = new boolean[G.V()];
    id = new int[G.V()];
    for (int v : dfs.reversePost()) {
      if (!marked[v]) {
        dfs(G, v);
        count++;
      }
    }

    // check that id[] gives strong components
    assert check(G);
  }
  public boolean recognizes(String txt) {
    Bag<Integer> pc = new Bag<Integer>();
    DirectedDFS dfs = new DirectedDFS(G, 0);
    for (int v = 0; v < G.V(); v++) if (dfs.marked(v)) pc.add(v);

    for (int i = 0; i < txt.length(); i++) {
      Bag<Integer> match = new Bag<Integer>();
      for (int v : pc) if (v < M) if (re[v] == txt.charAt(i) || re[v] == '.') match.add(v + 1);
      dfs = new DirectedDFS(G, match);
      pc = new Bag<Integer>();
      for (int v = 0; v < G.V(); v++) if (dfs.marked(v)) pc.add(v);

      // optimization if no states reachable
      if (pc.size() == 0) return false;
    }

    for (int v : pc) if (v == M) return true;
    return false;
  }
  // Determines whether a digraph has an Eulerian cycle using necessary
  // and sufficient conditions (without computing the cycle itself):
  //    - at least one edge
  //    - indegree(v) = outdegree(v) for every vertex
  //    - the graph is connected, when viewed as an undirected graph
  //      (ignoring isolated vertices)
  private static boolean hasEulerianCycle(Digraph G) {

    // Condition 0: at least 1 edge
    if (G.E() == 0) return false;

    // Condition 1: indegree(v) == outdegree(v) for every vertex
    for (int v = 0; v < G.V(); v++) if (G.outdegree(v) != G.indegree(v)) return false;

    // Condition 2: graph is connected, ignoring isolated vertices
    Graph H = new Graph(G.V());
    for (int v = 0; v < G.V(); v++) for (int w : G.adj(v)) H.addEdge(v, w);

    // check that all non-isolated vertices are conneted
    int s = nonIsolatedVertex(G);
    BreadthFirstPaths bfs = new BreadthFirstPaths(H, s);
    for (int v = 0; v < G.V(); v++) if (H.degree(v) > 0 && !bfs.hasPathTo(v)) return false;

    return true;
  }
Exemple #19
0
  public static void main(String[] args) {

    In in1 = new In(Inputs.DIGRAPH_SMALL);
    In in2 = new In(Inputs.DIGRAPH_SMALL);
    edu.princeton.cs.algs4.Digraph sedgewicks = new edu.princeton.cs.algs4.Digraph(in1);
    Digraph digraph = new Digraph(in2);
    in1.close();
    in2.close();

    StdOut.printf("Sedgewicks - v: %d, e: %d\n", sedgewicks.V(), sedgewicks.E());
    for (int i = 0; i < sedgewicks.V(); i++) {
      for (int w : sedgewicks.adj(i)) {
        StdOut.printf("%d -> %d\n", i, w);
      }
    }
    StdOut.println();

    StdOut.printf("My - v: %d, e: %d\n", digraph.V(), digraph.E());
    for (int i = 0; i < digraph.V(); i++) {
      for (int w : digraph.adj(i)) {
        StdOut.printf("%d -> %d\n", i, w);
      }
    }
    StdOut.println();

    edu.princeton.cs.algs4.Digraph sedwickDi = sedgewicks.reverse();
    StdOut.printf("Sedgewicks reverse - v: %d, e: %d\n", sedwickDi.V(), sedwickDi.E());
    for (int i = 0; i < sedwickDi.V(); i++) {
      for (int w : sedwickDi.adj(i)) {
        StdOut.printf("%d -> %d\n", i, w);
      }
    }
    StdOut.println();

    Digraph myReverse = digraph.reverse();
    StdOut.printf("My reverse - v: %d, e: %d\n", myReverse.V(), myReverse.E());
    for (int i = 0; i < myReverse.V(); i++) {
      for (int w : myReverse.adj(i)) {
        StdOut.printf("%d -> %d\n", i, w);
      }
    }
  }
 private boolean rootedDAG(Digraph g) {
   int roots = 0;
   for (int i = 0; i < g.V(); i++) {
     if (!g.adj(i).iterator().hasNext()) {
       roots++;
       if (roots > 1) {
         return false;
       }
     }
   }
   return roots == 1;
 }
Exemple #21
0
  // certify that digraph is acyclic
  private boolean check(Digraph G) {

    // digraph is acyclic
    if (hasOrder()) {
      // 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 topological order
      for (int v = 0; v < G.V(); v++) {
        for (int w : G.adj(v)) {
          if (rank(v) > rank(w)) {
            System.err.printf(
                "%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;
  }
Exemple #22
0
 private int[] path(int v, int w) {
   if (v < 0 || w < 0 || v > G.V() - 1 || w > G.V() - 1)
     throw new IndexOutOfBoundsException("Arguments not within [0, V-1]");
   SAPPath vPath = new SAPPath(G, v);
   SAPPath wPath = new SAPPath(G, w);
   int[] distV = vPath.breath();
   int[] distW = wPath.breath();
   int sap = INFINITY;
   int distVW = INFINITY;
   int ancestor = INFINITY;
   for (int i = 0; i < G.V(); i++) {
     if (distV[i] != INFINITY && distW[i] != INFINITY) {
       distVW = distV[i] + distW[i];
       if (distVW < sap) {
         sap = distVW;
         ancestor = i;
       }
     }
   }
   int[] p = {sap, ancestor};
   return p;
 }
  /** Unit tests the <tt>DirectedEulerianCycle</tt> data type. */
  public static void main(String[] args) {
    int V = Integer.parseInt(args[0]);
    int E = Integer.parseInt(args[1]);

    // Eulerian cycle
    Digraph G1 = DigraphGenerator.eulerianCycle(V, E);
    unitTest(G1, "Eulerian cycle");

    // Eulerian path
    Digraph G2 = DigraphGenerator.eulerianPath(V, E);
    unitTest(G2, "Eulerian path");

    // empty digraph
    Digraph G3 = new Digraph(V);
    unitTest(G3, "empty digraph");

    // self loop
    Digraph G4 = new Digraph(V);
    int v4 = StdRandom.uniform(V);
    G4.addEdge(v4, v4);
    unitTest(G4, "single self loop");

    // union of two disjoint cycles
    Digraph H1 = DigraphGenerator.eulerianCycle(V / 2, E / 2);
    Digraph H2 = DigraphGenerator.eulerianCycle(V - V / 2, E - E / 2);
    int[] perm = new int[V];
    for (int i = 0; i < V; i++) perm[i] = i;
    StdRandom.shuffle(perm);
    Digraph G5 = new Digraph(V);
    for (int v = 0; v < H1.V(); v++) for (int w : H1.adj(v)) G5.addEdge(perm[v], perm[w]);
    for (int v = 0; v < H2.V(); v++)
      for (int w : H2.adj(v)) G5.addEdge(perm[V / 2 + v], perm[V / 2 + w]);
    unitTest(G5, "Union of two disjoint cycles");

    // random digraph
    Digraph G6 = DigraphGenerator.simple(V, E);
    unitTest(G6, "simple digraph");
  }
  /**
   * Computes an Eulerian cycle in the specified digraph, if one exists.
   *
   * @param G the digraph
   */
  public DirectedEulerianCycle(Digraph G) {

    // must have at least one edge
    if (G.E() == 0) return;

    // necessary condition: indegree(v) = outdegree(v) for each vertex v
    // (without this check, DFS might return a path instead of a cycle)
    for (int v = 0; v < G.V(); v++) if (G.outdegree(v) != G.indegree(v)) return;

    // create local view of adjacency lists, to iterate one vertex at a time
    Iterator<Integer>[] adj = (Iterator<Integer>[]) new Iterator[G.V()];
    for (int v = 0; v < G.V(); v++) adj[v] = G.adj(v).iterator();

    // initialize stack with any non-isolated vertex
    int s = nonIsolatedVertex(G);
    Stack<Integer> stack = new Stack<Integer>();
    stack.push(s);

    // greedily add to putative cycle, depth-first search style
    cycle = new Stack<Integer>();
    while (!stack.isEmpty()) {
      int v = stack.pop();
      while (adj[v].hasNext()) {
        stack.push(v);
        v = adj[v].next();
      }
      // add vertex with no more leaving edges to cycle
      cycle.push(v);
    }

    // check if all edges have been used
    // (in case there are two or more vertex-disjoint Eulerian cycles)
    if (cycle.size() != G.E() + 1) cycle = null;

    assert certifySolution(G);
  }
  /** Unit tests the <tt>DirectedDFS</tt> data type. */
  public static void main(String[] args) {

    // read in digraph from command-line argument
    In in = new In(args[0]);
    Digraph G = new Digraph(in);

    // read in sources from command-line arguments
    Bag<Integer> sources = new Bag<Integer>();
    for (int i = 1; i < args.length; i++) {
      int s = Integer.parseInt(args[i]);
      sources.add(s);
    }

    // multiple-source reachability
    DirectedDFS dfs = new DirectedDFS(G, sources);

    // print out vertices reachable from sources
    for (int v = 0; v < G.V(); v++) {
      if (dfs.marked(v)) StdOut.print(v + " ");
    }
    StdOut.println();
  }
	public EdgeWeightedCycleFinder(Digraph G){
		onStack = new boolean[G.V()];
		edgeTo =new int[G.V()];
		marked =new boolean[G.V()];
		for(int v=0;v<G.V();v++) if(!marked[v]) dfs(G,v);
	}
  public NFADemo(String regexp) {
    // use stack to keep track of the positions of '('and '|'
    // issue : or的优先级最低
    Stack<Integer> ops = new Stack<Integer>();
    re = regexp.toCharArray();
    M = re.length;
    G = new Digraph(M + 1);

    // 第一次遍历,确定层次,仅为作图用
    int[] levels = new int[M]; // levels仅在 * 和 | 处非零
    for (int i = 0; i < M; i++) {
      int lp = i;
      if (re[i] == '(' || re[i] == '|') ops.push(i);
      else if (re[i] == ')') {
        int or = ops.pop();
        if (re[or] == '|') {
          lp = ops.pop();
          levels[or] = maxOfArr(levels, lp, i) + 1;
        } else lp = or;
      }
      if (i < M - 1 && re[i + 1] == '*') levels[i + 1] = maxOfArr(levels, lp, i + 1) + 1;
    }
    int maxLevel = maxOfArr(levels, 0, M);

    StdDraw.setCanvasSize(800, 800 * 2 * maxLevel / M);
    StdDraw.setXscale(0, M);
    StdDraw.setYscale(-maxLevel, maxLevel);

    double r = 0.2;
    for (int v = 0; v < G.V(); v++) {
      if (v < M) {
        StdDraw.circle((double) v, 0.0, r);
        StdDraw.text((double) v, 0.0, (new Character(re[v]).toString()));
      } else StdDraw.filledCircle((double) v, 0.0, r);
    }

    StdDraw.setPenColor(StdDraw.RED);
    StdDraw.setPenRadius(0.005);
    ops = new Stack<Integer>();
    for (int i = 0; i < M; i++) {
      int lp = i;
      if (re[i] == '(' || re[i] == '|') ops.push(i);
      else if (re[i] == ')') {
        int or = ops.pop();
        if (re[or] == '|') {
          lp = ops.pop();
          G.addEdge(lp, or + 1);
          G.addEdge(or, i);

          // connect (lp, or+1), (or, i)
          double level = (double) levels[or];
          StdDraw.line(or, r, or, level);
          StdDraw.line(or, level, i, level);
          StdDraw.arrow(i, level, i, r);
          StdDraw.line(lp, -r, lp, -level);
          StdDraw.line(lp, -level, or + 1, -level);
          StdDraw.filledArrow(or + 1, -level, or + 1, -r);
        } else lp = or; // 此时是'(', 在后面跟的是*时会用到
      }
      if (i < M - 1 && re[i + 1] == '*') {
        // look ahead
        G.addEdge(lp, i + 1);
        G.addEdge(i + 1, lp);

        // connect (lp, i+1), (i+1, lp)
        double level = (double) levels[i + 1];
        StdDraw.line(i + 1, r, i + 1, level);
        StdDraw.line(i + 1, level, lp, level);
        StdDraw.filledArrow(lp, level, lp, r);
        StdDraw.line(lp, -r, lp, -level);
        StdDraw.line(lp, -level, i + 1, -level);
        StdDraw.filledArrow(i + 1, -level, i + 1, -r);
      }
      if (re[i] == '(' || re[i] == '*' || re[i] == ')') {
        G.addEdge(i, i + 1);
        StdDraw.filledArrow(i + r, 0.0, i + 1 - r, 0.0);
      } else if (re[i] != '|') { // match transitions
        StdDraw.setPenColor();
        StdDraw.filledArrow(i + r, 0.0, i + 1 - r, 0.0);
        StdDraw.setPenColor(StdDraw.RED);
      }
    }
  }
Exemple #28
0
 /**
  * Determines whether the digraph <tt>G</tt> has a directed cycle and, if so, finds such a cycle.
  *
  * @param G the digraph
  */
 public DirectedCycle(Digraph G) {
   marked = new boolean[G.V()];
   onStack = new boolean[G.V()];
   edgeTo = new int[G.V()];
   for (int v = 0; v < G.V(); v++) if (!marked[v]) dfs(G, v);
 }
 /**
  * Computes the vertices in digraph <tt>G</tt> that are connected to any of the source vertices
  * <tt>sources</tt>.
  *
  * @param G the graph
  * @param sources the source vertices
  */
 public DirectedDFS(Digraph G, Iterable<Integer> sources) {
   marked = new boolean[G.V()];
   for (int v : sources) {
     if (!marked[v]) dfs(G, v);
   }
 }
 /**
  * Computes the vertices in digraph <tt>G</tt> that are reachable from the source vertex
  * <tt>s</tt>.
  *
  * @param G the digraph
  * @param s the source vertex
  */
 public DirectedDFS(Digraph G, int s) {
   marked = new boolean[G.V()];
   dfs(G, s);
 }