added shortest path finder with dijkstras alg
This commit is contained in:
parent
69676c68b1
commit
ae113856d0
@ -1,22 +1,37 @@
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class City {
|
||||
private String name;
|
||||
private Station trainStation;
|
||||
private Station busStation;
|
||||
private int row;
|
||||
private int col;
|
||||
private Location location;
|
||||
|
||||
City(String name, String train, String bus, int row, int col) {
|
||||
City(String name, String bus, String train, int row, int col) {
|
||||
this.name = name;
|
||||
this.trainStation = new Station(TransportType.TRAIN, train);
|
||||
this.busStation = new Station(TransportType.BUS, bus);
|
||||
this.location = new Location(row, col);
|
||||
}
|
||||
|
||||
City(String name, Station train, Station bus, int row, int col) {
|
||||
City(String name, Station bus, Station train, int row, int col) {
|
||||
this.name = name;
|
||||
this.trainStation = train;
|
||||
this.busStation = bus;
|
||||
this.row = row;
|
||||
this.col = col;
|
||||
this.location = new Location(row, col);
|
||||
}
|
||||
|
||||
public List<Departure> getDestinations() {
|
||||
List<Departure> departures = new ArrayList<>();
|
||||
|
||||
for (Departure dep : busStation.getDepartures()) {
|
||||
departures.add(dep);
|
||||
}
|
||||
for (Departure dep : trainStation.getDepartures()) {
|
||||
departures.add(dep);
|
||||
}
|
||||
|
||||
return departures;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
@ -43,20 +58,8 @@ public class City {
|
||||
this.busStation = busStation;
|
||||
}
|
||||
|
||||
public int getRow() {
|
||||
return row;
|
||||
}
|
||||
|
||||
public void setRow(int row) {
|
||||
this.row = row;
|
||||
}
|
||||
|
||||
public int getCol() {
|
||||
return col;
|
||||
}
|
||||
|
||||
public void setCol(int col) {
|
||||
this.col = col;
|
||||
public Location getLocation() {
|
||||
return this.location;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
14
src/CityManager.java
Normal file
14
src/CityManager.java
Normal file
@ -0,0 +1,14 @@
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class CityManager {
|
||||
private static Map<String, City> cities = new HashMap<>();
|
||||
|
||||
public static void addCity(City city) {
|
||||
cities.put(city.getName(), city);
|
||||
}
|
||||
|
||||
public static City getCityByName(String cityName) {
|
||||
return cities.get(cityName);
|
||||
}
|
||||
}
|
@ -27,6 +27,11 @@ public class Departure {
|
||||
this.minTransferTime = minTransferTime;
|
||||
}
|
||||
|
||||
public City getDestinationCity() {
|
||||
|
||||
return CityManager.getCityByName(to);
|
||||
}
|
||||
|
||||
public TransportType getType() {
|
||||
return type;
|
||||
}
|
||||
@ -70,6 +75,6 @@ public class Departure {
|
||||
+ price
|
||||
+ ", minTransferTime="
|
||||
+ minTransferTime
|
||||
+ '}';
|
||||
+ "}";
|
||||
}
|
||||
}
|
||||
|
89
src/Graph.java
Normal file
89
src/Graph.java
Normal file
@ -0,0 +1,89 @@
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
public class Graph {
|
||||
private City[][] matrix;
|
||||
|
||||
public static void main(String[] args) {
|
||||
List<City> cities = JsonParser.parseCities("transport_data.json", "stations");
|
||||
List<Departure> departures = JsonParser.getDeparturesList("transport_data.json", "departures");
|
||||
cities = JsonParser.loadDepartures(cities, departures);
|
||||
City[][] map = JsonParser.loadMap("transport_data.json", "countryMap", cities);
|
||||
|
||||
Graph graph = new Graph(map);
|
||||
cities = JsonParser.loadDepartures(cities, departures);
|
||||
System.out.println(cities.getFirst().getName() + " do " + cities.getLast().getName());
|
||||
for (City city : cities) {
|
||||
CityManager.addCity(city);
|
||||
}
|
||||
Map<Location, Double> result =
|
||||
graph.calculateShortestPath(cities.getFirst(), cities.get(3), "price");
|
||||
System.out.println(
|
||||
cities.getLast().getName() + " = " + result.get(cities.get(3).getLocation()));
|
||||
}
|
||||
|
||||
public Map<Location, Double> calculateShortestPath(City startCity, City endCity, String type) {
|
||||
int n = matrix.length;
|
||||
int m = matrix[0].length;
|
||||
|
||||
Map<Location, Double> distances = new HashMap<>();
|
||||
for (int i = 0; i < n; i++) {
|
||||
for (int j = 0; j < m; j++) {
|
||||
distances.put(new Location(i, j), Double.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
distances.put(startCity.getLocation(), 0.0);
|
||||
|
||||
PriorityQueue<City> pq =
|
||||
new PriorityQueue<>(Comparator.comparingDouble(city -> distances.get(city.getLocation())));
|
||||
pq.add(startCity);
|
||||
|
||||
while (!pq.isEmpty()) {
|
||||
City current = pq.poll();
|
||||
|
||||
// If we reached the end city, we can stop early
|
||||
if (current == endCity) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (Departure dep : current.getDestinations()) {
|
||||
City neighborCity = dep.getDestinationCity();
|
||||
Location neighborLocation = neighborCity.getLocation();
|
||||
|
||||
double newCost = 0.0;
|
||||
if (type.equals("price")) {
|
||||
newCost = distances.get(current.getLocation()) + dep.getPrice();
|
||||
} else if (type.equals("time")) {
|
||||
newCost = distances.get(current.getLocation()) + dep.getDuration();
|
||||
}
|
||||
|
||||
if (newCost < distances.get(neighborLocation)) {
|
||||
distances.put(neighborLocation, newCost);
|
||||
pq.add(neighborCity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return distances;
|
||||
}
|
||||
|
||||
public Graph(City[][] matrix) {
|
||||
this.matrix = matrix;
|
||||
}
|
||||
|
||||
public void updateMatrix(City[][] matrix) {
|
||||
this.matrix = matrix;
|
||||
}
|
||||
|
||||
public City[][] getMatrix() {
|
||||
return matrix;
|
||||
}
|
||||
|
||||
public City getCity(Location loc) {
|
||||
return matrix[loc.getX()][loc.getY()];
|
||||
}
|
||||
}
|
@ -2,20 +2,26 @@ import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class JsonParser {
|
||||
/*
|
||||
public static void main(String[] args) {
|
||||
String[][] map = JsonParser.parseCountryMap("transport_data.json", "countryMap");
|
||||
List<City> cities = JsonParser.parseCities("transport_data.json", "stations");
|
||||
List<Departure> departures = JsonParser.getDeparturesList("transport_data.json", "departures");
|
||||
|
||||
public static void main(String[] args) {
|
||||
// String[][] map = JsonParser.parseCountryMap("transport_data.json", "countryMap");
|
||||
// JsonParser.parseCities("transport_data.json", "stations");
|
||||
JsonParser.getDeparturesList("transport_data.json", "departures");
|
||||
}
|
||||
|
||||
cities = JsonParser.loadDepartures(cities, departures);
|
||||
for (City city : cities) {
|
||||
System.out.println(city);
|
||||
}
|
||||
}
|
||||
*/
|
||||
public static String getValue(String fileName, String key) {
|
||||
StringBuilder json = new StringBuilder();
|
||||
try {
|
||||
BufferedReader reader = new BufferedReader(new FileReader(fileName));
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
json.append(line.trim());
|
||||
@ -39,6 +45,17 @@ public class JsonParser {
|
||||
return jsonString.substring(startIndex, endIndex);
|
||||
}
|
||||
|
||||
public static City[][] loadMap(String fileName, String key, List<City> cities) {
|
||||
String[][] cityMap = parseCountryMap(fileName, key);
|
||||
City[][] map = new City[cityMap.length][cityMap[0].length];
|
||||
|
||||
for (City city : cities) {
|
||||
map[city.getLocation().getX()][city.getLocation().getY()] = city;
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
public static String[][] parseCountryMap(String fileName, String key) {
|
||||
|
||||
String mapData = getValue(fileName, key);
|
||||
@ -55,9 +72,6 @@ public class JsonParser {
|
||||
.map(s -> s.replaceAll("\"", "").trim())
|
||||
.filter(s -> !s.isEmpty())
|
||||
.toArray(String[]::new);
|
||||
for (String city : cities) {
|
||||
System.out.println(city);
|
||||
}
|
||||
if (cities.length > 0) matrixList.add(cities);
|
||||
}
|
||||
String[][] result = new String[matrixList.size()][];
|
||||
@ -65,13 +79,13 @@ public class JsonParser {
|
||||
|
||||
result[i] = matrixList.get(i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
for (int j = 0; j < result[i].length; j++) {
|
||||
System.out.println("result[" + i + "][" + j + "] = " + result[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
for (int j = 0; j < result[i].length; j++) {
|
||||
System.out.println("result[" + i + "][" + j + "] = " + result[i][j]);
|
||||
}
|
||||
}
|
||||
*/
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -79,7 +93,6 @@ public class JsonParser {
|
||||
List<Departure> departures = new ArrayList<>();
|
||||
|
||||
String departuresJson = getValue(fileName, key);
|
||||
System.out.println(departuresJson);
|
||||
|
||||
String res =
|
||||
departuresJson
|
||||
@ -91,8 +104,6 @@ public class JsonParser {
|
||||
"type:\\s|\\sfrom:\\s|\\sto:\\s|\\sdepartureTime:\\s|\\sduration:\\s|\\sprice:\\s|\\sminTransferTime:\\s",
|
||||
"");
|
||||
|
||||
System.out.println(res);
|
||||
|
||||
String[] arr = res.split("\\|");
|
||||
for (String a : arr) {
|
||||
String[] temp = a.split(",");
|
||||
@ -105,16 +116,13 @@ public class JsonParser {
|
||||
Integer.parseInt(temp[4]),
|
||||
Double.parseDouble(temp[5]),
|
||||
Integer.parseInt(temp[6])));
|
||||
System.out.println(a);
|
||||
}
|
||||
|
||||
for (Departure dep : departures) System.out.println(dep);
|
||||
return departures;
|
||||
}
|
||||
|
||||
public static List<City> parseCities(String fileName, String key) {
|
||||
String cityData = getValue(fileName, key);
|
||||
System.out.println(cityData);
|
||||
String res =
|
||||
cityData
|
||||
.replaceAll("[\\[\\]]+", "")
|
||||
@ -130,38 +138,82 @@ public class JsonParser {
|
||||
String[] temp = arr[i].split(",");
|
||||
list.add(temp);
|
||||
}
|
||||
int i = 0;
|
||||
List<String> temp = new ArrayList<>();
|
||||
List<String> formatedList = new ArrayList<>();
|
||||
for (String[] a : list) {
|
||||
temp.clear();
|
||||
formatedList.clear();
|
||||
System.out.println(i);
|
||||
i++;
|
||||
for (String b : a) {
|
||||
temp.add(b);
|
||||
}
|
||||
for (String item : temp) {
|
||||
item = (item.replaceAll("\\\"[a-zA-Z]+\\\":\\s", "").trim().replaceAll("\\\"", ""));
|
||||
System.out.println(item);
|
||||
}
|
||||
|
||||
for (int j = 0; j < temp.size(); j++) {
|
||||
formatedList.add(
|
||||
temp.get(j).replaceAll("\\\"[a-zA-Z]+\\\":\\s", "").trim().replaceAll("\\\"", ""));
|
||||
System.out.println(formatedList.get(j));
|
||||
}
|
||||
|
||||
cities.add(
|
||||
new City(
|
||||
formatedList.get(0),
|
||||
formatedList.get(1),
|
||||
formatedList.get(2),
|
||||
Integer.parseInt(String.valueOf(formatedList.get(0).charAt(2))),
|
||||
Integer.parseInt(String.valueOf(formatedList.get(0).charAt(4)))));
|
||||
String[] parts = formatedList.get(0).split("_");
|
||||
String name = formatedList.get(0);
|
||||
String bus = formatedList.get(1);
|
||||
String train = formatedList.get(2);
|
||||
int x = Integer.parseInt(parts[1]);
|
||||
int y = Integer.parseInt(parts[2]);
|
||||
cities.add(new City(name, bus, train, x, y));
|
||||
}
|
||||
return cities;
|
||||
}
|
||||
|
||||
// Way to slow for big sets of data because it has O(n*m)
|
||||
public static List<City> loadDeparturesOld(List<City> cities, List<Departure> departures) {
|
||||
|
||||
for (Departure dep : departures) {
|
||||
|
||||
for (City city : cities) {
|
||||
|
||||
if (dep.getType() == TransportType.BUS) {
|
||||
if (dep.getFrom().equals(city.getBusStation().getName())) {
|
||||
city.getBusStation().addDeparture(dep);
|
||||
}
|
||||
} else if (dep.getType() == TransportType.TRAIN) {
|
||||
|
||||
if (dep.getFrom().equals(city.getTrainStation().getName())) {
|
||||
city.getTrainStation().addDeparture(dep);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return cities;
|
||||
}
|
||||
|
||||
public static List<City> loadDepartures(List<City> cities, List<Departure> departures) {
|
||||
|
||||
Map<String, City> stationToCityMap = new HashMap();
|
||||
|
||||
for (City city : cities) {
|
||||
System.out.println(city);
|
||||
if (city.getBusStation() != null) {
|
||||
stationToCityMap.put(city.getBusStation().getName(), city);
|
||||
}
|
||||
if (city.getBusStation() != null) {
|
||||
stationToCityMap.put(city.getTrainStation().getName(), city);
|
||||
}
|
||||
}
|
||||
|
||||
for (Departure dep : departures) {
|
||||
City city = stationToCityMap.get(dep.getFrom());
|
||||
|
||||
if (city != null) {
|
||||
if (dep.getType() == TransportType.BUS
|
||||
&& city.getBusStation().getName().equals(dep.getFrom())) {
|
||||
|
||||
city.getBusStation().addDeparture(dep);
|
||||
} else if (dep.getType() == TransportType.TRAIN
|
||||
&& city.getTrainStation().getName().equals(dep.getFrom())) {
|
||||
city.getTrainStation().addDeparture(dep);
|
||||
}
|
||||
}
|
||||
}
|
||||
return cities;
|
||||
}
|
||||
@ -169,7 +221,6 @@ public class JsonParser {
|
||||
private static int findPair(String str, int startIndex) {
|
||||
|
||||
char open = str.charAt(startIndex);
|
||||
System.out.println(open);
|
||||
char closed = (open == '[') ? ']' : '}';
|
||||
|
||||
int depth = 0;
|
||||
|
41
src/Location.java
Normal file
41
src/Location.java
Normal file
@ -0,0 +1,41 @@
|
||||
import java.util.Objects;
|
||||
|
||||
public class Location {
|
||||
|
||||
private int x;
|
||||
private int y;
|
||||
|
||||
public Location(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(int x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(int y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Location location = (Location) o;
|
||||
return x == location.x && y == location.y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(x, y);
|
||||
}
|
||||
}
|
@ -13,4 +13,24 @@ public class Station {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public TransportType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public List<Departure> getDepartures() {
|
||||
return departures;
|
||||
}
|
||||
|
||||
public void addDeparture(Departure departure) {
|
||||
departures.add(departure);
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Station{" + "type=" + type + ", name=" + name + ", departures=" + departures;
|
||||
}
|
||||
}
|
||||
|
@ -7,11 +7,11 @@ public class TransportDataGenerator {
|
||||
private int n;
|
||||
private int m;
|
||||
|
||||
private static final int DEPARTURES_PER_STATION = 3;
|
||||
private static final int DEPARTURES_PER_STATION = 1;
|
||||
private static final Random random = new Random();
|
||||
|
||||
public static void main(String[] args) {
|
||||
TransportDataGenerator generator = new TransportDataGenerator(3, 4);
|
||||
TransportDataGenerator generator = new TransportDataGenerator(2, 2);
|
||||
TransportData data = generator.generateData();
|
||||
generator.saveToJson(data, "transport_data.json");
|
||||
System.out.println("Podaci su generisani i sacuvani kao transport_data.json");
|
||||
|
48
src/User.java
Normal file
48
src/User.java
Normal file
@ -0,0 +1,48 @@
|
||||
public class User {
|
||||
private String name;
|
||||
private int id;
|
||||
private Location location;
|
||||
private Location destination;
|
||||
|
||||
private static int idCounter = 1;
|
||||
// :TODO:
|
||||
private static final String ID_FILE = "id_counter.txt";
|
||||
|
||||
public User(String name) {
|
||||
this.name = name;
|
||||
this.id = idCounter++;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setLocation(Location location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public Location getDestination() {
|
||||
return destination;
|
||||
}
|
||||
|
||||
public void setDestination(Location destination) {
|
||||
this.destination = destination;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "User{id=" + id + ", name='" + name + "'}";
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user