From b52a103ae5676e82eabf438cbb5671748e4b9260 Mon Sep 17 00:00:00 2001 From: Stefan Schroeder <4sschroeder@gmail.com> Date: Mon, 2 Dec 2013 17:42:51 +0100 Subject: [PATCH] finalize test with open-routes --- .../recreate/AuxilliaryCostCalculator.java | 42 ++----- .../TestAuxilliaryCostCalculator.java | 103 ++++++++++++++++++ ...alculatesServiceInsertionOnRouteLevel.java | 7 +- ...LocalActivityInsertionCostsCalculator.java | 87 +++++++++++++-- ...LevelActivityInsertionCostsCalculator.java | 7 -- .../input/bicycle_messenger_demand.txt | 31 ------ .../input/bicycle_messenger_supply.txt | 6 - .../jsprit/examples/BicycleMessenger.java | 87 --------------- 8 files changed, 192 insertions(+), 178 deletions(-) create mode 100644 jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestAuxilliaryCostCalculator.java delete mode 100644 jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestRouteLevelActivityInsertionCostsCalculator.java delete mode 100644 jsprit-examples/input/bicycle_messenger_demand.txt delete mode 100644 jsprit-examples/input/bicycle_messenger_supply.txt delete mode 100644 jsprit-examples/src/main/java/jsprit/examples/BicycleMessenger.java diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/AuxilliaryCostCalculator.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/AuxilliaryCostCalculator.java index 2ff04582..0010f9f5 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/AuxilliaryCostCalculator.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/AuxilliaryCostCalculator.java @@ -22,6 +22,7 @@ import java.util.List; import jsprit.core.problem.cost.VehicleRoutingActivityCosts; import jsprit.core.problem.cost.VehicleRoutingTransportCosts; import jsprit.core.problem.driver.Driver; +import jsprit.core.problem.solution.route.activity.End; import jsprit.core.problem.solution.route.activity.TourActivity; import jsprit.core.problem.vehicle.Vehicle; @@ -33,10 +34,10 @@ final class AuxilliaryCostCalculator { private final VehicleRoutingActivityCosts activityCosts; - public AuxilliaryCostCalculator(final VehicleRoutingTransportCosts routingCosts, final VehicleRoutingActivityCosts costFunction) { + public AuxilliaryCostCalculator(final VehicleRoutingTransportCosts routingCosts, final VehicleRoutingActivityCosts actCosts) { super(); this.routingCosts = routingCosts; - this.activityCosts = costFunction; + this.activityCosts = actCosts; } /** @@ -59,6 +60,11 @@ final class AuxilliaryCostCalculator { double departureTimePrevAct = depTime; while(actIter.hasNext()){ TourActivity act = actIter.next(); + if(act instanceof End){ + if(!vehicle.isReturnToDepot()){ + return cost; + } + } double transportCost = routingCosts.getTransportCost(prevAct.getLocationId(), act.getLocationId(), departureTimePrevAct, driver, vehicle); double transportTime = routingCosts.getTransportTime(prevAct.getLocationId(), act.getLocationId(), departureTimePrevAct, driver, vehicle); cost += transportCost; @@ -72,37 +78,5 @@ final class AuxilliaryCostCalculator { return cost; } - public double costOfPath(String startLocationId, final double startTime, final List path, String endLocationId, final Driver driver, final Vehicle vehicle){ - if(path.isEmpty()){ - return 0.0; - } - double cost = 0.0; -// Iterator actIter = path.iterator(); - String prevActLocation = startLocationId; -// TourActivity prevAct = actIter.next(); - double startCost = 0.0; - cost += startCost; - double departureTimePrevAct = startTime; - for(TourActivity act : path){ -// TourActivity act = actIter.next(); - double transportCost = routingCosts.getTransportCost(prevActLocation, act.getLocationId(), departureTimePrevAct, driver, vehicle); - double transportTime = routingCosts.getTransportTime(prevActLocation, act.getLocationId(), departureTimePrevAct, driver, vehicle); - cost += transportCost; - double actStartTime = departureTimePrevAct + transportTime; - double earliestOperationStartTime = Math.max(actStartTime, act.getTheoreticalEarliestOperationStartTime()); - double actEndTime = earliestOperationStartTime + act.getOperationTime(); - departureTimePrevAct = actEndTime; - cost += activityCosts.getActivityCost(act, actStartTime, driver, vehicle); - prevActLocation = act.getLocationId(); - } - - /* - *!!! ENDLOCATION - => Start u. End können primitiv sein. - - */ - - return cost; - } } diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestAuxilliaryCostCalculator.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestAuxilliaryCostCalculator.java new file mode 100644 index 00000000..f0bb4d5c --- /dev/null +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestAuxilliaryCostCalculator.java @@ -0,0 +1,103 @@ +package jsprit.core.algorithm.recreate; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Arrays; + +import jsprit.core.problem.cost.VehicleRoutingActivityCosts; +import jsprit.core.problem.cost.VehicleRoutingTransportCosts; +import jsprit.core.problem.solution.route.activity.End; +import jsprit.core.problem.solution.route.activity.TourActivity; +import jsprit.core.problem.vehicle.Vehicle; + +import org.junit.Before; +import org.junit.Test; + +public class TestAuxilliaryCostCalculator { + + private VehicleRoutingTransportCosts routingCosts; + + private VehicleRoutingActivityCosts actCosts; + + private Vehicle vehicle; + + @Before + public void doBefore(){ + vehicle = mock(Vehicle.class); + + routingCosts = mock(VehicleRoutingTransportCosts.class); + actCosts = mock(VehicleRoutingActivityCosts.class); + + when(routingCosts.getTransportCost("i", "j", 0.0, null, vehicle)).thenReturn(2.0); + when(routingCosts.getTransportTime("i", "j", 0.0, null, vehicle)).thenReturn(0.0); + when(routingCosts.getTransportCost("i", "k", 0.0, null, vehicle)).thenReturn(3.0); + when(routingCosts.getTransportTime("i", "k", 0.0, null, vehicle)).thenReturn(0.0); + when(routingCosts.getTransportCost("k", "j", 0.0, null, vehicle)).thenReturn(3.0); + when(routingCosts.getTransportTime("k", "j", 0.0, null, vehicle)).thenReturn(0.0); + } + + @Test + public void whenRouteIsClosed_itCalculatesCostUpToEnd_v1(){ + TourActivity prevAct = mock(TourActivity.class); + when(prevAct.getLocationId()).thenReturn("i"); + TourActivity nextAct = mock(TourActivity.class); + when(nextAct.getLocationId()).thenReturn("j"); + TourActivity newAct = mock(TourActivity.class); + when(newAct.getLocationId()).thenReturn("k"); + + when(vehicle.isReturnToDepot()).thenReturn(true); + + AuxilliaryCostCalculator aCalc = new AuxilliaryCostCalculator(routingCosts, actCosts); + double costs = aCalc.costOfPath(Arrays.asList(prevAct,newAct,nextAct), 0.0, null, vehicle); + assertEquals(6.0,costs,0.01); + } + + @Test + public void whenRouteIsClosed_itCalculatesCostUpToEnd_v2(){ + TourActivity prevAct = mock(TourActivity.class); + when(prevAct.getLocationId()).thenReturn("i"); + End nextAct = End.newInstance("j", 0.0, 0.0); + TourActivity newAct = mock(TourActivity.class); + when(newAct.getLocationId()).thenReturn("k"); + + when(vehicle.isReturnToDepot()).thenReturn(true); + + AuxilliaryCostCalculator aCalc = new AuxilliaryCostCalculator(routingCosts, actCosts); + double costs = aCalc.costOfPath(Arrays.asList(prevAct,newAct,nextAct), 0.0, null, vehicle); + assertEquals(6.0,costs,0.01); + } + + @Test + public void whenRouteIsOpen_itCalculatesCostUpToEnd_v1(){ + TourActivity prevAct = mock(TourActivity.class); + when(prevAct.getLocationId()).thenReturn("i"); + TourActivity nextAct = mock(TourActivity.class); + when(nextAct.getLocationId()).thenReturn("j"); + TourActivity newAct = mock(TourActivity.class); + when(newAct.getLocationId()).thenReturn("k"); + + when(vehicle.isReturnToDepot()).thenReturn(false); + + AuxilliaryCostCalculator aCalc = new AuxilliaryCostCalculator(routingCosts, actCosts); + double costs = aCalc.costOfPath(Arrays.asList(prevAct,newAct,nextAct), 0.0, null, vehicle); + assertEquals(6.0,costs,0.01); + } + + @Test + public void whenRouteIsOpen_itCalculatesCostUpToEnd_v2(){ + TourActivity prevAct = mock(TourActivity.class); + when(prevAct.getLocationId()).thenReturn("i"); + End nextAct = End.newInstance("j", 0.0, 0.0); + TourActivity newAct = mock(TourActivity.class); + when(newAct.getLocationId()).thenReturn("k"); + + when(vehicle.isReturnToDepot()).thenReturn(false); + + AuxilliaryCostCalculator aCalc = new AuxilliaryCostCalculator(routingCosts, actCosts); + double costs = aCalc.costOfPath(Arrays.asList(prevAct,newAct,nextAct), 0.0, null, vehicle); + assertEquals(3.0,costs,0.01); + } + +} diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestCalculatesServiceInsertionOnRouteLevel.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestCalculatesServiceInsertionOnRouteLevel.java index 0c621a74..141ed220 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestCalculatesServiceInsertionOnRouteLevel.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestCalculatesServiceInsertionOnRouteLevel.java @@ -83,12 +83,14 @@ public class TestCalculatesServiceInsertionOnRouteLevel { when(vehicle.getLocationId()).thenReturn("0,0"); when(vehicle.getEarliestDeparture()).thenReturn(0.0); when(vehicle.getLatestArrival()).thenReturn(100.0); + when(vehicle.isReturnToDepot()).thenReturn(true); newVehicle = mock(Vehicle.class); when(newVehicle.getCapacity()).thenReturn(1000); when(newVehicle.getLocationId()).thenReturn("0,0"); when(newVehicle.getEarliestDeparture()).thenReturn(0.0); when(newVehicle.getLatestArrival()).thenReturn(100.0); + when(newVehicle.isReturnToDepot()).thenReturn(true); driver = DriverImpl.noDriver(); @@ -240,10 +242,5 @@ public class TestCalculatesServiceInsertionOnRouteLevel { assertEquals(2, iData.getDeliveryInsertionIndex()); } - @Test - public void whenInsertingAndRouteIsOpen(){ - assertTrue(false); - } - } diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestLocalActivityInsertionCostsCalculator.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestLocalActivityInsertionCostsCalculator.java index 824a04ce..b391adfa 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestLocalActivityInsertionCostsCalculator.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestLocalActivityInsertionCostsCalculator.java @@ -1,8 +1,16 @@ package jsprit.core.algorithm.recreate; +import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import jsprit.core.algorithm.recreate.ActivityInsertionCostsCalculator.ActivityInsertionCosts; import jsprit.core.problem.cost.VehicleRoutingActivityCosts; import jsprit.core.problem.cost.VehicleRoutingTransportCosts; +import jsprit.core.problem.misc.JobInsertionContext; +import jsprit.core.problem.solution.route.VehicleRoute; +import jsprit.core.problem.solution.route.activity.End; +import jsprit.core.problem.solution.route.activity.TourActivity; +import jsprit.core.problem.vehicle.Vehicle; import org.junit.Before; import org.junit.Test; @@ -15,28 +23,91 @@ public class TestLocalActivityInsertionCostsCalculator { LocalActivityInsertionCostsCalculator calc; + Vehicle vehicle; + + VehicleRoute route; + + JobInsertionContext jic; + @Before public void doBefore(){ + + vehicle = mock(Vehicle.class); + route = mock(VehicleRoute.class); + when(route.isEmpty()).thenReturn(false); + when(route.getVehicle()).thenReturn(vehicle); + + jic = mock(JobInsertionContext.class); + when(jic.getRoute()).thenReturn(route); + when(jic.getNewVehicle()).thenReturn(vehicle); + tpCosts = mock(VehicleRoutingTransportCosts.class); + when(tpCosts.getTransportCost("i", "j", 0.0, null, vehicle)).thenReturn(2.0); + when(tpCosts.getTransportTime("i", "j", 0.0, null, vehicle)).thenReturn(0.0); + when(tpCosts.getTransportCost("i", "k", 0.0, null, vehicle)).thenReturn(3.0); + when(tpCosts.getTransportTime("i", "k", 0.0, null, vehicle)).thenReturn(0.0); + when(tpCosts.getTransportCost("k", "j", 0.0, null, vehicle)).thenReturn(3.0); + when(tpCosts.getTransportTime("k", "j", 0.0, null, vehicle)).thenReturn(0.0); + actCosts = mock(VehicleRoutingActivityCosts.class); calc = new LocalActivityInsertionCostsCalculator(tpCosts, actCosts); } @Test public void whenInsertingActBetweenTwoRouteActs_itCalcsMarginalTpCosts(){ - VehicleRoutingTransportCosts tpCosts = mock(VehicleRoutingTransportCosts.class); - VehicleRoutingActivityCosts actCosts = mock(VehicleRoutingActivityCosts.class); + TourActivity prevAct = mock(TourActivity.class); + when(prevAct.getLocationId()).thenReturn("i"); + TourActivity nextAct = mock(TourActivity.class); + when(nextAct.getLocationId()).thenReturn("j"); + TourActivity newAct = mock(TourActivity.class); + when(newAct.getLocationId()).thenReturn("k"); - LocalActivityInsertionCostsCalculator calc = new LocalActivityInsertionCostsCalculator(tpCosts, actCosts); - } - - @Test - public void whenInsertingActBeforeEndANDRouteIsOpen_itReturnsTransportCostsToLastAct(){ + when(vehicle.isReturnToDepot()).thenReturn(true); + ActivityInsertionCosts costs = calc.getCosts(jic, prevAct, nextAct, newAct, 0.0); + assertEquals(4.0,costs.getAdditionalCosts(),0.01); } @Test - public void whenInsertingActBeforeEndANDRouteIsClosed_itReturnsMarginalTpCosts(){ + public void whenInsertingActBetweenLastActAndEnd_itCalcsMarginalTpCosts(){ + TourActivity prevAct = mock(TourActivity.class); + when(prevAct.getLocationId()).thenReturn("i"); + End nextAct = End.newInstance("j", 0.0, 0.0); + TourActivity newAct = mock(TourActivity.class); + when(newAct.getLocationId()).thenReturn("k"); + when(vehicle.isReturnToDepot()).thenReturn(true); + + ActivityInsertionCosts costs = calc.getCosts(jic, prevAct, nextAct, newAct, 0.0); + assertEquals(4.0,costs.getAdditionalCosts(),0.01); + } + + @Test + public void whenInsertingActBetweenTwoRouteActsAndRouteIsOpen_itCalcsMarginalTpCosts(){ + TourActivity prevAct = mock(TourActivity.class); + when(prevAct.getLocationId()).thenReturn("i"); + TourActivity nextAct = mock(TourActivity.class); + when(nextAct.getLocationId()).thenReturn("j"); + TourActivity newAct = mock(TourActivity.class); + when(newAct.getLocationId()).thenReturn("k"); + + when(vehicle.isReturnToDepot()).thenReturn(false); + + ActivityInsertionCosts costs = calc.getCosts(jic, prevAct, nextAct, newAct, 0.0); + assertEquals(4.0,costs.getAdditionalCosts(),0.01); + } + + @Test + public void whenInsertingActBetweenLastActAndEndAndRouteIsOpen_itCalculatesTpCostsFromPrevToNewAct(){ + TourActivity prevAct = mock(TourActivity.class); + when(prevAct.getLocationId()).thenReturn("i"); + End nextAct = End.newInstance("j", 0.0, 0.0); + TourActivity newAct = mock(TourActivity.class); + when(newAct.getLocationId()).thenReturn("k"); + + when(vehicle.isReturnToDepot()).thenReturn(false); + + ActivityInsertionCosts costs = calc.getCosts(jic, prevAct, nextAct, newAct, 0.0); + assertEquals(3.0,costs.getAdditionalCosts(),0.01); } } diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestRouteLevelActivityInsertionCostsCalculator.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestRouteLevelActivityInsertionCostsCalculator.java deleted file mode 100644 index 55d4d9a1..00000000 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestRouteLevelActivityInsertionCostsCalculator.java +++ /dev/null @@ -1,7 +0,0 @@ -package jsprit.core.algorithm.recreate; - -public class TestRouteLevelActivityInsertionCostsCalculator { - - - -} diff --git a/jsprit-examples/input/bicycle_messenger_demand.txt b/jsprit-examples/input/bicycle_messenger_demand.txt deleted file mode 100644 index 42890e1b..00000000 --- a/jsprit-examples/input/bicycle_messenger_demand.txt +++ /dev/null @@ -1,31 +0,0 @@ -item id pickup_x pickup_y deliver_x deliver_y -envelope 1 13745 55419 13883 55756 -envelope 2 8406 53246 13937 55854 -envelope 3 15738 57396 35996 79499 -envelope 4 12045 60418 19349 57118 -envelope 5 13750 56416 35733 78403 -envelope 6 13190 57068 11860 59749 -envelope 7 15021 55768 14098 57379 -envelope 8 11513 58543 11501 59683 -envelope 9 12013 64155 14120 59301 -envelope 10 15006 57578 35511 78426 -envelope 11 11450 58819 11916 58338 -envelope 12 13728 56304 35524 79013 -envelope 13 15104 60923 17937 57066 -envelope 14 11373 58388 13983 53804 -envelope 15 18575 55186 18718 54381 -envelope 16 11639 50071 17363 58375 -envelope 17 11273 53410 10860 60441 -envelope 18 13766 59041 13963 57769 -envelope 19 16138 55801 16183 56024 -envelope 20 13728 56146 14301 61694 -envelope 21 12848 57059 13586 59734 -envelope 22 13645 56488 13955 55859 -envelope 23 12896 56838 13937 55908 -envelope 24 13341 58150 35709 78924 -envelope 25 13483 57303 13614 57820 -envelope 26 12741 63478 15230 59838 -envelope 27 14676 51691 16501 48361 -envelope 28 13748 54933 14120 56110 -envelope 29 17875 59565 20453 61903 -envelope 30 9772 56424 6404 55601 \ No newline at end of file diff --git a/jsprit-examples/input/bicycle_messenger_supply.txt b/jsprit-examples/input/bicycle_messenger_supply.txt deleted file mode 100644 index f25f8b66..00000000 --- a/jsprit-examples/input/bicycle_messenger_supply.txt +++ /dev/null @@ -1,6 +0,0 @@ -type id x y -messenger A 13750 57578 -messenger B 15104 53410 -messenger C 13728 55801 -messenger D 12741 63478 -messenger E 14676 18575 \ No newline at end of file diff --git a/jsprit-examples/src/main/java/jsprit/examples/BicycleMessenger.java b/jsprit-examples/src/main/java/jsprit/examples/BicycleMessenger.java deleted file mode 100644 index 123834d9..00000000 --- a/jsprit-examples/src/main/java/jsprit/examples/BicycleMessenger.java +++ /dev/null @@ -1,87 +0,0 @@ -package jsprit.examples; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.util.Collection; - -import jsprit.analysis.toolbox.Plotter; -import jsprit.analysis.toolbox.SolutionPrinter; -import jsprit.core.algorithm.VehicleRoutingAlgorithm; -import jsprit.core.algorithm.io.VehicleRoutingAlgorithms; -import jsprit.core.algorithm.termination.IterationWithoutImprovementTermination; -import jsprit.core.problem.VehicleRoutingProblem; -import jsprit.core.problem.VehicleRoutingProblem.Builder; -import jsprit.core.problem.VehicleRoutingProblem.FleetSize; -import jsprit.core.problem.job.Shipment; -import jsprit.core.problem.solution.VehicleRoutingProblemSolution; -import jsprit.core.problem.vehicle.Vehicle; -import jsprit.core.problem.vehicle.VehicleImpl; -import jsprit.core.problem.vehicle.VehicleType; -import jsprit.core.problem.vehicle.VehicleTypeImpl; -import jsprit.core.util.Coordinate; -import jsprit.core.util.Solutions; - -public class BicycleMessenger { - - /** - * @param args - * @throws IOException - */ - public static void main(String[] args) throws IOException { - - VehicleRoutingProblem.Builder problemBuilder = VehicleRoutingProblem.Builder.newInstance(); - readEnvelopes(problemBuilder); - readMessengers(problemBuilder); - problemBuilder.setFleetSize(FleetSize.FINITE); - - VehicleRoutingProblem bicycleMessengerProblem = problemBuilder.build(); - - VehicleRoutingAlgorithm algorithm = VehicleRoutingAlgorithms.readAndCreateAlgorithm(bicycleMessengerProblem, 6, "input/algorithmConfig_open.xml"); - algorithm.setPrematureAlgorithmTermination(new IterationWithoutImprovementTermination(50)); - Collection solutions = algorithm.searchSolutions(); - - SolutionPrinter.print(Solutions.bestOf(solutions)); - Plotter plotter = new Plotter(bicycleMessengerProblem); - plotter.plotShipments(true); - plotter.plot("output/bicycleMessengerProblem.png", "bicycleMenssenger"); - - - Plotter plotter1 = new Plotter(bicycleMessengerProblem, Solutions.bestOf(solutions)); - plotter1.plotShipments(false); - plotter1.plot("output/bicycleMessengerSolution.png", "bicycleMenssenger"); - - - } - - private static void readEnvelopes(Builder problemBuilder) throws IOException { - BufferedReader reader = new BufferedReader(new FileReader(new File("input/bicycle_messenger_demand.txt"))); - String line = null; - boolean firstLine = true; - while((line = reader.readLine()) != null){ - if(firstLine) { firstLine = false; continue; } - String[] tokens = line.split("\\s+"); - Shipment envelope = Shipment.Builder.newInstance(tokens[1], 1).setPickupCoord(Coordinate.newInstance(Double.parseDouble(tokens[2]), Double.parseDouble(tokens[3]))) - .setDeliveryCoord(Coordinate.newInstance(Double.parseDouble(tokens[4]), Double.parseDouble(tokens[5]))).build(); - problemBuilder.addJob(envelope); - } - reader.close(); - } - - private static void readMessengers(Builder problemBuilder) throws IOException { - BufferedReader reader = new BufferedReader(new FileReader(new File("input/bicycle_messenger_supply.txt"))); - String line = null; - boolean firstLine = true; - VehicleType messengerType = VehicleTypeImpl.Builder.newInstance("messengerType", 15).setCostPerDistance(1).build(); - while((line = reader.readLine()) != null){ - if(firstLine) { firstLine = false; continue; } - String[] tokens = line.split("\\s+"); - Vehicle vehicle = VehicleImpl.Builder.newInstance(tokens[1]).setLocationCoord(Coordinate.newInstance(Double.parseDouble(tokens[2]), Double.parseDouble(tokens[3]))) - .setReturnToDepot(false).setType(messengerType).build(); - problemBuilder.addVehicle(vehicle); - } - reader.close(); - } - -}