From 99db1345ae55a7948836167fce5620e69f3b5864 Mon Sep 17 00:00:00 2001 From: Shautvast Date: Fri, 8 Nov 2024 14:07:59 +0100 Subject: [PATCH] this seems to work --- pom.xml | 16 ++++ src/main/java/assessment/BestPathFinder.java | 80 +++++++++++++++----- src/main/java/assessment/Path.java | 43 +++++++++-- src/main/java/assessment/Point.java | 21 +++++ src/test/java/PathFinderTest.java | 2 +- 5 files changed, 134 insertions(+), 28 deletions(-) diff --git a/pom.xml b/pom.xml index cabd31a..bad3271 100644 --- a/pom.xml +++ b/pom.xml @@ -7,12 +7,20 @@ org.github.shautvast.exceptional avalor 1.0-SNAPSHOT + jar + + + org.springframework.boot + spring-boot-starter-parent + 3.3.5 + 22 22 UTF-8 + org.junit.jupiter @@ -22,4 +30,12 @@ + + + + org.springframework.boot + spring-boot-maven-plugin + + + \ No newline at end of file diff --git a/src/main/java/assessment/BestPathFinder.java b/src/main/java/assessment/BestPathFinder.java index 1d9ceb8..0128d05 100644 --- a/src/main/java/assessment/BestPathFinder.java +++ b/src/main/java/assessment/BestPathFinder.java @@ -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 paths = new PriorityQueue<>(); + // TODO replace by time check (MH) private static volatile boolean running = true; + private final static Set 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 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; } diff --git a/src/main/java/assessment/Path.java b/src/main/java/assessment/Path.java index 63fde90..e12557b 100644 --- a/src/main/java/assessment/Path.java +++ b/src/main/java/assessment/Path.java @@ -2,6 +2,7 @@ package assessment; import java.util.ArrayList; import java.util.HashSet; +import java.util.Objects; public class Path implements Comparable { // beide bevatten de al afgelegde punten @@ -15,9 +16,10 @@ public class Path implements Comparable { 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 { 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); + } } diff --git a/src/main/java/assessment/Point.java b/src/main/java/assessment/Point.java index 3c09cfb..c474730 100644 --- a/src/main/java/assessment/Point.java +++ b/src/main/java/assessment/Point.java @@ -1,5 +1,7 @@ package assessment; +import java.util.Objects; + public class Point implements Comparable { final int x; @@ -16,4 +18,23 @@ public class Point implements Comparable { 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); + } } diff --git a/src/test/java/PathFinderTest.java b/src/test/java/PathFinderTest.java index 3fbbca3..c8278fc 100644 --- a/src/test/java/PathFinderTest.java +++ b/src/test/java/PathFinderTest.java @@ -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); } }