solver
This commit is contained in:
parent
a9383ce3e7
commit
e2e6b817f1
|
@ -11,6 +11,9 @@ import java.io.ObjectOutputStream;
|
|||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
|
@ -113,6 +116,83 @@ 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() {
|
||||
visited = new boolean[labyrinth.getWidth()][labyrinth.getHeight()]; // initially all false
|
||||
|
||||
ArrayDeque<Point> startPath = new ArrayDeque<>();
|
||||
Point start = labyrinth.getStart();
|
||||
PointAndDirection startPD = new PointAndDirection(start, Direction.N); // Dummy-Richtung
|
||||
//startPath.addLast(start);
|
||||
|
||||
SolverForkJoinTask task = new SolverForkJoinTask(startPath, startPD);
|
||||
ForkJoinPool pool = ForkJoinPool.commonPool();
|
||||
Point[] solution = pool.invoke(task);
|
||||
return solution;
|
||||
}
|
||||
|
||||
public class SolverForkJoinTask extends RecursiveTask<Point[]> {
|
||||
private ArrayDeque<Point> pathSoFar; // Path from start to just before current
|
||||
Point current;
|
||||
|
||||
//Jede Task muss den pathSoFar übergeben kriegen, aber braucht einen neuen backtrackStack, denn wenn die Task
|
||||
//in eine Sackgasse läuft, soll sie nur maximal bis zur ihrer Erstellungs-Zelle zurück gehen
|
||||
public SolverForkJoinTask(ArrayDeque<Point> pathSoFar, PointAndDirection pd) {
|
||||
this.pathSoFar = new ArrayDeque<>(pathSoFar);
|
||||
this.current = pd.getPoint();
|
||||
}
|
||||
@Override
|
||||
public Point[] compute() {
|
||||
List<SolverForkJoinTask> subTasks = new ArrayList<>();
|
||||
|
||||
while (!labyrinth.isDestination(current)) {
|
||||
Point next = null;
|
||||
visit(current);
|
||||
Direction[] dirs = Direction.values();
|
||||
|
||||
for (Direction directionToNeighbor : dirs) {
|
||||
Point neighbor = current.getNeighbor(directionToNeighbor);
|
||||
if (labyrinth.hasPassage(current, directionToNeighbor)
|
||||
&& !visitedBefore(neighbor)
|
||||
&& (!labyrinth.isBlindAlley(neighbor, directionToNeighbor.opposite)
|
||||
|| labyrinth.isDestination(neighbor))) {
|
||||
|
||||
if (next == null) {
|
||||
next = neighbor;
|
||||
} else {
|
||||
// pathSoFar kopieren!
|
||||
ArrayDeque<Point> newPath = new ArrayDeque<>(pathSoFar);
|
||||
newPath.addLast(current);
|
||||
|
||||
SolverForkJoinTask subTask = new SolverForkJoinTask(newPath,
|
||||
new PointAndDirection(neighbor, directionToNeighbor.opposite));
|
||||
subTask.fork();
|
||||
subTasks.add(subTask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Es wurde ein Nachbar gefunden
|
||||
if (next != null) {
|
||||
pathSoFar.addLast(current);
|
||||
current = next;
|
||||
} else { //Es wurde kein gültiger Nachbar gefunden
|
||||
for (SolverForkJoinTask sub : subTasks) {
|
||||
Point[] result = sub.join();
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//Ziel erreicht
|
||||
pathSoFar.addLast(current);
|
||||
return pathSoFar.toArray(new Point[0]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics graphics) {
|
||||
|
@ -242,7 +322,7 @@ private static void displayLabyrinth(Solver solver) {
|
|||
}
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
solver.solution = solver.solve();
|
||||
solver.solution = solver.solveConcurrently();
|
||||
long endTime = System.currentTimeMillis();
|
||||
|
||||
if (solver.solution == null)
|
||||
|
|
Loading…
Reference in New Issue