modified graph
This commit is contained in:
parent
5f68391cdc
commit
167dea9451
@ -5,167 +5,291 @@ import dev.ksan.travelpathoptimizer.model.Departure;
|
|||||||
import dev.ksan.travelpathoptimizer.model.Location;
|
import dev.ksan.travelpathoptimizer.model.Location;
|
||||||
import dev.ksan.travelpathoptimizer.service.CityManager;
|
import dev.ksan.travelpathoptimizer.service.CityManager;
|
||||||
import dev.ksan.travelpathoptimizer.util.JsonParser;
|
import dev.ksan.travelpathoptimizer.util.JsonParser;
|
||||||
import java.util.ArrayList;
|
import java.time.LocalTime;
|
||||||
import java.util.Comparator;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.HashSet;
|
import java.util.stream.Collectors;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.PriorityQueue;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class Graph {
|
public class Graph {
|
||||||
private City[][] matrix;
|
private City[][] matrix;
|
||||||
private List<PathResult> allPaths = new ArrayList<>();
|
private List<PathResult> allPaths = new ArrayList<>();
|
||||||
private int pathIdCounter = 1;
|
private int pathIdCounter = 1;
|
||||||
|
private static int nextid = 0;
|
||||||
|
private static Set<String> visitedRoutes = new HashSet<>();
|
||||||
|
public static PriorityQueue<PathResult> topPaths = new PriorityQueue<>(5, Comparator.comparingDouble(PathResult::getCost).reversed());
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
List<City> cities = JsonParser.parseCities("transport_data.json", "stations");
|
List<City> cities = JsonParser.parseCities("transport_data.json", "stations");
|
||||||
List<Departure> departures = JsonParser.getDeparturesList("transport_data.json", "departures");
|
List<Departure> departures = JsonParser.getDeparturesList("transport_data.json", "departures");
|
||||||
|
for (Departure dep : departures) {
|
||||||
|
for (City city : cities) {
|
||||||
|
if (dep.getTo().equals(city.getName())) {
|
||||||
|
dep.setToCity(city);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
cities = JsonParser.loadDepartures(cities, departures);
|
cities = JsonParser.loadDepartures(cities, departures);
|
||||||
City[][] map = JsonParser.loadMap("transport_data.json", "countryMap", cities);
|
City[][] map = JsonParser.loadMap("transport_data.json", "countryMap", cities);
|
||||||
|
|
||||||
Graph graph = new Graph(map);
|
Graph graph = new Graph(map);
|
||||||
cities = JsonParser.loadDepartures(cities, departures);
|
cities = JsonParser.loadDepartures(cities, departures);
|
||||||
System.out.println(cities.getFirst().getName() + " do " + cities.get(3).getName());
|
System.out.println(cities.getFirst().getName() + " do " + cities.getLast().getName());
|
||||||
for (City city : cities) {
|
for (City city : cities) {
|
||||||
CityManager.addCity(city);
|
CityManager.addCity(city);
|
||||||
}
|
}
|
||||||
Map<Location, Double> result =
|
|
||||||
graph.calculateShortestPath(cities.getFirst(), cities.get(3), "time");
|
|
||||||
System.out.println(cities.get(3).getName() + " = " + result.get(cities.get(3).getLocation()));
|
|
||||||
List<PathResult> ranked = graph.calculateRankedPaths(cities.getFirst(), cities.get(3), "time");
|
|
||||||
for (PathResult path : ranked) {
|
|
||||||
String cityNames =
|
|
||||||
path.getPath().stream().map(City::getName).reduce((x, y) -> x + " -> " + y).orElse("");
|
|
||||||
|
|
||||||
System.out.println("Path ID: " + path.getId());
|
Map<Location, Double> result =
|
||||||
System.out.println("Cities: " + cityNames);
|
graph.calculateShortestPath(cities.getFirst(), cities.getLast(), "time");
|
||||||
System.out.println("Cost: " + path.getCost());
|
System.out.println(
|
||||||
|
cities.get(1).getName() + " = " + result.get(cities.getLast().getLocation()));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
graph.calculateTopPaths(cities.getFirst(), cities.getLast());
|
||||||
|
|
||||||
|
List<PathResult> sorted = new ArrayList<>(graph.topPaths);
|
||||||
|
sorted.sort(Comparator.comparingDouble(PathResult::getCost));
|
||||||
|
for (PathResult res : sorted) {
|
||||||
|
System.out.println("Path ID: " + res.getId());
|
||||||
|
System.out.print("Cities: ");
|
||||||
|
for (City city : res.getPath()) {
|
||||||
|
System.out.print(city.getName() + " → ");
|
||||||
|
}
|
||||||
|
System.out.println("End");
|
||||||
|
|
||||||
System.out.println("Departures:");
|
System.out.println("Departures:");
|
||||||
for (Departure dep : path.getDepartures()) {
|
|
||||||
System.out.println(
|
|
||||||
" "
|
|
||||||
+ dep.getDestinationCity().getName()
|
|
||||||
+ " (Price: "
|
|
||||||
+ dep.getPrice()
|
|
||||||
+ ", Time: "
|
|
||||||
+ dep.getDuration()
|
|
||||||
+ ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("-----");
|
|
||||||
|
System.out.println("Total Cost: " + res.getCost() + " min");
|
||||||
|
System.out.println("Arrival Time: " + res.getArrivalTime());
|
||||||
|
System.out.println("--------------------------------------------------");
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
List<City> path = new ArrayList<>();
|
||||||
|
List<Integer> departuress = new ArrayList<>();
|
||||||
|
LocalTime currentTime = LocalTime.of(1, 0); // Assume starting at 8:00 AM
|
||||||
|
double totalCost = 0.0;
|
||||||
|
|
||||||
|
calculateTopPaths(
|
||||||
|
cities.getFirst(), cities.getLast(), path, totalCost, currentTime, departuress);
|
||||||
|
System.out.println(topPaths.size());
|
||||||
|
// Output the top 5 paths
|
||||||
|
printTopPaths(); }
|
||||||
|
|
||||||
|
|
||||||
|
public static void addToTopPaths(PathResult newPath) {
|
||||||
|
String routeHash = generateRouteHash(newPath.getDeparturesUsed());
|
||||||
|
|
||||||
|
if (visitedRoutes.contains(routeHash)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
visitedRoutes.add(routeHash);
|
||||||
|
|
||||||
|
if (topPaths.size() < 5) {
|
||||||
|
topPaths.offer(newPath);
|
||||||
|
} else {
|
||||||
|
if (newPath.getCost() < topPaths.peek().getCost()) {
|
||||||
|
System.out.println("Removing path with cost: " + topPaths.peek().getCost());
|
||||||
|
topPaths.poll();
|
||||||
|
topPaths.offer(newPath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasCycle(List<City> path) {
|
|
||||||
Set<String> seen = new HashSet<>();
|
|
||||||
for (City c : path) {
|
|
||||||
if (!seen.add(c.getName())) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<PathResult> calculateRankedPaths(City startCity, City endCity, String type) {
|
private static String generateRouteHash(List<Integer> departures) {
|
||||||
|
|
||||||
List<PathResult> allFoundPaths = new ArrayList<>();
|
|
||||||
|
|
||||||
PriorityQueue<PathState> pq = new PriorityQueue<>(Comparator.comparingDouble(s -> s.cost));
|
|
||||||
pq.add(new PathState(startCity, new ArrayList<>(List.of(startCity)), new ArrayList<>(), 0.0));
|
|
||||||
|
|
||||||
Set<String> visitedPaths = new HashSet<>();
|
|
||||||
|
|
||||||
while (!pq.isEmpty()) {
|
|
||||||
PathState current = pq.poll();
|
|
||||||
City currentCity = current.getCity();
|
|
||||||
|
|
||||||
String pathKey = current.getPathSignature();
|
|
||||||
// if (visitedPaths.contains(pathKey)) continue;
|
|
||||||
if (hasCycle(current.getPath())) continue;
|
|
||||||
visitedPaths.add(pathKey);
|
|
||||||
|
|
||||||
if (currentCity.getName().equals(endCity.getName())) {
|
|
||||||
|
|
||||||
allFoundPaths.add(
|
|
||||||
new PathResult(
|
|
||||||
pathIdCounter++,
|
|
||||||
new ArrayList<>(current.getPath()),
|
|
||||||
new ArrayList<>(current.getDepartures()),
|
|
||||||
current.getCost()));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Departure dep : currentCity.getDestinations()) {
|
|
||||||
City nextCity = dep.getDestinationCity();
|
|
||||||
double additionalCost =
|
|
||||||
switch (type) {
|
|
||||||
case "price" -> dep.getPrice();
|
|
||||||
case "time" -> dep.getDuration();
|
|
||||||
case "hops" -> 1.0;
|
|
||||||
default -> throw new IllegalArgumentException("Invalid type: " + type);
|
|
||||||
};
|
|
||||||
|
|
||||||
List<City> newPath = new ArrayList<>(current.getPath());
|
|
||||||
newPath.add(nextCity);
|
|
||||||
|
|
||||||
List<Departure> newDepartures = new ArrayList<>(current.getDepartures());
|
|
||||||
newDepartures.add(dep);
|
|
||||||
|
|
||||||
pq.add(new PathState(nextCity, newPath, newDepartures, current.getCost() + additionalCost));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// allFoundPaths.sort(Comparator.comparingDouble(PathResult::getCost));
|
|
||||||
|
|
||||||
// int toStore = Math.max(5, (int) Math.ceil(allFoundPaths.size() * 0.05));
|
|
||||||
|
|
||||||
// List<PathResult> selectedPaths = allFoundPaths.subList(0, Math.min(toStore,
|
|
||||||
// allFoundPaths.size()));
|
|
||||||
|
|
||||||
Map<String, PathResult> bestPaths = new HashMap<>();
|
|
||||||
|
|
||||||
for (PathResult pathResult : allFoundPaths) {
|
|
||||||
String signature = getRichPathSignature(pathResult.getPath(), pathResult.getDepartures());
|
|
||||||
|
|
||||||
bestPaths.merge(
|
|
||||||
signature,
|
|
||||||
pathResult,
|
|
||||||
(existing, candidate) -> candidate.getCost() < existing.getCost() ? candidate : existing);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<PathResult> selectedPaths =
|
|
||||||
bestPaths.values().stream()
|
|
||||||
.sorted(Comparator.comparingDouble(PathResult::getCost))
|
|
||||||
.limit(5)
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
allPaths.clear();
|
|
||||||
allPaths.addAll(selectedPaths);
|
|
||||||
return selectedPaths;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getRichPathSignature(List<City> path, List<Departure> departures) {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (int i = 0; i < path.size(); i++) {
|
for (Integer depId : departures) {
|
||||||
City city = path.get(i);
|
sb.append(depId).append("-");
|
||||||
sb.append(city.getLocation().toString());
|
|
||||||
if (i > 0) {
|
|
||||||
Departure dep = departures.get(i - 1);
|
|
||||||
sb.append(":")
|
|
||||||
.append(dep.getType())
|
|
||||||
.append("-")
|
|
||||||
.append(dep.getDuration())
|
|
||||||
.append("-")
|
|
||||||
.append(dep.getPrice());
|
|
||||||
}
|
|
||||||
if (i < path.size() - 1) {
|
|
||||||
sb.append("->");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
public static void calculateTopPaths(
|
||||||
|
City currentCity,
|
||||||
|
City endCity,
|
||||||
|
List<City> path,
|
||||||
|
double totalCost,
|
||||||
|
LocalTime currentTime,
|
||||||
|
List<Integer> departures) {
|
||||||
|
|
||||||
|
if (currentCity.getLocation().equals(endCity.getLocation())) {
|
||||||
|
|
||||||
|
addToTopPaths(new PathResult(nextid++, new ArrayList<>(path), new ArrayList<>(departures), totalCost, currentTime));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Departure dep : currentCity.getDestinations()) {
|
||||||
|
if (dep.getDepartureTime().isBefore(currentTime)) continue;
|
||||||
|
City nextCity;
|
||||||
|
if (path.contains(dep.getDestinationCity())) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
nextCity = dep.getDestinationCity();
|
||||||
|
}
|
||||||
|
LocalTime arrivalTime = dep.getDepartureTime().plusMinutes(dep.getDuration());
|
||||||
|
|
||||||
|
if (topPaths.size() >= 5 && totalCost + dep.getDuration() > topPaths.peek().getCost()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
path.add(nextCity);
|
||||||
|
departures.add(dep.getIdCounter());
|
||||||
|
calculateTopPaths(
|
||||||
|
nextCity, endCity, path, totalCost + dep.getDuration(), arrivalTime, departures);
|
||||||
|
|
||||||
|
departures.remove(departures.size() - 1);
|
||||||
|
path.remove(path.size() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void printTopPaths() {
|
||||||
|
System.out.println("Top 5 Paths:");
|
||||||
|
int rank = 5;
|
||||||
|
while (!topPaths.isEmpty()) {
|
||||||
|
PathResult pathResult = topPaths.poll();
|
||||||
|
System.out.println("Rank: " + rank--);
|
||||||
|
System.out.println("ID: " + pathResult.getId());
|
||||||
|
System.out.println("Cost: " + pathResult.getCost());
|
||||||
|
System.out.println("Path: " + pathResult.getPath().size());
|
||||||
|
System.out.println("Departures: " + pathResult.getDeparturesUsed());
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
private PriorityQueue<PathResult> topPaths =
|
||||||
|
new PriorityQueue<>(Comparator.comparingDouble(PathResult::getCost).reversed());
|
||||||
|
private final AtomicInteger pathIdGenerator = new AtomicInteger(1); // Start from 1
|
||||||
|
private final Set<String> uniquePathKeys = new HashSet<>();
|
||||||
|
|
||||||
|
private int makeDeparturePathHash(Set<Departure> departures) {
|
||||||
|
// A simple approach: sum of hashes or use Objects.hash(...)
|
||||||
|
return departures.stream()
|
||||||
|
.mapToInt(
|
||||||
|
dep ->
|
||||||
|
Objects.hash(
|
||||||
|
dep.getDepartureTime()
|
||||||
|
.toSecondOfDay(), // convert time to int seconds for consistency
|
||||||
|
dep.getDestinationCity()
|
||||||
|
.getLocation(), // assuming Location implements hashCode properly
|
||||||
|
Double.valueOf(dep.getDuration()).hashCode()))
|
||||||
|
.sorted() // sort to avoid order affecting hash
|
||||||
|
.reduce(1, (a, b) -> 31 * a + b); // combine with a hash combiner
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private HashSet<Integer> uniquePathHashes = new HashSet<Integer>();
|
||||||
|
public void calculateTopPaths(City start, City end) {
|
||||||
|
topPaths.clear();
|
||||||
|
uniquePathKeys.clear();
|
||||||
|
pathIdGenerator.set(1);
|
||||||
|
|
||||||
|
for (Departure dep : start.getDestinations()) {
|
||||||
|
City next = dep.getDestinationCity();
|
||||||
|
double duration = dep.getDuration();
|
||||||
|
LocalTime depTime = dep.getDepartureTime();
|
||||||
|
LocalTime arrivalTime = depTime.plusMinutes((long) duration);
|
||||||
|
|
||||||
|
List<City> initialPath = new ArrayList<>();
|
||||||
|
Set<Departure> usedDepartures = new HashSet<>();
|
||||||
|
usedDepartures.add(dep);
|
||||||
|
|
||||||
|
initialPath.add(start); // include start
|
||||||
|
initialPath.add(next); // move to first destination
|
||||||
|
List<Integer> initialDepartures = new ArrayList<>();
|
||||||
|
initialDepartures.add(dep.getIdCounter());
|
||||||
|
Set<Location> visited = new HashSet<>();
|
||||||
|
visited.add(start.getLocation());
|
||||||
|
|
||||||
|
findPaths(
|
||||||
|
next,
|
||||||
|
end,
|
||||||
|
initialPath,
|
||||||
|
usedDepartures,
|
||||||
|
initialDepartures,
|
||||||
|
duration,
|
||||||
|
arrivalTime,
|
||||||
|
visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void findPaths(
|
||||||
|
City current,
|
||||||
|
City end,
|
||||||
|
List<City> pathSoFar,
|
||||||
|
Set<Departure> usedDepartures,
|
||||||
|
List<Integer> departuresSoFar,
|
||||||
|
double totalCost,
|
||||||
|
LocalTime currentTime,
|
||||||
|
Set<Location> visitedCities
|
||||||
|
) {
|
||||||
|
if (visitedCities.contains(current.getLocation())) return;
|
||||||
|
|
||||||
|
visitedCities.add(current.getLocation());
|
||||||
|
|
||||||
|
if (current.getLocation().equals(end.getLocation())) {
|
||||||
|
int pathHash = makeDeparturePathHash(usedDepartures);
|
||||||
|
if (uniquePathHashes.contains(pathHash)) {
|
||||||
|
visitedCities.remove(current.getLocation());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uniquePathHashes.add(pathHash);
|
||||||
|
int pathId = pathIdGenerator.getAndIncrement();
|
||||||
|
topPaths.add(
|
||||||
|
new PathResult(
|
||||||
|
pathId,
|
||||||
|
new ArrayList<>(pathSoFar),
|
||||||
|
new ArrayList<>(departuresSoFar),
|
||||||
|
totalCost,
|
||||||
|
currentTime));
|
||||||
|
|
||||||
|
if (topPaths.size() > 5) topPaths.poll();
|
||||||
|
|
||||||
|
visitedCities.remove(current.getLocation()); // backtrack
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Departure dep : current.getDestinations()) {
|
||||||
|
if (usedDepartures.contains(dep)) continue;
|
||||||
|
if (dep.getDepartureTime().isBefore(currentTime)) continue;
|
||||||
|
|
||||||
|
City next = dep.getDestinationCity();
|
||||||
|
if (visitedCities.contains(next.getLocation())) continue; // skip if already visited
|
||||||
|
|
||||||
|
LocalTime arrivalTime = dep.getDepartureTime().plusMinutes((long) dep.getDuration());
|
||||||
|
|
||||||
|
usedDepartures.add(dep);
|
||||||
|
departuresSoFar.add(dep.getIdCounter());
|
||||||
|
pathSoFar.add(next);
|
||||||
|
if (!(topPaths.peek() == null)) {
|
||||||
|
if (totalCost + dep.getDuration() > topPaths.peek().getCost()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
findPaths(
|
||||||
|
next,
|
||||||
|
end,
|
||||||
|
pathSoFar,
|
||||||
|
usedDepartures,
|
||||||
|
departuresSoFar,
|
||||||
|
totalCost + dep.getDuration(),
|
||||||
|
arrivalTime,
|
||||||
|
visitedCities);
|
||||||
|
|
||||||
|
// backtrack
|
||||||
|
pathSoFar.remove(pathSoFar.size() - 1);
|
||||||
|
departuresSoFar.remove(departuresSoFar.size() - 1);
|
||||||
|
usedDepartures.remove(dep);
|
||||||
|
}
|
||||||
|
|
||||||
|
visitedCities.remove(current.getLocation()); // backtrack
|
||||||
|
}
|
||||||
|
*/
|
||||||
public Map<Location, Double> calculateShortestPath(City startCity, City endCity, String type) {
|
public Map<Location, Double> calculateShortestPath(City startCity, City endCity, String type) {
|
||||||
int n = matrix.length;
|
int n = matrix.length;
|
||||||
int m = matrix[0].length;
|
int m = matrix[0].length;
|
||||||
@ -186,7 +310,6 @@ public class Graph {
|
|||||||
while (!pq.isEmpty()) {
|
while (!pq.isEmpty()) {
|
||||||
City current = pq.poll();
|
City current = pq.poll();
|
||||||
|
|
||||||
// If we reached the end city, we can stop early
|
|
||||||
if (current == endCity) {
|
if (current == endCity) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -215,6 +338,8 @@ public class Graph {
|
|||||||
return distances;
|
return distances;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public List<PathResult> getAllPaths() {
|
public List<PathResult> getAllPaths() {
|
||||||
return allPaths;
|
return allPaths;
|
||||||
}
|
}
|
||||||
|
@ -2,50 +2,47 @@ package dev.ksan.travelpathoptimizer.graph;
|
|||||||
|
|
||||||
import dev.ksan.travelpathoptimizer.model.City;
|
import dev.ksan.travelpathoptimizer.model.City;
|
||||||
import dev.ksan.travelpathoptimizer.model.Departure;
|
import dev.ksan.travelpathoptimizer.model.Departure;
|
||||||
|
|
||||||
|
import java.time.LocalTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class PathResult {
|
public class PathResult {
|
||||||
private int id;
|
private int id;
|
||||||
private List<City> path;
|
private List<City> path = new ArrayList<>();
|
||||||
private List<Departure> departures;
|
private List<Integer> departuresUsed = new ArrayList<>();
|
||||||
private double cost;
|
private double cost;
|
||||||
|
private LocalTime arrivalTime;
|
||||||
|
|
||||||
public PathResult(int id, List<City> path, List<Departure> departures, double cost) {
|
public PathResult(int id, List<City> path, List<Integer> departuresUsed, double cost, LocalTime arrivalTime) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.path = path;
|
this.path = path;
|
||||||
this.departures = departures;
|
this.departuresUsed = departuresUsed;
|
||||||
this.cost = cost;
|
this.cost = cost;
|
||||||
|
this.arrivalTime = arrivalTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setId(int id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<City> getPath() {
|
public List<City> getPath() {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPath(List<City> path) {
|
public List<Integer> getDeparturesUsed() {
|
||||||
this.path = path;
|
return departuresUsed;
|
||||||
}
|
|
||||||
|
|
||||||
public List<Departure> getDepartures() {
|
|
||||||
return departures;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDepartures(List<Departure> departures) {
|
|
||||||
this.departures = departures;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getCost() {
|
public double getCost() {
|
||||||
return cost;
|
return cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCost(double cost) {
|
public LocalTime getArrivalTime() {
|
||||||
this.cost = cost;
|
return arrivalTime;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "PathResult{id=" + id + " cost = " + cost + ", path=" + path + ", arrivalTime=" + arrivalTime + '}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,14 @@ public class PathState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getPathSignature() {
|
public String getPathSignature() {
|
||||||
return path.stream().map(c -> c.getLocation().toString()).collect(Collectors.joining("->"));
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < path.size(); i++) {
|
||||||
|
sb.append(path.get(i).getLocation().toString());
|
||||||
|
if (i < path.size() - 1) {
|
||||||
|
sb.append("->");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public City getCity() {
|
public City getCity() {
|
||||||
|
@ -13,7 +13,9 @@ public class Departure {
|
|||||||
private LocalTime departureTime;
|
private LocalTime departureTime;
|
||||||
private double price;
|
private double price;
|
||||||
private int minTransferTime;
|
private int minTransferTime;
|
||||||
|
private City toCity;
|
||||||
|
private static int idCounter = 0;
|
||||||
|
private int id;
|
||||||
public Departure(
|
public Departure(
|
||||||
TransportType type,
|
TransportType type,
|
||||||
String from,
|
String from,
|
||||||
@ -22,6 +24,7 @@ public class Departure {
|
|||||||
int duration,
|
int duration,
|
||||||
double price,
|
double price,
|
||||||
int minTransferTime) {
|
int minTransferTime) {
|
||||||
|
this.id = idCounter++;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.from = from;
|
this.from = from;
|
||||||
this.to = to;
|
this.to = to;
|
||||||
@ -30,12 +33,21 @@ public class Departure {
|
|||||||
this.price = price;
|
this.price = price;
|
||||||
this.minTransferTime = minTransferTime;
|
this.minTransferTime = minTransferTime;
|
||||||
}
|
}
|
||||||
|
public int getIdCounter() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
public void setToCity(City toCity) {
|
||||||
|
this.toCity = toCity;
|
||||||
|
}
|
||||||
public City getDestinationCity() {
|
public City getDestinationCity() {
|
||||||
|
|
||||||
return CityManager.getCityByName(to);
|
return toCity;
|
||||||
|
// return CityManager.getCityByName(to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LocalTime getDepartureTime() {
|
||||||
|
return departureTime;
|
||||||
|
}
|
||||||
public TransportType getType() {
|
public TransportType getType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,26 @@
|
|||||||
package dev.ksan.travelpathoptimizer.service;
|
package dev.ksan.travelpathoptimizer.service;
|
||||||
|
|
||||||
import dev.ksan.travelpathoptimizer.model.City;
|
import dev.ksan.travelpathoptimizer.model.City;
|
||||||
|
import dev.ksan.travelpathoptimizer.model.Location;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class CityManager {
|
public class CityManager {
|
||||||
private static Map<String, City> cities = new HashMap<>();
|
private static Map<String, City> cities = new HashMap<>();
|
||||||
|
private static Map<Location, City> citiesByLocation = new HashMap<>();
|
||||||
|
|
||||||
public static void clear() {
|
public static void clear() {
|
||||||
|
citiesByLocation.clear();
|
||||||
cities.clear();
|
cities.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addCity(City city) {
|
public static void addCity(City city) {
|
||||||
cities.put(city.getName(), city);
|
cities.put(city.getName(), city);
|
||||||
|
citiesByLocation.put(city.getLocation(), city);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static City getCityByLocation(Location loc) {
|
||||||
|
return citiesByLocation.get(loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static City getCityByName(String cityName) {
|
public static City getCityByName(String cityName) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user