this seems to work

This commit is contained in:
Shautvast 2024-11-08 14:07:59 +01:00
parent e396b1ce39
commit 99db1345ae
5 changed files with 134 additions and 28 deletions

16
pom.xml
View file

@ -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>

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}