diff --git a/src/main/assembly/assembly-release.xml b/src/main/assembly/assembly-release.xml index 4c23e958..101ad60c 100644 --- a/src/main/assembly/assembly-release.xml +++ b/src/main/assembly/assembly-release.xml @@ -1,34 +1,34 @@ - release - - - zip - + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + + + /libs/ + false + false + + + + + + ./scenarios/ + scenarios + + - - - ./scenarios/ - scenarios - - + + + / + ${project.build.directory}/${project.build.finalName}.jar + + - - - ${project.build.directory}/${project.build.finalName}.jar - / - - + + zip + - - - false - /libs/ - false - - + release diff --git a/src/main/java/org/matsim/freight/logistics/ForwardLogisticChainSchedulerImpl.java b/src/main/java/org/matsim/freight/logistics/ForwardLogisticChainSchedulerImpl.java index d5f5b42f..52eb84ac 100644 --- a/src/main/java/org/matsim/freight/logistics/ForwardLogisticChainSchedulerImpl.java +++ b/src/main/java/org/matsim/freight/logistics/ForwardLogisticChainSchedulerImpl.java @@ -20,167 +20,170 @@ package org.matsim.freight.logistics; -import org.matsim.freight.logistics.shipment.LSPShipment; -import org.matsim.api.core.v01.Id; - import java.util.ArrayList; +import org.matsim.api.core.v01.Id; +import org.matsim.freight.logistics.shipment.LSPShipment; /** - * .... - * Macht 3 Schritte: - * 1.) the LSPShipments are handed over to the first {@link LogisticChainElement} of their {@link LogisticChain} - * 2.) the neighbors, i.e. the predecessors and successors of all {@link LSPResource}s are determined - * 3.) the Resources are brought into the right sequence according to the algorithm. - *

- * When traversing this list of {@link LSPResource}s, the operations in - * each {@link LSPResource} are scheduled individually by calling their {@link LSPResourceScheduler}. + * .... Macht 3 Schritte: 1.) the LSPShipments are handed over to the first {@link + * LogisticChainElement} of their {@link LogisticChain} 2.) the neighbors, i.e. the predecessors and + * successors of all {@link LSPResource}s are determined 3.) the Resources are brought into the + * right sequence according to the algorithm. + * + *

When traversing this list of {@link LSPResource}s, the operations in each {@link LSPResource} + * are scheduled individually by calling their {@link LSPResourceScheduler}. */ /* package-private */ class ForwardLogisticChainSchedulerImpl implements LogisticChainScheduler { - /** - * The Resources are brought into the right sequence according to the algorithm. - * The result of this algorithm is a list of Resources that is later - * traversed from the front to the back, i.e. starting with the entry at index 0. In the algorithm, - * this list is called sortedResourceList. - */ - private final ArrayList sortedResourceList; - /** - * The determination of the neighborhood structure among the Resources resulted in the neighborList. - */ - private final ArrayList neighbourList; - private LSP lsp; - private int bufferTime; - - ForwardLogisticChainSchedulerImpl() { - this.sortedResourceList = new ArrayList<>(); - this.neighbourList = new ArrayList<>(); - } - - @Override - public void scheduleLogisticChain() { - insertShipmentsAtBeginning(); - setResourceNeighbours(); - sortResources(); - for (LSPResource resource : sortedResourceList) { - resource.schedule(bufferTime, lsp.getSelectedPlan() ); - } - } - - @Override - public void setEmbeddingContainer(LSP lsp) { - this.lsp = lsp; - } - - private void setResourceNeighbours() { - // internal data structure, try to ignore when looking from outside. kai/kai, jan'22 - neighbourList.clear(); - for (LSPResource resource : lsp.getResources()) { - ResourceNeighbours neighbours = new ResourceNeighbours(resource); - for (LogisticChainElement element : resource.getClientElements()) { - LogisticChainElement predecessor = element.getPreviousElement(); - LSPResource previousResource = predecessor.getResource(); - neighbours.addPredecessor(previousResource); - LogisticChainElement successor = element.getNextElement(); - LSPResource nextResource = successor.getResource(); - neighbours.addSuccessor(nextResource); - } - neighbourList.add(neighbours); - } - } - - private void sortResources() { - sortedResourceList.clear(); - while (!neighbourList.isEmpty()) { - for (ResourceNeighbours neighbours : neighbourList) { - if (allPredecessorsAlreadyScheduled(neighbours) && noSuccessorAlreadyScheduled(neighbours)) { - sortedResourceList.add(neighbours.resource); - neighbourList.remove(neighbours); - } - } - } - } - - private boolean allPredecessorsAlreadyScheduled(ResourceNeighbours neighbours) { - if (neighbours.predecessors.isEmpty()) { - return true; - } - - for (LSPResource predecessor : neighbours.predecessors) { - if (!sortedResourceList.contains(predecessor)) { - return true; - } - } - return false; - } - - private boolean noSuccessorAlreadyScheduled(ResourceNeighbours neighbours) { - if (neighbours.successors.isEmpty()) { - return true; - } - - for (LSPResource successor : neighbours.successors) { - if (!sortedResourceList.contains(successor)) { - return true; - } - } - return false; - } - - private void insertShipmentsAtBeginning() { - for (LogisticChain solution : lsp.getSelectedPlan().getLogisticChains()) { - LogisticChainElement firstElement = getFirstElement(solution); - assert firstElement != null; - for (Id lspShipmentId : solution.getShipmentIds()) { - var shipment = LSPUtils.findLspShipment(lsp, lspShipmentId); - assert shipment != null; - firstElement.getIncomingShipments().addShipment(shipment.getPickupTimeWindow().getStart(), shipment); - } - } - } - - private LogisticChainElement getFirstElement(LogisticChain solution) { - for (LogisticChainElement element : solution.getLogisticChainElements()) { - if (element.getPreviousElement() == null) { - return element; - } - } - return null; - } - - @Override - public void setBufferTime(int bufferTime) { - this.bufferTime = bufferTime; - } - - /** - * The relationship between different {@link LSPResource}s allows to handle various supply - * structures that the {@link LSP} might decide to maintain. Thus, a {@link LSPResource} can have several - * successors or predecessors or can be used by several different {@link LogisticChain}s. - * The neighborhood structure among the {@link LSPResource}s is stored in instances of the class - * {@link ResourceNeighbours} which contain references on the considered {@link LSPResource} and on the set - * of immediate successors respective predecessors. As the result of this step, a collection of - * {@link ResourceNeighbours} called neighborList is created that contains the neighbors of all - * {@link LSPResource}s in the plan of the considered {@link LSP}. - */ - private static class ResourceNeighbours { - // internal data structure, try to ignore when looking from outside. kai/kai, jan'22 - - private final ArrayList predecessors; - private final ArrayList successors; - private final LSPResource resource; - - private ResourceNeighbours(LSPResource resource) { - this.resource = resource; - this.predecessors = new ArrayList<>(); - this.successors = new ArrayList<>(); - } - - private void addPredecessor(LSPResource resource) { - this.predecessors.add(resource); - } - - private void addSuccessor(LSPResource resource) { - this.successors.add(resource); - } - } + /** + * The Resources are brought into the right sequence according to the algorithm. The result of + * this algorithm is a list of Resources that is later traversed from the front to the back, i.e. + * starting with the entry at index 0. In the algorithm, this list is called sortedResourceList. + */ + private final ArrayList sortedResourceList; + + /** + * The determination of the neighborhood structure among the Resources resulted in the + * neighborList. + */ + private final ArrayList neighbourList; + + private LSP lsp; + private int bufferTime; + + ForwardLogisticChainSchedulerImpl() { + this.sortedResourceList = new ArrayList<>(); + this.neighbourList = new ArrayList<>(); + } + + @Override + public void scheduleLogisticChain() { + insertShipmentsAtBeginning(); + setResourceNeighbours(); + sortResources(); + for (LSPResource resource : sortedResourceList) { + resource.schedule(bufferTime, lsp.getSelectedPlan()); + } + } + + @Override + public void setEmbeddingContainer(LSP lsp) { + this.lsp = lsp; + } + + private void setResourceNeighbours() { + // internal data structure, try to ignore when looking from outside. kai/kai, jan'22 + neighbourList.clear(); + for (LSPResource resource : lsp.getResources()) { + ResourceNeighbours neighbours = new ResourceNeighbours(resource); + for (LogisticChainElement element : resource.getClientElements()) { + LogisticChainElement predecessor = element.getPreviousElement(); + LSPResource previousResource = predecessor.getResource(); + neighbours.addPredecessor(previousResource); + LogisticChainElement successor = element.getNextElement(); + LSPResource nextResource = successor.getResource(); + neighbours.addSuccessor(nextResource); + } + neighbourList.add(neighbours); + } + } + + private void sortResources() { + sortedResourceList.clear(); + while (!neighbourList.isEmpty()) { + for (ResourceNeighbours neighbours : neighbourList) { + if (allPredecessorsAlreadyScheduled(neighbours) + && noSuccessorAlreadyScheduled(neighbours)) { + sortedResourceList.add(neighbours.resource); + neighbourList.remove(neighbours); + } + } + } + } + + private boolean allPredecessorsAlreadyScheduled(ResourceNeighbours neighbours) { + if (neighbours.predecessors.isEmpty()) { + return true; + } + + for (LSPResource predecessor : neighbours.predecessors) { + if (!sortedResourceList.contains(predecessor)) { + return true; + } + } + return false; + } + + private boolean noSuccessorAlreadyScheduled(ResourceNeighbours neighbours) { + if (neighbours.successors.isEmpty()) { + return true; + } + + for (LSPResource successor : neighbours.successors) { + if (!sortedResourceList.contains(successor)) { + return true; + } + } + return false; + } + + private void insertShipmentsAtBeginning() { + for (LogisticChain solution : lsp.getSelectedPlan().getLogisticChains()) { + LogisticChainElement firstElement = getFirstElement(solution); + assert firstElement != null; + for (Id lspShipmentId : solution.getShipmentIds()) { + var shipment = LSPUtils.findLspShipment(lsp, lspShipmentId); + assert shipment != null; + firstElement + .getIncomingShipments() + .addShipment(shipment.getPickupTimeWindow().getStart(), shipment); + } + } + } + + private LogisticChainElement getFirstElement(LogisticChain solution) { + for (LogisticChainElement element : solution.getLogisticChainElements()) { + if (element.getPreviousElement() == null) { + return element; + } + } + return null; + } + + @Override + public void setBufferTime(int bufferTime) { + this.bufferTime = bufferTime; + } + + /** + * The relationship between different {@link LSPResource}s allows to handle various supply + * structures that the {@link LSP} might decide to maintain. Thus, a {@link LSPResource} can have + * several successors or predecessors or can be used by several different {@link LogisticChain}s. + * The neighborhood structure among the {@link LSPResource}s is stored in instances of the class + * {@link ResourceNeighbours} which contain references on the considered {@link LSPResource} and + * on the set of immediate successors respective predecessors. As the result of this step, a + * collection of {@link ResourceNeighbours} called neighborList is created that contains the + * neighbors of all {@link LSPResource}s in the plan of the considered {@link LSP}. + */ + private static class ResourceNeighbours { + // internal data structure, try to ignore when looking from outside. kai/kai, jan'22 + + private final ArrayList predecessors; + private final ArrayList successors; + private final LSPResource resource; + + private ResourceNeighbours(LSPResource resource) { + this.resource = resource; + this.predecessors = new ArrayList<>(); + this.successors = new ArrayList<>(); + } + + private void addPredecessor(LSPResource resource) { + this.predecessors.add(resource); + } + + private void addSuccessor(LSPResource resource) { + this.successors.add(resource); + } + } } diff --git a/src/main/java/org/matsim/freight/logistics/HasBackpointer.java b/src/main/java/org/matsim/freight/logistics/HasBackpointer.java index a7c98fc4..73f97386 100644 --- a/src/main/java/org/matsim/freight/logistics/HasBackpointer.java +++ b/src/main/java/org/matsim/freight/logistics/HasBackpointer.java @@ -2,11 +2,11 @@ @SuppressWarnings("InterfaceMayBeAnnotatedFunctional") public interface HasBackpointer { - // In general, we set backpointers when we add to the container. + // In general, we set backpointers when we add to the container. - // yy maybe also have interface HasSettableBackpointer? - void setEmbeddingContainer(T pointer); + // yy maybe also have interface HasSettableBackpointer? + void setEmbeddingContainer(T pointer); -// T getEmbeddingContainer(); + // T getEmbeddingContainer(); } diff --git a/src/main/java/org/matsim/freight/logistics/HasLspShipmentId.java b/src/main/java/org/matsim/freight/logistics/HasLspShipmentId.java index 35fae734..7fe90472 100644 --- a/src/main/java/org/matsim/freight/logistics/HasLspShipmentId.java +++ b/src/main/java/org/matsim/freight/logistics/HasLspShipmentId.java @@ -18,7 +18,6 @@ * *********************************************************************** */ package org.matsim.freight.logistics; - import org.matsim.api.core.v01.Id; import org.matsim.freight.logistics.shipment.LSPShipment; @@ -27,7 +26,7 @@ */ public interface HasLspShipmentId { - String ATTRIBUTE_LSP_SHIPMENT_ID = "lspShipmentId"; - Id getLspShipmentId(); + String ATTRIBUTE_LSP_SHIPMENT_ID = "lspShipmentId"; + Id getLspShipmentId(); } diff --git a/src/main/java/org/matsim/freight/logistics/HasSimulationTrackers.java b/src/main/java/org/matsim/freight/logistics/HasSimulationTrackers.java index f89dc015..33ba5007 100644 --- a/src/main/java/org/matsim/freight/logistics/HasSimulationTrackers.java +++ b/src/main/java/org/matsim/freight/logistics/HasSimulationTrackers.java @@ -2,12 +2,13 @@ import java.util.Collection; -// One could say that the simulation trackers are the decorators that convert the data objects into behavioral objects. In core matsim, we instead -// create behavioral objects, which contain the data objects. E.g. MobsimAgent, DriverAgent, CarrierAgent, etc. kai, may'22 +// One could say that the simulation trackers are the decorators that convert the data objects into +// behavioral objects. In core matsim, we instead +// create behavioral objects, which contain the data objects. E.g. MobsimAgent, DriverAgent, +// CarrierAgent, etc. kai, may'22 public interface HasSimulationTrackers { - void addSimulationTracker(LSPSimulationTracker tracker); - - Collection> getSimulationTrackers(); + void addSimulationTracker(LSPSimulationTracker tracker); + Collection> getSimulationTrackers(); } diff --git a/src/main/java/org/matsim/freight/logistics/KnowsLSP.java b/src/main/java/org/matsim/freight/logistics/KnowsLSP.java index 1f9270ca..60a9c8ea 100644 --- a/src/main/java/org/matsim/freight/logistics/KnowsLSP.java +++ b/src/main/java/org/matsim/freight/logistics/KnowsLSP.java @@ -1,7 +1,7 @@ package org.matsim.freight.logistics; interface KnowsLSP { - void setLSP(LSP lsp); + LSP getLSP(); - LSP getLSP(); + void setLSP(LSP lsp); } diff --git a/src/main/java/org/matsim/freight/logistics/LSP.java b/src/main/java/org/matsim/freight/logistics/LSP.java index e153a513..e91ea87f 100644 --- a/src/main/java/org/matsim/freight/logistics/LSP.java +++ b/src/main/java/org/matsim/freight/logistics/LSP.java @@ -20,56 +20,46 @@ package org.matsim.freight.logistics; -import org.matsim.freight.logistics.shipment.LSPShipment; -import org.matsim.api.core.v01.population.HasPlansAndId; - import java.util.Collection; +import org.matsim.api.core.v01.population.HasPlansAndId; +import org.matsim.freight.logistics.shipment.LSPShipment; /** - * In the class library, the interface LSP has the following tasks: - * 1. Maintain one or several transport chains through which {@link LSPShipment}s are routed. - * 2. Assign {@link LSPShipment}s to the suitable transport chain. --> {@link ShipmentAssigner}. - * 3. Interact with the agents that embody the demand side of the freight transport market, if they are specified in the setting. - * 4. Coordinate carriers that are in charge of the physical transport. + * In the class library, the interface LSP has the following tasks: 1. Maintain one or several + * transport chains through which {@link LSPShipment}s are routed. 2. Assign {@link LSPShipment}s to + * the suitable transport chain. --> {@link ShipmentAssigner}. 3. Interact with the agents that + * embody the demand side of the freight transport market, if they are specified in the setting. 4. + * Coordinate carriers that are in charge of the physical transport. */ public interface LSP extends HasPlansAndId, HasSimulationTrackers { - /** - * yyyy does this have to be exposed? - */ - Collection getShipments(); - - /** - * ok (behavioral method) - */ - void scheduleLogisticChains(); - - - /** - * yyyy does this have to be exposed? - */ - Collection getResources(); + /** yyyy does this have to be exposed? */ + Collection getShipments(); + /** ok (behavioral method) */ + void scheduleLogisticChains(); - /** - * ok (behavioral method) - * - */ - void scoreSelectedPlan(); + /** yyyy does this have to be exposed? */ + Collection getResources(); + /** ok (behavioral method) */ + void scoreSelectedPlan(); - /** - * @param shipment ok (LSP needs to be told that it is responsible for shipment) - */ - void assignShipmentToLSP(LSPShipment shipment); + /** + * @param shipment ok (LSP needs to be told that it is responsible for shipment) + */ + void assignShipmentToLSP(LSPShipment shipment); -// void replan(ReplanningEvent arg0); -// -// /** -// * @deprecated -- It feels attractive to attach this to the "agent". A big disadvantage with this approach, however, is that -// * we cannot use injection ... since we cannot inject as many replanners as we have agents. (At least this is what I think.) yyyyyy So -// * this needs to be changed. kai, jul'22 yyyy Need to understand how this is done in core matsim. kai, jul'22 -// */ -// void setReplanner(LSPReplanner replanner); + // void replan(ReplanningEvent arg0); + // + // /** + // * @deprecated -- It feels attractive to attach this to the "agent". A big disadvantage with + // this approach, however, is that + // * we cannot use injection ... since we cannot inject as many replanners as we have agents. + // (At least this is what I think.) yyyyyy So + // * this needs to be changed. kai, jul'22 yyyy Need to understand how this is done in core + // matsim. kai, jul'22 + // */ + // void setReplanner(LSPReplanner replanner); -} +} diff --git a/src/main/java/org/matsim/freight/logistics/LSPCarrierResource.java b/src/main/java/org/matsim/freight/logistics/LSPCarrierResource.java index 1fdbcc63..1a26be79 100644 --- a/src/main/java/org/matsim/freight/logistics/LSPCarrierResource.java +++ b/src/main/java/org/matsim/freight/logistics/LSPCarrierResource.java @@ -24,6 +24,5 @@ public interface LSPCarrierResource extends LSPResource { - Carrier getCarrier(); - + Carrier getCarrier(); } diff --git a/src/main/java/org/matsim/freight/logistics/LSPConstants.java b/src/main/java/org/matsim/freight/logistics/LSPConstants.java index 5e743c78..1d9d1b7b 100644 --- a/src/main/java/org/matsim/freight/logistics/LSPConstants.java +++ b/src/main/java/org/matsim/freight/logistics/LSPConstants.java @@ -2,53 +2,52 @@ public abstract class LSPConstants { - public static final String LSPS_DEFINITIONS = "lspsDefinitions"; - public static final String LSPS = "LSPs"; - public static final String LSP = "lsp"; - public static final String HUB = "hub"; - public static final String LOCATION = "location"; - public static final String FIXED_COST = "fixedCost"; - public static final String SCHEDULER = "scheduler"; - public static final String CAPACITY_NEED_FIXED = "capacityNeedFixed"; - public static final String CAPACITY_NEED_LINEAR = "capacityNeedLinear"; - public static final String CARRIER = "carrier"; - public static final String ATTRIBUTES = "attributes"; - public static final String ATTRIBUTE = "attribute"; - public static final String CAPABILITIES = "capabilities"; - public static final String FLEET_SIZE = "fleetSize"; - public static final String VEHICLE = "vehicle"; - public static final String DEPOT_LINK_ID = "depotLinkId"; - public static final String TYPE_ID = "typeId"; - public static final String VEHICLE_EARLIEST_START = "earliestStart"; - public static final String VEHICLE_LATEST_END = "latestEnd"; - public static final String SHIPMENTS = "shipments"; - public static final String SHIPMENT = "shipment"; - public static final String ID = "id"; - public static final String FROM = "from"; - public static final String TO = "to"; - public static final String SIZE = "size"; - public static final String START_PICKUP = "startPickup"; - public static final String END_PICKUP = "endPickup"; - public static final String START_DELIVERY = "startDelivery"; - public static final String END_DELIVERY = "endDelivery"; - public static final String PICKUP_SERVICE_TIME = "pickupServiceTime"; - public static final String DELIVERY_SERVICE_TIME = "deliveryServiceTime"; - public static final String LSP_PLANS = "LspPlans"; - public static final String LSP_PLAN = "LspPlan"; - public static final String SCORE = "score"; - public static final String SELECTED = "selected"; - public static final String RESOURCES = "resources"; - public static final String LOGISTIC_CHAINS = "logisticChains"; - public static final String LOGISTIC_CHAIN = "logisticChain"; - public static final String LOGISTIC_CHAIN_ELEMENT = "logisticChainElement"; - public static final String SHIPMENT_PLANS = "shipmentPlans"; - public static final String SHIPMENT_PLAN = "shipmentPlan"; - public static final String SHIPMENT_ID = "shipmentId"; - public static final String CHAIN_ID = "chainId"; - public static final String ELEMENT = "element"; - public static final String TYPE = "type"; - public static final String START_TIME = "startTime"; - public static final String END_TIME = "endTime"; - public static final String RESOURCE_ID = "resourceId"; - + public static final String LSPS_DEFINITIONS = "lspsDefinitions"; + public static final String LSPS = "LSPs"; + public static final String LSP = "lsp"; + public static final String HUB = "hub"; + public static final String LOCATION = "location"; + public static final String FIXED_COST = "fixedCost"; + public static final String SCHEDULER = "scheduler"; + public static final String CAPACITY_NEED_FIXED = "capacityNeedFixed"; + public static final String CAPACITY_NEED_LINEAR = "capacityNeedLinear"; + public static final String CARRIER = "carrier"; + public static final String ATTRIBUTES = "attributes"; + public static final String ATTRIBUTE = "attribute"; + public static final String CAPABILITIES = "capabilities"; + public static final String FLEET_SIZE = "fleetSize"; + public static final String VEHICLE = "vehicle"; + public static final String DEPOT_LINK_ID = "depotLinkId"; + public static final String TYPE_ID = "typeId"; + public static final String VEHICLE_EARLIEST_START = "earliestStart"; + public static final String VEHICLE_LATEST_END = "latestEnd"; + public static final String SHIPMENTS = "shipments"; + public static final String SHIPMENT = "shipment"; + public static final String ID = "id"; + public static final String FROM = "from"; + public static final String TO = "to"; + public static final String SIZE = "size"; + public static final String START_PICKUP = "startPickup"; + public static final String END_PICKUP = "endPickup"; + public static final String START_DELIVERY = "startDelivery"; + public static final String END_DELIVERY = "endDelivery"; + public static final String PICKUP_SERVICE_TIME = "pickupServiceTime"; + public static final String DELIVERY_SERVICE_TIME = "deliveryServiceTime"; + public static final String LSP_PLANS = "LspPlans"; + public static final String LSP_PLAN = "LspPlan"; + public static final String SCORE = "score"; + public static final String SELECTED = "selected"; + public static final String RESOURCES = "resources"; + public static final String LOGISTIC_CHAINS = "logisticChains"; + public static final String LOGISTIC_CHAIN = "logisticChain"; + public static final String LOGISTIC_CHAIN_ELEMENT = "logisticChainElement"; + public static final String SHIPMENT_PLANS = "shipmentPlans"; + public static final String SHIPMENT_PLAN = "shipmentPlan"; + public static final String SHIPMENT_ID = "shipmentId"; + public static final String CHAIN_ID = "chainId"; + public static final String ELEMENT = "element"; + public static final String TYPE = "type"; + public static final String START_TIME = "startTime"; + public static final String END_TIME = "endTime"; + public static final String RESOURCE_ID = "resourceId"; } diff --git a/src/main/java/org/matsim/freight/logistics/LSPControlerListener.java b/src/main/java/org/matsim/freight/logistics/LSPControlerListener.java index bcbcab6e..01954cdf 100644 --- a/src/main/java/org/matsim/freight/logistics/LSPControlerListener.java +++ b/src/main/java/org/matsim/freight/logistics/LSPControlerListener.java @@ -20,10 +20,10 @@ package org.matsim.freight.logistics; - import jakarta.inject.Inject; -import org.matsim.freight.logistics.io.LSPPlanXmlWriter; -import org.matsim.freight.logistics.shipment.LSPShipment; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Nullable; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.Scenario; @@ -35,158 +35,164 @@ import org.matsim.core.events.handler.EventHandler; import org.matsim.freight.carriers.Carrier; import org.matsim.freight.carriers.CarrierPlanWriter; -import org.matsim.freight.carriers.CarriersUtils; import org.matsim.freight.carriers.Carriers; +import org.matsim.freight.carriers.CarriersUtils; import org.matsim.freight.carriers.controler.CarrierAgentTracker; +import org.matsim.freight.logistics.io.LSPPlanXmlWriter; +import org.matsim.freight.logistics.shipment.LSPShipment; -import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.List; - - -class LSPControlerListener implements BeforeMobsimListener, AfterMobsimListener, ScoringListener, - ReplanningListener, IterationStartsListener, IterationEndsListener, ShutdownListener { - private static final Logger log = LogManager.getLogger( LSPControlerListener.class ); - private final Scenario scenario; - private final List registeredHandlers = new ArrayList<>(); - - @Inject private EventsManager eventsManager; - @Inject private MatsimServices matsimServices; - @Inject private LSPScorerFactory lspScoringFunctionFactory; - @Inject @Nullable private LSPStrategyManager strategyManager; - @Inject private OutputDirectoryHierarchy controlerIO; - @Inject private CarrierAgentTracker carrierAgentTracker; - @Inject LSPControlerListener( Scenario scenario ) { - this.scenario = scenario; - } - - @Override - public void notifyBeforeMobsim(BeforeMobsimEvent event) { - LSPs lsps = LSPUtils.getLSPs(scenario); - - //TODO: Why do we add all simTrackers in every iteration beforeMobsim starts? - // Doing so results in a lot of "not adding eventsHandler since already added" warnings. - // @KN: Would it be possible to do it in (simulation) startup and therefor only oce? - for (LSP lsp : lsps.getLSPs().values()) { - ((LSPImpl) lsp).setScorer( lspScoringFunctionFactory.createScoringFunction() ); - - - // simulation trackers of lsp: - registerSimulationTrackers(lsp ); - - // simulation trackers of resources: - for (LSPResource resource : lsp.getResources()) { - registerSimulationTrackers(resource); - } - - // simulation trackers of shipments: - for (LSPShipment shipment : lsp.getShipments()) { - registerSimulationTrackers(shipment ); - } - - // simulation trackers of solutions: - for (LogisticChain solution : lsp.getSelectedPlan().getLogisticChains()) { - registerSimulationTrackers(solution ); - - // simulation trackers of solution elements: - for (LogisticChainElement element : solution.getLogisticChainElements()) { - registerSimulationTrackers(element ); - - // simulation trackers of resources: - registerSimulationTrackers(element.getResource() ); - - } - } - } - } - - private void registerSimulationTrackers( HasSimulationTrackers hasSimulationTrackers) { - // get all simulation trackers ... - for (LSPSimulationTracker simulationTracker : hasSimulationTrackers.getSimulationTrackers()) { - // ... register them ... - if (!registeredHandlers.contains(simulationTracker)) { - log.warn("adding eventsHandler: " + simulationTracker); - eventsManager.addHandler(simulationTracker); - registeredHandlers.add(simulationTracker); - matsimServices.addControlerListener(simulationTracker); - simulationTracker.setEventsManager( eventsManager ); - } else { - log.warn("not adding eventsHandler since already added: " + simulationTracker); - } - } - } - - - @Override - public void notifyReplanning(ReplanningEvent event) { - if ( strategyManager==null ) { - throw new RuntimeException( "You need to set LSPStrategyManager to something meaningful to run iterations." ); - } - - LSPs lsps = LSPUtils.getLSPs(scenario); - strategyManager.run(lsps.getLSPs().values(), event.getIteration(), event.getReplanningContext()); - - for (LSP lsp : lsps.getLSPs().values()) { - lsp.getSelectedPlan().getShipmentPlans().clear(); //clear ShipmentPlans to start with clear(n) state. Otherwise, some times were accumulating over the time. :( - lsp.scheduleLogisticChains(); - } - - //Update carriers in scenario and CarrierAgentTracker - carrierAgentTracker.getCarriers().getCarriers().clear(); - for (Carrier carrier : getCarriersFromLSP().getCarriers().values()) { - CarriersUtils.getCarriers(scenario).addCarrier(carrier); - carrierAgentTracker.getCarriers().addCarrier(carrier); - } - - } - - @Override - public void notifyScoring(ScoringEvent scoringEvent) { - for (LSP lsp : LSPUtils.getLSPs(scenario).getLSPs().values()) { - lsp.scoreSelectedPlan(); - } - // yyyyyy might make more sense to register the lsps directly as scoring controler listener (??) - } - - @Override - public void notifyAfterMobsim(AfterMobsimEvent event) { - } - - - Carriers getCarriersFromLSP() { - LSPs lsps = LSPUtils.getLSPs(scenario); - assert ! lsps.getLSPs().isEmpty(); - - Carriers carriers = new Carriers(); - for (LSP lsp : lsps.getLSPs().values()) { - LSPPlan selectedPlan = lsp.getSelectedPlan(); - for (LogisticChain solution : selectedPlan.getLogisticChains()) { - for (LogisticChainElement element : solution.getLogisticChainElements()) { - if( element.getResource() instanceof LSPCarrierResource carrierResource ) { - Carrier carrier = carrierResource.getCarrier(); - if (!carriers.getCarriers().containsKey(carrier.getId())) { - carriers.addCarrier(carrier); - } - } - } - } - } - return carriers; - } - - @Override - public void notifyIterationStarts(IterationStartsEvent event) { - } - - @Override - public void notifyIterationEnds(IterationEndsEvent event) { - new LSPPlanXmlWriter(LSPUtils.getLSPs(scenario)).write(controlerIO.getIterationFilename(event.getIteration(), "lsps.xml")); - } - - @Override - public void notifyShutdown(ShutdownEvent event) { - new LSPPlanXmlWriter(LSPUtils.getLSPs(scenario)).write(controlerIO.getOutputPath() + "/output_lsps.xml.gz"); - new CarrierPlanWriter(CarriersUtils.getCarriers(scenario)).write(controlerIO.getOutputPath() + "/output_carriers.xml.gz"); - } - +class LSPControlerListener + implements BeforeMobsimListener, + AfterMobsimListener, + ScoringListener, + ReplanningListener, + IterationStartsListener, + IterationEndsListener, + ShutdownListener { + private static final Logger log = LogManager.getLogger(LSPControlerListener.class); + private final Scenario scenario; + private final List registeredHandlers = new ArrayList<>(); + + @Inject private EventsManager eventsManager; + @Inject private MatsimServices matsimServices; + @Inject private LSPScorerFactory lspScoringFunctionFactory; + @Inject @Nullable private LSPStrategyManager strategyManager; + @Inject private OutputDirectoryHierarchy controlerIO; + @Inject private CarrierAgentTracker carrierAgentTracker; + + @Inject + LSPControlerListener(Scenario scenario) { + this.scenario = scenario; + } + + @Override + public void notifyBeforeMobsim(BeforeMobsimEvent event) { + LSPs lsps = LSPUtils.getLSPs(scenario); + + // TODO: Why do we add all simTrackers in every iteration beforeMobsim starts? + // Doing so results in a lot of "not adding eventsHandler since already added" warnings. + // @KN: Would it be possible to do it in (simulation) startup and therefor only oce? + for (LSP lsp : lsps.getLSPs().values()) { + ((LSPImpl) lsp).setScorer(lspScoringFunctionFactory.createScoringFunction()); + + // simulation trackers of lsp: + registerSimulationTrackers(lsp); + + // simulation trackers of resources: + for (LSPResource resource : lsp.getResources()) { + registerSimulationTrackers(resource); + } + + // simulation trackers of shipments: + for (LSPShipment shipment : lsp.getShipments()) { + registerSimulationTrackers(shipment); + } + + // simulation trackers of solutions: + for (LogisticChain solution : lsp.getSelectedPlan().getLogisticChains()) { + registerSimulationTrackers(solution); + + // simulation trackers of solution elements: + for (LogisticChainElement element : solution.getLogisticChainElements()) { + registerSimulationTrackers(element); + + // simulation trackers of resources: + registerSimulationTrackers(element.getResource()); + } + } + } + } + + private void registerSimulationTrackers(HasSimulationTrackers hasSimulationTrackers) { + // get all simulation trackers ... + for (LSPSimulationTracker simulationTracker : + hasSimulationTrackers.getSimulationTrackers()) { + // ... register them ... + if (!registeredHandlers.contains(simulationTracker)) { + log.warn("adding eventsHandler: " + simulationTracker); + eventsManager.addHandler(simulationTracker); + registeredHandlers.add(simulationTracker); + matsimServices.addControlerListener(simulationTracker); + simulationTracker.setEventsManager(eventsManager); + } else { + log.warn("not adding eventsHandler since already added: " + simulationTracker); + } + } + } + + @Override + public void notifyReplanning(ReplanningEvent event) { + if (strategyManager == null) { + throw new RuntimeException( + "You need to set LSPStrategyManager to something meaningful to run iterations."); + } + + LSPs lsps = LSPUtils.getLSPs(scenario); + strategyManager.run( + lsps.getLSPs().values(), event.getIteration(), event.getReplanningContext()); + + for (LSP lsp : lsps.getLSPs().values()) { + lsp.getSelectedPlan() + .getShipmentPlans() + .clear(); // clear ShipmentPlans to start with clear(n) state. Otherwise, some times were + // accumulating over the time. :( + lsp.scheduleLogisticChains(); + } + + // Update carriers in scenario and CarrierAgentTracker + carrierAgentTracker.getCarriers().getCarriers().clear(); + for (Carrier carrier : getCarriersFromLSP().getCarriers().values()) { + CarriersUtils.getCarriers(scenario).addCarrier(carrier); + carrierAgentTracker.getCarriers().addCarrier(carrier); + } + } + + @Override + public void notifyScoring(ScoringEvent scoringEvent) { + for (LSP lsp : LSPUtils.getLSPs(scenario).getLSPs().values()) { + lsp.scoreSelectedPlan(); + } + // yyyyyy might make more sense to register the lsps directly as scoring controler listener (??) + } + + @Override + public void notifyAfterMobsim(AfterMobsimEvent event) {} + + Carriers getCarriersFromLSP() { + LSPs lsps = LSPUtils.getLSPs(scenario); + assert !lsps.getLSPs().isEmpty(); + + Carriers carriers = new Carriers(); + for (LSP lsp : lsps.getLSPs().values()) { + LSPPlan selectedPlan = lsp.getSelectedPlan(); + for (LogisticChain solution : selectedPlan.getLogisticChains()) { + for (LogisticChainElement element : solution.getLogisticChainElements()) { + if (element.getResource() instanceof LSPCarrierResource carrierResource) { + Carrier carrier = carrierResource.getCarrier(); + if (!carriers.getCarriers().containsKey(carrier.getId())) { + carriers.addCarrier(carrier); + } + } + } + } + } + return carriers; + } + + @Override + public void notifyIterationStarts(IterationStartsEvent event) {} + + @Override + public void notifyIterationEnds(IterationEndsEvent event) { + new LSPPlanXmlWriter(LSPUtils.getLSPs(scenario)) + .write(controlerIO.getIterationFilename(event.getIteration(), "lsps.xml")); + } + + @Override + public void notifyShutdown(ShutdownEvent event) { + new LSPPlanXmlWriter(LSPUtils.getLSPs(scenario)) + .write(controlerIO.getOutputPath() + "/output_lsps.xml.gz"); + new CarrierPlanWriter(CarriersUtils.getCarriers(scenario)) + .write(controlerIO.getOutputPath() + "/output_carriers.xml.gz"); + } } diff --git a/src/main/java/org/matsim/freight/logistics/LSPDataObject.java b/src/main/java/org/matsim/freight/logistics/LSPDataObject.java index 6789e7d9..ff150a79 100644 --- a/src/main/java/org/matsim/freight/logistics/LSPDataObject.java +++ b/src/main/java/org/matsim/freight/logistics/LSPDataObject.java @@ -1,42 +1,45 @@ package org.matsim.freight.logistics; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Identifiable; import org.matsim.utils.objectattributes.attributable.Attributable; import org.matsim.utils.objectattributes.attributable.Attributes; import org.matsim.utils.objectattributes.attributable.AttributesImpl; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedList; - public class LSPDataObject implements HasSimulationTrackers, Attributable, Identifiable { - private final Collection> trackers = new LinkedList<>(); - private final Attributes attributes = new AttributesImpl(); - private final Id id; - - public LSPDataObject(Id id) { - this.id = id; - } - - @Override public final void addSimulationTracker( LSPSimulationTracker tracker ){ - this.trackers.add( tracker ); - tracker.setEmbeddingContainer( (T) this ); - // It may not be possible to do this without this cast. Since "this" only knows that it is at least an LSPDataObject, and only we - // know that it is truly of type T. kai, jun'22 - } - - @Override public final Collection> getSimulationTrackers(){ - return Collections.unmodifiableCollection( this.trackers ); - } - - @Override public final Attributes getAttributes() { - return attributes; - } - - @Override public final Id getId() { - return id; - } + private final Collection> trackers = new LinkedList<>(); + private final Attributes attributes = new AttributesImpl(); + private final Id id; + + public LSPDataObject(Id id) { + this.id = id; + } + + @Override + public final void addSimulationTracker(LSPSimulationTracker tracker) { + this.trackers.add(tracker); + tracker.setEmbeddingContainer((T) this); + // It may not be possible to do this without this cast. Since "this" only knows that it is at + // least an LSPDataObject, and only we + // know that it is truly of type T. kai, jun'22 + } + + @Override + public final Collection> getSimulationTrackers() { + return Collections.unmodifiableCollection(this.trackers); + } + + @Override + public final Attributes getAttributes() { + return attributes; + } + + @Override + public final Id getId() { + return id; + } } diff --git a/src/main/java/org/matsim/freight/logistics/LSPImpl.java b/src/main/java/org/matsim/freight/logistics/LSPImpl.java index 6293586f..530ef40b 100644 --- a/src/main/java/org/matsim/freight/logistics/LSPImpl.java +++ b/src/main/java/org/matsim/freight/logistics/LSPImpl.java @@ -20,146 +20,144 @@ package org.matsim.freight.logistics; -import org.matsim.freight.logistics.shipment.LSPShipment; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - import java.util.ArrayList; import java.util.Collection; import java.util.List; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.matsim.freight.logistics.shipment.LSPShipment; -/* package-private */class LSPImpl extends LSPDataObject implements LSP { - private static final Logger log = LogManager.getLogger(LSPImpl.class); - - private final Collection shipments; - private final ArrayList plans; - private final LogisticChainScheduler logisticChainScheduler; - private final Collection resources; - private LSPPlan selectedPlan; - private LSPScorer scorer; -// private LSPReplanner replanner; - - - LSPImpl(LSPUtils.LSPBuilder builder) { - super(builder.id); - this.shipments = new ArrayList<>(); - this.plans = new ArrayList<>(); - this.logisticChainScheduler = builder.logisticChainScheduler; - this.logisticChainScheduler.setEmbeddingContainer(this); - this.selectedPlan = builder.initialPlan; - this.selectedPlan.setLSP(this); - this.plans.add(builder.initialPlan); - this.resources = builder.resources; - } - - /** - * This is used from {@link LSPControlerListener} and not meant to be used from user code. Users should bind {@link LSPScorerFactory}. - */ - /* package-private */ void setScorer(LSPScorer scorer){ - this.scorer = scorer; - scorer.setEmbeddingContainer(this); - this.addSimulationTracker(scorer); - } - - public static LSPPlan copyPlan(LSPPlan plan2copy) { - List newPlanChains = new ArrayList<>(); - for (LogisticChain initialPlanChain : plan2copy.getLogisticChains()) { - LogisticChain newPlanChain = LSPUtils.LogisticChainBuilder.newInstance(initialPlanChain.getId()).build(); - newPlanChain.getLogisticChainElements().addAll(initialPlanChain.getLogisticChainElements()); - newPlanChain.getShipmentIds().addAll(initialPlanChain.getShipmentIds()); - newPlanChains.add(newPlanChain); - } - - - LSPPlan copiedPlan = LSPUtils.createLSPPlan(); - copiedPlan.setAssigner(plan2copy.getAssigner()); - copiedPlan.setLSP(plan2copy.getLSP()); - copiedPlan.setScore(plan2copy.getScore()); - copiedPlan.setType(plan2copy.getType()); - copiedPlan.getLogisticChains().addAll(newPlanChains); - return copiedPlan; - } - - @Override - public void scheduleLogisticChains() { - logisticChainScheduler.scheduleLogisticChain(); - } - - @Override - public boolean addPlan(LSPPlan plan) { - for (LogisticChain solution : plan.getLogisticChains()) { - for (LogisticChainElement element : solution.getLogisticChainElements()) { - if (!resources.contains(element.getResource())) { - resources.add(element.getResource()); - } - } - } - plan.setLSP(this); - return plans.add(plan); - } - - @Override - public LSPPlan createCopyOfSelectedPlanAndMakeSelected() { - LSPPlan newPlan = LSPImpl.copyPlan(this.selectedPlan); - this.setSelectedPlan(newPlan); - return newPlan; - } - - @Override - public ArrayList getPlans() { - return plans; - } - - @Override - public LSPPlan getSelectedPlan() { - return selectedPlan; - } - - @Override - public void setSelectedPlan(LSPPlan selectedPlan) { - if (!plans.contains(selectedPlan)) { - plans.add(selectedPlan); - } - this.selectedPlan = selectedPlan; - - } - - @Override - public boolean removePlan(LSPPlan plan) { - if (plans.contains(plan)) { - plans.remove(plan); - return true; - } else { - return false; - } - } - - @Override - public Collection getResources() { - return resources; - } - - public void scoreSelectedPlan() { - if (this.scorer != null) { - this.selectedPlan.setScore(scorer.getScoreForCurrentPlan() ); - } else { - throw new RuntimeException("trying to score the current LSP plan, but scorer is not set."); - } - } - - - @Override - public void assignShipmentToLSP(LSPShipment shipment) { -// shipment.setLspId(this.getId()); // und rückweg dann auch darüber und dann lsp.getselectedPlan.getShipment... - shipments.add(shipment); - for (LSPPlan lspPlan : plans) { - lspPlan.getAssigner().assignToPlan(lspPlan, shipment); - } - } - - @Override - public Collection getShipments() { - return this.shipments; - } - +/* package-private */ class LSPImpl extends LSPDataObject implements LSP { + private static final Logger log = LogManager.getLogger(LSPImpl.class); + + private final Collection shipments; + private final ArrayList plans; + private final LogisticChainScheduler logisticChainScheduler; + private final Collection resources; + private LSPPlan selectedPlan; + private LSPScorer scorer; + + // private LSPReplanner replanner; + + LSPImpl(LSPUtils.LSPBuilder builder) { + super(builder.id); + this.shipments = new ArrayList<>(); + this.plans = new ArrayList<>(); + this.logisticChainScheduler = builder.logisticChainScheduler; + this.logisticChainScheduler.setEmbeddingContainer(this); + this.selectedPlan = builder.initialPlan; + this.selectedPlan.setLSP(this); + this.plans.add(builder.initialPlan); + this.resources = builder.resources; + } + + public static LSPPlan copyPlan(LSPPlan plan2copy) { + List newPlanChains = new ArrayList<>(); + for (LogisticChain initialPlanChain : plan2copy.getLogisticChains()) { + LogisticChain newPlanChain = + LSPUtils.LogisticChainBuilder.newInstance(initialPlanChain.getId()).build(); + newPlanChain.getLogisticChainElements().addAll(initialPlanChain.getLogisticChainElements()); + newPlanChain.getShipmentIds().addAll(initialPlanChain.getShipmentIds()); + newPlanChains.add(newPlanChain); + } + + LSPPlan copiedPlan = LSPUtils.createLSPPlan(); + copiedPlan.setAssigner(plan2copy.getAssigner()); + copiedPlan.setLSP(plan2copy.getLSP()); + copiedPlan.setScore(plan2copy.getScore()); + copiedPlan.setType(plan2copy.getType()); + copiedPlan.getLogisticChains().addAll(newPlanChains); + return copiedPlan; + } + + /** + * This is used from {@link LSPControlerListener} and not meant to be used from user code. Users + * should bind {@link LSPScorerFactory}. + */ + /* package-private */ void setScorer(LSPScorer scorer) { + this.scorer = scorer; + scorer.setEmbeddingContainer(this); + this.addSimulationTracker(scorer); + } + + @Override + public void scheduleLogisticChains() { + logisticChainScheduler.scheduleLogisticChain(); + } + + @Override + public boolean addPlan(LSPPlan plan) { + for (LogisticChain solution : plan.getLogisticChains()) { + for (LogisticChainElement element : solution.getLogisticChainElements()) { + if (!resources.contains(element.getResource())) { + resources.add(element.getResource()); + } + } + } + plan.setLSP(this); + return plans.add(plan); + } + + @Override + public LSPPlan createCopyOfSelectedPlanAndMakeSelected() { + LSPPlan newPlan = LSPImpl.copyPlan(this.selectedPlan); + this.setSelectedPlan(newPlan); + return newPlan; + } + + @Override + public ArrayList getPlans() { + return plans; + } + + @Override + public LSPPlan getSelectedPlan() { + return selectedPlan; + } + + @Override + public void setSelectedPlan(LSPPlan selectedPlan) { + if (!plans.contains(selectedPlan)) { + plans.add(selectedPlan); + } + this.selectedPlan = selectedPlan; + } + + @Override + public boolean removePlan(LSPPlan plan) { + if (plans.contains(plan)) { + plans.remove(plan); + return true; + } else { + return false; + } + } + + @Override + public Collection getResources() { + return resources; + } + + public void scoreSelectedPlan() { + if (this.scorer != null) { + this.selectedPlan.setScore(scorer.getScoreForCurrentPlan()); + } else { + throw new RuntimeException("trying to score the current LSP plan, but scorer is not set."); + } + } + + @Override + public void assignShipmentToLSP(LSPShipment shipment) { + // shipment.setLspId(this.getId()); // und rückweg dann auch darüber und dann + // lsp.getselectedPlan.getShipment... + shipments.add(shipment); + for (LSPPlan lspPlan : plans) { + lspPlan.getAssigner().assignToPlan(lspPlan, shipment); + } + } + + @Override + public Collection getShipments() { + return this.shipments; + } } diff --git a/src/main/java/org/matsim/freight/logistics/LSPModule.java b/src/main/java/org/matsim/freight/logistics/LSPModule.java index 1f581551..afe76ac6 100644 --- a/src/main/java/org/matsim/freight/logistics/LSPModule.java +++ b/src/main/java/org/matsim/freight/logistics/LSPModule.java @@ -23,6 +23,7 @@ import com.google.inject.Provides; import jakarta.inject.Inject; import jakarta.inject.Singleton; +import java.util.List; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.Scenario; @@ -40,153 +41,207 @@ import org.matsim.core.replanning.ReplanningContext; import org.matsim.core.replanning.selectors.PlanSelector; import org.matsim.core.scoring.ScoringFunction; -import org.matsim.freight.carriers.FreightCarriersConfigGroup; import org.matsim.freight.carriers.Carrier; import org.matsim.freight.carriers.Carriers; +import org.matsim.freight.carriers.FreightCarriersConfigGroup; import org.matsim.freight.carriers.controler.*; -import java.util.List; - - public class LSPModule extends AbstractModule { - private static final Logger log = LogManager.getLogger(LSPModule.class); - -// private final FreightCarriersConfigGroup carrierConfig = new FreightCarriersConfigGroup(); - - @Override - public void install() { - FreightCarriersConfigGroup freightConfig = ConfigUtils.addOrGetModule(getConfig(), FreightCarriersConfigGroup.class); - - bind(LSPControlerListener.class).in(Singleton.class); - addControlerListenerBinding().to(LSPControlerListener.class); - - bind(CarrierControlerListener.class).in( Singleton.class ); - addControlerListenerBinding().to(CarrierControlerListener.class); - - bind( CarrierAgentTracker.class ).in( Singleton.class ); - addEventHandlerBinding().to( CarrierAgentTracker.class ); - - // this switches on certain qsim components: - QSimComponentsConfigGroup qsimComponents = ConfigUtils.addOrGetModule(getConfig(), QSimComponentsConfigGroup.class); - List abc = qsimComponents.getActiveComponents(); - abc.add(FreightAgentSource.COMPONENT_NAME); - switch (freightConfig.getTimeWindowHandling()) { - case ignore: - break; - case enforceBeginnings: -//// abc.add( WithinDayActivityReScheduling.COMPONENT_NAME ); - log.warn("LSP has never hedged against time window openings; this is probably wrong; but I don't know what to do ..."); -// break; - default: - throw new IllegalStateException("Unexpected value: " + freightConfig.getTimeWindowHandling()); - } - qsimComponents.setActiveComponents(abc); - - // this installs qsim components, which are switched on (or not) via the above syntax: - this.installQSimModule(new AbstractQSimModule() { - @Override - protected void configureQSim() { - this.bind(FreightAgentSource.class).in(Singleton.class); - this.addQSimComponentBinding(FreightAgentSource.COMPONENT_NAME).to(FreightAgentSource.class); - switch (freightConfig.getTimeWindowHandling()) { - case ignore: - break; - case enforceBeginnings: -//// this.addQSimComponentBinding(WithinDayActivityReScheduling.COMPONENT_NAME).to( WithinDayActivityReScheduling.class ); - log.warn("LSP has never hedged against time window openings; this is probably wrong; but I don't know what to do ..."); -// break; - default: - throw new IllegalStateException("Unexpected value: " + freightConfig.getTimeWindowHandling()); - } - } - }); - - // the scorers are necessary to run a zeroth iteration to the end: - bind( CarrierScoringFunctionFactory.class ).to( CarrierScoringFactoryDummyImpl.class ); - bind( LSPScorerFactory.class ).to( LSPScoringFunctionFactoryDummyImpl.class ); - - // for iterations, one needs to replace the following with something meaningful. If nothing else, there are "empty implementations" that do nothing. kai, jul'22 - bind( CarrierStrategyManager.class ).toProvider( ()->null ); - bind( LSPStrategyManager.class ).toProvider( ()->null ); - - this.addControlerListenerBinding().to( DumpLSPPlans.class ); - } - - @Provides Carriers provideCarriers(LSPControlerListener lspControlerListener ) { - return lspControlerListener.getCarriersFromLSP(); - } - - private static class LSPScoringFunctionFactoryDummyImpl implements LSPScorerFactory{ - @Override public LSPScorer createScoringFunction( ){ - return new LSPScorer(){ - @Override public double getScoreForCurrentPlan(){ - return Double.NEGATIVE_INFINITY; - } - @Override public void setEmbeddingContainer( LSP pointer ){ - } - }; - } - } - private static class CarrierScoringFactoryDummyImpl implements CarrierScoringFunctionFactory { - @Override public ScoringFunction createScoringFunction( Carrier carrier ){ - return new ScoringFunction(){ - @Override public void handleActivity( Activity activity ){ - } - @Override public void handleLeg( Leg leg ){ - } - @Override public void agentStuck( double time ){ - } - @Override public void addMoney( double amount ){ - } - @Override public void addScore( double amount ){ - } - @Override public void finish(){ - } - @Override public double getScore(){ - return Double.NEGATIVE_INFINITY; - } - @Override public void handleEvent( Event event ){ - } - }; - } - } - public static final class LSPStrategyManagerEmptyImpl implements LSPStrategyManager { - - @Override public void addStrategy( GenericPlanStrategy strategy, String subpopulation, double weight ){ - throw new RuntimeException( "not implemented" ); - } - @Override public void run( Iterable> persons, int iteration, ReplanningContext replanningContext ){ - log.warn("Running iterations without a strategy may lead to unclear results.");// "run" is possible, but will not do anything. kai, jul'22 - } - @Override public void setMaxPlansPerAgent( int maxPlansPerAgent ){ - throw new RuntimeException( "not implemented" ); - } - @Override public void addChangeRequest( int iteration, GenericPlanStrategy strategy, String subpopulation, double newWeight ){ - throw new RuntimeException( "not implemented" ); - } - @Override public void setPlanSelectorForRemoval( PlanSelector planSelector ){ - throw new RuntimeException( "not implemented" ); - } - @Override public List> getStrategies( String subpopulation ){ - throw new RuntimeException( "not implemented" ); - } - @Override public List getWeights( String subpopulation ){ - throw new RuntimeException( "not implemented" ); - } - } - - public static final class DumpLSPPlans implements BeforeMobsimListener { - @Inject Scenario scenario; - @Override public void notifyBeforeMobsim( BeforeMobsimEvent event ){ - LSPs lsps = LSPUtils.getLSPs( scenario ); - for( LSP lsp : lsps.getLSPs().values() ){ - log.warn("Dumping plan(s) of [LSP="+lsp.getId() + "] ; [No of plans=" + lsp.getPlans().size() + "]"); - for( LSPPlan plan : lsp.getPlans() ){ - log.warn( "[LSPPlan: " + plan.toString() + "]") ; - } - log.warn("Plan(s) of [LSP="+lsp.getId() + "] dumped."); - } - } - } - + private static final Logger log = LogManager.getLogger(LSPModule.class); + + // private final FreightCarriersConfigGroup carrierConfig = new FreightCarriersConfigGroup(); + + @Override + public void install() { + FreightCarriersConfigGroup freightConfig = + ConfigUtils.addOrGetModule(getConfig(), FreightCarriersConfigGroup.class); + + bind(LSPControlerListener.class).in(Singleton.class); + addControlerListenerBinding().to(LSPControlerListener.class); + + bind(CarrierControlerListener.class).in(Singleton.class); + addControlerListenerBinding().to(CarrierControlerListener.class); + + bind(CarrierAgentTracker.class).in(Singleton.class); + addEventHandlerBinding().to(CarrierAgentTracker.class); + + // this switches on certain qsim components: + QSimComponentsConfigGroup qsimComponents = + ConfigUtils.addOrGetModule(getConfig(), QSimComponentsConfigGroup.class); + List abc = qsimComponents.getActiveComponents(); + abc.add(FreightAgentSource.COMPONENT_NAME); + switch (freightConfig.getTimeWindowHandling()) { + case ignore: + break; + case enforceBeginnings: + //// abc.add( WithinDayActivityReScheduling.COMPONENT_NAME ); + log.warn( + "LSP has never hedged against time window openings; this is probably wrong; but I don't know what to do ..."); + // break; + default: + throw new IllegalStateException( + "Unexpected value: " + freightConfig.getTimeWindowHandling()); + } + qsimComponents.setActiveComponents(abc); + + // this installs qsim components, which are switched on (or not) via the above syntax: + this.installQSimModule( + new AbstractQSimModule() { + @Override + protected void configureQSim() { + this.bind(FreightAgentSource.class).in(Singleton.class); + this.addQSimComponentBinding(FreightAgentSource.COMPONENT_NAME) + .to(FreightAgentSource.class); + switch (freightConfig.getTimeWindowHandling()) { + case ignore: + break; + case enforceBeginnings: + //// + // this.addQSimComponentBinding(WithinDayActivityReScheduling.COMPONENT_NAME).to( + // WithinDayActivityReScheduling.class ); + log.warn( + "LSP has never hedged against time window openings; this is probably wrong; but I don't know what to do ..."); + // break; + default: + throw new IllegalStateException( + "Unexpected value: " + freightConfig.getTimeWindowHandling()); + } + } + }); + + // the scorers are necessary to run a zeroth iteration to the end: + bind(CarrierScoringFunctionFactory.class).to(CarrierScoringFactoryDummyImpl.class); + bind(LSPScorerFactory.class).to(LSPScoringFunctionFactoryDummyImpl.class); + + // for iterations, one needs to replace the following with something meaningful. If nothing + // else, there are "empty implementations" that do nothing. kai, jul'22 + bind(CarrierStrategyManager.class).toProvider(() -> null); + bind(LSPStrategyManager.class).toProvider(() -> null); + + this.addControlerListenerBinding().to(DumpLSPPlans.class); + } + + @Provides + Carriers provideCarriers(LSPControlerListener lspControlerListener) { + return lspControlerListener.getCarriersFromLSP(); + } + + private static class LSPScoringFunctionFactoryDummyImpl implements LSPScorerFactory { + @Override + public LSPScorer createScoringFunction() { + return new LSPScorer() { + @Override + public double getScoreForCurrentPlan() { + return Double.NEGATIVE_INFINITY; + } + + @Override + public void setEmbeddingContainer(LSP pointer) {} + }; + } + } + + private static class CarrierScoringFactoryDummyImpl implements CarrierScoringFunctionFactory { + @Override + public ScoringFunction createScoringFunction(Carrier carrier) { + return new ScoringFunction() { + @Override + public void handleActivity(Activity activity) {} + + @Override + public void handleLeg(Leg leg) {} + + @Override + public void agentStuck(double time) {} + + @Override + public void addMoney(double amount) {} + + @Override + public void addScore(double amount) {} + + @Override + public void finish() {} + + @Override + public double getScore() { + return Double.NEGATIVE_INFINITY; + } + + @Override + public void handleEvent(Event event) {} + }; + } + } + + public static final class LSPStrategyManagerEmptyImpl implements LSPStrategyManager { + + @Override + public void addStrategy( + GenericPlanStrategy strategy, String subpopulation, double weight) { + throw new RuntimeException("not implemented"); + } + + @Override + public void run( + Iterable> persons, + int iteration, + ReplanningContext replanningContext) { + log.warn("Running iterations without a strategy may lead to unclear results."); // "run" is + // possible, but + // will not do + // anything. kai, + // jul'22 + } + + @Override + public void setMaxPlansPerAgent(int maxPlansPerAgent) { + throw new RuntimeException("not implemented"); + } + + @Override + public void addChangeRequest( + int iteration, + GenericPlanStrategy strategy, + String subpopulation, + double newWeight) { + throw new RuntimeException("not implemented"); + } + + @Override + public void setPlanSelectorForRemoval(PlanSelector planSelector) { + throw new RuntimeException("not implemented"); + } + + @Override + public List> getStrategies(String subpopulation) { + throw new RuntimeException("not implemented"); + } + + @Override + public List getWeights(String subpopulation) { + throw new RuntimeException("not implemented"); + } + } + + public static final class DumpLSPPlans implements BeforeMobsimListener { + @Inject Scenario scenario; + + @Override + public void notifyBeforeMobsim(BeforeMobsimEvent event) { + LSPs lsps = LSPUtils.getLSPs(scenario); + for (LSP lsp : lsps.getLSPs().values()) { + log.warn( + "Dumping plan(s) of [LSP=" + + lsp.getId() + + "] ; [No of plans=" + + lsp.getPlans().size() + + "]"); + for (LSPPlan plan : lsp.getPlans()) { + log.warn("[LSPPlan: " + plan.toString() + "]"); + } + log.warn("Plan(s) of [LSP=" + lsp.getId() + "] dumped."); + } + } + } } diff --git a/src/main/java/org/matsim/freight/logistics/LSPPlan.java b/src/main/java/org/matsim/freight/logistics/LSPPlan.java index 2acdbc0d..4f1f6fd5 100644 --- a/src/main/java/org/matsim/freight/logistics/LSPPlan.java +++ b/src/main/java/org/matsim/freight/logistics/LSPPlan.java @@ -20,36 +20,40 @@ package org.matsim.freight.logistics; +import java.util.Collection; +import org.matsim.api.core.v01.population.BasicPlan; import org.matsim.freight.logistics.shipment.LSPShipment; import org.matsim.freight.logistics.shipment.ShipmentPlan; -import org.matsim.api.core.v01.population.BasicPlan; - -import java.util.Collection; /** - * This interface has the following properties: