/** * 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); }
// 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; }
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(); } } }
/** * 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); }
/** 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; }
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 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); }
/** * 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; }
// 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++; }
/** 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"); }
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; } } } }
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); } } } }
// 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; }
// 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; }
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++; } }
/** * 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); }
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); }