/** * Reads in a social network from a file, and then repeatedly reads in * individuals from standard input and prints out their degrees of * separation. * Takes three command-line arguments: the name of a file, * a delimiter, and the name of the distinguished individual. * Each line in the file contains the name of a vertex, followed by a * list of the names of the vertices adjacent to that vertex, * separated by the delimiter. * * @param args the command-line arguments */ public static void main(String[] args) { String filename = args[0]; String delimiter = args[1]; String source = args[2]; // StdOut.println("Source: " + source); SymbolGraph sg = new SymbolGraph(filename, delimiter); Graph G = sg.graph(); if (!sg.contains(source)) { StdOut.println(source + " not in database."); return; } int s = sg.indexOf(source); BreadthFirstPaths bfs = new BreadthFirstPaths(G, s); while (!StdIn.isEmpty()) { String sink = StdIn.readLine(); if (sg.contains(sink)) { int t = sg.indexOf(sink); if (bfs.hasPathTo(t)) { for (int v : bfs.pathTo(t)) { StdOut.println(" " + sg.nameOf(v)); } } else { StdOut.println("Not connected"); } } else { StdOut.println(" Not in database."); } } }
/************************************************************************** * * The code below is solely for testing correctness of the data type. * **************************************************************************/ // Determines whether a graph has an Eulerian path using necessary // and sufficient conditions (without computing the path itself): // - degree(v) is even for every vertex, except for possibly two // - the graph is connected (ignoring isolated vertices) // This method is solely for unit testing. private static boolean satisfiesNecessaryAndSufficientConditions(Graph G) { if (G.E() == 0) return true; // Condition 1: degree(v) is even except for possibly two int oddDegreeVertices = 0; for (int v = 0; v < G.V(); v++) if (G.degree(v) % 2 != 0) oddDegreeVertices++; if (oddDegreeVertices > 2) return false; // Condition 2: graph is connected, ignoring isolated vertices int s = nonIsolatedVertex(G); BreadthFirstPaths bfs = new BreadthFirstPaths(G, s); for (int v = 0; v < G.V(); v++) if (G.degree(v) > 0 && !bfs.hasPathTo(v)) return false; return true; }
/************************************************************************** * * The code below is solely for testing correctness of the data type. * **************************************************************************/ // Determines whether a graph has an Eulerian cycle using necessary // and sufficient conditions (without computing the cycle itself): // - at least one edge // - degree(v) is even for every vertex v // - the graph is connected (ignoring isolated vertices) private static boolean satisfiesNecessaryAndSufficientConditions(Graph G) { // Condition 0: at least 1 edge if (G.E() == 0) return false; // Condition 1: degree(v) is even for every vertex for (int v = 0; v < G.V(); v++) if (G.degree(v) % 2 != 0) return false; // Condition 2: graph is connected, ignoring isolated vertices int s = nonIsolatedVertex(G); BreadthFirstPaths bfs = new BreadthFirstPaths(G, s); for (int v = 0; v < G.V(); v++) if (G.degree(v) > 0 && !bfs.hasPathTo(v)) return false; return true; }
/** * Unit tests the {@code BreadthFirstPaths} data type. * * @param args the command-line arguments */ public static void main(String[] args) { In in = new In(args[0]); Graph G = new Graph(in); // StdOut.println(G); int s = Integer.parseInt(args[1]); BreadthFirstPaths bfs = new BreadthFirstPaths(G, s); for (int v = 0; v < G.V(); v++) { if (bfs.hasPathTo(v)) { StdOut.printf("%d to %d (%d): ", s, v, bfs.distTo(v)); for (int x : bfs.pathTo(v)) { if (x == s) StdOut.print(x); else StdOut.print("-" + x); } StdOut.println(); } else { StdOut.printf("%d to %d (-): not connected\n", s, v); } } }