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.ArrayDeque;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
@ -114,6 +117,83 @@ final public class Solver extends JPanel {
|
||||||
return pathSoFar.toArray(new Point[0]);
|
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
|
@Override
|
||||||
protected void paintComponent(Graphics graphics) {
|
protected void paintComponent(Graphics graphics) {
|
||||||
super.paintComponent(graphics);
|
super.paintComponent(graphics);
|
||||||
|
@ -242,7 +322,7 @@ private static void displayLabyrinth(Solver solver) {
|
||||||
}
|
}
|
||||||
|
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
solver.solution = solver.solve();
|
solver.solution = solver.solveConcurrently();
|
||||||
long endTime = System.currentTimeMillis();
|
long endTime = System.currentTimeMillis();
|
||||||
|
|
||||||
if (solver.solution == null)
|
if (solver.solution == null)
|
||||||
|
|
Loading…
Reference in New Issue