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> <groupId>org.github.shautvast.exceptional</groupId>
<artifactId>avalor</artifactId> <artifactId>avalor</artifactId>
<version>1.0-SNAPSHOT</version> <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> <properties>
<maven.compiler.source>22</maven.compiler.source> <maven.compiler.source>22</maven.compiler.source>
<maven.compiler.target>22</maven.compiler.target> <maven.compiler.target>22</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
@ -22,4 +30,12 @@
</dependency> </dependency>
</dependencies> </dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project> </project>

View file

@ -1,15 +1,19 @@
package assessment; package assessment;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.PriorityQueue;
//TODO make non static (CH)
public class BestPathFinder { public class BestPathFinder {
private final static double timeDistanceFactor = .2; private final static double timeDistanceFactor = .2;
// overall best path
private static Path max; private static Path max;
// paths to be considered
private final static PriorityQueue<Path> paths = new PriorityQueue<>(); private final static PriorityQueue<Path> paths = new PriorityQueue<>();
// TODO replace by time check (MH)
private static volatile boolean running = true; private static volatile boolean running = true;
private final static Set<Path> takenPaths = new HashSet<>();
/** /**
* @param g het Grid (vierkant) * @param g het Grid (vierkant)
@ -18,7 +22,7 @@ public class BestPathFinder {
* @param T maximale tijdsduur * @param T maximale tijdsduur
* @param x startpositie X * @param x startpositie X
* @param y startpositie Y * @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) { public static Path findMaxValPath(Grid g, int N, int t, int T, int x, int y) {
Path path = Path.newPath(g, x, 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 // start looping until T is reached or all paths have been considered
while (running && !paths.isEmpty()) { 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 // take current highest ranking path
path = paths.peek(); path = paths.peek();
assert path != null; assert path != null;
while (path.length() > t) { 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 paths.poll(); // geen nieuwe paden op basis van deze, we pakken de vorige in waardering
// heeft dit pad meer waarde dan de huidige max ? // heeft dit pad meer waarde dan de huidige max ?
if (path.value() > max.value()) { if (path.value() > max.value()) {
max = path; 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 // find best new directions
List<Point> newPointsFromHere = new ArrayList<>(); List<Point> newPointsFromHere = new ArrayList<>();
if (y > 0) { if (y > 0) {
newPointsFromHere.add(new Point(x, y - 1, getValueFromGrid(g, path, x, y - 1))); 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))); newPointsFromHere.add(new Point(x + 1, y - 1, getValueFromGrid(g, path, x + 1, y - 1)));
}
} }
if (x > 0) { if (x > 0) {
newPointsFromHere.add(new Point(x - 1, y, getValueFromGrid(g, path, x - 1, y))); 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))); newPointsFromHere.add(new Point(x - 1, y - 1, getValueFromGrid(g, path, x - 1, y - 1)));
}
} }
if (x < N - 1) { if (x < N - 1) {
newPointsFromHere.add(new Point(x + 1, y, getValueFromGrid(g, path, x + 1, y))); 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))); newPointsFromHere.add(new Point(x + 1, y + 1, getValueFromGrid(g, path, x + 1, y + 1)));
}
} }
if (y < N - 1) { if (y < N - 1) {
newPointsFromHere.add(new Point(x, y + 1, getValueFromGrid(g, path, x, y + 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 // sort the new points in descending order of value
newPointsFromHere.sort(Point::compareTo); 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 if (!newPointsFromHere.isEmpty()) {
newPath.add(g, p); 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 // add the new point
if (p.value < max) { newPath.add(g, p);
break; 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) { private static double getValueFromGrid(Grid grid, Path path, int x, int y) {
int gridValue = grid.get(x, y); int gridValue = grid.get(x, y);
if (path.hasPoint(x, y)) { if (path.hasPoint(grid, x, y)) {
// been there // been there
int distanceInPath = path.getDistanceInPath(x, y); 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 { } else {
return gridValue; return gridValue;
} }

View file

@ -2,6 +2,7 @@ package assessment;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.Objects;
public class Path implements Comparable<Path> { public class Path implements Comparable<Path> {
// beide bevatten de al afgelegde punten // beide bevatten de al afgelegde punten
@ -15,9 +16,10 @@ public class Path implements Comparable<Path> {
private Path() { private Path() {
} }
// meh row/col vs x/y
static Path newPath(Grid g, int x, int y) { static Path newPath(Grid g, int x, int y) {
Path p = new Path(); Path p = new Path();
newPath(g, x, y); p.add(g, new Point(x, y, g.get(y, x)));
return p; return p;
} }
@ -30,34 +32,61 @@ public class Path implements Comparable<Path> {
return points.stream().mapToDouble(point -> point.value).sum(); return points.stream().mapToDouble(point -> point.value).sum();
} }
// compare descending, highest value first
@Override @Override
public int compareTo(Path o) { public int compareTo(Path o) {
return this.value().compareTo(o.value()); return -this.value().compareTo(o.value());
} }
public int length() { public int length() {
return points.size(); return points.size();
} }
boolean hasPoint(int x, int y) { public Point getHead() {
return trodden.contains(x * y); 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) { int getDistanceInPath(int x, int y) {
for (int i = points.size() - 1; i >= 0; i++) { if (points.isEmpty()) {
if (points.get(i).x == x && points.get(i).y == y) { 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 points.size() - i;
} }
} }
return -1; return -1;
} }
public Path copy(){ public Path copy() {
Path p = new Path(); Path p = new Path();
p.points.addAll(points); p.points.addAll(points);
p.trodden.addAll(trodden); p.trodden.addAll(trodden);
return p; 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; package assessment;
import java.util.Objects;
public class Point implements Comparable<Point> { public class Point implements Comparable<Point> {
final int x; final int x;
@ -16,4 +18,23 @@ public class Point implements Comparable<Point> {
public int compareTo(Point that) { public int compareTo(Point that) {
return -Double.compare(this.value, that.value); 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 @Test
public void testBestPath() { public void testBestPath() {
Grid grid = Grid.fromFile("grids/20.txt"); 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); System.out.println(path);
} }
} }