Beispiel #1
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();
  }
Beispiel #2
0
  public static boolean isTree(Digraph digraph) {
    Object root = null;
    for (Iterator i = digraph.vertexIterator(); i.hasNext(); ) {
      Object vertex = i.next();
      int inSize = digraph.incomingSize(vertex);
      if (inSize == 0) {
        root = vertex;
        break;
      }
    }

    // not a tree - no vertex with 0 in-degree
    if (root == null) return false;

    // try to reach all vertices from the root candidate
    BreadthFirstSearch traversal = new BreadthFirstSearch(digraph, root);
    while (traversal.isValidTree() && traversal.hasNext()) traversal.next();

    // not a tree - one of vertices has been seen more than once by the BFS
    if (!traversal.isValidTree()) return false;

    // has every vertex been reached?
    Set seenVertices = traversal.getSeenVertices();
    for (Iterator i = digraph.vertexIterator(); i.hasNext(); )
      if (!seenVertices.contains(i.next())) return false;

    // all tests are passed - good!
    return true;
  }
Beispiel #3
0
 public static boolean isAcyclic(Digraph digraph) {
   int order = digraph.order();
   if (order == 0) return true;
   Set spanned = new HashSet(order);
   DepthFirstStampSearch dfs = new DepthFirstStampSearch(digraph, digraph.vertexIterator().next());
   for (Iterator i = digraph.vertexIterator(); i.hasNext(); ) {
     Object dfsRoot = i.next();
     if (spanned.contains(dfsRoot)) continue;
     dfs.reset(dfsRoot);
     Map dfsOrders = dfs.traverse(new HashMap(digraph.order()));
     for (Iterator j = dfsOrders.entrySet().iterator(); j.hasNext(); ) {
       Map.Entry entry = (Map.Entry) j.next();
       Object origin = entry.getKey();
       DepthFirstStampSearch.OrderPair orgOrders =
           (DepthFirstStampSearch.OrderPair) entry.getValue();
       spanned.add(origin);
       for (ArcIterator k = digraph.outgoingIterator(origin); k.hasNext(); ) {
         k.next();
         Object dst = k.getDestination();
         DepthFirstStampSearch.OrderPair dstOrders =
             (DepthFirstStampSearch.OrderPair) dfsOrders.get(dst);
         if (dstOrders.getPostOrder() > orgOrders.getPostOrder()) return false;
       }
     }
     if (dfsOrders.size() == order) break;
   }
   return true;
 }
  /**
   * Returns a random rooted-out DAG on <tt>V</tt> vertices and <tt>E</tt> edges. The DAG returned
   * is not chosen uniformly at random among all such DAGs.
   *
   * @param V the number of vertices
   * @param E the number of edges
   * @return a random rooted-out DAG on <tt>V</tt> vertices and <tt>E</tt> edges
   */
  public static Digraph rootedOutDAG(int V, int E) {
    if (E > (long) V * (V - 1) / 2) throw new IllegalArgumentException("Too many edges");
    if (E < V - 1) throw new IllegalArgumentException("Too few edges");
    Digraph G = new Digraph(V);
    SET<Edge> set = new SET<Edge>();

    // fix a topological order
    int[] vertices = new int[V];
    for (int i = 0; i < V; i++) vertices[i] = i;
    StdRandom.shuffle(vertices);

    // one edge pointing from each vertex, other than the root = vertices[V-1]
    for (int v = 0; v < V - 1; v++) {
      int w = StdRandom.uniform(v + 1, V);
      Edge e = new Edge(v, w);
      set.add(e);
      G.addEdge(vertices[w], vertices[v]);
    }

    while (G.E() < E) {
      int v = StdRandom.uniform(V);
      int w = StdRandom.uniform(V);
      Edge e = new Edge(v, w);
      if ((v < w) && !set.contains(e)) {
        set.add(e);
        G.addEdge(vertices[w], vertices[v]);
      }
    }
    return G;
  }
  /**
   * 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();
      }
    }
  }
Beispiel #6
0
  /** Unit tests the <tt>com.akieus.algos.coursera.lib.TopologicalX</tt> data type. */
  public static void main(String[] args) {

    // 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 = DigraphGenerator.dag(V, E);

    // add F extra edges
    for (int i = 0; i < F; i++) {
      int v = StdRandom.uniform(V);
      int w = StdRandom.uniform(V);
      G.addEdge(v, w);
    }

    StdOut.println(G);

    // find a directed cycle
    TopologicalX topological = new TopologicalX(G);
    if (!topological.hasOrder()) {
      StdOut.println("Not a DAG");
    }

    // or give topologial sort
    else {
      StdOut.print("com.akieus.algos.coursera.lib.Topological order: ");
      for (int v : topological.order()) {
        StdOut.print(v + " ");
      }
      StdOut.println();
    }
  }
Beispiel #7
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;
  }
Beispiel #8
0
  /** 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();
    }
  }
Beispiel #9
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);
  }
Beispiel #10
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);
 }
Beispiel #11
0
 /**
  * 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);
 }
 /** 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();
 }
Beispiel #13
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);
  }
 /**
  * Returns a random simple digraph on <tt>V</tt> vertices, with an edge between any two vertices
  * with probability <tt>p</tt>. This is sometimes referred to as the Erdos-Renyi random digraph
  * model.
  *
  * @param V the number of vertices
  * @param p the probability of choosing an edge
  * @return a random simple digraph on <tt>V</tt> vertices, with an edge between any two vertices
  *     with probability <tt>p</tt>
  * @throws IllegalArgumentException if probability is not between 0 and 1
  */
 public static Digraph simple(int V, double p) {
   if (p < 0.0 || p > 1.0)
     throw new IllegalArgumentException("Probability must be between 0 and 1");
   Digraph G = new Digraph(V);
   for (int v = 0; v < V; v++)
     for (int w = 0; w < V; w++) if (v != w) if (StdRandom.bernoulli(p)) G.addEdge(v, w);
   return G;
 }
Beispiel #15
0
 // 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;
 }
Beispiel #16
0
  public static Map shiftLevelsDown(Map vertexLevelMap, Digraph digraph) {
    for (Iterator i = digraph.vertexIterator(); i.hasNext(); ) {
      Object rootCandidate = i.next();
      if (digraph.incomingSize(rootCandidate) == 0)
        shiftLevelsDown(vertexLevelMap, digraph, rootCandidate);
    }

    return vertexLevelMap;
  }
Beispiel #17
0
 /** Return the reverse of the digraph. */
 public Digraph reverse() {
   Digraph R = new Digraph(V);
   for (int v = 0; v < V; v++) {
     for (int w : adj(v)) {
       R.addEdge(w, v);
     }
   }
   return R;
 }
 /**
  * Returns a complete binary tree digraph on <tt>V</tt> vertices.
  *
  * @param V the number of vertices in the binary tree
  * @return a digraph that is a complete binary tree on <tt>V</tt> vertices
  */
 public static Digraph binaryTree(int V) {
   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 = 1; i < V; i++) {
     G.addEdge(vertices[i], vertices[(i - 1) / 2]);
   }
   return G;
 }
Beispiel #19
0
 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++;
     }
 }
 /**
  * Returns a path digraph on <tt>V</tt> vertices.
  *
  * @param V the number of vertices in the path
  * @return a digraph that is a directed path on <tt>V</tt> vertices
  */
 public static Digraph path(int V) {
   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 < V - 1; i++) {
     G.addEdge(vertices[i], vertices[i + 1]);
   }
   return G;
 }
Beispiel #21
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);
     }
   }
 }
Beispiel #22
0
  public static Map computeLevels(Map vertexLevelMap, Digraph digraph, boolean longest) {
    if (vertexLevelMap == null) vertexLevelMap = new HashMap(digraph.order());

    for (Iterator i = digraph.vertexIterator(); i.hasNext(); ) {
      Object rootCandidate = i.next();
      if (digraph.incomingSize(rootCandidate) == 0)
        computeLevels(vertexLevelMap, digraph, rootCandidate, longest);
    }

    return vertexLevelMap;
  }
 /**
  * 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;
 }
Beispiel #25
0
 public static Digraph merge(Digraph destination, DigraphIteration graphToMerge) {
   for (Iterator i = graphToMerge.vertexIterator(); i.hasNext(); ) {
     destination.addVertex(i.next());
   }
   for (ArcIterator i = graphToMerge.arcIterator(); i.hasNext(); ) {
     Object arc = i.next();
     Object origin = i.getOrigin();
     Object dst = i.getDestination();
     destination.putArc(origin, dst, arc);
   }
   return destination;
 }
  private Digraph initHypernyms(String sss) {
    In in = new In(sss);
    Digraph graph = new Digraph(this.idToSynset.size());

    while (in.hasNextLine()) {
      String[] getLines = in.readLine().split(",");
      Integer id = Integer.valueOf(getLines[0]);
      for (int i = 1; i < getLines.length; i++) {
        graph.addEdge(id, Integer.valueOf(getLines[i]));
      }
    }
    return graph;
  }
Beispiel #27
0
 public static Digraph randomize(Digraph digraph, int order, int size, Random randomizer) {
   for (int i = 1; i <= order; i++) digraph.addVertex(new Integer(i));
   Random random = randomizer;
   int n_2 = order * order;
   size = Math.min(size, n_2);
   for (int arc = 1; arc <= size; arc++) {
     int arcCode = random.nextInt(n_2);
     int origin = arcCode / order + 1;
     int dst = arcCode % order + 1;
     digraph.putArc(new Integer(origin), new Integer(dst), new Integer(arc));
   }
   return digraph;
 }
Beispiel #28
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);
     }
   }
 }
  private KosarajuSharirSCC(Digraph<V> digraph) {
    ids = new HashMap<>(digraph.vertexCount());
    visited = new HashSet<>(digraph.vertexCount());
    size = new int[digraph.vertexCount()];

    DepthFirstOrder<V> dfo = DepthFirstOrder.from(digraph.reverse());

    for (V vertex : dfo.reversePost()) {
      if (!visited.contains(vertex)) {
        dfs(digraph, vertex);
        count++;
      }
    }
  }
Beispiel #30
0
  /**
   * 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);
  }