diff --git a/projekt/Solver.java b/projekt/Solver.java index a21b8f3..103308b 100644 --- a/projekt/Solver.java +++ b/projekt/Solver.java @@ -27,10 +27,10 @@ final public class Solver extends JPanel { private static final long serialVersionUID = 1L; // The default size of the labyrinth (i.e. unless program is invoked with size arguments): - private static final int DEFAULT_WIDTH_IN_CELLS = 1000; - private static final int DEFAULT_HEIGHT_IN_CELLS = 1000; + private static final int DEFAULT_WIDTH_IN_CELLS = 5000; + private static final int DEFAULT_HEIGHT_IN_CELLS = 5000; - private static final int N_RUNS_HALF = 10; // #runs will be 2*N_RUNS_HALF + 1 + private static final int N_RUNS_HALF = 5; // #runs will be 2*N_RUNS_HALF + 1 // The grid defining the structure of the labyrinth private final Labyrinth labyrinth; @@ -38,7 +38,6 @@ final public class Solver extends JPanel { // For each cell in the labyrinth: Has solve() visited it yet? private boolean[][] visited; // initialized in solve() private AtomicBoolean[][] visitedAtomic; - private AtomicInteger numTasks = new AtomicInteger(0); private Semaphore[] sectors; private static final int SECTOR_SIZE = (int) Math.sqrt(DEFAULT_WIDTH_IN_CELLS * DEFAULT_HEIGHT_IN_CELLS) / 50; @@ -48,6 +47,8 @@ final public class Solver extends JPanel { private Point[] solution = null; // set to solution path once that has been computed + private ArrayList solutionArrayList; + public Solver(Labyrinth labyrinth) { this.labyrinth = labyrinth; } @@ -156,14 +157,27 @@ final public class Solver extends JPanel { sectors[i] = new Semaphore(1); } + solutionArrayList = new ArrayList<>(); + ForkJoinPool pool = ForkJoinPool.commonPool(); ArrayDeque pathSoFar = new ArrayDeque<>(); - ConcurrentSolverTask t = new ConcurrentSolverTask(start, pathSoFar, pool); - Point[] result = pool.invoke(t); + ConcurrentSolverTask t = new ConcurrentSolverTask(start, pathSoFar, pool, solutionArrayList); + pool.submit(t); + + synchronized (solutionArrayList) { + while (solutionArrayList.isEmpty()) { + try { + solutionArrayList.wait(); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + Point[] result = solutionArrayList.toArray(new Point[0]); - System.out.println("Used tasks: " + numTasks.get()); - System.out.println("Task to Solution Length Ratio: " + (double)result.length / numTasks.get()); return result; } @@ -174,11 +188,13 @@ final public class Solver extends JPanel { private ArrayDeque pathSoFar; private ForkJoinPool pool; private ArrayList subtasks; + private ArrayList solutionArrayList; private int currentSector; - public ConcurrentSolverTask(PointAndDirection start, ArrayDeque pathSoFar, ForkJoinPool pool) { + public ConcurrentSolverTask(PointAndDirection start, ArrayDeque pathSoFar, ForkJoinPool pool, ArrayList solutionArrayList) { this.start = start; this.pathSoFar = pathSoFar; this.pool = pool; + this.solutionArrayList = solutionArrayList; this.backtrackStack = new ArrayDeque<>(); this.subtasks = new ArrayList<>(); @@ -208,7 +224,6 @@ final public class Solver extends JPanel { } public Point[] compute() { - numTasks.incrementAndGet(); int currentLength = 0; Point current = this.start.getPoint(); @@ -266,7 +281,8 @@ final public class Solver extends JPanel { ConcurrentSolverTask subtask = new ConcurrentSolverTask( new PointAndDirection(neighbour, dir.opposite), subPath, - this.pool + this.pool, + this.solutionArrayList ); subtasks.add(subtask); @@ -298,13 +314,13 @@ final public class Solver extends JPanel { // check for solutions in subtasks // System.out.println("End of task reached - waiting for " + subtasks.size() + " subtasks"); - for (ConcurrentSolverTask subtask : subtasks) { - Point[] subtaskResult = subtask.join(); - if (subtaskResult != null) { - // found a solution in a subtask - return subtaskResult; - } - } + // for (ConcurrentSolverTask subtask : subtasks) { + // Point[] subtaskResult = subtask.join(); + // if (subtaskResult != null) { + // // found a solution in a subtask + // return subtaskResult; + // } + // } // no solution found return null; } @@ -332,6 +348,11 @@ final public class Solver extends JPanel { subtask.cancel(true); } + synchronized (this.solutionArrayList) { + this.solutionArrayList.addAll(pathSoFar); + this.solutionArrayList.notify(); + } + return pathSoFar.toArray(new Point[0]); } } @@ -455,6 +476,7 @@ private static void displayLabyrinth(Solver solver) { */ public static void main(String[] args) { long[] runTimes = new long[2*N_RUNS_HALF + 1]; + long[] concurrentRunTimes = new long[2*N_RUNS_HALF + 1]; for (int run = 0; run < 2*N_RUNS_HALF + 1; ++run) { @@ -464,7 +486,7 @@ private static void displayLabyrinth(Solver solver) { } long startTime = System.currentTimeMillis(); - solver.solution = solver.solveConcurrently(); + solver.solution = solver.solve(); long endTime = System.currentTimeMillis(); if (solver.solution == null) @@ -484,9 +506,37 @@ private static void displayLabyrinth(Solver solver) { System.out.println("Solution correct :-)"); else System.out.println("Solution incorrect :-("); - } + } + + solver.solution = null; + + long concurrentStartTime = System.currentTimeMillis(); + solver.solution = solver.solveConcurrently(); + long concurrentEndTime = System.currentTimeMillis(); + + if (solver.solution == null) + System.out.println("No solution exists."); + else { + System.out.println("Computed concurrent solution of length " + solver.solution.length + " to labyrinth of size " + + solver.labyrinth.getWidth() + "x" + solver.labyrinth.getHeight() + " in " + (concurrentEndTime - concurrentStartTime) + "ms."); + + concurrentRunTimes[run] = concurrentEndTime - concurrentStartTime; + + if (solver.labyrinth.smallEnoughToDisplay()) { + solver.displaySolution(); + solver.printSolution(); + } + + if (solver.labyrinth.checkSolution(solver.solution)) + System.out.println("Solution correct :-)"); + else + System.out.println("Solution incorrect :-("); + } + System.out.println(); } Arrays.sort(runTimes); - System.out.println("Median run time was " + runTimes[N_RUNS_HALF] + " ms."); + System.out.println("Median sequential run time was " + runTimes[N_RUNS_HALF] + " ms."); + Arrays.sort(concurrentRunTimes); + System.out.println("Median concurrent run time was " + concurrentRunTimes[N_RUNS_HALF] + " ms."); } } \ No newline at end of file