this seems to work
This commit is contained in:
parent
e396b1ce39
commit
99db1345ae
5 changed files with 134 additions and 28 deletions
16
pom.xml
16
pom.xml
|
|
@ -7,12 +7,20 @@
|
|||
<groupId>org.github.shautvast.exceptional</groupId>
|
||||
<artifactId>avalor</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.3.5</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>22</maven.compiler.source>
|
||||
<maven.compiler.target>22</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
|
|
@ -22,4 +30,12 @@
|
|||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -1,15 +1,19 @@
|
|||
package assessment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.*;
|
||||
|
||||
//TODO make non static (CH)
|
||||
public class BestPathFinder {
|
||||
private final static double timeDistanceFactor = .2;
|
||||
// overall best path
|
||||
private static Path max;
|
||||
|
||||
// paths to be considered
|
||||
private final static PriorityQueue<Path> paths = new PriorityQueue<>();
|
||||
// TODO replace by time check (MH)
|
||||
private static volatile boolean running = true;
|
||||
|
||||
private final static Set<Path> takenPaths = new HashSet<>();
|
||||
|
||||
/**
|
||||
* @param g het Grid (vierkant)
|
||||
|
|
@ -18,7 +22,7 @@ public class BestPathFinder {
|
|||
* @param T maximale tijdsduur
|
||||
* @param x startpositie X
|
||||
* @param y startpositie Y
|
||||
* @return het meest waardevole pad
|
||||
* @return het meest waardevolle pad
|
||||
*/
|
||||
public static Path findMaxValPath(Grid g, int N, int t, int T, int x, int y) {
|
||||
Path path = Path.newPath(g, x, y);
|
||||
|
|
@ -27,34 +31,56 @@ public class BestPathFinder {
|
|||
|
||||
// start looping until T is reached or all paths have been considered
|
||||
while (running && !paths.isEmpty()) {
|
||||
|
||||
//TODO take out (MH)
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
// if (System.currentTimeMillis() > T) {
|
||||
// running = false;
|
||||
// }
|
||||
|
||||
// take current highest ranking path
|
||||
path = paths.peek();
|
||||
assert path != null;
|
||||
while (path.length() > t) {
|
||||
// dit pad heeft lengte t bereikt
|
||||
// dit pad heeft lengte t bereikt, we kunnen niet verder
|
||||
paths.poll(); // geen nieuwe paden op basis van deze, we pakken de vorige in waardering
|
||||
// heeft dit pad meer waarde dan de huidige max ?
|
||||
if (path.value() > max.value()) {
|
||||
max = path;
|
||||
}
|
||||
path = paths.peek();
|
||||
}
|
||||
|
||||
System.out.println("paths:" + paths.size());
|
||||
System.out.println("CUR: " + path);
|
||||
Point currentPos = path.getHead();
|
||||
x = currentPos.x;
|
||||
y = currentPos.y;
|
||||
|
||||
// find best new directions
|
||||
List<Point> newPointsFromHere = new ArrayList<>();
|
||||
if (y > 0) {
|
||||
newPointsFromHere.add(new Point(x, y - 1, getValueFromGrid(g, path, x, y - 1)));
|
||||
if (x < N - 1)
|
||||
if (x < N - 1) {
|
||||
newPointsFromHere.add(new Point(x + 1, y - 1, getValueFromGrid(g, path, x + 1, y - 1)));
|
||||
}
|
||||
}
|
||||
if (x > 0) {
|
||||
newPointsFromHere.add(new Point(x - 1, y, getValueFromGrid(g, path, x - 1, y)));
|
||||
if (y > 0)
|
||||
if (y > 0) {
|
||||
newPointsFromHere.add(new Point(x - 1, y - 1, getValueFromGrid(g, path, x - 1, y - 1)));
|
||||
}
|
||||
}
|
||||
if (x < N - 1) {
|
||||
newPointsFromHere.add(new Point(x + 1, y, getValueFromGrid(g, path, x + 1, y)));
|
||||
if (y < N - 1)
|
||||
if (y < N - 1) {
|
||||
newPointsFromHere.add(new Point(x + 1, y + 1, getValueFromGrid(g, path, x + 1, y + 1)));
|
||||
}
|
||||
}
|
||||
if (y < N - 1) {
|
||||
newPointsFromHere.add(new Point(x, y + 1, getValueFromGrid(g, path, x, y + 1)));
|
||||
|
|
@ -64,17 +90,31 @@ public class BestPathFinder {
|
|||
|
||||
// sort the new points in descending order of value
|
||||
newPointsFromHere.sort(Point::compareTo);
|
||||
double max = newPointsFromHere.getFirst().value;
|
||||
for (Point p : newPointsFromHere) {
|
||||
// create a new Path based on the current
|
||||
Path newPath = path.copy();
|
||||
|
||||
// add the new point
|
||||
newPath.add(g, p);
|
||||
if (!newPointsFromHere.isEmpty()) {
|
||||
boolean pointsAdded = false;
|
||||
for (Point p : newPointsFromHere) {
|
||||
// is it worthwile going there?
|
||||
if (p.value > 0) {
|
||||
// create a new Path based on the current
|
||||
Path newPath = path.copy();
|
||||
|
||||
// stop adding points once their value decreases
|
||||
if (p.value < max) {
|
||||
break;
|
||||
// add the new point
|
||||
newPath.add(g, p);
|
||||
if (!takenPaths.contains(newPath)) {
|
||||
paths.add(newPath);
|
||||
takenPaths.add(newPath);
|
||||
pointsAdded = true;
|
||||
System.out.println("add " + newPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!pointsAdded) {
|
||||
//evict
|
||||
Path ended = paths.poll();
|
||||
if (ended != null && ended.value() > max.value()) {
|
||||
max = ended;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -90,12 +130,12 @@ public class BestPathFinder {
|
|||
*/
|
||||
private static double getValueFromGrid(Grid grid, Path path, int x, int y) {
|
||||
int gridValue = grid.get(x, y);
|
||||
if (path.hasPoint(x, y)) {
|
||||
if (path.hasPoint(grid, x, y)) {
|
||||
// been there
|
||||
int distanceInPath = path.getDistanceInPath(x, y);
|
||||
double increment = gridValue / timeDistanceFactor;
|
||||
double increment = gridValue * timeDistanceFactor;
|
||||
|
||||
return Math.max((distanceInPath - 1) * increment, gridValue);
|
||||
return Math.min((distanceInPath - 1) * increment, gridValue);
|
||||
} else {
|
||||
return gridValue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package assessment;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Path implements Comparable<Path> {
|
||||
// beide bevatten de al afgelegde punten
|
||||
|
|
@ -15,9 +16,10 @@ public class Path implements Comparable<Path> {
|
|||
private Path() {
|
||||
}
|
||||
|
||||
// meh row/col vs x/y
|
||||
static Path newPath(Grid g, int x, int y) {
|
||||
Path p = new Path();
|
||||
newPath(g, x, y);
|
||||
p.add(g, new Point(x, y, g.get(y, x)));
|
||||
return p;
|
||||
}
|
||||
|
||||
|
|
@ -30,34 +32,61 @@ public class Path implements Comparable<Path> {
|
|||
return points.stream().mapToDouble(point -> point.value).sum();
|
||||
}
|
||||
|
||||
// compare descending, highest value first
|
||||
@Override
|
||||
public int compareTo(Path o) {
|
||||
return this.value().compareTo(o.value());
|
||||
return -this.value().compareTo(o.value());
|
||||
}
|
||||
|
||||
public int length() {
|
||||
return points.size();
|
||||
}
|
||||
|
||||
boolean hasPoint(int x, int y) {
|
||||
return trodden.contains(x * y);
|
||||
public Point getHead() {
|
||||
return points.get(points.size() - 1);
|
||||
}
|
||||
|
||||
boolean hasPoint(Grid g, int x, int y) {
|
||||
return trodden.contains(y * g.getWidth() + x);
|
||||
}
|
||||
|
||||
int getDistanceInPath(int x, int y) {
|
||||
for (int i = points.size() - 1; i >= 0; i++) {
|
||||
if (points.get(i).x == x && points.get(i).y == y) {
|
||||
if (points.isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
for (int i = points.size() - 1; i >= 0; i--) {
|
||||
Point p = points.get(i);
|
||||
if (p.x == x && p.y == y) {
|
||||
return points.size() - i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public Path copy(){
|
||||
public Path copy() {
|
||||
Path p = new Path();
|
||||
p.points.addAll(points);
|
||||
p.trodden.addAll(trodden);
|
||||
return p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "P:" + points + ":" + value();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Path path = (Path) o;
|
||||
return Objects.equals(points, path.points);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(points);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package assessment;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class Point implements Comparable<Point> {
|
||||
|
||||
final int x;
|
||||
|
|
@ -16,4 +18,23 @@ public class Point implements Comparable<Point> {
|
|||
public int compareTo(Point that) {
|
||||
return -Double.compare(this.value, that.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
// return "(" + x + "," + y + ")";
|
||||
return "(" + x + "," + y + ":" + value + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Point point = (Point) o;
|
||||
return x == point.x && y == point.y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(x, y);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ public class PathFinderTest {
|
|||
@Test
|
||||
public void testBestPath() {
|
||||
Grid grid = Grid.fromFile("grids/20.txt");
|
||||
Path path = BestPathFinder.findMaxValPath(grid, 20, 10, 1000, 9, 9);
|
||||
Path path = BestPathFinder.findMaxValPath(grid, 20, 3, 1000, 9, 9);
|
||||
System.out.println(path);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue