예제 #1
0
  /**
   * returns a set of lists that represent all possible breadth-first traversals of the graph. Each
   * traversal is always the shortest possible way to traverse the graph from a starting index. The
   * number of lists in the set represents the possible number of starting vertices.
   *
   * @param graph the graph to be traversed
   * @return Set<List<Vertex>> the set of lists of all possible ways to traverse the graph
   */
  public static Set<List<Vertex>> breadthFirstSearch(Graph graph) {
    // TODO: Representation safety required
    Set<List<Vertex>> result = new HashSet<List<Vertex>>();
    for (Vertex a : graph.getVertices()) {

      Queue<Vertex> nextVertexQueue = new LinkedList<Vertex>();
      HashSet<Vertex> scheduledSet = new HashSet<Vertex>();

      // initialize the first root queue
      nextVertexQueue.addAll(graph.getDownstreamNeighbors(a));
      scheduledSet.addAll(graph.getDownstreamNeighbors(a));

      // one traversal of the graph starting at a vertex a
      List<Vertex> traversal = new LinkedList<Vertex>();
      traversal.add(a);
      // loop until run out of new vertexes to visit
      while (!nextVertexQueue.isEmpty()) {

        // add the current vertex to the traversal
        Vertex currentRoot = nextVertexQueue.poll();
        traversal.add(currentRoot);

        // add children if they aren't already scheduled
        for (Vertex each_child : graph.getDownstreamNeighbors(currentRoot)) {
          if (!scheduledSet.contains(each_child)) {
            nextVertexQueue.add(each_child);
            scheduledSet.add(each_child);
          }
        }
      }

      result.add(traversal);
    }
    return result;
  }
예제 #2
0
  /**
   * traverses the graph using a depth first search algorithm. Returns a set of lists that represent
   * all possible ways to traverse the graph. Each list contains the traversal of the vertices in
   * the graph in the order that they were visited starting from a start index. The number of lists
   * in the set represents all possible starting vertices in the graph.
   *
   * @param graph the graph to be traversed
   * @return Set<List<Vertex>> a set of the lists of all possible ways to traverse the graph.
   */
  public static Set<List<Vertex>> depthFirstSearch(Graph graph) {
    Set<List<Vertex>> result = new HashSet<List<Vertex>>();
    for (Vertex primaryRoot : graph.getVertices()) {
      Stack<Vertex> vertexStack = new Stack<Vertex>();
      HashSet<Vertex> scheduledSet = new HashSet<Vertex>();
      List<Vertex> traversal = new LinkedList<Vertex>();

      vertexStack.add(primaryRoot);
      scheduledSet.add(primaryRoot);
      traversal.add(primaryRoot);

      while (!vertexStack.isEmpty()) {
        boolean noChildLeft = true;
        for (Vertex each_childRoot : graph.getDownstreamNeighbors(vertexStack.peek())) {
          if (!scheduledSet.contains(each_childRoot)) {
            scheduledSet.add(each_childRoot);
            vertexStack.add(each_childRoot);
            traversal.add(each_childRoot);
            noChildLeft = false;
            break;
          }
        }
        if (noChildLeft) {
          vertexStack.pop();
        }
      }
      result.add(traversal);
    }
    return result;
  }
  /**
   * Helper method for parseQuery. Writes the results of the queries to the output file.
   *
   * @param output initialized BufferedWriter for the output file
   * @param g initialized graph of edges and vertices
   * @param u1 one vertex used in commands
   * @param u2 another vertex used in commands
   * @param command command to execute
   */
  private static void printResults(
      BufferedWriter output, Graph g, Vertex u1, Vertex u2, String command) {
    final String commonInfluencers = "commonInfluencers";
    final String numRetweets = "numRetweets";

    final String VERTEX_NOT_FOUND_ERROR =
        "ERROR: One or more vertices does not exist in the graph.";
    final String INVALID_COMMAND_ERROR = "\tError: invalid command ";
    final String PATH_NOT_FOUND_ERROR = "\tPath not found.";

    List<Vertex> allVertices = new ArrayList<Vertex>(g.getVertices());

    try {
      output.write("query: " + command + " " + u1.toString() + " " + u2.toString());
      output.newLine();
      output.write("<result>");
      output.newLine();

      // check if vertices exist in graph
      if (!allVertices.contains(u1) || !allVertices.contains(u2)) {
        output.write(VERTEX_NOT_FOUND_ERROR);
        output.newLine();
        output.write("</result>");
        output.newLine();
        output.newLine();
        return;
      }
      // if query is commonInfluencers
      if (command.equals(commonInfluencers)) {
        List<Vertex> commonFollowers =
            new LinkedList<Vertex>(Algorithms.commonDownstreamVertices(g, u1, u2));
        for (Vertex v : commonFollowers) {
          output.write("\t" + v.toString());
          output.newLine();
        }
      }

      // if query is numRetweets
      else if (command.equals(numRetweets)) {
        // note switch in u1 and u2; this is because tweets go upstream
        int distance = Algorithms.shortestDistance(g, u2, u1);

        if (distance == -1) {
          output.write(PATH_NOT_FOUND_ERROR);
        } else {
          // implicitly convert distance to string as printing out ints somehow didn't work
          output.write("" + distance);
          // System.out.println(distance);
        }

        output.newLine();
      } else {
        output.write(INVALID_COMMAND_ERROR + command);
        output.newLine();
      }
      output.write("</result>");
      output.newLine();
      output.newLine();
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }