package F28DA_CW2; import org.jgrapht.GraphPath; import org.jgrapht.alg.shortestpath.*; import org.jgrapht.graph.*; import java.util.*; public class FlyingPlanner implements IFlyingPlannerPartB, IFlyingPlannerPartC { private DirectedWeightedMultigraph flight = new DirectedWeightedMultigraph( Flight.class); private DirectedAcyclicGraph DAG = new DirectedAcyclicGraph(Flight.class); public boolean populate(FlightsReader fr) { HashSet airport = fr.getAirports(); HashSet flights = fr.getFlights(); return populate(airport, flights); } public boolean populate(HashSet airports, HashSet flights) { Iterator airIter = airports.iterator(); Iterator flyIter = flights.iterator(); try { while (airIter.hasNext()) { String[] name = airIter.next(); Airport V = new Airport(name[0], name[1], 0); flight.addVertex(V); } while (flyIter.hasNext()) { String[] curr = flyIter.next(); Airport from = airport(curr[1]); Airport to = airport(curr[3]); Flight E = new Flight(curr[0], from, to, curr[2], curr[4], Integer.parseInt(curr[5])); flight.addEdge(from, to, E); flight.setEdgeWeight(E, Integer.parseInt(curr[5])); } return true; } catch (Exception e) { return false; } } public Airport airport(String code) { Iterator airportIter = flight.vertexSet().iterator(); while (airportIter.hasNext()) { Airport tempAirport = airportIter.next(); if (tempAirport.getCode().equals(code)) return tempAirport; } return null; } public Flight flight(String code) { Iterator flightIter = flight.edgeSet().iterator(); while (flightIter.hasNext()) { Flight tempFlight = flightIter.next(); if (tempFlight.getFlightCode().equals(code)) return tempFlight; } return null; } public Journey leastCost(String from, String to) throws FlyingPlannerException { if (!flight.containsVertex(airport(from)) || (!flight.containsVertex(airport(to)))) throw new FlyingPlannerException("Error: No airport with entered name found"); DijkstraShortestPath path = new DijkstraShortestPath(flight); GraphPath optimalPath = path.getPath(airport(from), airport(to)); if (optimalPath == null) throw new FlyingPlannerException("Error: No path found"); return tripGen(optimalPath); } public Journey leastHop(String from, String to) throws FlyingPlannerException { if (!flight.containsVertex(airport(from)) || (!flight.containsVertex(airport(to)))) throw new FlyingPlannerException("Error: No airport with entered name found"); BellmanFordShortestPath path = new BellmanFordShortestPath(flight); GraphPath optimalPath = path.getPath(airport(from), airport(to)); if (optimalPath == null) throw new FlyingPlannerException("Error: No path found"); return tripGen(optimalPath); } public Journey leastCost(String from, String to, List excluding) throws FlyingPlannerException { if (!flight.containsVertex(airport(from)) || (!flight.containsVertex(airport(to)))) throw new FlyingPlannerException("Error: No airport with entered name found"); DirectedWeightedMultigraph tempGraph = new DirectedWeightedMultigraph( Flight.class); Iterator vertexIter = flight.vertexSet().iterator(); Iterator edgeIter = flight.edgeSet().iterator(); Iterator excludeIter = excluding.iterator(); while (excludeIter.hasNext()) { Airport airports = airport(excludeIter.next()); if (!flight.containsVertex(airports)) { throw new FlyingPlannerException("Error: Airport in excluded list does not exist in the graph"); } } boolean excluded; edgeIter = flight.edgeSet().iterator(); while (vertexIter.hasNext()) { Airport V = vertexIter.next(); excludeIter = excluding.iterator(); excluded = false; while (excludeIter.hasNext()) if (V.getCode().equals(excludeIter.next())) excluded = true; if (!excluded) tempGraph.addVertex(V); } while (edgeIter.hasNext()) { Flight E = edgeIter.next(); if (!(tempGraph.containsVertex(flight.getEdgeSource(E))) || !(tempGraph.containsVertex(flight.getEdgeTarget(E)))) continue; tempGraph.addEdge(flight.getEdgeSource(E), flight.getEdgeTarget(E), E); } DijkstraShortestPath path = new DijkstraShortestPath(tempGraph); GraphPath optimalPath = path.getPath(airport(from), airport(to)); if (optimalPath == null) throw new FlyingPlannerException("Error: No path found"); return tripGen(optimalPath); } public Journey leastHop(String from, String to, List excluding) throws FlyingPlannerException { if (!flight.containsVertex(airport(from)) || (!flight.containsVertex(airport(to)))) throw new FlyingPlannerException("Error: No airport with entered name found"); DirectedWeightedMultigraph tempGraph = new DirectedWeightedMultigraph( Flight.class); Iterator vertexIter = flight.vertexSet().iterator(); Iterator edgeIter = flight.edgeSet().iterator(); Iterator excludeIter = excluding.iterator(); while (excludeIter.hasNext()) { Airport airports = airport(excludeIter.next()); if (!flight.containsVertex(airports)) { throw new FlyingPlannerException("Error: Airport in excluded list does not exist in the graph"); } } boolean excluded; while (vertexIter.hasNext()) { excluded = false; Airport V = vertexIter.next(); excludeIter = excluding.iterator(); while (excludeIter.hasNext()) if (V.getCode().equals(excludeIter.next())) excluded = true; if (!excluded) tempGraph.addVertex(V); } while (edgeIter.hasNext()) { Flight E = edgeIter.next(); if (!(tempGraph.containsVertex(flight.getEdgeSource(E))) || !(tempGraph.containsVertex(flight.getEdgeTarget(E)))) continue; tempGraph.addEdge(flight.getEdgeSource(E), flight.getEdgeTarget(E), E); } BellmanFordShortestPath path = new BellmanFordShortestPath(tempGraph); GraphPath optimalPath = path.getPath(airport(from), airport(to)); if (optimalPath == null) throw new FlyingPlannerException("Error: No path found"); return tripGen(optimalPath); } public Set directlyConnected(Airport airport) { Set directConnected = new HashSet(); Iterator outEdgeIter = flight.outgoingEdgesOf(airport).iterator(); while (outEdgeIter.hasNext()) { Airport toAirport = outEdgeIter.next().getTo(); Iterator toEdgeIter = flight.outgoingEdgesOf(toAirport).iterator(); while (toEdgeIter.hasNext()) { Flight tempFlight = toEdgeIter.next(); if (tempFlight.getTo().getCode().equals(airport.getCode())) { directConnected.add(tempFlight.getFrom()); break; } } } return directConnected; } public Set getBetterConnectedInOrder(Airport airports) { setDirectlyConnectedOrder(); Set betterConnected = new HashSet(); Iterator DAGiter = DAG.getDescendants(airports).iterator(); while (DAGiter.hasNext()) { Airport Airport = DAGiter.next(); if (Airport.getDirectlyConnectedOrder() > airports.getDirectlyConnectedOrder()) { betterConnected.add(Airport); } } return betterConnected; } public String leastCostMeetUp(String at1, String at2) throws FlyingPlannerException { int finalTotalCost = -1, totalCost; String meetupCode = null; if (!flight.containsVertex(airport(at1)) || (!flight.containsVertex(airport(at2)))) throw new FlyingPlannerException("Error: No airport with entered name found"); DijkstraShortestPath path = new DijkstraShortestPath(flight); Set possibleDest = flight.vertexSet(); Iterator destIter = possibleDest.iterator(); while (destIter.hasNext()) { Airport destination = destIter.next(); if ((destination.getCode().equals(at1)) || (destination.getCode().equals(at2))) continue; GraphPath path1 = path.getPath(airport(at1), destination); GraphPath path2 = path.getPath(airport(at2), destination); if ((path1 == null) || (path2 == null)) continue; totalCost = (int) (path1.getWeight() + path2.getWeight()); if ((finalTotalCost == -1) || (totalCost < finalTotalCost)) { finalTotalCost = totalCost; meetupCode = destination.getCode(); } } return meetupCode; } public String leastHopMeetUp(String at1, String at2) throws FlyingPlannerException { int finalTotalHop = -1, totalHop; String meetupCode = null; if (!flight.containsVertex(airport(at1)) || (!flight.containsVertex(airport(at2)))) throw new FlyingPlannerException("Error: No airport with entered name found"); BellmanFordShortestPath path = new BellmanFordShortestPath(flight); Set possibleDest = flight.vertexSet(); Iterator destIter = possibleDest.iterator(); while (destIter.hasNext()) { Airport destination = destIter.next(); if ((destination.getCode().equals(at1)) || (destination.getCode().equals(at2))) continue; GraphPath path1 = path.getPath(airport(at1), destination); GraphPath path2 = path.getPath(airport(at2), destination); if ((path1 == null) || (path2 == null)) continue; totalHop = path1.getVertexList().size() + path2.getVertexList().size() - 2; if ((finalTotalHop == -1) || (totalHop < finalTotalHop)) { finalTotalHop = totalHop; meetupCode = destination.getCode(); } } return meetupCode; } public String leastTimeMeetUp(String at1, String at2, String startTime) throws FlyingPlannerException { if (!flight.containsVertex(airport(at1)) || (!flight.containsVertex(airport(at2)))) throw new FlyingPlannerException("Error: No airport with entered name found"); if (!(startTime.matches("[0-9]+")) || !(startTime.length() == 4)) throw new FlyingPlannerException("Error: Wrong time format entered"); DirectedWeightedMultigraph tempGraph = new DirectedWeightedMultigraph( Flight.class); Iterator vertexIter = flight.vertexSet().iterator(); Iterator edgeIter = flight.edgeSet().iterator(); while (vertexIter.hasNext()) tempGraph.addVertex(vertexIter.next()); while (edgeIter.hasNext()) { Flight E = edgeIter.next(); if (Integer.parseInt(startTime) > Integer.parseInt(E.getFromGMTime())) continue; tempGraph.addEdge(flight.getEdgeSource(E), flight.getEdgeTarget(E), E); tempGraph.setEdgeWeight(E, subTime(Integer.parseInt(E.getToGMTime()), Integer.parseInt(E.getFromGMTime()))); } int finalTotalTime = -1, totalTime; String meetupCode = null; DijkstraShortestPath path = new DijkstraShortestPath(tempGraph); Set possibleDest = tempGraph.vertexSet(); Iterator destIter = possibleDest.iterator(); while (destIter.hasNext()) { Airport destination = destIter.next(); if ((destination.getCode().equals(at1)) || (destination.getCode().equals(at2))) continue; GraphPath path1 = path.getPath(airport(at1), destination); GraphPath path2 = path.getPath(airport(at2), destination); if ((path1 == null) || (path2 == null)) continue; totalTime = (int) (path1.getWeight() + path2.getWeight()); if ((finalTotalTime == -1) || (totalTime < finalTotalTime)) { finalTotalTime = totalTime; meetupCode = destination.getCode(); } } return meetupCode; } private Journey tripGen(GraphPath path) { int lastToTime = 0; boolean first = true; List stopList = new ArrayList(); List flightList = new ArrayList(); Journey shortestPath = new Journey(lastToTime, lastToTime, lastToTime, lastToTime, lastToTime); Iterator vertexIter = path.getVertexList().iterator(); Iterator edgeIter = path.getEdgeList().iterator(); while (vertexIter.hasNext()) stopList.add(vertexIter.next().getCode()); while (edgeIter.hasNext()) { Flight fEdge = edgeIter.next(); if (first) first = false; else { } flightList.add(fEdge.getFlightCode()); lastToTime = Integer.parseInt(fEdge.getToGMTime()); } shortestPath.getStops(); shortestPath.getFlights(); shortestPath.totalHop(); shortestPath.totalCost(); shortestPath.airTime(); shortestPath.connectingTime(); shortestPath.totalTime(); return shortestPath; } private int subTime(int t1, int t2) { if (t1 < t2) t1 += 2400; return toMinutes(t1) - toMinutes(t2); } private int toMinutes(int t1) { return (((int) t1 / 100) * 60) + (t1 % 100); } public int setDirectlyConnected() { int sum = 0; Iterator airportIter = flight.vertexSet().iterator(); while (airportIter.hasNext()) { Airport airport = airportIter.next(); airport.setDicrectlyConnected(directlyConnected(airport)); airport.setDicrectlyConnectedOrder(directlyConnected(airport).size()); sum += airport.getDicrectlyConnected().size(); } return sum; } public int setDirectlyConnectedOrder() { setDirectlyConnected(); int flightNo = 0; Iterator airportIter = flight.vertexSet().iterator(); Iterator flightIter = flight.edgeSet().iterator(); while (airportIter.hasNext()) { DAG.addVertex(airportIter.next()); } while (flightIter.hasNext()) { Flight flights = flightIter.next(); if (flights.getTo().getDirectlyConnectedOrder() > flights.getFrom().getDirectlyConnectedOrder()) { DAG.addEdge(flights.getFrom(), flights.getTo()); flightNo++; } } return flightNo; } }