private void readLocationDistancesShuttles() throws IOException {
   List<RoadLocation> locationList = solution.getLocationList();
   int locationListSize = locationList.size();
   File file = new File(inputFile.getParentFile(), "DistanceTimesData_SHUTTLES.csv");
   int locationListIndex = 0;
   try (BufferedReader subBufferedReader =
       new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"))) {
     subBufferedReader.readLine(); // Ignore first line (comment)
     for (String line = subBufferedReader.readLine();
         line != null;
         line = subBufferedReader.readLine()) {
       if (line.isEmpty()) {
         continue;
       }
       RoadLocation sourceLocation = locationList.get(locationListIndex);
       locationListIndex++;
       String[] lineTokens = splitBySemicolonSeparatedValue(line, locationListSize * 2);
       for (int i = 0; i < locationListSize; i++) {
         RoadLocation targetLocation = locationList.get(i);
         RoadLocationArc locationArc = sourceLocation.getTravelDistanceMap().get(targetLocation);
         locationArc.setShuttleDistance(Integer.parseInt(lineTokens[i * 2]));
         locationArc.setShuttleDuration(Integer.parseInt(lineTokens[i * 2 + 1]));
       }
     }
   } catch (IOException e) {
     throw new IllegalArgumentException("Could not read the file (" + file.getName() + ").", e);
   }
 }
    @Override
    public CoachShuttleGatheringSolution readSolution() throws IOException {
      solution = new CoachShuttleGatheringSolution();
      solution.setId(0L);
      readLocationList();
      busOrStopOrHubId = 0L;
      readBusList();
      readBusStopList();

      int busListSize = solution.getCoachList().size() + solution.getShuttleList().size();
      int base = solution.getStopList().size() + solution.getShuttleList().size();
      BigInteger possibleSolutionSize =
          factorial(base + busListSize - 1).divide(factorial(busListSize - 1));
      logger.info(
          "CoachShuttleGathering {} has {} road locations, {} coaches, {} shuttles and {} bus stops"
              + " with a search space of {}.",
          getInputId(),
          solution.getLocationList().size(),
          solution.getCoachList().size(),
          solution.getShuttleList().size(),
          solution.getStopList().size(),
          getFlooredPossibleSolutionSize(possibleSolutionSize));
      return solution;
    }
 private void readLocationList() throws IOException {
   File file = new File(inputFile.getParentFile(), "DistanceTimesCoordinates.csv");
   latLongToLocationMap = new HashMap<>();
   List<RoadLocation> locationList = new ArrayList<>();
   long locationId = 0L;
   try (BufferedReader subBufferedReader =
       new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"))) {
     subBufferedReader.readLine(); // Ignore first line (comment)
     for (String line = subBufferedReader.readLine();
         line != null;
         line = subBufferedReader.readLine()) {
       if (line.isEmpty()) {
         continue;
       }
       String[] lineTokens = splitBySemicolonSeparatedValue(line, 2);
       RoadLocation location = new RoadLocation();
       location.setId(locationId);
       locationId++;
       location.setLatitude(Double.parseDouble(lineTokens[0]));
       location.setLongitude(Double.parseDouble(lineTokens[1]));
       locationList.add(location);
       latLongToLocationMap.put(
           Arrays.asList(location.getLatitude(), location.getLongitude()), location);
     }
   } catch (IOException e) {
     throw new IllegalArgumentException("Could not read the file (" + file.getName() + ").", e);
   }
   solution.setLocationList(locationList);
   for (RoadLocation sourceLocation : locationList) {
     LinkedHashMap<RoadLocation, RoadLocationArc> travelDistanceMap =
         new LinkedHashMap<>(locationList.size());
     for (RoadLocation targetLocation : locationList) {
       travelDistanceMap.put(targetLocation, new RoadLocationArc());
     }
     sourceLocation.setTravelDistanceMap(travelDistanceMap);
   }
   readLocationDistancesCoaches();
   readLocationDistancesShuttles();
 }
 private void readBusStopList() throws IOException {
   List<BusStop> busStopList = new ArrayList<>();
   bufferedReader.readLine(); // Ignore first line (comment)
   for (String line = bufferedReader.readLine();
       line != null;
       line = bufferedReader.readLine()) {
     if (line.isEmpty()) {
       continue;
     }
     String[] lineTokens = splitBySemicolonSeparatedValue(line, 8);
     String busStopType = lineTokens[0];
     String name = lineTokens[1];
     if (busStopType.equalsIgnoreCase("HUB")) {
       if (solution.getHub() != null) {
         throw new IllegalArgumentException(
             "The hub with name ("
                 + name
                 + ") is not the only hub ("
                 + solution.getHub().getName()
                 + ").");
       }
       BusHub hub = new BusHub();
       hub.setId(busOrStopOrHubId);
       busOrStopOrHubId++;
       hub.setName(name);
       // Ignore lineTokens[2] and lineTokens[3]
       double latitude = Double.parseDouble(lineTokens[4]);
       double longitude = Double.parseDouble(lineTokens[5]);
       RoadLocation location = latLongToLocationMap.get(Arrays.asList(latitude, longitude));
       if (location == null) {
         throw new IllegalArgumentException(
             "The bus stop with name ("
                 + name
                 + ") has a coordinate ("
                 + latitude
                 + ", "
                 + longitude
                 + ") which is not in the coordinates file.");
       }
       hub.setLocation(location);
       int passengerQuantity = Integer.parseInt(lineTokens[6]);
       if (passengerQuantity != 0) {
         throw new IllegalArgumentException(
             "The hub with name ("
                 + name
                 + ") has an unsupported passengerQuantity ("
                 + passengerQuantity
                 + ").");
       }
       int transportTimeLimit = Integer.parseInt(lineTokens[7]);
       if (transportTimeLimit != 0) {
         throw new IllegalArgumentException(
             "The hub with name ("
                 + name
                 + ") has an unsupported transportTimeLimit ("
                 + transportTimeLimit
                 + ").");
       }
       for (Coach coach : solution.getCoachList()) {
         coach.setDestination(hub);
       }
       ArrayList<Shuttle> transferShuttleList =
           new ArrayList<>(solution.getShuttleList().size());
       for (Shuttle shuttle : solution.getShuttleList()) {
         // TODO Use a fixed value Construction Heuristic to initialize the destination variable
         shuttle.setDestination(hub);
         transferShuttleList.add(shuttle);
       }
       hub.setTransferShuttleList(transferShuttleList);
       solution.setHub(hub);
     } else if (busStopType.equalsIgnoreCase("BUSSTOP")) {
       BusStop busStop = new BusStop();
       busStop.setId(busOrStopOrHubId);
       busOrStopOrHubId++;
       busStop.setName(name);
       // Ignore lineTokens[2] and lineTokens[3]
       double latitude = Double.parseDouble(lineTokens[4]);
       double longitude = Double.parseDouble(lineTokens[5]);
       RoadLocation location = latLongToLocationMap.get(Arrays.asList(latitude, longitude));
       if (location == null) {
         throw new IllegalArgumentException(
             "The bus stop with name ("
                 + name
                 + ") has a coordinate ("
                 + latitude
                 + ", "
                 + longitude
                 + ") which is not in the coordinates file.");
       }
       busStop.setLocation(location);
       busStop.setPassengerQuantity(Integer.parseInt(lineTokens[6]));
       busStop.setTransportTimeLimit(Integer.parseInt(lineTokens[7]));
       // Trade memory for performance (might not be desired if it is too memory hungry)
       busStop.setTransferShuttleList(new ArrayList<>(solution.getShuttleList().size()));
       busStopList.add(busStop);
     } else {
       throw new IllegalArgumentException(
           "The bus stop with name ("
               + name
               + ") has an unsupported type ("
               + busStopType
               + ").");
     }
   }
   solution.setStopList(busStopList);
 }
 private void readBusList() throws IOException {
   File file = new File(inputFile.getParentFile(), "Fleet.csv");
   List<Coach> coachList = new ArrayList<>();
   List<Shuttle> shuttleList = new ArrayList<>();
   try (BufferedReader subBufferedReader =
       new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"))) {
     subBufferedReader.readLine(); // Ignore first line (comment)
     for (String line = subBufferedReader.readLine();
         line != null;
         line = subBufferedReader.readLine()) {
       if (line.isEmpty()) {
         continue;
       }
       String[] lineTokens = splitBySemicolonSeparatedValue(line, 8);
       Bus bus;
       String busType = lineTokens[0];
       String name = lineTokens[1];
       if (busType.equalsIgnoreCase("COACH")) {
         bus = new Coach();
         coachList.add((Coach) bus);
       } else if (busType.equalsIgnoreCase("SHUTTLE")) {
         bus = new Shuttle();
         shuttleList.add((Shuttle) bus);
       } else {
         throw new IllegalArgumentException(
             "The fleet vehicle with name ("
                 + name
                 + ") has an unsupported type ("
                 + busType
                 + ").");
       }
       bus.setId(busOrStopOrHubId);
       busOrStopOrHubId++;
       bus.setName(name);
       bus.setCapacity(Integer.parseInt(lineTokens[2]));
       int stopLimit = Integer.parseInt(lineTokens[3]);
       if (bus instanceof Coach) {
         ((Coach) bus).setStopLimit(stopLimit);
       } else {
         if (stopLimit != -1) {
           throw new IllegalArgumentException(
               "The shuttle with name ("
                   + name
                   + ") has an unsupported stopLimit ("
                   + stopLimit
                   + ").");
         }
       }
       bus.setMileageCost(Integer.parseInt(lineTokens[4]));
       int setupCost = Integer.parseInt(lineTokens[5]);
       if (bus instanceof Coach) {
         if (setupCost != 0) {
           throw new IllegalArgumentException(
               "The coach with name ("
                   + name
                   + ") has an unsupported setupCost ("
                   + setupCost
                   + ").");
         }
       } else {
         ((Shuttle) bus).setSetupCost(setupCost);
       }
       double latitude = Double.parseDouble(lineTokens[6]);
       double longitude = Double.parseDouble(lineTokens[7]);
       RoadLocation location = latLongToLocationMap.get(Arrays.asList(latitude, longitude));
       if (location == null) {
         throw new IllegalArgumentException(
             "The fleet vehicle with name ("
                 + name
                 + ") has a coordinate ("
                 + latitude
                 + ", "
                 + longitude
                 + ") which is not in the coordinates file.");
       }
       bus.setDepartureLocation(location);
     }
   } catch (IOException e) {
     throw new IllegalArgumentException("Could not read the file (" + file.getName() + ").", e);
   }
   solution.setCoachList(coachList);
   solution.setShuttleList(shuttleList);
 }