-
Notifications
You must be signed in to change notification settings - Fork 0
/
ExperimentController.java
218 lines (201 loc) · 10.1 KB
/
ExperimentController.java
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
import java.util.*;
import java.io.*;
/**
* The ExperimentController class
* Where everything is run. Uses the large data set by default, but can be changed to use the small data set with the smallData method
*
* @version 11/30/18
*/
public class ExperimentController
{
Graph cityMap = new Graph();
String center;
String roadsFile;
String centerFile;
String warehouseFile;
boolean smallData = false;
ArrayList<Warehouse> cargoList;
public ExperimentController(){
//Constructs the new ExperimentController object using the large set of data
center = "A";
roadsFile = "roads.txt";
centerFile = "center.txt";
warehouseFile = "warehouses.txt";
smallData = false;
}
public void smallData(){
//Changes the data to use the small set of data (used in unit tests)
roadsFile = "roadsS.txt";
centerFile = "centerS.txt";
warehouseFile = "warehousesS.txt";
smallData = true;
}
public void shortestPath(){
//Runs the shortest path method on the center
cityMap.shortestPath(center);
}
public void setCenterShortestPath(){
//Sets the center distance of each city (used to make it a bit easier and faster)
cityMap.shortestPath(center,0);
}
public static void main(String[] args){
ExperimentController ec = new ExperimentController();
ec.cargoList = ec.mapCity();//Constructs the graph
ec.setCenterShortestPath();//Sets the centerDist of each city
ec.cityMap.shortestPath(ec.cityMap.getVertex(ec.center));//Sets the first dist of each city
Collections.sort(ec.cargoList);//Sorts the warehouses again (just to be sure)
ArrayList<Truck> dispatch = new ArrayList<Truck>();//The array list of trucks that will eventually be printed
int truckNumber=1;//Used for creating trucks
int incompleteWarehouses = ec.cargoList.size();//Used to keep track of how long to run the loops
int startingWarehouse = 0;//Keeps track of the closest warehouse that still needs orders
while(incompleteWarehouses != 0){
Truck t = new Truck(truckNumber);
truckNumber++;
if (truckNumber == 5) {//Used in debugging
int r = 5;
}
while(ec.cargoList.get(startingWarehouse).incomingCargo.isEmpty()){//Increments the startingWarehouse if the current startingWarehouse is empty
startingWarehouse++;
}
Warehouse currentWarehouse = ec.cargoList.get(startingWarehouse);
Shipment s = new Shipment(currentWarehouse.city,500);//Creates a new shipment going to the current startingWarehouse
ec.shortestPath();//Sets the dist values
s.setDestination(ec.cityMap.getVertex(s.location));//Sets the shipment's variables
s.setDistance();
while(!t.truckReady){//Continues until the truck can not take any more cargo
s.destination.setClosestCities(ec.cityMap.shortestPath(s.destination));//Sets the city's arrayList of every other city in order
boolean shipmentCheck = false;
while(!shipmentCheck){//Run until the shipment can not be added to
if(currentWarehouse.incomingCargo.isEmpty()){//Increments the values that keep the program running
//warehouseNumber++;
currentWarehouse.location.hasWarehouse = false;
shipmentCheck = true;
if(!currentWarehouse.complete){
incompleteWarehouses--;
}
currentWarehouse.complete = true;
continue;
}
Cargo c = currentWarehouse.incomingCargo.remove(0);//Removes a cargo each iteration until a cargo can not be added to the shipment
if(!s.addCargo(c)){
currentWarehouse.incomingCargo.add(0,c);
shipmentCheck = true;
}
}
if(!s.shipmentCargo.isEmpty()){
//Occasionally an empty shipment could make it through the loop above. This makes sure that it does not
//get added to the truck and mess up the distances
t.addShipment(s);
}
shipmentCheck = false;
t.truckReady = true;
ArrayList<City> closest = s.destination.closestCities;
for(int i = 0;i<closest.size();i++){
/*
* This loop and the if statements look for a warehouse that has a shipment that could fit into the truck. It will stop and break
* the loop when it finds the closest city that has a viable order. otherwise, it will skip right to the next city
*/
if(closest.get(i).hasWarehouse){
if(!closest.get(i).cityWarehouse.incomingCargo.isEmpty() && closest.get(i).cityWarehouse.incomingCargo.get(0).weight <= 500-t.weight){
t.truckReady = false;
City c = closest.get(i);
ec.cityMap.shortestPath(s.destination);
s = new Shipment(closest.get(i).name,500-t.weight);
//ec.cityMap.shortestPath(c);
s.setDestination(ec.cityMap.getVertex(s.location));
//ec.cityMap.shortestPath(s.destination);
s.setDistance();
currentWarehouse = closest.get(i).cityWarehouse;
break;
}
else{
}
}
else{
closest.remove(i);
i--;
}
}
}
t.distanceTraveled += ec.cityMap.getVertex(ec.center).dist;//Once it reaches the end, the distance from the center is added to the truck's total distance
dispatch.add(t);
}
int totalDist = 0;
try{
PrintWriter output = new PrintWriter("output.txt");
for(Truck t : dispatch){
ArrayList<String> truckLines = t.printStrings();
for(String s : truckLines){//All of the trucks run the printStrings method which creates an array list. Each arrayList is printed to the file
output.write(s);
output.println();
}
output.println();
totalDist += t.distanceTraveled;
}
//System.out.println("Total Distance: " + totalDist);
output.write("Total Distance: " + totalDist);
output.close();
System.out.println("All data successfully printed to output.txt");
}
catch(Exception e){
System.out.println(e);
}
}
public ArrayList<Warehouse> mapCity(){
//Takes the input and constructs the graph
try{
Scanner fileInput = new Scanner(new FileReader(roadsFile));
Scanner fileInput2 = new Scanner(new FileReader(centerFile));
Scanner fileInput3 = new Scanner(new FileReader(warehouseFile));
if(!smallData){
fileInput.nextLine();//The large set of data needs to skip the first line in order to run
}
while(fileInput.hasNextLine()){//Takes each line and divides it up into the two cities it connects and the weight, then adds that edge and vertices
String line = fileInput.nextLine();
if(line.length() < 3){//This was created for unit tests as it was having a hard time reading the small input files
line = fileInput.nextLine();
}
String v1 = line.substring(0,line.indexOf(" "));
line = line.substring(line.indexOf(" ")+1);
String v2 = line.substring(0,line.indexOf(" "));
line = line.substring(line.indexOf(" ")+1);
int w = Integer.parseInt(line);
cityMap.addEdge(v1,v2,w);
}
center = fileInput2.nextLine();//Sets the center
ArrayList<Warehouse> cargoList = new ArrayList<Warehouse>();
if(!smallData){
fileInput3.nextLine();//The large set of data needs to skip the first line in order to run
}
while(fileInput3.hasNextLine()){
//Takes each line from the warehouses file and grabs all the different orders, assigns them id numbers, then adds them
//to a warehouse object which is returned in an array list
String line = fileInput3.nextLine();
String destination = line.substring(0,line.indexOf(" "));
cityMap.hasWarehouse(destination);
Warehouse w = new Warehouse(destination);
line = line.substring(line.indexOf(" ")+1);
int id = 1;
while(line.indexOf(" ")!=-1){//This loop runs until there are no more orders for this warehouse
int weight = Integer.parseInt(line.substring(0,line.indexOf(" ")));
Cargo c = new Cargo(weight,destination,id);
id++;
w.addCargo(c);
line = line.substring(line.indexOf(" ")+1);
}
int weight = Integer.parseInt(line);//These 3 lines are to grab the last one (after there are no more space characters left)
Cargo c = new Cargo(weight,destination,id);
w.addCargo(c);
w.cargoSort();//Sorts the cargo in the warehouse (original order is stored with id number)
cargoList.add(w);
cityMap.setWarehouse(w);//Links the city and warehouse
}
Collections.sort(cargoList);//Sorts the warehouse list by distance from center
return cargoList;
}
catch(Exception e){
System.out.println(e);
return null;
}
}
}