start concurrent

This commit is contained in:
Luca Conte 2025-06-09 14:34:21 +02:00
parent a9383ce3e7
commit 502458d373
1 changed files with 79 additions and 0 deletions

View File

@ -10,12 +10,17 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet;
import javax.swing.JFrame; import javax.swing.JFrame;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
final public class Solver extends JPanel { final public class Solver extends JPanel {
private static final long serialVersionUID = 1L; 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? // 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 static final int DISTANCE_PER_TASK = 20;
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
@ -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[]): // Point[0] is only for making the return value have type Point[] (and not Object[]):
return pathSoFar.toArray(new Point[0]); 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 @Override
protected void paintComponent(Graphics graphics) { protected void paintComponent(Graphics graphics) {