diff --git a/jsprit-core/src/main/java/algorithms/CalculatesVehTypeDepServiceInsertion.java b/jsprit-core/src/main/java/algorithms/CalculatesVehTypeDepServiceInsertion.java index 91bd5ebe..445b537c 100644 --- a/jsprit-core/src/main/java/algorithms/CalculatesVehTypeDepServiceInsertion.java +++ b/jsprit-core/src/main/java/algorithms/CalculatesVehTypeDepServiceInsertion.java @@ -61,16 +61,23 @@ final class CalculatesVehTypeDepServiceInsertion implements JobInsertionCalculat InsertionData bestIData = InsertionData.noInsertionFound(); double bestKnownCost_ = bestKnownCost; Collection relevantVehicles = new ArrayList(); - if(!(selectedVehicle instanceof NoVehicle)) relevantVehicles.add(selectedVehicle); - for(TypeKey typeKey : fleetManager.getAvailableVehicleTypes()){ - if(!(currentRoute.getVehicle() instanceof NoVehicle)){ - TypeKey key = makeTypeKey(currentRoute.getVehicle().getType(),currentRoute.getVehicle().getLocationId()); - if(typeKey.equals(key)){ - continue; - } - } - relevantVehicles.add(fleetManager.getEmptyVehicle(typeKey)); + if(!(selectedVehicle instanceof NoVehicle)) { + relevantVehicles.add(selectedVehicle); + relevantVehicles.addAll(fleetManager.getAvailableVehicle(selectedVehicle.getType().getTypeId(),selectedVehicle.getLocationId())); } + else{ + relevantVehicles.addAll(fleetManager.getAvailableVehicles()); + } +// +// for(TypeKey typeKey : fleetManager.getAvailableVehicleTypes()){ +// if(!(currentRoute.getVehicle() instanceof NoVehicle)){ +// TypeKey key = makeTypeKey(currentRoute.getVehicle().getType(),currentRoute.getVehicle().getLocationId()); +// if(typeKey.equals(key)){ +// continue; +// } +// } +// relevantVehicles.add(fleetManager.getEmptyVehicle(typeKey)); +// } for(Vehicle v : relevantVehicles){ double depTime = v.getEarliestDeparture(); InsertionData iData = insertionCalculator.calculate(currentRoute, jobToInsert, v, depTime, selectedDriver, bestKnownCost_); @@ -86,8 +93,8 @@ final class CalculatesVehTypeDepServiceInsertion implements JobInsertionCalculat return bestIData; } - private TypeKey makeTypeKey(VehicleType type, String locationId) { - return new TypeKey(type,locationId); - } +// private TypeKey makeTypeKey(VehicleType type, String locationId) { +// return new TypeKey(type,locationId); +// } } diff --git a/jsprit-core/src/main/java/algorithms/FindCheaperVehicleAlgo.java b/jsprit-core/src/main/java/algorithms/FindCheaperVehicleAlgo.java index ca3415ef..61c97d67 100644 --- a/jsprit-core/src/main/java/algorithms/FindCheaperVehicleAlgo.java +++ b/jsprit-core/src/main/java/algorithms/FindCheaperVehicleAlgo.java @@ -72,7 +72,7 @@ final class FindCheaperVehicleAlgo { if(vehicleRoute.getTourActivities() == null || vehicleRoute.getVehicle() == null){ return vehicleRoute; } - Collection availableVehicleTypes = fleetManager.getAvailableVehicleTypes(new TypeKey(vehicleRoute.getVehicle().getType(),vehicleRoute.getVehicle().getLocationId())); +// Collection availableVehicleTypes = fleetManager.getAvailableVehicleTypes(new TypeKey(vehicleRoute.getVehicle().getType(),vehicleRoute.getVehicle().getLocationId())); double bestSaving = 0.0; Vehicle bestVehicle = null; List path = new ArrayList(); @@ -80,8 +80,8 @@ final class FindCheaperVehicleAlgo { path.addAll(vehicleRoute.getTourActivities().getActivities()); path.add(vehicleRoute.getEnd()); - for(TypeKey vehicleType : availableVehicleTypes){ - Vehicle vehicle = fleetManager.getEmptyVehicle(vehicleType); + for(Vehicle vehicle : fleetManager.getAvailableVehicle(vehicleRoute.getVehicle().getType().getTypeId(), vehicleRoute.getVehicle().getLocationId())){ +// Vehicle vehicle = fleetManager.getEmptyVehicle(vehicleType); if(vehicle.getType().typeId.equals(vehicleRoute.getVehicle().getType().typeId)){ continue; } diff --git a/jsprit-core/src/main/java/algorithms/InfiniteVehicles.java b/jsprit-core/src/main/java/algorithms/InfiniteVehicles.java index b214854d..0f8fe66c 100644 --- a/jsprit-core/src/main/java/algorithms/InfiniteVehicles.java +++ b/jsprit-core/src/main/java/algorithms/InfiniteVehicles.java @@ -22,8 +22,6 @@ package algorithms; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -33,20 +31,19 @@ import java.util.Set; import org.apache.log4j.Logger; import basics.route.Vehicle; -import basics.route.VehicleImpl.VehicleType; class InfiniteVehicles implements VehicleFleetManager{ - static class TypeKeyComparator implements Comparator{ - - @Override - public int compare(TypeKey k1, TypeKey k2) { - double k1_fix = k1.type.getVehicleCostParams().fix; - double k2_fix = k2.type.getVehicleCostParams().fix; - return (int)(k1_fix - k2_fix); - } - - } +// static class TypeKeyComparator implements Comparator{ +// +// @Override +// public int compare(TypeKey k1, TypeKey k2) { +// double k1_fix = k1.type.getVehicleCostParams().fix; +// double k2_fix = k2.type.getVehicleCostParams().fix; +// return (int)(k1_fix - k2_fix); +// } +// +// } private static Logger logger = Logger.getLogger(InfiniteVehicles.class); @@ -66,12 +63,12 @@ class InfiniteVehicles implements VehicleFleetManager{ private void extractTypes(Collection vehicles) { for(Vehicle v : vehicles){ - TypeKey typeKey = new TypeKey(v.getType(),v.getLocationId()); + TypeKey typeKey = new TypeKey(v.getType().getTypeId(),v.getLocationId()); types.put(typeKey,v); sortedTypes.add(typeKey); } - Collections.sort(sortedTypes, new TypeKeyComparator()); +// Collections.sort(sortedTypes, new TypeKeyComparator()); } @@ -112,4 +109,17 @@ class InfiniteVehicles implements VehicleFleetManager{ } + @Override + public Collection getAvailableVehicles() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Collection getAvailableVehicle( + String withoutThisType, String locationId) { + // TODO Auto-generated method stub + return null; + } + } diff --git a/jsprit-core/src/main/java/algorithms/VehicleFleetManager.java b/jsprit-core/src/main/java/algorithms/VehicleFleetManager.java index 8148c56f..099f1909 100644 --- a/jsprit-core/src/main/java/algorithms/VehicleFleetManager.java +++ b/jsprit-core/src/main/java/algorithms/VehicleFleetManager.java @@ -29,12 +29,12 @@ interface VehicleFleetManager { public static class TypeKey { - public final VehicleType type; + public final String type; public final String locationId; - public TypeKey(VehicleType type, String locationId) { + public TypeKey(String typeId, String locationId) { super(); - this.type = type; + this.type = typeId; this.locationId = locationId; } @@ -69,7 +69,8 @@ interface VehicleFleetManager { return false; return true; } - + + } @@ -87,4 +88,8 @@ interface VehicleFleetManager { public abstract void unlockAll(); + public abstract Collection getAvailableVehicles(); + + Collection getAvailableVehicle(String withoutThisType, String locationId); + } diff --git a/jsprit-core/src/main/java/algorithms/VehicleFleetManagerImpl.java b/jsprit-core/src/main/java/algorithms/VehicleFleetManagerImpl.java index a6f30556..3671e252 100644 --- a/jsprit-core/src/main/java/algorithms/VehicleFleetManagerImpl.java +++ b/jsprit-core/src/main/java/algorithms/VehicleFleetManagerImpl.java @@ -97,6 +97,10 @@ class VehicleFleetManagerImpl implements VehicleFleetManager { private Map typeMapOfAvailableVehicles; + private Map penaltyVehicles = new HashMap(); + +// private Map typeMapOfAvailablePenaltyVehicles; + public VehicleFleetManagerImpl(Collection vehicles) { super(); this.vehicles = vehicles; @@ -122,6 +126,7 @@ class VehicleFleetManagerImpl implements VehicleFleetManager { private void makeMap() { typeMapOfAvailableVehicles = new HashMap(); + penaltyVehicles = new HashMap(); for(Vehicle v : vehicles){ addVehicle(v); } @@ -131,18 +136,28 @@ class VehicleFleetManagerImpl implements VehicleFleetManager { if(v.getType() == null){ throw new IllegalStateException("vehicle needs type"); } -// String typeId = v.getType().typeId; - TypeKey typeKey = new TypeKey(v.getType(),v.getLocationId()); - if(!typeMapOfAvailableVehicles.containsKey(typeKey)){ - typeMapOfAvailableVehicles.put(typeKey, new TypeContainer(typeKey)); + String typeId = v.getType().typeId; + if(typeId.contains("penalty")){ + String[] typeIdTokens = typeId.split("#"); + TypeKey typeKey = new TypeKey(typeIdTokens[0],v.getLocationId()); + penaltyVehicles.put(typeKey, v); + } + else{ + TypeKey typeKey = new TypeKey(v.getType().getTypeId(),v.getLocationId()); + if(!typeMapOfAvailableVehicles.containsKey(typeKey)){ + typeMapOfAvailableVehicles.put(typeKey, new TypeContainer(typeKey)); + } + typeMapOfAvailableVehicles.get(typeKey).add(v); } - typeMapOfAvailableVehicles.get(typeKey).add(v); } private void removeVehicle(Vehicle v){ - TypeKey key = new TypeKey(v.getType(),v.getLocationId()); - if(typeMapOfAvailableVehicles.containsKey(key)){ - typeMapOfAvailableVehicles.get(key).remove(v); + //it might be better to introduce a class PenaltyVehicle + if(!v.getType().getTypeId().contains("penalty")){ + TypeKey key = new TypeKey(v.getType().getTypeId(),v.getLocationId()); + if(typeMapOfAvailableVehicles.containsKey(key)){ + typeMapOfAvailableVehicles.get(key).remove(v); + } } } @@ -168,10 +183,65 @@ class VehicleFleetManagerImpl implements VehicleFleetManager { if(!typeMapOfAvailableVehicles.get(key).isEmpty()){ types.add(key); } + else{ + + } } return types; } + /** + * Returns a collection of available vehicles. + * + *

If there is no vehicle with a certain type and location anymore, it looks up whether a penalty vehicle has been specified with + * this type and location. If so, it returns this penalty vehicle. If not, no vehicle with this type and location is returned. + */ + @Override + public Collection getAvailableVehicles() { + List vehicles = new ArrayList(); + for(TypeKey key : typeMapOfAvailableVehicles.keySet()){ + if(!typeMapOfAvailableVehicles.get(key).isEmpty()){ + vehicles.add(typeMapOfAvailableVehicles.get(key).getVehicle()); + } + else{ + if(penaltyVehicles.containsKey(key)){ + vehicles.add(penaltyVehicles.get(key)); + } + } + } + return vehicles; + } + + /** + * Returns a collection of available vehicles without vehicles with typeId 'withoutThisType' and locationId 'withThisLocation'. + * + *

If there is no vehicle with a certain type and location anymore, it looks up whether a penalty vehicle has been specified with + * this type and location. If so, it returns this penalty vehicle. If not, no vehicle with this type and location is returned. + * + * @param typeId to specify the typeId that should not be the returned collection + * @param locationId to specify the locationId that should not be in the returned collection + * @return collection of available vehicles without the vehicles that have the typeId 'withoutThisType' AND the locationId 'withThisLocation'. + */ + @Override + public Collection getAvailableVehicle(String withoutThisType, String withThisLocationId) { + List vehicles = new ArrayList(); + TypeKey thisKey = new TypeKey(withoutThisType,withThisLocationId); + for(TypeKey key : typeMapOfAvailableVehicles.keySet()){ + if(key.equals(thisKey)) continue; + if(!typeMapOfAvailableVehicles.get(key).isEmpty()){ + vehicles.add(typeMapOfAvailableVehicles.get(key).getVehicle()); + } + else{ + if(penaltyVehicles.containsKey(key)){ + vehicles.add(penaltyVehicles.get(key)); + } + } + } + return vehicles; + } + + + /* (non-Javadoc) * @see org.matsim.contrib.freight.vrp.basics.VehicleFleetManager#lock(org.matsim.contrib.freight.vrp.basics.Vehicle) */ @@ -217,6 +287,8 @@ class VehicleFleetManagerImpl implements VehicleFleetManager { return types; } + + /* (non-Javadoc) * @see org.matsim.contrib.freight.vrp.basics.VehicleFleetManager#isLocked(org.matsim.contrib.freight.vrp.basics.Vehicle) */ @@ -244,4 +316,6 @@ class VehicleFleetManagerImpl implements VehicleFleetManager { } + + } diff --git a/jsprit-core/src/test/java/algorithms/CalcVehicleTypeDependentServiceInsertionTest.java b/jsprit-core/src/test/java/algorithms/CalcVehicleTypeDependentServiceInsertionTest.java index 7f2ca681..e20f03d0 100644 --- a/jsprit-core/src/test/java/algorithms/CalcVehicleTypeDependentServiceInsertionTest.java +++ b/jsprit-core/src/test/java/algorithms/CalcVehicleTypeDependentServiceInsertionTest.java @@ -60,8 +60,8 @@ public class CalcVehicleTypeDependentServiceInsertionTest { fleetManager = mock(VehicleFleetManager.class); service = mock(Service.class); vehicleRoute = mock(VehicleRoute.class); - TypeKey typeKey1 = new TypeKey(veh1.getType(),veh1.getLocationId()); - TypeKey typeKey2 = new TypeKey(veh2.getType(),veh2.getLocationId()); + TypeKey typeKey1 = new TypeKey(veh1.getType().getTypeId(),veh1.getLocationId()); + TypeKey typeKey2 = new TypeKey(veh2.getType().getTypeId(),veh2.getLocationId()); when(fleetManager.getAvailableVehicleTypes()).thenReturn(Arrays.asList(typeKey1,typeKey2)); when(fleetManager.getEmptyVehicle(typeKey1)).thenReturn(veh1); when(fleetManager.getEmptyVehicle(typeKey2)).thenReturn(veh2); diff --git a/jsprit-core/src/test/java/algorithms/TestVehicleFleetManager.java b/jsprit-core/src/test/java/algorithms/TestVehicleFleetManager.java index f3e2333d..d64445df 100644 --- a/jsprit-core/src/test/java/algorithms/TestVehicleFleetManager.java +++ b/jsprit-core/src/test/java/algorithms/TestVehicleFleetManager.java @@ -61,7 +61,7 @@ public class TestVehicleFleetManager extends TestCase{ } public void testGetVehicle(){ - TypeKey typeKey = new TypeKey(v1.getType(),v1.getLocationId()); + TypeKey typeKey = new TypeKey(v1.getType().getTypeId(),v1.getLocationId()); Vehicle v = fleetManager.getEmptyVehicle(typeKey); assertEquals(v.getId(), v1.getId()); } @@ -87,10 +87,10 @@ public class TestVehicleFleetManager extends TestCase{ } public void testGetTypesWithout(){ - TypeKey typeKey = new TypeKey(v1.getType(),v1.getLocationId()); + TypeKey typeKey = new TypeKey(v1.getType().getTypeId(),v1.getLocationId()); Collection types = fleetManager.getAvailableVehicleTypes(typeKey); - assertEquals(new TypeKey(v2.getType(),v2.getLocationId()), types.iterator().next()); + assertEquals(new TypeKey(v2.getType().getTypeId(),v2.getLocationId()), types.iterator().next()); assertEquals(1, types.size()); }