/* The method improvements looks for any possible negative cycles in the graph. IF negative cycle is encountered, it is nullified with the posi- -tive cycle. If there are no negative cycles, then it is an optimal solution. This method returns true if there are improvements and false if there aren't any. To be precise, this method gives us the optimal CPT. */ boolean improvements() { CPP residual = new CPP(N); for (int u = 0; u < neg.length; u++) { int i = neg[u]; for (int v = 0; v < pos.length; v++) { int j = pos[v]; residual.addArc(null, i, j, c[i][j]); if (f[i][j] != 0) residual.addArc(null, j, i, -c[i][j]); } } residual.shortestPaths(); // find a negative cycle for (int i = 0; i < N; i++) if (residual.c[i][i] < 0) // cancel the cycle (if any) { int k = 0, u, v; boolean kunset = true; u = i; // find k to cancel do { v = residual.path[u][i]; if (residual.c[u][v] < 0 && (kunset || k > f[v][u])) { k = f[v][u]; kunset = false; } } while ((u = v) != i); u = i; // cancel k along the cycle { v = residual.path[u][i]; if (residual.c[u][v] < 0) f[v][u] -= k; else f[u][v] += k; } while ((u = v) != i) ; return true; // have another go } return false; // no improvements found }
public static void main(String[] args) throws IOException { int n; int u, v; float c; String line; Scanner s = new Scanner(System.in); File f = new File("vertices.txt"); Scanner scan = new Scanner(f.getAbsoluteFile()); n = scan.nextInt(); System.out.println("The number of vertices= " + n); CPP obj = new CPP(n); // Closed Chinese Postman Tour OpenCPP ob = new OpenCPP(n); // Open Chinese Postman Tour File fi1 = new File("label.txt"); File fi2 = new File("from.txt"); File fi3 = new File("to.txt"); File fi4 = new File("cost.txt"); FileReader in1 = new FileReader(fi1.getAbsolutePath()); FileReader in2 = new FileReader(fi2.getAbsolutePath()); FileReader in3 = new FileReader(fi3.getAbsolutePath()); FileReader in4 = new FileReader(fi4.getAbsolutePath()); Scanner scan1 = new Scanner(in1); Scanner scan2 = new Scanner(in2); Scanner scan3 = new Scanner(in3); Scanner scan4 = new Scanner(in4); File fi1o = new File("labelopen.txt"); File fi2o = new File("fromopen.txt"); File fi3o = new File("toopen.txt"); File fi4o = new File("costopen.txt"); FileReader in1o = new FileReader(fi1o.getAbsolutePath()); FileReader in2o = new FileReader(fi2o.getAbsolutePath()); FileReader in3o = new FileReader(fi3o.getAbsolutePath()); FileReader in4o = new FileReader(fi4o.getAbsolutePath()); Scanner scan1o = new Scanner(in1o); Scanner scan2o = new Scanner(in2o); Scanner scan3o = new Scanner(in3o); Scanner scan4o = new Scanner(in4o); long start = System.nanoTime(); do { line = scan1.nextLine(); u = scan2.nextInt(); v = scan3.nextInt(); c = scan4.nextFloat(); obj.addArc(line, u - 1, v - 1, c); } while (scan2.hasNext() && scan1.hasNext() && scan3.hasNext() && scan4.hasNext()); obj.solve(); obj.printCPT(0); System.out.println("Cost= " + obj.cost()); do { line = scan1o.nextLine(); u = scan2o.nextInt(); v = scan3o.nextInt(); c = scan4o.nextFloat(); ob.addArc(line, u - 1, v - 1, c); } while (scan2o.hasNext() && scan1o.hasNext() && scan3o.hasNext() && scan4o.hasNext()); float x; x = ob.printCPT(1); System.out.println("Cost= " + x); long Time = System.nanoTime() - start; double timeInSeconds = Time / 1e9; System.out.println("Elapsed time: " + timeInSeconds); }
float printCPT(int startVertex) { CPP bestGraph = null, g; float bestCost = 0, cost; int i = 0; do { g = new CPP(N + 1); for (int j = 0; j < arcs.size(); j++) { Arc it = (Arc) arcs.elementAt(j); g.addArc(it.lab, it.u, it.v, it.cost); } cost = g.basicCost; g.findUnbalanced(); // initialise g.neg on original graph g.addArc("Virtual start", N, startVertex, cost); g.addArc( "Virtual end", // graph is Eulerian if neg.length=0 g.neg.length == 0 ? startVertex : g.neg[i], N, cost); g.solve(); if (bestGraph == null || bestCost > g.cost()) { bestCost = g.cost(); bestGraph = g; } } while (++i < g.neg.length); System.out.println("Open CPT from " + startVertex + "(ignore virtual arcs)"); bestGraph.printCPT(N); return cost + bestGraph.phi(); }