示例#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);
  }
示例#2
0
  // check that algorithm computes either the topological order or finds a directed cycle
  private void dfs(Digraph G, int v) {
    onStack[v] = true;
    marked[v] = true;
    for (int w : G.adj(v)) {

      // short circuit if directed cycle found
      if (cycle != null) return;

      // found new vertex, so recur
      else if (!marked[w]) {
        edgeTo[w] = v;
        dfs(G, w);
      }

      // trace back directed cycle
      else if (onStack[w]) {
        cycle = new Stack<Integer>();
        for (int x = v; x != w; x = edgeTo[x]) {
          cycle.push(x);
        }
        cycle.push(w);
        cycle.push(v);
      }
    }

    onStack[v] = false;
  }
示例#3
0
	private void dfs(Digraph G ,int v){
		onStack[v] = true ; 
		marked[v] = true ; 
		for(int w:G.adj(v)) 

		if(this.hasCycle()) {

		}
		if(!marked[v]){
				edgeTo[w] = v;
				dfs(G,w);
			}
		else{
			if(onStack[w]){
				cycle = new Stack<Integer>();
				for(int x = v; x!=w;x =edgeTo[x]) cycle.push(x);
				cycle.push(w);
				cycle.push(v);
			}
		} 

		onStack[v] = false;

		
	}
 private void dfs(Digraph G, int v) {
   count++;
   marked[v] = true;
   for (int w : G.adj(v)) {
     if (!marked[w]) dfs(G, w);
   }
 }
  /**
   * 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();
      }
    }
  }
示例#6
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);
  }
示例#7
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);
  }
 private boolean hasPath(int start, int end) {
   for (int w : di.adj(start)) {
     if (w == end) {
       return true;
     }
   }
   return false;
 }
示例#9
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);
      }
    }
  }
示例#10
0
 private void dfs(Digraph G, int v) {
   marked[v] = true;
   pre.offer(v);
   for (int w : G.adj(v)) {
     if (!marked[w]) {
       dfs(G, w);
     }
   }
   post.offer(v);
   reversePost.push(v);
 }
示例#11
0
 /**
  * Unit tests the <tt>SymbolDigraph</tt> data type.
  */
 public static void main(String[] args) {
     String filename  = args[0];
     String delimiter = args[1];
     SymbolDigraph sg = new SymbolDigraph(filename, delimiter);
     Digraph G = sg.G();
     while (!StdIn.isEmpty()) {
         String t = StdIn.readLine();
         for (int v : G.adj(sg.index(t))) {
             StdOut.println("   " + sg.name(v));
         }
     }
 }
 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;
 }
示例#13
0
 // run DFS in digraph G from vertex v and compute preorder/postorder
 private void dfs(Digraph G, int v) {
   marked[v] = true;
   pre[v] = preCounter++;
   preorder.enqueue(v);
   for (int w : G.adj(v)) {
     if (!marked[w]) {
       dfs(G, w);
     }
   }
   postorder.enqueue(v);
   post[v] = postCounter++;
 }
示例#14
0
  /** 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");
  }
示例#15
0
  public void bfs(Digraph G, int v) {
    Queue<Integer> q = new Queue<Integer>();
    q.enqueue(v);
    marked[v] = true;

    while (!q.isEmpty()) {
      q.dequeue();
      for (int w : G.adj(v)) {
        if (!marked[w]) {
          q.enqueue(w);
          marked[w] = true;
          edgeTo[w] = v;
        }
      }
    }
  }
示例#16
0
 private void bfs(Digraph G, int s) {
   Queue<Integer> q = new Queue<Integer>();
   marked[s] = true;
   distTo[s] = 0;
   q.enqueue(s);
   while (!q.isEmpty()) {
     int v = q.dequeue();
     for (int w : G.adj(v)) {
       if (!marked[w]) {
         edgeTo[w] = v;
         distTo[w] = distTo[v] + 1;
         marked[w] = true;
         q.enqueue(w);
       }
     }
   }
 }
示例#17
0
  // 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;
  }
示例#18
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;
  }
示例#19
0
  private void dfs(Digraph G, int v) {
    marked[v] = true;
    preorder[v] = pre++;
    stack1.push(v);
    stack2.push(v);
    for (int w : G.adj(v)) {
      if (!marked[w]) dfs(G, w);
      else if (id[w] == -1) {
        while (preorder[stack2.peek()] > preorder[w]) stack2.pop();
      }
    }

    // found strong component containing v
    if (stack2.peek() == v) {
      stack2.pop();
      int w;
      do {
        w = stack1.pop();
        id[w] = count;
      } while (w != v);
      count++;
    }
  }
示例#20
0
  /**
   * 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);
  }
示例#21
0
 private void dfs(Digraph G, int v) {
   marked[v] = true;
   id[v] = count;
   for (int w : G.adj(v)) if (!marked[w]) dfs(G, w);
 }