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