start concurrent
This commit is contained in:
parent
a9383ce3e7
commit
502458d373
|
@ -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<PointAndDirection> backtrackStack = new ArrayDeque<PointAndDirection>();
|
||||
|
||||
ForkJoinPool pool = ForkJoinPool.commonPool();
|
||||
|
||||
|
||||
ConcurrentSolverTask t = new ConcurrentSolverTask(backtrackStack, start);
|
||||
Point[] result = pool.invoke(t);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private class ConcurrentSolverTask extends RecursiveTask<Point[]> {
|
||||
private ArrayDeque<PointAndDirection> backtrackStack;
|
||||
private PointAndDirection start;
|
||||
private int initialStackSize;
|
||||
private HashSet<Point> visitedThisTask;
|
||||
public ConcurrentSolverTask(ArrayDeque<PointAndDirection> 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<PointAndDirection> 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) {
|
||||
|
|
Loading…
Reference in New Issue