diff --git a/projekt/Solver.java b/projekt/Solver.java index b3eb119..8cff5ea 100644 --- a/projekt/Solver.java +++ b/projekt/Solver.java @@ -10,12 +10,17 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.ArrayDeque; +import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicBoolean; + final public class Solver extends JPanel { private static final long serialVersionUID = 1L; @@ -31,6 +36,9 @@ 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 static final int DISTANCE_PER_TASK = 20; private Point[] solution = null; // set to solution path once that has been computed @@ -113,6 +121,77 @@ final public class Solver extends JPanel { // Point[0] is only for making the return value have type Point[] (and not Object[]): return pathSoFar.toArray(new Point[0]); } + + public Point[] solveConcurrently() { + // dummy origin direction for start + PointAndDirection start = new PointAndDirection(labyrinth.getStart(), Direction.N); + + visitedAtomic = new AtomicBoolean[labyrinth.getWidth()][labyrinth.getHeight()]; + + ArrayDeque backtrackStack = new ArrayDeque(); + + ForkJoinPool pool = ForkJoinPool.commonPool(); + + + ConcurrentSolverTask t = new ConcurrentSolverTask(backtrackStack, start); + Point[] result = pool.invoke(t); + + return result; + } + + private class ConcurrentSolverTask extends RecursiveTask { + private ArrayDeque backtrackStack; + private PointAndDirection start; + private int initialStackSize; + private HashSet visitedThisTask; + public ConcurrentSolverTask(ArrayDeque backtrackStack, PointAndDirection start) { + this.backtrackStack = backtrackStack; + this.start = start; + this.initialStackSize = backtrackStack.size(); + this.visitedThisTask = new HashSet<>(); + } + + public Point[] compute() { + PointAndDirection current = this.start; + + if (labyrinth.isDestination(current.getPoint())) { + return backtrackStackToPath(backtrackStack); + } + + if (!current.getDirectionToBranchingPoint().equals(Direction.N)) { + if () { + + } + } + + return null; + } + + private boolean visit(PointAndDirection p) { + if (visitedThisTask.contains(p.getPoint())) { + return false; + } + Point lastPoint = backtrackStack.getLast().getPoint(); + if (Math.abs(lastPoint.y - p.getPoint().y) + Math.abs(lastPoint.x - p.getPoint().x) > 1) { + System.err.println("Cannot visit point " + p.getPoint() + " because it is not adjacened to " + lastPoint); + return false; + } + if (!visitedAtomic[p.getPoint().x][p.getPoint().y].compareAndSet(false, true)) return false; + + backtrackStack.add(p); + visitedThisTask.add(p.getPoint()); + + return true; + } + } + + private Point[] backtrackStackToPath(ArrayDeque backtrackStack) { + Point[] result = new Point[backtrackStack.size()]; + for (int i = 0; i < result.length; i++) { + result[backtrackStack.size() - 1] = backtrackStack.remove().getPoint(); + } + return result; + } @Override protected void paintComponent(Graphics graphics) {