@Override public SolutionObject solve(int[][] travelTime, int[] releaseDates, int[] dueDates, int[][] servicePairs, int[] serviceTimes, @Nullable SolutionObject currentSolution) { // first check inputs validateInputs(travelTime, releaseDates, dueDates, servicePairs, serviceTimes); // execute solver final SolutionObject output = delegateSolver.solve(travelTime, releaseDates, dueDates, servicePairs, serviceTimes, currentSolution); // check outputs return validateOutputs(output, travelTime, releaseDates, dueDates, servicePairs, serviceTimes, currentSolution); } }
@Override public SolutionObject[] solve(int[][] travelTime, int[] releaseDates, int[] dueDates, int[][] servicePairs, int[] serviceTimes, int[][] vehicleTravelTimes, int[][] inventories, int[] remainingServiceTimes, int[] currentDestinations, @Nullable SolutionObject[] currentSolutions) { validateInputs(travelTime, releaseDates, dueDates, servicePairs, serviceTimes, vehicleTravelTimes, inventories, remainingServiceTimes, currentDestinations, currentSolutions); final SolutionObject[] output = delegateSolver.solve(travelTime, releaseDates, dueDates, servicePairs, serviceTimes, vehicleTravelTimes, inventories, remainingServiceTimes, currentDestinations, currentSolutions); return validateOutputs(output, travelTime, releaseDates, dueDates, servicePairs, serviceTimes, vehicleTravelTimes, inventories, remainingServiceTimes, currentDestinations); } }
/** * The last location visited must always be the depot (n-1). */ @Test(expected = IllegalArgumentException.class) public void validateInvalidRouteDepot() { validateOutputs( new SolutionObject(new int[] {0, 1, 3, 2}, new int[1], 0), new int[4][4], new int[4], new int[4], new int[][] {}, new int[4], null); }
@Test(expected = IllegalArgumentException.class) public void validateInvalidArrivalTimesFirst() { validateOutputs(new SolutionObject(new int[] {0, 1, 2, 3}, new int[] {1, -1, 0, 1}, 0), new int[4][4], new int[4], new int[4], new int[][] {}, new int[4], null); }
@Test(expected = IllegalArgumentException.class) public void validateInvalidArrivalTimes1() { validateOutputs(new SolutionObject(new int[] {0, 1, 2, 3}, new int[] {0, -1, 0, 1}, 0), new int[4][4], new int[4], new int[4], new int[][] {}, new int[4], null); }
/** * The first location visited must always be the vehicle start location (0). */ @Test(expected = IllegalArgumentException.class) public void validateInvalidRouteDuplicates() { validateOutputs( new SolutionObject(new int[] {1, 2, 0, 3}, new int[1], 0), new int[4][4], new int[4], new int[4], new int[][] {}, new int[4], null); }
@Test(expected = IllegalArgumentException.class) public void validateInvalidArrivalTimesLength() { validateOutputs( new SolutionObject(new int[] {0, 1, 2, 3}, new int[1], 0), new int[4][4], new int[4], new int[4], new int[][] {}, new int[4], null); }
@Test(expected = IllegalArgumentException.class) public void validateInvalidArrivalTimes3() { validateOutputs(new SolutionObject(new int[] {0, 1, 2, 3}, new int[] {0, 10, 0, 1}, 0), travelTimes, new int[4], new int[4], new int[][] {}, new int[4], null); }
@Test(expected = IllegalArgumentException.class) public void validateInvalidArrivalOrder() { validateOutputs( new SolutionObject(// new int[] {0, 2, 1, 3}, // route new int[] {0, 1998, 999, 2997}, // arrival times 238), // obj. value travelTimes, new int[4], new int[4], new int[][] {{1, 2}}, new int[4], null); }
/** * All locations must be visited, can not visit non-existing locations. */ @Test(expected = IllegalArgumentException.class) public void validateInvalidRouteNonExisting() { validateOutputs( new SolutionObject(new int[] {0, 1, 9, 3}, new int[1], 0), new int[4][4], new int[4], new int[4], new int[][] {}, new int[4], null); }
@Test(expected = IllegalArgumentException.class) public void validateInvalidObjective() { validateOutputs(new SolutionObject(new int[] {0, 1, 2, 3}, new int[] {0, 10, 100, 108}, 0), travelTimes, new int[4], new int[4], new int[][] {}, new int[4], null); }
/** * Route length must be equal to number of locations (4). */ @Test(expected = IllegalArgumentException.class) public void validateInvalidRouteLength() { validateOutputs(new SolutionObject(new int[3], new int[1], 0), new int[4][4], new int[4], new int[4], new int[][] {}, new int[4], null); }
/** * A location may only be visited once, duplicates are not allowed. */ @Test(expected = IllegalArgumentException.class) public void validateDuplicatesInRouteStart() { validateOutputs( new SolutionObject(new int[] {1, 1, 1, 1}, new int[1], 0), new int[4][4], new int[4], new int[4], new int[][] {}, new int[4], null); }
@Test(expected = IllegalArgumentException.class) public void validateInvalidArrivalTimes2() { validateOutputs(new SolutionObject(new int[] {0, 1, 2, 3}, new int[] {0, 0, 0, 1}, 0), travelTimes, new int[4], new int[4], new int[][] {}, new int[4], null); }
@Test(expected = IllegalArgumentException.class) public void validateMissingLocation2Vehicles() { final SolutionObject sol1 = new SolutionObject(new int[] {0, 2, 3}, new int[] {0, 10, 100, 108}, 238); final SolutionObject sol2 = new SolutionObject(new int[] {0, 2, 3}, new int[] {0, 10, 100, 108}, 238); validateOutputs(new SolutionObject[] {sol1, sol2}, travelTimes, new int[4], new int[4], new int[][] {}, new int[4], new int[2][4], new int[2][2], new int[2], new int[2]); }
@Test public void validateCorrect() { validateOutputs( new SolutionObject(new int[] {0, 1, 2, 3}, new int[] {0, 10, 100, 108}, 238), travelTimes, new int[4], new int[4], new int[][] {}, new int[4], null).toString(); }
/** * The first arrival time should reflect the remainingServiceTime for each * vehicle. */ @Test(expected = IllegalArgumentException.class) public void validateRemainingServiceTime() { final SolutionObject sol1 = new SolutionObject(new int[] {0, 1, 3}, new int[] {0, 10, 100}, 73); final SolutionObject sol2 = new SolutionObject(new int[] {0, 2, 3}, new int[] {0, 15, 90}, 59); final int[] remainingServiceTimes = new int[] {3, 700}; validateOutputs(new SolutionObject[] {sol1, sol2}, new int[4][4], new int[4], new int[4], new int[][] {}, new int[4], new int[2][4], new int[0][0], remainingServiceTimes, new int[2]); }
/** * The first point to visit in a route must be the destination (if there is a * destination). */ @Test(expected = IllegalArgumentException.class) public void validateCurrentDestination() { final SolutionObject sol1 = new SolutionObject(new int[] {0, 2, 3}, new int[] {0, 10, 100}, 73); final SolutionObject sol2 = new SolutionObject(new int[] {0, 1, 3}, new int[] {0, 15, 90}, 59); final int[] remainingServiceTimes = new int[] {0, 0}; validateOutputs(new SolutionObject[] {sol1, sol2}, new int[4][4], new int[4], new int[4], new int[][] {}, new int[4], new int[2][4], new int[0][0], remainingServiceTimes, new int[] {1, 2}); }
/** * In this test the vehicles attempt to deliver parcels which are not in their * own inventory. */ @Test(expected = IllegalArgumentException.class) public void validateRouteWithoutInventoryLocations() { final SolutionObject sol1 = new SolutionObject(new int[] {0, 1, 3}, new int[] {0, 10, 100}, 73); final SolutionObject sol2 = new SolutionObject(new int[] {0, 2, 3}, new int[] {0, 15, 90}, 59); // vehicle 0 has location 2 // vehicle 1 has location 1 final int[][] inventories = new int[][] {{0, 2}, {1, 1}}; validateOutputs(new SolutionObject[] {sol1, sol2}, new int[4][4], new int[4], new int[4], new int[][] {}, new int[4], new int[2][4], inventories, new int[2], new int[2]); }
@Test public void validateMultiVehicleCorrect() { final int[][] travelTime = new int[][] { /* */new int[] {999, 999, 999, 999}, /* */new int[] {999, 0, 999, 3}, /* */new int[] {999, 999, 0, 7}, /* */new int[] {999, 999, 999, 0}}; final int[] releaseDates = {0, 7, 8, 0}; final int[] dueDates = {0, 9, 100, 40}; final int[][] vehicleTravelTime = new int[][] { /* */new int[] {999, 9, 999, 999}, /* */new int[] {999, 999, 2, 999}}; // travel time for this route: 9 + 3 // tardiness: 1 + 60 final SolutionObject sol1 = new SolutionObject(new int[] {0, 1, 3}, new int[] {0, 10, 100}, 73); // travel time for this route: 2 + 7 // tardiness: 0 + 50 final SolutionObject sol2 = new SolutionObject(new int[] {0, 2, 3}, new int[] {0, 15, 90}, 59); validateOutputs(new SolutionObject[] {sol1, sol2}, travelTime, releaseDates, dueDates, new int[][] {}, new int[4], vehicleTravelTime, new int[2][2], new int[2], new int[2]); }