import java.io.File; import java.util.Scanner; /** * The Test class is the main class used to test and grade the CPS420 assignment. *
DO NOT MODIFY THIS CLASS. * @author Sophie Quigley */ public class Test { /** * Input stream. */ private static Scanner input = null; /** * Path of directory containing test files. */ public static final String testDirPath = "/misc/cps420/public_html/doc/Now/A/Tests/"; /** * Main test program calculates score for program. *
It first tests the getEulerian method on graphs in test files. *
Then it tests it on randomly generated undirected simple graphs. * @param args the command line arguments */ public static void main(String[] args) { int result; int score=0; // Run test files System.out.println("\n======================= TEST CORRECTNESS ======================="); score += 6 - testFile("noEulerian", 0, true); System.out.println("Score so far: " + score); score += testFile("small", 7, true); System.out.println("Score so far: " + score); score += testFile("medium", 5, true); System.out.println("Score so far: " + score); score += 2*testFile("large", 6, true); System.out.println("Score so far: " + score); score += 5*testFile("verylarge", 1, true); System.out.println("Score so far: " + score + " out of 35."); System.out.println("======================= TEST EFFICIENCY ======================="); score += 4*testFile("huge1", 1, true); System.out.println("Score so far: " + score); score += 4*testFile("huge2", 1, true); System.out.println("Score so far: " + score); score += 4*testFile("huge3", 1, true); System.out.println("Score so far: " + score); score += 4*testFile("huge4", 1, true); System.out.println("Score so far: " + score); score += 4*testFile("huge5", 1, true); System.out.println("Score so far: " + score); // Print final score System.out.println("Total score: " + score + " out of 55."); } /** * Reads graphs described in a test file and tests the findEuler method on these graphs. * @param filename name of test file. The directory containing that file is hard coded in testDirPath * @param expected number of graphs in file which have a Eulerian circult * @param showcircuit when this is true, the Eulerian circuits found will be printed. * @return The number of valid Eulerian circuits found for the graphs in the file. */ public static int testFile(String filename, int expected, boolean showcircuit) { String filepath = testDirPath + filename; System.out.println("\n======= Test " + filepath +" ======="); try { input = new Scanner(new File(filepath)); } catch (Exception ex) { System.out.println(ex); System.exit(0); } int found = 0; Graph graph = null; while (input.hasNext()) { // Read and print input Graph try { graph = new Graph(input); } catch (InstantiationException ex) { System.out.println(ex); System.exit(0); } catch (Exception ex) { System.out.println(ex); System.exit(0); } found += testGraph(graph,showcircuit); } System.out.println("\nEulerian circuits expected: " + expected + ", found: " + found); return found; } /** * Tests the findEuler method for a graph and prints the results. * @param graph graph on which the findEuler method will be tested * @param showcircuit when this is true, the Eulerian circuit found will be printed. * @return 1 if a valid Eulerian circuit has been found and 0 otherwise */ public static int testGraph(Graph graph, boolean showcircuit) { // Print graph System.out.println("\nGraph has " + graph.getTotalVertices() + " vertices, and " + graph.getTotalEdges() + " edges."); // Try to find a Eulerian circuit Walk circuit = Euler.findEuler(graph); if (circuit == null) { System.out.println("Graph has no Eulerian circuit"); return 0; } if (showcircuit) System.out.println("The following circuit was found:\n" + circuit); if (isValidEulerian(graph,circuit)) { System.out.println("Valid Eulerian Circuit"); return 1; } else { System.out.println("Invalid Eulerian Circuit"); return 0; } } /** * Verifies whether a walk is a valid Eulerian circuit for a graph. * @param graph original graph * @param walk potential Eulerian circuit for graph * @return true iff walk is a valid Eulerian circuit for graph, and false otherwise. */ public static boolean isValidEulerian(Graph graph, Walk walk) { // First check if the walk is a circuit if (!walk.isClosed()) { System.out.println("Error: This walk is not a circuit"); return false; } // Then check if the circuit has the correct number of edges int totalEdges = graph.getTotalEdges(); int walklength = walk.getLength(); if (walklength < totalEdges) { System.out.println("Error: Some edges have not been visited"); return false; } if (walklength > totalEdges) { System.out.println("Error: Some edges have not been visited more than once"); return false; } // Now check whether the circuit encompasses the same number of vertices as the graph // By finding the highest vertex index in the circuit int maxvertex = 0; for (int i=walk.getTotalVertices()-1; i>=0; i--) if (walk.getVertex(i) > maxvertex) maxvertex = walk.getVertex(i); if (maxvertex != graph.getTotalVertices()-1) { System.out.println("Error: The circuit does not have the same number of vertices as the original graph"); return false; } // Finally, check whether the graph formed by this circuit is the same as the original graph: // The edges counts between vertices should be identical. // Because the circuit and the graph do have the same number of edges at this point, // then if these edges are not the identical, // there will be n>0 graph edges that are unvisited in the circuit // matched by n>0 graph edges that are visited too much in the circuit. // This algorithm checks the second condition. graph.resetVisitation(); int i, v1, v2; v1 = walk.getVertex(0); for (i=1; i