1
0
Fork 0
mirror of https://github.com/graphhopper/jsprit.git synced 2020-01-24 07:45:05 +01:00

Merge branch 'pickupAndDelivery' into PickupMergeRelaxAPI

Conflicts:
	jsprit-core/src/main/java/algorithms/BestInsertionBuilder.java
	jsprit-core/src/main/java/algorithms/VehicleRoutingAlgorithmFactoryImpl.java
	jsprit-core/src/test/java/algorithms/BuildPDVRPWithShipmentsAlgoFromScratchTest.java
	jsprit-core/src/test/resources/pdp_sol.xml
This commit is contained in:
Stefan Schroeder 2013-11-21 12:20:59 +01:00
commit a9da587f6a
35 changed files with 609 additions and 36828 deletions

View file

@ -23,24 +23,16 @@ import org.junit.Before;
import org.junit.Test;
import util.Solutions;
import algorithms.StateManager.StateImpl;
import algorithms.acceptors.AcceptNewIfBetterThanWorst;
import algorithms.selectors.SelectBest;
import basics.Delivery;
import basics.Job;
import basics.Pickup;
import basics.VehicleRoutingAlgorithm;
import basics.VehicleRoutingProblem;
import basics.VehicleRoutingProblemSolution;
import basics.algo.InsertionStartsListener;
import basics.algo.JobInsertedListener;
import basics.algo.SearchStrategy;
import basics.algo.SearchStrategyManager;
import basics.algo.SolutionCostCalculator;
import basics.io.VrpXMLReader;
import basics.route.InfiniteFleetManagerFactory;
import basics.route.ReverseRouteActivityVisitor;
import basics.route.RouteActivityVisitor;
import basics.route.VehicleFleetManager;
import basics.route.VehicleRoute;
@ -61,22 +53,16 @@ public class BuildPDVRPAlgoFromScratchTest {
final StateManager stateManager = new StateManager();
ConstraintManager actLevelConstraintAccumulator = new ConstraintManager(vrp,stateManager);
actLevelConstraintAccumulator.addConstraint(new ServiceLoadActivityLevelConstraint(stateManager));
actLevelConstraintAccumulator.addConstraint(new TimeWindowConstraint(stateManager, vrp.getTransportCosts()));
ActivityInsertionCostsCalculator marginalCalculus = new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts());
ServiceInsertionCalculator serviceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), marginalCalculus, new ServiceLoadRouteLevelConstraint(stateManager), actLevelConstraintAccumulator);
// CalculatesServiceInsertion serviceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), marginalCalculus, new HardConstraints.HardLoadConstraint(stateManager));
ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager);
constraintManager.addTimeWindowConstraint();
constraintManager.addLoadConstraint();
VehicleFleetManager fleetManager = new InfiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
JobInsertionCostsCalculator finalServiceInsertion = new VehicleTypeDependentJobInsertionCalculator(fleetManager, serviceInsertion);
BestInsertion bestInsertion = new BestInsertion(finalServiceInsertion);
BestInsertionBuilder iBuilder = new BestInsertionBuilder(vrp, fleetManager, stateManager, constraintManager);
// iBuilder.setConstraintManager(constraintManger);
InsertionStrategy bestInsertion = iBuilder.build();
RuinRadial radial = new RuinRadial(vrp, 0.15, new JobDistanceAvgCosts(vrp.getTransportCosts()));
RuinRandom random = new RuinRandom(vrp, 0.25);
@ -104,80 +90,14 @@ public class BuildPDVRPAlgoFromScratchTest {
strategyManager.addStrategy(radialStrategy, 0.5);
strategyManager.addStrategy(randomStrategy, 0.5);
vra = new VehicleRoutingAlgorithm(vrp, strategyManager);
vra.getAlgorithmListeners().addListener(stateManager);
final RouteActivityVisitor iterateForward = new RouteActivityVisitor();
iterateForward.addActivityVisitor(new UpdateActivityTimes(vrp.getTransportCosts()));
// iterateForward.addActivityVisitor(new UpdateEarliestStartTime(stateManager, vrp.getTransportCosts()));
iterateForward.addActivityVisitor(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
iterateForward.addActivityVisitor(new UpdateOccuredDeliveries(stateManager));
iterateForward.addActivityVisitor(new UpdateLoads(stateManager));
final ReverseRouteActivityVisitor iterateBackward = new ReverseRouteActivityVisitor();
iterateBackward.addActivityVisitor(new TimeWindowUpdater(stateManager, vrp.getTransportCosts()));
iterateBackward.addActivityVisitor(new UpdateFuturePickups(stateManager));
InsertionStartsListener loadVehicleInDepot = new InsertionStartsListener() {
@Override
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
for(VehicleRoute route : vehicleRoutes){
int loadAtDepot = 0;
int loadAtEnd = 0;
for(Job j : route.getTourActivities().getJobs()){
if(j instanceof Delivery){
loadAtDepot += j.getCapacityDemand();
}
if(j instanceof Pickup){
loadAtEnd += j.getCapacityDemand();
}
}
stateManager.putRouteState(route, StateFactory.LOAD_AT_BEGINNING, new StateImpl(loadAtDepot));
stateManager.putRouteState(route, StateFactory.LOAD, new StateImpl(loadAtEnd));
iterateForward.visit(route);
iterateBackward.visit(route);
}
}
};
vra.getSearchStrategyManager().addSearchStrategyModuleListener(new RemoveEmptyVehicles(fleetManager));
JobInsertedListener updateLoadAfterJobHasBeenInserted = new JobInsertedListener() {
@Override
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
// log.info("insert job " + job2insert.getClass().toString() + " job " + job2insert + "" + job2insert.getCapacityDemand() + " in route " + inRoute.getTourActivities());
if(job2insert instanceof Delivery){
int loadAtDepot = (int) stateManager.getRouteState(inRoute, StateFactory.LOAD_AT_BEGINNING).toDouble();
// log.info("loadAtDepot="+loadAtDepot);
stateManager.putRouteState(inRoute, StateFactory.LOAD_AT_BEGINNING, StateFactory.createState(loadAtDepot + job2insert.getCapacityDemand()));
}
if(job2insert instanceof Pickup){
int loadAtEnd = (int) stateManager.getRouteState(inRoute, StateFactory.LOAD_AT_END).toDouble();
// log.info("loadAtEnd="+loadAtEnd);
stateManager.putRouteState(inRoute, StateFactory.LOAD_AT_END, StateFactory.createState(loadAtEnd + job2insert.getCapacityDemand()));
}
iterateForward.visit(inRoute);
iterateBackward.visit(inRoute);
}
};
bestInsertion.addListener(loadVehicleInDepot);
bestInsertion.addListener(updateLoadAfterJobHasBeenInserted);
vra = new VehicleRoutingAlgorithmFactoryImpl(strategyManager, stateManager, fleetManager).createAlgorithm(vrp);
VehicleRoutingProblemSolution iniSolution = new InsertionInitialSolutionFactory(bestInsertion, solutionCostCalculator).createSolution(vrp);
// System.out.println("ini: costs="+iniSolution.getCost()+";#routes="+iniSolution.getRoutes().size());
vra.addInitialSolution(iniSolution);
vra.setNuOfIterations(10000);
vra.setPrematureBreak(1000);
vra.setNuOfIterations(1000);
vra.setPrematureBreak(100);
}

View file

@ -80,7 +80,7 @@ public class BuildPDVRPWithShipmentsAlgoFromScratchTest {
ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager);
constraintManager.addTimeWindowConstraint();
constraintManager.addLoadConstraint();
constraintManager.addConstraint(new HardPickupAndDeliveryShipmentActivityLevelConstraint(stateManager,true));
// constraintManager.addConstraint(new HardPickupAndDeliveryShipmentActivityLevelConstraint(stateManager));
VehicleFleetManager fleetManager = new InfiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
@ -88,6 +88,7 @@ public class BuildPDVRPWithShipmentsAlgoFromScratchTest {
executorService = Executors.newFixedThreadPool(nuOfThreads);
BestInsertionBuilder bestIBuilder = new BestInsertionBuilder(vrp, fleetManager, stateManager,constraintManager);
bestIBuilder.setConcurrentMode(executorService, nuOfThreads);
InsertionStrategy bestInsertion = bestIBuilder.build();
@ -139,20 +140,58 @@ public class BuildPDVRPWithShipmentsAlgoFromScratchTest {
strategyManager.addStrategy(randomStrategy, 0.5);
vra = new VehicleRoutingAlgorithmFactoryImpl(strategyManager, stateManager, fleetManager).createAlgorithm(vrp);
// vra.getAlgorithmListeners().addListener(stateManager);
// final RouteActivityVisitor iterateForward = new RouteActivityVisitor();
// iterateForward.addActivityVisitor(new UpdateActivityTimes(vrp.getTransportCosts()));
// iterateForward.addActivityVisitor(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
//
// iterateForward.addActivityVisitor(new UpdateOccuredDeliveries(stateManager));
//// vra.getAlgorithmListeners().addListener(stateManager);
//
//// final RouteActivityVisitor iterateForward = new RouteActivityVisitor();
//
//// iterateForward.addActivityVisitor(new UpdateActivityTimes(vrp.getTransportCosts()));
//// iterateForward.addActivityVisitor(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
////
//// iterateForward.addActivityVisitor(new UpdateOccuredDeliveries(stateManager));
//// iterateForward.addActivityVisitor(new UpdateLoads(stateManager));
////
//// final ReverseRouteActivityVisitor iterateBackward = new ReverseRouteActivityVisitor();
//// iterateBackward.addActivityVisitor(new TimeWindowUpdater(stateManager, vrp.getTransportCosts()));
//// iterateBackward.addActivityVisitor(new UpdateFuturePickups(stateManager));
////
//// JobInsertedListener updateWhenJobHasBeenInserted = new JobInsertedListener() {
////
//// @Override
//// public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
//// iterateForward.visit(inRoute);
//// iterateBackward.visit(inRoute);
//// }
////
//// };
////
//// InsertionStartsListener updateRoutesWhenInsertionStarts = new InsertionStartsListener() {
////
//// @Override
//// public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
//// for(VehicleRoute route : vehicleRoutes){
//// iterateForward.visit(route);
//// iterateBackward.visit(route);
//// }
////
//// }
//// };
//
//<<<<<<< HEAD
//// vra.getSearchStrategyManager().addSearchStrategyModuleListener(new RemoveEmptyVehicles(fleetManager));
//=======
// iterateForward.addActivityVisitor(new UpdatePrevMaxLoad(stateManager));
// iterateForward.addActivityVisitor(new UpdateLoads(stateManager));
//>>>>>>> branch 'PickupAndDelivery' of https://github.com/jsprit/jsprit.git
//
//<<<<<<< HEAD
//// bestInsertion.addListener(new UpdateLoads(stateManager));
//// bestInsertion.addListener(updateWhenJobHasBeenInserted);
//// bestInsertion.addListener(updateRoutesWhenInsertionStarts);
//=======
// final ReverseRouteActivityVisitor iterateBackward = new ReverseRouteActivityVisitor();
// iterateBackward.addActivityVisitor(new TimeWindowUpdater(stateManager, vrp.getTransportCosts()));
// iterateBackward.addActivityVisitor(new UpdateFuturePickups(stateManager));
// iterateBackward.addActivityVisitor(new UpdateMaxLoad(stateManager));
//
// JobInsertedListener updateWhenJobHasBeenInserted = new JobInsertedListener() {
//
@ -175,13 +214,14 @@ public class BuildPDVRPWithShipmentsAlgoFromScratchTest {
//
// }
// };
//
// vra.getSearchStrategyManager().addSearchStrategyModuleListener(new RemoveEmptyVehicles(fleetManager));
//
// bestInsertion.addListener(new UpdateLoads(stateManager));
// bestInsertion.addListener(updateWhenJobHasBeenInserted);
// bestInsertion.addListener(updateRoutesWhenInsertionStarts);
//>>>>>>> branch 'PickupAndDelivery' of https://github.com/jsprit/jsprit.git
//
VehicleRoutingProblemSolution iniSolution = new InsertionInitialSolutionFactory(bestInsertion, solutionCostCalculator).createSolution(vrp);
// System.out.println("ini: costs="+iniSolution.getCost()+";#routes="+iniSolution.getRoutes().size());
vra.addInitialSolution(iniSolution);

View file

@ -23,7 +23,7 @@ public class HardPickupAndDeliveryShipmentActivityConstraintTest {
Shipment shipment;
HardPickupAndDeliveryShipmentActivityLevelConstraint constraint;
PickupAndDeliverShipmentLoadActivityLevelConstraint constraint;
InsertionContext iFacts;
@ -35,7 +35,7 @@ public class HardPickupAndDeliveryShipmentActivityConstraintTest {
shipment = mock(Shipment.class);
when(shipment.getCapacityDemand()).thenReturn(1);
iFacts = new InsertionContext(null, null, vehicle, null, 0.0);
constraint = new HardPickupAndDeliveryShipmentActivityLevelConstraint(stateManager);
constraint = new PickupAndDeliverShipmentLoadActivityLevelConstraint(stateManager);
}
@Test

View file

@ -0,0 +1,135 @@
package algorithms;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import java.util.Arrays;
import org.junit.Before;
import org.junit.Test;
import util.Coordinate;
import util.Locations;
import util.ManhattanCosts;
import basics.Delivery;
import basics.Pickup;
import basics.Shipment;
import basics.VehicleRoutingProblem;
import basics.costs.VehicleRoutingActivityCosts;
import basics.costs.VehicleRoutingTransportCosts;
import basics.route.Driver;
import basics.route.DriverImpl;
import basics.route.TourActivity;
import basics.route.Vehicle;
import basics.route.VehicleImpl;
import basics.route.VehicleRoute;
import basics.route.VehicleType;
import basics.route.VehicleTypeImpl;
public class ServiceInsertionAndLoadConstraintsTest {
VehicleRoutingTransportCosts routingCosts;
VehicleRoutingActivityCosts activityCosts = new VehicleRoutingActivityCosts(){
@Override
public double getActivityCost(TourActivity tourAct, double arrivalTime,Driver driver, Vehicle vehicle) {
return 0;
}
};
HardActivityStateLevelConstraint hardActivityLevelConstraint = new HardActivityStateLevelConstraint() {
@Override
public ConstraintsStatus fulfilled(InsertionContext iFacts, TourActivity prevAct,TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
return ConstraintsStatus.FULFILLED;
}
};
HardRouteStateLevelConstraint hardRouteLevelConstraint = new HardRouteStateLevelConstraint(){
@Override
public boolean fulfilled(InsertionContext insertionContext) {
return true;
}
};
ActivityInsertionCostsCalculator activityInsertionCostsCalculator;
ShipmentInsertionCalculator insertionCalculator;
Vehicle vehicle;
@Before
public void doBefore(){
Locations locations = new Locations(){
@Override
public Coordinate getCoord(String id) {
//assume: locationId="x,y"
String[] splitted = id.split(",");
return Coordinate.newInstance(Double.parseDouble(splitted[0]),
Double.parseDouble(splitted[1]));
}
};
routingCosts = new ManhattanCosts(locations);
VehicleType type = VehicleTypeImpl.Builder.newInstance("t", 2).setCostPerDistance(1).build();
vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("0,0").setType(type).build();
activityInsertionCostsCalculator = new LocalActivityInsertionCostsCalculator(routingCosts, activityCosts);
createInsertionCalculator(hardRouteLevelConstraint);
}
private void createInsertionCalculator(HardRouteStateLevelConstraint hardRouteLevelConstraint) {
insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityInsertionCostsCalculator, hardRouteLevelConstraint, hardActivityLevelConstraint);
}
@Test
public void whenInsertingServiceWhileNoCapIsAvailable_itMustReturnTheCorrectInsertionIndex(){
Delivery delivery = (Delivery) Delivery.Builder.newInstance("del", 41).setLocationId("10,10").build();
Pickup pickup = (Pickup) Pickup.Builder.newInstance("pick", 15).setLocationId("0,10").build();
VehicleType type = VehicleTypeImpl.Builder.newInstance("t", 50).setCostPerDistance(1).build();
Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("0,0").setType(type).build();
VehicleRoute route = VehicleRoute.emptyRoute();
route.setVehicle(vehicle, 0.0);
Inserter inserter = new Inserter(new InsertionListeners());
inserter.insertJob(delivery, new InsertionData(0,0,0,vehicle,null), route);
// inserter.insertJob(shipment2, new InsertionData(0,1,2,vehicle,null), route);
// inserter.insertJob(shipment2, new InsertionData(0,1,2,vehicle,null), route);
StateManager stateManager = new StateManager();
// RouteActivityVisitor routeActVisitor = new RouteActivityVisitor();
// routeActVisitor.addActivityVisitor(new UpdateLoads(stateManager));
// routeActVisitor.visit(route);
VehicleRoutingProblem vrp = mock(VehicleRoutingProblem.class);
ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager);
constraintManager.addLoadConstraint();
// constraintManager.addConstraint(new PickupAndDeliverShipmentLoadActivityLevelConstraint(stateManager),Priority.CRITICAL);
// constraintManager.addConstraint(new ShipmentPickupsFirstConstraint(),Priority.CRITICAL);
stateManager.informInsertionStarts(Arrays.asList(route), null);
JobCalculatorSwitcher switcher = new JobCalculatorSwitcher();
ServiceInsertionCalculator serviceInsertionCalc = new ServiceInsertionCalculator(routingCosts, activityInsertionCostsCalculator, hardRouteLevelConstraint, constraintManager);
ShipmentInsertionCalculator insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityInsertionCostsCalculator, hardRouteLevelConstraint, constraintManager);
switcher.put(Pickup.class, serviceInsertionCalc);
switcher.put(Delivery.class, serviceInsertionCalc);
switcher.put(Shipment.class, insertionCalculator);
// Pickup service = (Pickup)Pickup.Builder.newInstance("pick", 1).setLocationId("5,5").build();
InsertionData iData = switcher.getInsertionData(route, pickup, vehicle, 0, DriverImpl.noDriver(), Double.MAX_VALUE);
// routeActVisitor.visit(route);
assertEquals(1, iData.getDeliveryInsertionIndex());
}
}

View file

@ -2,9 +2,9 @@ package algorithms;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.Arrays;
import org.junit.Before;
import org.junit.Test;
@ -12,7 +12,8 @@ import org.junit.Test;
import util.Coordinate;
import util.Locations;
import util.ManhattanCosts;
import algorithms.HardActivityStateLevelConstraint.ConstraintsStatus;
import algorithms.ConstraintManager.Priority;
import basics.Pickup;
import basics.Shipment;
import basics.VehicleRoutingProblem;
import basics.costs.VehicleRoutingActivityCosts;
@ -188,8 +189,9 @@ public class ShipmentInsertionCalculatorTest {
VehicleRoutingProblem vrp = mock(VehicleRoutingProblem.class);
ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager);
constraintManager.addConstraint(new HardPickupAndDeliveryShipmentActivityLevelConstraint(stateManager,true));
constraintManager.addConstraint(new PickupAndDeliverShipmentLoadActivityLevelConstraint(stateManager),Priority.CRITICAL);
constraintManager.addConstraint(new ShipmentPickupsFirstConstraint(),Priority.CRITICAL);
ShipmentInsertionCalculator insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityInsertionCostsCalculator,
hardRouteLevelConstraint, constraintManager);
@ -199,4 +201,48 @@ public class ShipmentInsertionCalculatorTest {
}
@Test
public void whenInsertingServiceWhileNoCapIsAvailable_itMustReturnNoInsertionData(){
Shipment shipment = Shipment.Builder.newInstance("s", 1).setPickupLocation("0,10").setDeliveryLocation("0,0").build();
Shipment shipment2 = Shipment.Builder.newInstance("s2", 1).setPickupLocation("10,10").setDeliveryLocation("0,0").build();
Shipment shipment3 = Shipment.Builder.newInstance("s3", 1).setPickupLocation("10,10").setDeliveryLocation("0,").build();
VehicleRoute route = VehicleRoute.emptyRoute();
route.setVehicle(vehicle, 0.0);
Inserter inserter = new Inserter(new InsertionListeners());
inserter.insertJob(shipment, new InsertionData(0,0,0,vehicle,null), route);
inserter.insertJob(shipment2, new InsertionData(0,1,2,vehicle,null), route);
// inserter.insertJob(shipment2, new InsertionData(0,1,2,vehicle,null), route);
StateManager stateManager = new StateManager();
// RouteActivityVisitor routeActVisitor = new RouteActivityVisitor();
// routeActVisitor.addActivityVisitor(new UpdateLoads(stateManager));
// routeActVisitor.visit(route);
VehicleRoutingProblem vrp = mock(VehicleRoutingProblem.class);
ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager);
constraintManager.addLoadConstraint();
// constraintManager.addConstraint(new PickupAndDeliverShipmentLoadActivityLevelConstraint(stateManager),Priority.CRITICAL);
// constraintManager.addConstraint(new ShipmentPickupsFirstConstraint(),Priority.CRITICAL);
stateManager.informInsertionStarts(Arrays.asList(route), null);
JobCalculatorSwitcher switcher = new JobCalculatorSwitcher();
ServiceInsertionCalculator serviceInsertionCalc = new ServiceInsertionCalculator(routingCosts, activityInsertionCostsCalculator, hardRouteLevelConstraint, constraintManager);
ShipmentInsertionCalculator insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityInsertionCostsCalculator, hardRouteLevelConstraint, constraintManager);
switcher.put(Pickup.class, serviceInsertionCalc);
switcher.put(Shipment.class, insertionCalculator);
Pickup service = (Pickup)Pickup.Builder.newInstance("pick", 1).setLocationId("5,5").build();
InsertionData iData = switcher.getInsertionData(route, service, vehicle, 0, DriverImpl.noDriver(), Double.MAX_VALUE);
// routeActVisitor.visit(route);
assertEquals(3, iData.getDeliveryInsertionIndex());
}
}

View file

@ -45,7 +45,7 @@ class UpdateStates implements JobInsertedListener, InsertionStartsListener{
routeActivityVisitor.addActivityVisitor(new UpdateActivityTimes(routingCosts));
routeActivityVisitor.addActivityVisitor(new UpdateVariableCosts(activityCosts, routingCosts, states));
routeActivityVisitor.addActivityVisitor(new UpdateLoads(states));
routeActivityVisitor.addActivityVisitor(new UpdateMaxLoad(states));
routeActivityVisitor.addActivityVisitor(new UpdateMaxLoad_(states));
revRouteActivityVisitor = new ReverseRouteActivityVisitor();
revRouteActivityVisitor.addActivityVisitor(new TimeWindowUpdater(states, routingCosts));
insertionListeners.addListener(new UpdateLoads(states));

View file

@ -1,10 +1,11 @@
package basics.route;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import org.junit.Test;
import basics.Shipment;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
public class VehicleRouteBuilderTest {

File diff suppressed because it is too large Load diff