write solution to array instead of returning
test concurrent and sequential at the same time
This commit is contained in:
parent
e2acf6899e
commit
3cd69b92c8
|
@ -27,10 +27,10 @@ final public class Solver extends JPanel {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
// The default size of the labyrinth (i.e. unless program is invoked with size arguments):
|
// 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_WIDTH_IN_CELLS = 5000;
|
||||||
private static final int DEFAULT_HEIGHT_IN_CELLS = 1000;
|
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
|
// The grid defining the structure of the labyrinth
|
||||||
private final Labyrinth 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?
|
// For each cell in the labyrinth: Has solve() visited it yet?
|
||||||
private boolean[][] visited; // initialized in solve()
|
private boolean[][] visited; // initialized in solve()
|
||||||
private AtomicBoolean[][] visitedAtomic;
|
private AtomicBoolean[][] visitedAtomic;
|
||||||
private AtomicInteger numTasks = new AtomicInteger(0);
|
|
||||||
|
|
||||||
private Semaphore[] sectors;
|
private Semaphore[] sectors;
|
||||||
private static final int SECTOR_SIZE = (int) Math.sqrt(DEFAULT_WIDTH_IN_CELLS * DEFAULT_HEIGHT_IN_CELLS) / 50;
|
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 Point[] solution = null; // set to solution path once that has been computed
|
||||||
|
|
||||||
|
private ArrayList<Point> solutionArrayList;
|
||||||
|
|
||||||
public Solver(Labyrinth labyrinth) {
|
public Solver(Labyrinth labyrinth) {
|
||||||
this.labyrinth = labyrinth;
|
this.labyrinth = labyrinth;
|
||||||
}
|
}
|
||||||
|
@ -156,14 +157,27 @@ final public class Solver extends JPanel {
|
||||||
sectors[i] = new Semaphore(1);
|
sectors[i] = new Semaphore(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
solutionArrayList = new ArrayList<>();
|
||||||
|
|
||||||
ForkJoinPool pool = ForkJoinPool.commonPool();
|
ForkJoinPool pool = ForkJoinPool.commonPool();
|
||||||
|
|
||||||
ArrayDeque<Point> pathSoFar = new ArrayDeque<>();
|
ArrayDeque<Point> pathSoFar = new ArrayDeque<>();
|
||||||
ConcurrentSolverTask t = new ConcurrentSolverTask(start, pathSoFar, pool);
|
ConcurrentSolverTask t = new ConcurrentSolverTask(start, pathSoFar, pool, solutionArrayList);
|
||||||
Point[] result = pool.invoke(t);
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -174,11 +188,13 @@ final public class Solver extends JPanel {
|
||||||
private ArrayDeque<Point> pathSoFar;
|
private ArrayDeque<Point> pathSoFar;
|
||||||
private ForkJoinPool pool;
|
private ForkJoinPool pool;
|
||||||
private ArrayList<ConcurrentSolverTask> subtasks;
|
private ArrayList<ConcurrentSolverTask> subtasks;
|
||||||
|
private ArrayList<Point> solutionArrayList;
|
||||||
private int currentSector;
|
private int currentSector;
|
||||||
public ConcurrentSolverTask(PointAndDirection start, ArrayDeque<Point> pathSoFar, ForkJoinPool pool) {
|
public ConcurrentSolverTask(PointAndDirection start, ArrayDeque<Point> pathSoFar, ForkJoinPool pool, ArrayList<Point> solutionArrayList) {
|
||||||
this.start = start;
|
this.start = start;
|
||||||
this.pathSoFar = pathSoFar;
|
this.pathSoFar = pathSoFar;
|
||||||
this.pool = pool;
|
this.pool = pool;
|
||||||
|
this.solutionArrayList = solutionArrayList;
|
||||||
|
|
||||||
this.backtrackStack = new ArrayDeque<>();
|
this.backtrackStack = new ArrayDeque<>();
|
||||||
this.subtasks = new ArrayList<>();
|
this.subtasks = new ArrayList<>();
|
||||||
|
@ -208,7 +224,6 @@ final public class Solver extends JPanel {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Point[] compute() {
|
public Point[] compute() {
|
||||||
numTasks.incrementAndGet();
|
|
||||||
int currentLength = 0;
|
int currentLength = 0;
|
||||||
Point current = this.start.getPoint();
|
Point current = this.start.getPoint();
|
||||||
|
|
||||||
|
@ -266,7 +281,8 @@ final public class Solver extends JPanel {
|
||||||
ConcurrentSolverTask subtask = new ConcurrentSolverTask(
|
ConcurrentSolverTask subtask = new ConcurrentSolverTask(
|
||||||
new PointAndDirection(neighbour, dir.opposite),
|
new PointAndDirection(neighbour, dir.opposite),
|
||||||
subPath,
|
subPath,
|
||||||
this.pool
|
this.pool,
|
||||||
|
this.solutionArrayList
|
||||||
);
|
);
|
||||||
subtasks.add(subtask);
|
subtasks.add(subtask);
|
||||||
|
|
||||||
|
@ -298,13 +314,13 @@ final public class Solver extends JPanel {
|
||||||
|
|
||||||
// check for solutions in subtasks
|
// check for solutions in subtasks
|
||||||
// System.out.println("End of task reached - waiting for " + subtasks.size() + " subtasks");
|
// System.out.println("End of task reached - waiting for " + subtasks.size() + " subtasks");
|
||||||
for (ConcurrentSolverTask subtask : subtasks) {
|
// for (ConcurrentSolverTask subtask : subtasks) {
|
||||||
Point[] subtaskResult = subtask.join();
|
// Point[] subtaskResult = subtask.join();
|
||||||
if (subtaskResult != null) {
|
// if (subtaskResult != null) {
|
||||||
// found a solution in a subtask
|
// // found a solution in a subtask
|
||||||
return subtaskResult;
|
// return subtaskResult;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
// no solution found
|
// no solution found
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -332,6 +348,11 @@ final public class Solver extends JPanel {
|
||||||
subtask.cancel(true);
|
subtask.cancel(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
synchronized (this.solutionArrayList) {
|
||||||
|
this.solutionArrayList.addAll(pathSoFar);
|
||||||
|
this.solutionArrayList.notify();
|
||||||
|
}
|
||||||
|
|
||||||
return pathSoFar.toArray(new Point[0]);
|
return pathSoFar.toArray(new Point[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -455,6 +476,7 @@ private static void displayLabyrinth(Solver solver) {
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
long[] runTimes = new long[2*N_RUNS_HALF + 1];
|
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) {
|
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();
|
long startTime = System.currentTimeMillis();
|
||||||
solver.solution = solver.solveConcurrently();
|
solver.solution = solver.solve();
|
||||||
long endTime = System.currentTimeMillis();
|
long endTime = System.currentTimeMillis();
|
||||||
|
|
||||||
if (solver.solution == null)
|
if (solver.solution == null)
|
||||||
|
@ -484,9 +506,37 @@ private static void displayLabyrinth(Solver solver) {
|
||||||
System.out.println("Solution correct :-)");
|
System.out.println("Solution correct :-)");
|
||||||
else
|
else
|
||||||
System.out.println("Solution incorrect :-(");
|
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);
|
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.");
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue