-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFlights.java
More file actions
226 lines (188 loc) · 8.49 KB
/
Copy pathFlights.java
File metadata and controls
226 lines (188 loc) · 8.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
import java.io.*;
import java.util.*;
/**
* uses collected information on airlines (respective airports, countries and cities involved)
* to recommend a route to the destination country for the user
* @author: Ruvimbo Joy Sithole
*/
public class Flights{
HashMap<String, String> city_countries = new HashMap(); //stores the citycountry and the corresponding code
HashMap<String, ArrayList<Node>> all_Routes = new HashMap<>(); //stores all the routes associated with a certain airport code
/**
* Takes city names, country names and codes
* @param file contains cities names, country names, codes, etc required
* @throws FileNotFoundException if file provided doesn't exist
*/
public void set_CountryCity(File file) throws FileNotFoundException {
Scanner scanner_object = new Scanner(new FileReader(file));
while (scanner_object.hasNextLine()){
String[] line = scanner_object.nextLine().split(",");
if(line.length == 14) { //skips the inconsistent data
String temp = line[2] + line[3];// takes the city and country name from the read line
city_countries.put(temp, line[4]); //value for the (citycountry) key will be the airport's code
}
}
scanner_object.close();
}
public String start() throws IOException {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter start location in the form: city,country ");
String[] src = scanner.nextLine().split(",");
System.out.println("Enter desired destination location in the form: city,country ");
String[] dest = scanner.nextLine().split(",");
String name = src[0] + "-" + dest[0];
FileWriter uInput = new FileWriter(name + ".txt");
uInput.write(String.join(",", src) + "\n");
uInput.write(String.join(",", dest));
uInput.close();
return name;
}
/**
* Reads from the user's file
* @param user_input contains the user's desired source and destination
* @return the list containing city-country for source and for the destination
* @throws FileNotFoundException
*/
public ArrayList<String> getCodes(File user_input) throws FileNotFoundException{
Scanner scanner = new Scanner(new FileReader(user_input));
ArrayList<String> source_dest = new ArrayList<>();
String[] temp= scanner.nextLine().split(",");
String[] temp2= scanner.nextLine().split(",");
String s = temp[0].strip() + temp[1].strip();
String d = temp2[0].strip() + temp2[1].strip();
scanner.close();
//find the code for stated start location and destination
if(city_countries.containsKey(s) && city_countries.containsKey(d) ){
source_dest.add(city_countries.get(s));
source_dest.add(city_countries.get(d));
}
else
return null; //destination airport does not exit
return source_dest;
}
/**
* read information on routes available from the file
* creates Nodes to represent the flights, airport destination and airline associated with each source airport
* @param routes file containing all available routes
* @throws FileNotFoundException if there exists no route from stated city to destination
*/
public void routesInfor(File routes) throws FileNotFoundException{
Scanner sc = new Scanner(new FileReader(routes));
while (sc.hasNextLine()){
String[] line = sc.nextLine().split(",");
if(line.length < 9)
continue;
ArrayList<Node> temp = new ArrayList<>();
Node new_destination = new Node(line[4], line[0], line[7]); //create Node with destination code ,airline ID, No.stops
//if the key already exists, add the new destination code found to the list
if(all_Routes.containsKey(line[2])){
temp = all_Routes.get(line[2]);
temp.add(new_destination);
all_Routes.put(line[2], temp);
}
temp.add(new_destination);
all_Routes.put(line[2], temp); //adding an array to hold the Node destinations associated with the current airport code
}
sc.close();
}
/**
* Bakctracks Nodes from the found destination to the start airport
* @param end the found destination airport
* @return a list/ generations of Nodes that lead to the destination
*/
public ArrayList<Node> solution(Node end){
ArrayList<Node> result = new ArrayList<>();
Node child = end;
while (child.getParent()!= null){
result.add(child);
child = child.getParent();
}
Collections.reverse(result);
return result;
}
/**
* writes out the generation of Nodes from the start to destination into file
* @param res an Array List of Nodes comprising the solution route
* @param filename to be used in creating Output filename
* @throws IOException if the Filewriter is unsuccessful
*/
public void writeOutput(ArrayList<Node> res, String filename) throws IOException
{
FileWriter outputFile = new FileWriter(filename + "_output" + ".txt");
int stops = 0;
for(int r = 0 ; r < res.size(); r++)
{
outputFile.write(r + 1 + ". " + res.get(r) + "\n");
}
outputFile.write("Total flights: "+ res.size()+ "\n" + " Total additional stops: " + stops);
outputFile.close();
}
/**
* Find the route from the given source to destination
* @param source_destination provided by user
* @return the route found
*/
public ArrayList<Node> generateRoute(ArrayList<String> source_destination)
{
if (source_destination == null){
return null;
}
String source_code = source_destination.get(0);
String destination_code = source_destination.get(1);
LinkedList<Node> frontier = new LinkedList<>();
HashSet<String> explored = new HashSet<>();
Node curr_node = new Node(source_code, null, null);
frontier.add(curr_node); //add start airport Node to the frontier
//To find the route to user's destination airport:
//explore the breadth of all the destination nodes connected to the source airport
while (!frontier.isEmpty())
{
Node src = frontier.removeFirst(); //explore nodes in FIFO sequence
ArrayList<Node> src_routes = all_Routes.get(src.getCode());
explored.add(src.getCode()); // +1 explored Node
//if any destination node is == to user's destination return solution
if(src_routes!= null) {
for (Node potential : src_routes) {
potential.setParent(src);
if (potential.getCode().equals(destination_code)) {
return solution(potential);
}
if (!explored.contains(potential.getCode()) && !frontier.contains(potential)) {
frontier.add(potential); //to be explored later
}
}
}
}
return null; //failed: no path/route found
}
//-------------------------------------------DRIVER'S CODE -----------------------------------------------------------//
public static void main(String[] args)
{
Flights demoProgram = new Flights();
// Program files: Access airport, airline, and routes data
try {
demoProgram.set_CountryCity(new File("airports.csv"));
demoProgram.routesInfor(new File("routes.csv"));
}
catch (FileNotFoundException fnfe){
fnfe.getMessage();
}
//USER
try{
String fName = demoProgram.start();
File userInput = new File(fName + ".txt");
ArrayList<String> source_destination = demoProgram.getCodes(userInput);
ArrayList<Node> result = demoProgram.generateRoute(source_destination);
if (result == null)
System.out.println(" There exists no route from " + source_destination.get(0) +
" to your desired destination " + source_destination.get(1));
else{
demoProgram.writeOutput(result,fName);
System.out.println("Route Found. Find the results in " + fName + "_output.txt");
}
}
catch (IOException ioe){
System.out.println("The city and country names are invalid");
}
}
}