Beispiel #1
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);
  }
  // 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;
  }
  /**
   * 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);
  }
 // returns any non-isolated vertex; -1 if no such vertex
 private static int nonIsolatedVertex(Digraph G) {
   for (int v = 0; v < G.V(); v++) if (G.outdegree(v) > 0) return v;
   return -1;
 }