From 4e1b7dce360c3db5bb120c9afcd1b8828f552272 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kub=C3=ADkov=C3=A1=2C=20Ad=C3=A9la?= Date: Mon, 22 Nov 2021 23:51:50 +0100 Subject: [PATCH 01/21] GreedyTASeT: raw implementation attempt #1 --- .../cz/cvut/fel/aic/simod/MainModule.java | 4 + .../fel/aic/simod/config/GreedyTASeT.java | 10 + .../fel/aic/simod/config/Ridesharing.java | 5 + .../ridesharing/DroppedDemandsAnalyzer.java | 60 +- .../RideSharingOnDemandVehicle.java | 4 + .../greedyTASeT/GreedyTASeTSolver.java | 659 ++++++++++++++++++ .../insertionheuristic/DriverPlan.java | 25 + .../AstarTravelTimeProvider.java | 20 +- .../greedyTASeT/GreedyTASeTSolverTest.java | 129 ++++ .../cz/cvut/fel/aic/simod/config/config.cfg | 4 +- 10 files changed, 896 insertions(+), 24 deletions(-) create mode 100644 src/main/java/cz/cvut/fel/aic/simod/config/GreedyTASeT.java create mode 100644 src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java create mode 100644 src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java diff --git a/src/main/java/cz/cvut/fel/aic/simod/MainModule.java b/src/main/java/cz/cvut/fel/aic/simod/MainModule.java index 15d96090..4785a7a4 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/MainModule.java +++ b/src/main/java/cz/cvut/fel/aic/simod/MainModule.java @@ -18,6 +18,7 @@ */ package cz.cvut.fel.aic.simod; +import cz.cvut.fel.aic.simod.ridesharing.greedyTASeT.GreedyTASeTSolver; import cz.cvut.fel.aic.simod.traveltimecomputation.DistanceMatrixTravelTimeProvider; import cz.cvut.fel.aic.simod.traveltimecomputation.TNRTravelTimeProvider; import cz.cvut.fel.aic.simod.traveltimecomputation.TNRAFTravelTimeProvider; @@ -146,6 +147,9 @@ protected void configureNext() { bind(SingleVehicleDARPSolver.class).to(ArrayOptimalVehiclePlanFinder.class); // bind(OptimalVehiclePlanFinder.class).to(PlanBuilderOptimalVehiclePlanFinder.class); break; + case "greedy-taset": + bind(DARPSolver.class).to(GreedyTASeTSolver.class); + break; } } else{ diff --git a/src/main/java/cz/cvut/fel/aic/simod/config/GreedyTASeT.java b/src/main/java/cz/cvut/fel/aic/simod/config/GreedyTASeT.java new file mode 100644 index 00000000..15cc7b14 --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/config/GreedyTASeT.java @@ -0,0 +1,10 @@ +package cz.cvut.fel.aic.simod.config; + +import java.util.Map; + +public class GreedyTASeT { + + public GreedyTASeT(Map greedytaset) { + + } +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/config/Ridesharing.java b/src/main/java/cz/cvut/fel/aic/simod/config/Ridesharing.java index a4408f2b..6a33f8f5 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/config/Ridesharing.java +++ b/src/main/java/cz/cvut/fel/aic/simod/config/Ridesharing.java @@ -1,5 +1,7 @@ package cz.cvut.fel.aic.simod.config; +import cz.cvut.fel.aic.simod.ridesharing.greedyTASeT.GreedyTASeTSolver; + import java.lang.Boolean; import java.lang.Double; import java.lang.Integer; @@ -7,6 +9,8 @@ import java.util.Map; public class Ridesharing { + public GreedyTASeT greedytaset; + public Vga vga; public Integer batchPeriod; @@ -28,6 +32,7 @@ public class Ridesharing { public Boolean on; public Ridesharing(Map ridesharing) { + this.greedytaset = new GreedyTASeT((Map) ridesharing.get("greedy_taset")); this.vga = new Vga((Map) ridesharing.get("vga")); this.batchPeriod = (Integer) ridesharing.get("batch_period"); this.method = (String) ridesharing.get("method"); diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/DroppedDemandsAnalyzer.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/DroppedDemandsAnalyzer.java index 5a341943..71d240b6 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/DroppedDemandsAnalyzer.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/DroppedDemandsAnalyzer.java @@ -46,38 +46,62 @@ public class DroppedDemandsAnalyzer { private final PositionUtil positionUtil; - private final double maxDistance; +// private final double maxDistance; + private final double maxDistance = 1000; protected final TravelTimeProvider travelTimeProvider; - private final int maxDelayTime; +// private final int maxDelayTime; + private final int maxDelayTime = 10; private final OnDemandvehicleStationStorage onDemandvehicleStationStorage; - - - + + + +// @Inject +// public DroppedDemandsAnalyzer( +// OnDemandVehicleStorage vehicleStorage, +// PositionUtil positionUtil, +// TravelTimeProvider travelTimeProvider, +// SimodConfig config, +// OnDemandvehicleStationStorage onDemandvehicleStationStorage, +// AgentpolisConfig agentpolisConfig) { +// this.vehicleStorage = vehicleStorage; +// this.positionUtil = positionUtil; +// this.travelTimeProvider = travelTimeProvider; +// this.onDemandvehicleStationStorage = onDemandvehicleStationStorage; +// this.config = config; +// +// // max distance in meters between vehicle and request for the vehicle to be considered to serve the request +// maxDistance = (double) config.ridesharing.maxProlongationInSeconds +// * agentpolisConfig.maxVehicleSpeedInMeters; +// +// // the traveltime from vehicle to request cannot be greater than max prolongation in milliseconds for the +// // vehicle to be considered to serve the request +// maxDelayTime = config.ridesharing.maxProlongationInSeconds * 1000; +// } @Inject public DroppedDemandsAnalyzer( - OnDemandVehicleStorage vehicleStorage, - PositionUtil positionUtil, - TravelTimeProvider travelTimeProvider, - SimodConfig config, + OnDemandVehicleStorage vehicleStorage, + PositionUtil positionUtil, + TravelTimeProvider travelTimeProvider, + SimodConfig config, OnDemandvehicleStationStorage onDemandvehicleStationStorage, AgentpolisConfig agentpolisConfig) { this.vehicleStorage = vehicleStorage; this.positionUtil = positionUtil; this.travelTimeProvider = travelTimeProvider; this.onDemandvehicleStationStorage = onDemandvehicleStationStorage; - this.config = config; - - // max distance in meters between vehicle and request for the vehicle to be considered to serve the request - maxDistance = (double) config.ridesharing.maxProlongationInSeconds - * agentpolisConfig.maxVehicleSpeedInMeters; - - // the traveltime from vehicle to request cannot be greater than max prolongation in milliseconds for the - // vehicle to be considered to serve the request - maxDelayTime = config.ridesharing.maxProlongationInSeconds * 1000; + this.config = config; + +// // max distance in meters between vehicle and request for the vehicle to be considered to serve the request +// maxDistance = (double) config.ridesharing.maxProlongationInSeconds +// * agentpolisConfig.maxVehicleSpeedInMeters; +// +// // the traveltime from vehicle to request cannot be greater than max prolongation in milliseconds for the +// // vehicle to be considered to serve the request +// maxDelayTime = config.ridesharing.maxProlongationInSeconds * 1000; } diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java index 3b385a7f..42bc048c 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java @@ -298,6 +298,10 @@ public VehicleTrip getCurrentTripPlan() { return currentTrip; } + public PlanAction getCurrentTask() { + return currentTask; + } + public boolean hasFreeCapacity() { return getFreeCapacity() > 0; } diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java new file mode 100644 index 00000000..dac42377 --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java @@ -0,0 +1,659 @@ +package cz.cvut.fel.aic.simod.ridesharing.greedyTASeT; + +import com.google.inject.Inject; +import com.sun.xml.internal.xsom.impl.scd.Iterators; +import cz.cvut.fel.aic.agentpolis.config.AgentpolisConfig; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.TimeProvider; +import cz.cvut.fel.aic.agentpolis.simmodel.activity.Drive; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.AgentPolisEntity; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.agentpolis.utils.Benchmark; +import cz.cvut.fel.aic.agentpolis.utils.PositionUtil; +import cz.cvut.fel.aic.alite.common.event.Event; +import cz.cvut.fel.aic.alite.common.event.EventHandler; +import cz.cvut.fel.aic.alite.common.event.EventProcessor; +import cz.cvut.fel.aic.alite.common.event.typed.TypedSimulation; +import cz.cvut.fel.aic.simod.config.SimodConfig; +import cz.cvut.fel.aic.simod.entity.DemandAgent; +import cz.cvut.fel.aic.simod.entity.OnDemandVehicleState; +import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicle; +import cz.cvut.fel.aic.simod.event.OnDemandVehicleEvent; +import cz.cvut.fel.aic.simod.io.SimulationNodeArrayConstructor; +import cz.cvut.fel.aic.simod.ridesharing.DARPSolver; +import cz.cvut.fel.aic.simod.ridesharing.DroppedDemandsAnalyzer; +import cz.cvut.fel.aic.simod.ridesharing.PlanCostProvider; +import cz.cvut.fel.aic.simod.ridesharing.RideSharingOnDemandVehicle; +import cz.cvut.fel.aic.simod.ridesharing.insertionheuristic.DriverPlan; +import cz.cvut.fel.aic.simod.ridesharing.insertionheuristic.InsertionHeuristicSolver; +import cz.cvut.fel.aic.simod.ridesharing.model.*; +import cz.cvut.fel.aic.simod.ridesharing.vga.model.Plan; +import cz.cvut.fel.aic.simod.storage.OnDemandVehicleStorage; +import cz.cvut.fel.aic.simod.storage.OnDemandvehicleStationStorage; +import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider; +import me.tongfei.progressbar.ProgressBar; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +public class GreedyTASeTSolver extends DARPSolver implements EventHandler { + + + private final TypedSimulation eventProcessor; + + private final SimodConfig config; + + private final TimeProvider timeProvider; + + private final PositionUtil positionUtil; + + private final DroppedDemandsAnalyzer droppedDemandsAnalyzer; + + private final OnDemandvehicleStationStorage onDemandvehicleStationStorage; + + private final double maxDistance = 100; + + private final double maxDistanceSquared = 10000; + + private final int maxDelayTime = 10; + + + //copied from insertionHeuristicSolver + private GreedyTASeTSolver.PlanData bestPlan; + + + + + + @Inject + public GreedyTASeTSolver( + OnDemandVehicleStorage vehicleStorage, + TravelTimeProvider travelTimeProvider, + PlanCostProvider travelCostProvider, + DefaultPlanComputationRequest.DefaultPlanComputationRequestFactory requestFactory, + TypedSimulation eventProcessor, + SimodConfig config, + TimeProvider timeProvider, + PositionUtil positionUtil, + DroppedDemandsAnalyzer droppedDemandsAnalyzer, + OnDemandvehicleStationStorage onDemandvehicleStationStorage, + AgentpolisConfig agentpolisConfig) { + super(vehicleStorage, travelTimeProvider, travelCostProvider, requestFactory); + this.eventProcessor = eventProcessor; + this.config = config; + this.timeProvider = timeProvider; + this.positionUtil = positionUtil; + this.droppedDemandsAnalyzer = droppedDemandsAnalyzer; + this.onDemandvehicleStationStorage = onDemandvehicleStationStorage; + + //TODO: resolve + // commented because config is null in test +// // max distance in meters between vehicle and request for the vehicle to be considered to serve the request +// maxDistance = (double) config.ridesharing.maxProlongationInSeconds +// * agentpolisConfig.maxVehicleSpeedInMeters; +// maxDistanceSquared = maxDistance * maxDistance; +// +// // the traveltime from vehicle to request cannot be greater than max prolongation in milliseconds for the +// // vehicle to be considered to serve the request +// maxDelayTime = config.ridesharing.maxProlongationInSeconds * 1000; + + setEventHandeling(); + } + + @Override + public EventProcessor getEventProcessor() { + return eventProcessor; + } + + @Override + public void handleEvent(Event event) { + + } + + private void setEventHandeling() { + List typesToHandle = new LinkedList<>(); + + typesToHandle.add(OnDemandVehicleEvent.PICKUP); + eventProcessor.addEventHandler(this, typesToHandle); + } + + + + /** + * Transfer-allowed scheduling solver + * @return Map + */ + @Override + public Map solve(List newRequests, List waitingRequests) { + Map planMap = new ConcurrentHashMap<>(); + List taxis = new ArrayList<>(); + AgentPolisEntity[] tVvehicles = vehicleStorage.getEntitiesForIteration(); + for(AgentPolisEntity tVvehicle: tVvehicles) { + RideSharingOnDemandVehicle vehicle = (RideSharingOnDemandVehicle) tVvehicle; + taxis.add(vehicle); + } + // TODO: fix it + List driverPlans = dispatch(taxis, newRequests); + for (int i = 0; i < driverPlans.size(); i++) { + planMap.put(taxis.get(i), driverPlans.get(i)); + } + return planMap; + } + + /** + * Transfer-allowed scheduling function + * @return + */ + private List dispatch(List taxis, List requests) { + List lst1 = dispatchVacantTaxi(taxis, requests); + List carpoolAcceptingTaxis = taxis; + List carpoolAcceptingPassengers = requests; + List lst2 = heuristics(carpoolAcceptingTaxis, carpoolAcceptingPassengers); + for(PlanComputationRequest request : requests) { + // TODO: check duplicates + // wtf + // is request in lst? + } + lst1.addAll(lst2); + return lst1; + } + + /** + * traditional taxi dispatch strategy that schedules taxis based on the shortest waiting time for the passengers + * @return + */ + private List dispatchVacantTaxi(List taxis, List requests) { + //taxi dispatch strategy that schedules taxis based on the shortest waiting time for the passengers + //TODO: implement method + //function can be changed to any dispatch strategy that a taxi company may currently be using (e.g., shortest waiting time and shortest cruising distance) + return null; + } + + + /** + * Greedy TASeT heuristics function + * @return + */ + private List heuristics(List taxis, List requests) { + //transfer points = charging stations + List transferPoints = new ArrayList<>(); + //TODO: fill transfer points + + //lookup table LT - LT [t][k] stores the earliest arrival time for taxi k to charging station t without violating the tolerable delay for k’s current passengers + int stationsCount = transferPoints.size(); + int taxisCount = taxis.size(); + long[][] LT = new long[stationsCount][taxisCount]; + //fill the LT table + for(int i = 0; i < taxisCount; i++) { + RideSharingOnDemandVehicle taxi = taxis.get(i); + SimulationNode taxiPosition = taxis.get(i).getPosition(); + List requestsOnBoard = taxi.getVehicle().getTransportedEntities(); + boolean taxiFree = taxi.hasFreeCapacity(); + for(int j = 0; j < stationsCount; j++) { + //timeProvider is set to null so getCurrentSimTime() wont work + //the idea is to fill LT with times of arrival of taxis +// LT[j][i] = this.timeProvider.getCurrentSimTime() + travelTime; + //check if taxi has free seat + if (!taxiFree) { + LT[j][i] = Long.MAX_VALUE; + } + else { + SimulationNode station = transferPoints.get(j); + long travelTime = this.travelTimeProvider.getExpectedTravelTime(taxiPosition, station); + //check if setting a new via point will exceed the tolerable delay for onboard passengers + if (checkTolerableDelay(requestsOnBoard, station, taxi)) { + LT[j][i] = travelTime; + } else { + LT[j][i] = Long.MAX_VALUE; + } + } + } + } + + //itinerary list + List itinerarylist = new ArrayList<>(); + + //we rank the requests in descending order by the number of taxis that are possible to pick them up in time (without considering transfer or destination) + //get possible taxis for every request and number of possible taxis + int[] possiblePickupTaxisCounts = new int[requests.size()]; + int i = 0; + Map> possiblePickupTaxisMap = new HashMap<>(); + for(PlanComputationRequest request : requests) { + int counter = 0; + List possiblePickupTaxisOneRequest = new ArrayList<>(); + for(RideSharingOnDemandVehicle t : taxis) { + if (canServeRequestTASeT(t, request)) { + counter++; + possiblePickupTaxisOneRequest.add(t); + } + } + possiblePickupTaxisCounts[i] = counter; + possiblePickupTaxisMap.put(request, possiblePickupTaxisOneRequest); + i++; + } + //sort R by the number of possible pickup taxis + List requestsCopy = new ArrayList<>(requests); + requests.sort(Comparator.comparing(x -> possiblePickupTaxisCounts[requestsCopy.indexOf(x)])); + //order to descending order + Collections.reverse(requests); + + + for(PlanComputationRequest request : requests) { + List templist = new ArrayList<>(); + + List canPickupRequestTaxis = possiblePickupTaxisMap.get(request); + for(RideSharingOnDemandVehicle taxi : canPickupRequestTaxis) { + DriverPlan posbitnry = findPlanWithNoTransfer(request, taxi); + templist.add(posbitnry); + //charge stations list = transferPoints + int stationIndex = 0; + for(SimulationNode station : transferPoints) { + // find k' = taxis that taxi k can transfer to at station + for(int k = 0; k < taxisCount; k++) + { + //not possible to transfer to + if(LT[stationIndex][k] == Long.MAX_VALUE) { + continue; + } else { + //TODO (check): get requestFactory and DemandAgent? + PlanActionPickup p = (PlanActionPickup) taxi.getCurrentTask(); + // split request to two requests with transfer point + DefaultPlanComputationRequest newRequest1 = requestFactory.create(0, request.getFrom(), + station, p.getRequest().getDemandAgent()); + DefaultPlanComputationRequest newRequest2 = requestFactory.create(1, station, + request.getTo(), p.getRequest().getDemandAgent()); + //find optimal plans for these two requests + DriverPlan itryp1 = findPlanWithNoTransfer(newRequest1, taxi); + DriverPlan itnryp2 = findPlanWithNoTransfer(newRequest2, taxis.get(k)); + // TODO: create Charge plan (TransferPlan) from itnryp1 and itnryp2 + // idea: transfer time = zjistim z LT tabulky + // create DriverPlan from itnryp1 and itnryp2, add transfer time between + // check constraints for DriverPlan + // if ok, +// templist.add(ZKONTROLOVANY PLAN); + } + } + stationIndex++; + } + } + // TODO: + // sort templist by delay and transfer time + // podobna funkce jako findItineraryWithMinimumDelay, akorat nevrati jeden DriverPlan, ale seradi je + // selected = itinerary with longest transfer time in the top β% shortest delay + // budu si nekde drzet transfer time pro kazdy DriverPlan (nebo request?) + // update k, k′ and LT +// itinerarylist.add(selected) + } + return itinerarylist; + } + + + /** + * Find DriverPlan with smallest delay without transfer allowed. + * @return valid DriverPlan with smallest delay. + */ + private DriverPlan findPlanWithNoTransfer(PlanComputationRequest newRequest, RideSharingOnDemandVehicle taxi) { + int n = taxi.getOnBoardCount(); + List lst = new ArrayList<>(); + DriverPlan currentPlan = taxi.getCurrentPlan(); + //add pickup and dropoff for new request + currentPlan.plan.add(newRequest.getPickUpAction()); + currentPlan.plan.add(newRequest.getDropOffAction()); + //get pickup order based on heuristic from TASeT paper + List pickups = currentPlan.getPickupActions(); + //get dropoff actions in currentPlan + List dropoffs = currentPlan.getDropoffActions(); + //permute dropoff orders + List> dropoffOrders = permute(dropoffs); + for (List dropoffPlan : dropoffOrders) { + lst.add(createItinerary(pickups, dropoffPlan)); + } + DriverPlan bestPlan = findItineraryWithMinimumDelay(lst); + return bestPlan; + + } + + /** + * Checks time constraints and counts delay among DriverPlans. + * @return valid DriverPlan with smallest delay. + */ + private DriverPlan findItineraryWithMinimumDelay(List plans) + { + long[] delays = new long[plans.size()]; + int index = 0; + for(DriverPlan driverPlan : plans) { + long time = 0; + long delay = 0; + // TODO: how to set (initialize) previousDestination? + SimulationNode previousDestination = driverPlan.plan.get(0).getPosition(); + + for (int i = 0; i < driverPlan.getLength(); i++) { + PlanAction action = driverPlan.plan.get(i); + if (action instanceof PlanRequestAction) { + PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); + if(action instanceof PlanActionPickup) { + PlanActionPickup pickup = (PlanActionPickup) action; + SimulationNode dest = pcq.getFrom(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if(!(time < pcq.getMaxPickupTime())) { + //not valid itinerary - check new driver plan + break; + } else { + //valid itinerary + delay = delay + (pcq.getMaxPickupTime() - time); + } + previousDestination = dest; + } + else if (action instanceof PlanActionDropoff) { + PlanActionDropoff dropoff = (PlanActionDropoff) action; + SimulationNode dest = pcq.getTo(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if(!(time < pcq.getMaxDropoffTime())) { + //not valid itinerary - check new driver plan + break; + } else { + delay = delay + (pcq.getMaxDropoffTime() - time); + } + previousDestination = dest; + } + } + } + // save delay to array + delays[index] = delay; + index++; + } + //find max in delay + int maxAt = 0; + for (int i = 0; i < delays.length; i++) { + maxAt = delays[i] > delays[maxAt] ? i : maxAt; + } + DriverPlan bestPlan = plans.get(maxAt); + return bestPlan; + } + + /** + * Creates new DriverPlan with pickups and dropoffs. + * @return new DriverPlan + */ + private DriverPlan createItinerary(List pickupOrder, List dropoffOrder) { + List listOfActionsOrdered = new LinkedList<>(pickupOrder); + listOfActionsOrdered.addAll(dropoffOrder); + return new DriverPlan(listOfActionsOrdered, 0, 0); + } + + /** + * @return new list with all permutations of PlanActrions from lst List. + */ + public List> permute(List lst) { + List> list = new ArrayList<>(); + permuteHelper(list, new ArrayList<>(), lst); + return list; + } + + /** + * Helper function for permute() + */ + private void permuteHelper(List> list, List resultList, List lst){ + // Base case + if(resultList.size() == lst.size()){ + list.add(new ArrayList<>(resultList)); + } + else{ + for(int i = 0; i < lst.size(); i++){ + if(resultList.contains(lst.get(i))) + { + // If element already exists in the list then skip + continue; + } + // Choose element + resultList.add(lst.get(i)); + // Explore + permuteHelper(list, resultList, lst); + // Unchoose element + resultList.remove(resultList.size() - 1); + } + } + } + + /** + * Checks if setting a new via point will exceed the tolerable delay for onboard passengers + * @return boolean + */ + private boolean checkTolerableDelay(List requestsOnBoard, SimulationNode viaPoint, RideSharingOnDemandVehicle taxi) { + //for every onboard passenger in taxi + for(PlanComputationRequest plan : requestsOnBoard) { + SimulationNode destination = plan.getTo(); + //get new time of arrival with new via point + //TODO (check): count new Arrival time + long newArrivalTime = timeProvider.getCurrentSimTime() + travelTimeProvider.getTravelTime(taxi, viaPoint) + travelTimeProvider.getTravelTime(taxi, viaPoint, destination); + if (newArrivalTime > plan.getMaxDropoffTime()) { + return false; + } + } + return true; + } + + /** + * counts arrival time of taxi to pickup location and check if is smaller than MaxPickupTime + * @return boolean. + */ + private boolean canServeRequestTASeT(RideSharingOnDemandVehicle vehicle, PlanComputationRequest request) { + //TODO (check): if taxi can pick request in time + //wont work since timeProvider is set null in test +// return travelTimeProvider.getTravelTime(vehicle, request.getFrom()) + timeProvider.getCurrentSimTime() +// < request.getMaxPickupTime(); + return travelTimeProvider.getTravelTime(vehicle, request.getFrom()) < request.getMaxPickupTime(); + } + + + + + + + + + + + + + + + + + + + //copied from InsertionHeuristicSolver + private void computeOptimalPlan(RideSharingOnDemandVehicle vehicle, DriverPlan currentPlan, PlanComputationRequest planComputationRequest) { + + int freeCapacity = vehicle.getFreeCapacity(); + + for(int pickupOptionIndex = 1; pickupOptionIndex <= currentPlan.getLength(); pickupOptionIndex++){ + + // continue if the vehicle is full + if(freeCapacity == 0){ + continue; + } + + for(int dropoffOptionIndex = pickupOptionIndex + 1; dropoffOptionIndex <= currentPlan.getLength() + 1; + dropoffOptionIndex++){ + DriverPlan potentialPlan = insertIntoPlan(currentPlan, pickupOptionIndex, dropoffOptionIndex, + vehicle, planComputationRequest); + if(potentialPlan != null){ + double costIncrement = potentialPlan.cost - currentPlan.cost; + GreedyTASeTSolver.PlanData bestPlanData = new PlanData(vehicle, potentialPlan, costIncrement); + tryUpdateBestPlan(bestPlanData); + } + } + + // change free capacity for next index + if(pickupOptionIndex < currentPlan.getLength()){ + if(currentPlan.plan.get(pickupOptionIndex) instanceof PlanActionPickup){ + freeCapacity--; + } + else{ + freeCapacity++; + } + } + } + } + + //copied from InsertionHeuristicSolver + /** + * Returns list of plan tasks with new request actions added at specified indexes or null if the plan is infeasible. + * @param currentPlan Current plan, starting with the current position action + * @param pickupOptionIndex Pick up index: 1 - current plan length + * @param dropoffOptionIndex Drop off index: 2 - current plan length + 1 + * @param vehicle + * @param planComputationRequest + * @return list of plan tasks with new request actions added at specified indexes or null if the plan is infeasible. + */ + private DriverPlan insertIntoPlan(final DriverPlan currentPlan, final int pickupOptionIndex, + final int dropoffOptionIndex, final RideSharingOnDemandVehicle vehicle, + final PlanComputationRequest planComputationRequest) { + + List newPlanTasks = new LinkedList<>(); + + + // travel time of the new plan in milliseconds + int newPlanTravelTime = 0; + + // discomfort of the new plan in milliseconds + int newPlanDiscomfort = 0; + + PlanAction previousTask = null; + + // index of the lastly added action from the old plan (not considering current position action) + int indexInOldPlan = -1; + + Iterator oldPlanIterator = currentPlan.iterator(); + int freeCapacity = vehicle.getFreeCapacity(); + + for(int newPlanIndex = 0; newPlanIndex <= currentPlan.getLength() + 1; newPlanIndex++){ + + /* get new task */ + PlanAction newTask = null; + if(newPlanIndex == pickupOptionIndex){ + newTask = planComputationRequest.getPickUpAction(); +// new PlanActionPickup(request.getDemandAgent(), request.getDemandAgent().getPosition()); + } + else if(newPlanIndex == dropoffOptionIndex){ + newTask = planComputationRequest.getDropOffAction(); +// = new DriverPlanTask(DriverPlanTaskType.DROPOFF, request.getDemandAgent(), +// request.getTargetLocation()); + } + else{ + newTask = oldPlanIterator.next(); + } + + // travel time increment + if(previousTask != null){ + if(previousTask instanceof PlanActionCurrentPosition){ + newPlanTravelTime += travelTimeProvider.getTravelTime(vehicle, newTask.getPosition()); + } + else{ + newPlanTravelTime += travelTimeProvider.getTravelTime(vehicle, previousTask.getPosition(), + newTask.getPosition()); + } + } + long currentTaskTimeInSeconds = (timeProvider.getCurrentSimTime() + newPlanTravelTime) / 1000; +// LOGGER.debug("currentTaskTimeInSeconds: {}", currentTaskTimeInSeconds); + + /* check max time for all unfinished demands */ + + // check max time check for the new action + if(newTask instanceof PlanRequestAction){ + int maxTime = ((PlanRequestAction) newTask).getMaxTime(); + if(maxTime < currentTaskTimeInSeconds){ +// LOGGER.debug("currentTaskTimeInSeconds {} \n> maxTime {}",currentTaskTimeInSeconds, maxTime); + return null; + } + } + + // check max time for actions in the current plan + for(int index = indexInOldPlan + 1; index < currentPlan.getLength(); index++){ + PlanAction remainingAction = currentPlan.plan.get(index); + if(!(remainingAction instanceof PlanActionCurrentPosition)){ + PlanRequestAction remainingRequestAction = (PlanRequestAction) remainingAction; + if(remainingRequestAction.getMaxTime() < currentTaskTimeInSeconds){ + return null; + } + } + } + + // check max time for pick up action + if(newPlanIndex <= pickupOptionIndex){ + if(planComputationRequest.getPickUpAction().getMaxTime() < currentTaskTimeInSeconds){ + return null; + } + } + + // check max time for drop off action + if(newPlanIndex <= dropoffOptionIndex){ + if(planComputationRequest.getDropOffAction().getMaxTime() < currentTaskTimeInSeconds){ + return null; + } + } + + + /* pickup and drop off handeling */ + if(newTask instanceof PlanActionDropoff){ + freeCapacity++; + + // discomfort increment + PlanComputationRequest newRequest = ((PlanActionDropoff) newTask).getRequest(); + long taskExecutionTime = timeProvider.getCurrentSimTime() + newPlanTravelTime; + newPlanDiscomfort += taskExecutionTime - newRequest.getOriginTime() * 1000 + - newRequest.getMinTravelTime() * 1000; + } + else if(newTask instanceof PlanActionPickup){ + // capacity check + if(freeCapacity == 0){ + return null; + } + freeCapacity--; + } + + + // index in old plan if the action was not new + if(newPlanIndex != pickupOptionIndex && newPlanIndex != dropoffOptionIndex){ + indexInOldPlan++; + } + + newPlanTasks.add(newTask); + previousTask = newTask; + } + + // cost computation + double newPlanCost = planCostProvider.calculatePlanCost(newPlanDiscomfort, newPlanTravelTime); + + return new DriverPlan(newPlanTasks, newPlanTravelTime, newPlanCost); + } + //copied from InsertionHeuristicSolver + private class PlanData{ + final DriverPlan plan; + + final double increment; + + final RideSharingOnDemandVehicle vehicle; + + public PlanData(RideSharingOnDemandVehicle vehicle, DriverPlan plan, double increment) { + this.vehicle = vehicle; + this.plan = plan; + this.increment = increment; + } + } + + //copied from InsertionHeuristicSolver - edited + private synchronized void tryUpdateBestPlan(GreedyTASeTSolver.PlanData newPlanData){ + if(newPlanData != null){ + bestPlan = newPlanData; + } + } +} + + + + + + + + diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/insertionheuristic/DriverPlan.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/insertionheuristic/DriverPlan.java index 14850036..bb814c9d 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/insertionheuristic/DriverPlan.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/insertionheuristic/DriverPlan.java @@ -21,6 +21,10 @@ import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; import cz.cvut.fel.aic.simod.ridesharing.model.PlanAction; import cz.cvut.fel.aic.simod.ridesharing.model.PlanActionCurrentPosition; +import cz.cvut.fel.aic.simod.ridesharing.model.PlanActionDropoff; +import cz.cvut.fel.aic.simod.ridesharing.model.PlanActionPickup; + +import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -76,6 +80,27 @@ public String toString() { sb.append("]"); return sb.toString(); } + + // TODO: check if that works + public List getPickupActions() { + List pickups = new ArrayList<>(); + for(PlanAction action : plan) { + if(action instanceof PlanActionPickup) { + pickups.add(action); + } + } + return pickups; + } + + public List getDropoffActions() { + List dropoffs = new ArrayList<>(); + for(PlanAction action : plan) { + if(action instanceof PlanActionDropoff) { + dropoffs.add(action); + } + } + return dropoffs; + } } diff --git a/src/main/java/cz/cvut/fel/aic/simod/traveltimecomputation/AstarTravelTimeProvider.java b/src/main/java/cz/cvut/fel/aic/simod/traveltimecomputation/AstarTravelTimeProvider.java index 80e738a5..1990314e 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/traveltimecomputation/AstarTravelTimeProvider.java +++ b/src/main/java/cz/cvut/fel/aic/simod/traveltimecomputation/AstarTravelTimeProvider.java @@ -49,16 +49,28 @@ public class AstarTravelTimeProvider extends TravelTimeProvider{ private final MoveUtil moveUtil; +// @Inject +// public AstarTravelTimeProvider( +// TimeProvider timeProvider, +// TripsUtil tripsUtil, +// TransportNetworks transportNetworks, +// MoveUtil moveUtil) { +// super(timeProvider); +// this.tripsUtil = tripsUtil; +// this.moveUtil = moveUtil; +// this.graph = transportNetworks.getGraph(EGraphType.HIGHWAY); +// } + @Inject public AstarTravelTimeProvider( - TimeProvider timeProvider, - TripsUtil tripsUtil, - TransportNetworks transportNetworks, + TimeProvider timeProvider, + TripsUtil tripsUtil, + Graph graph, MoveUtil moveUtil) { super(timeProvider); this.tripsUtil = tripsUtil; this.moveUtil = moveUtil; - this.graph = transportNetworks.getGraph(EGraphType.HIGHWAY); + this.graph = graph; } diff --git a/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java b/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java new file mode 100644 index 00000000..2ba3d6df --- /dev/null +++ b/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java @@ -0,0 +1,129 @@ +package cz.cvut.fel.aic.simod.visual.ridesharing.greedyTASeT; + +import cz.cvut.fel.aic.agentpolis.config.AgentpolisConfig; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.ShortestPathPlanner; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.TripsUtil; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.TimeProvider; +import cz.cvut.fel.aic.agentpolis.simmodel.MoveUtil; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.MovingEntity; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.GraphType; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.NearestElementUtils; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.Utils; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationEdge; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.networks.HighwayNetwork; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.networks.TransportNetworks; +import cz.cvut.fel.aic.agentpolis.utils.PositionUtil; +import cz.cvut.fel.aic.alite.common.event.Event; +import cz.cvut.fel.aic.alite.common.event.EventHandler; +import cz.cvut.fel.aic.alite.common.event.EventProcessor; +import cz.cvut.fel.aic.alite.common.event.typed.TypedSimulation; +import cz.cvut.fel.aic.geographtools.Graph; +import cz.cvut.fel.aic.geographtools.util.Transformer; +import cz.cvut.fel.aic.simod.config.SimodConfig; +import cz.cvut.fel.aic.simod.event.OnDemandVehicleEvent; +import cz.cvut.fel.aic.simod.ridesharing.DARPSolver; +import cz.cvut.fel.aic.simod.ridesharing.DroppedDemandsAnalyzer; +import cz.cvut.fel.aic.simod.ridesharing.PlanCostProvider; +import cz.cvut.fel.aic.simod.ridesharing.RideSharingOnDemandVehicle; +import cz.cvut.fel.aic.simod.ridesharing.insertionheuristic.DriverPlan; +import cz.cvut.fel.aic.simod.ridesharing.model.DefaultPlanComputationRequest; +import cz.cvut.fel.aic.simod.ridesharing.model.PlanActionDropoff; +import cz.cvut.fel.aic.simod.ridesharing.model.PlanActionPickup; +import cz.cvut.fel.aic.simod.ridesharing.model.PlanComputationRequest; +import cz.cvut.fel.aic.simod.ridesharing.vga.model.Plan; +import cz.cvut.fel.aic.simod.storage.OnDemandVehicleStorage; +import cz.cvut.fel.aic.simod.storage.OnDemandvehicleStationStorage; +import cz.cvut.fel.aic.simod.traveltimecomputation.AstarTravelTimeProvider; +import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider; +import cz.cvut.fel.aic.simod.ridesharing.greedyTASeT.GreedyTASeTSolver; +import cz.cvut.fel.aic.simod.visual.ridesharing.vga.mock.TestPlanRequest; +import jdk.nashorn.internal.runtime.Debug; +import org.apache.commons.lang.exception.ExceptionUtils; +import org.junit.Test; + +import java.util.*; + +public class GreedyTASeTSolverTest { + + @Test + public void run() { + OnDemandVehicleStorage vehicleStorage = new OnDemandVehicleStorage(); + TravelTimeProvider travelTimeProvider = null; + TimeProvider timeProvider = null; + PlanCostProvider travelCostProvider = null; + DefaultPlanComputationRequest.DefaultPlanComputationRequestFactory requestFactory = null; + TypedSimulation eventProcessor = new TypedSimulation(120); + SimodConfig config = new SimodConfig(); + TimeProvider timeProvider1 = new TimeProvider() { + @Override + public long getCurrentSimTime() { + return 0; + } + }; + PositionUtil positionUtil = new PositionUtil(); + TripsUtil tripsUtil = null; + // TripsUtil(ShortestPathPlanner pathPlanner, NearestElementUtils nearestElementUtils, HighwayNetwork network, IdGenerator tripIdGenerator) + ShortestPathPlanner pathPlanner = null; + NearestElementUtils nearestElementUtils = new NearestElementUtils(null, null); + HighwayNetwork highwayNetwork = new HighwayNetwork(null); + + + Map> map = null; + int citySRID = 32618; + Transformer transformer = new Transformer(citySRID); + Graph graph = Utils.getCompleteGraph(4, transformer); + AgentpolisConfig agentpolisConfig = new AgentpolisConfig(); + MoveUtil moveUtil = new MoveUtil(agentpolisConfig); + AstarTravelTimeProvider astarTravelTimeProvider = new AstarTravelTimeProvider(timeProvider1, null, graph, moveUtil); + OnDemandvehicleStationStorage onDemandvehicleStationStorage = new OnDemandvehicleStationStorage(transformer); + DroppedDemandsAnalyzer droppedDemandsAnalyzer = new DroppedDemandsAnalyzer(vehicleStorage, positionUtil, astarTravelTimeProvider, config, onDemandvehicleStationStorage, agentpolisConfig); + + + GreedyTASeTSolver solver = new GreedyTASeTSolver(vehicleStorage, astarTravelTimeProvider, null, null, + eventProcessor, config, timeProvider1, positionUtil, null, + onDemandvehicleStationStorage, agentpolisConfig); + + SimulationNode origin = new SimulationNode(1, 2, 55, 45, 55, 45, 200, 0); + SimulationNode destination = new SimulationNode(2, 3, 56, 46, 56, 46, 210, 0); + // null pointer exception because trips util is null + TestPlanRequest r1 = new TestPlanRequest(2, config, origin, destination, 0, false, astarTravelTimeProvider); + SimulationNode origin2 = new SimulationNode(1, 2, 55, 46, 55, 46, 200, 0); + SimulationNode destination2 = new SimulationNode(2, 3, 56, 45, 56, 5, 210, 0); + TestPlanRequest r2 = new TestPlanRequest(2, config, origin2, destination2, 0, false, astarTravelTimeProvider); + List req = new ArrayList<>(); + PlanComputationRequest rp1 = (PlanComputationRequest)r1; + PlanComputationRequest rp2 = (PlanComputationRequest)r2; + req.add(rp1); + req.add(rp2); + List rr = new ArrayList<>(); + + Map retMap = solver.solve(req, rr); + + + } + + @Test + public void testSort() { + int [] array = {10, 2, 5, 9, 3}; + List list = new ArrayList<>(); + Double one = 1d; + Double two = 2d; + Double three = 3d; + Double four = 4d; + Double five = 5d; + list.add(one); + list.add(two); + list.add(three); + list.add(four); + list.add(five); + + System.out.println("sort"); + List listCopy = new ArrayList<>(list); + list.sort(Comparator.comparing(x -> array[listCopy.indexOf(x)])); + Collections.reverse(list); + System.out.println(Arrays.toString(array)); + System.out.println(list); + + } +} diff --git a/src/test/resources/cz/cvut/fel/aic/simod/config/config.cfg b/src/test/resources/cz/cvut/fel/aic/simod/config/config.cfg index 1bd52bc5..0983f307 100644 --- a/src/test/resources/cz/cvut/fel/aic/simod/config/config.cfg +++ b/src/test/resources/cz/cvut/fel/aic/simod/config/config.cfg @@ -4,10 +4,10 @@ experiment_name: 'test' # common data for all experiments -amodsim_data_dir: 'FILL THIS WITH PATH TO DATA DIR' +amodsim_data_dir: '/Users/adela/Documents/bakalarka/test_simod/data/' # experiment specific data (cache, results,...) -amodsim_experiment_dir: "FILL THIS WITH PATH TO EXPERIMENT DIR" +amodsim_experiment_dir: "/Users/adela/Documents/bakalarka/test_simod/" map_dir: $amodsim_data_dir + 'maps/' From 6ff8a24d42cd3bdc517480d9e9fa1301e2596b21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kub=C3=ADkov=C3=A1=2C=20Ad=C3=A9la?= Date: Sat, 1 Jan 2022 19:06:32 +0100 Subject: [PATCH 02/21] Implement heuristics function --- .../cz/cvut/fel/aic/simod/MainModule.java | 1 + .../fel/aic/simod/entity/DemandAgent.java | 4 + .../aic/simod/entity/DemandAgentState.java | 3 +- .../simod/entity/vehicle/OnDemandVehicle.java | 2 + .../RideSharingOnDemandVehicle.java | 21 +- .../greedyTASeT/GreedyTASeTSolver.java | 613 ++++++++++++++++-- .../ridesharing/greedyTASeT/RequestPlan.java | 38 ++ .../insertionheuristic/DriverPlan.java | 23 + .../ridesharing/model/PlanActionOffboard.java | 22 + .../ridesharing/model/PlanActionOnboard.java | 22 + .../ridesharing/model/PlanActionWait.java | 27 + .../greedyTASeT/GreedyTASeTSolverTest.java | 21 +- 12 files changed, 715 insertions(+), 82 deletions(-) create mode 100644 src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/RequestPlan.java create mode 100644 src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionOffboard.java create mode 100644 src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionOnboard.java create mode 100644 src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionWait.java diff --git a/src/main/java/cz/cvut/fel/aic/simod/MainModule.java b/src/main/java/cz/cvut/fel/aic/simod/MainModule.java index 4785a7a4..7b52d3eb 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/MainModule.java +++ b/src/main/java/cz/cvut/fel/aic/simod/MainModule.java @@ -149,6 +149,7 @@ protected void configureNext() { break; case "greedy-taset": bind(DARPSolver.class).to(GreedyTASeTSolver.class); + // nabindovat i nove tridy (treba waiting akci) break; } } diff --git a/src/main/java/cz/cvut/fel/aic/simod/entity/DemandAgent.java b/src/main/java/cz/cvut/fel/aic/simod/entity/DemandAgent.java index 3998c4bd..3683eb32 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/entity/DemandAgent.java +++ b/src/main/java/cz/cvut/fel/aic/simod/entity/DemandAgent.java @@ -214,6 +214,10 @@ public void tripStarted(OnDemandVehicle vehicle) { Logger.getLogger(DemandAgent.class.getName()).log(Level.SEVERE, null, ex); } } +// TODO to do +// else if(state == DemandAgentState.TRANSFERING) { +// +// } else{ state = DemandAgentState.DRIVING; realPickupTime = timeProvider.getCurrentSimTime(); diff --git a/src/main/java/cz/cvut/fel/aic/simod/entity/DemandAgentState.java b/src/main/java/cz/cvut/fel/aic/simod/entity/DemandAgentState.java index ee8c2f7b..687ee9ab 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/entity/DemandAgentState.java +++ b/src/main/java/cz/cvut/fel/aic/simod/entity/DemandAgentState.java @@ -24,5 +24,6 @@ */ public enum DemandAgentState { WAITING, - DRIVING + DRIVING, + TRANSFERING } diff --git a/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicle.java b/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicle.java index 4b5d7c1b..465675d1 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicle.java +++ b/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicle.java @@ -255,6 +255,8 @@ public void finishedDriving(boolean wasStopped) { } } +// TODO add method with wait activity + protected void driveToDemandStartLocation() { if(getPosition() == demandNodes.get(0)){ diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java index 42bc048c..4f4f5b44 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java @@ -26,7 +26,10 @@ import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.StandardTimeProvider; import cz.cvut.fel.aic.agentpolis.simmodel.IdGenerator; import cz.cvut.fel.aic.agentpolis.simmodel.activity.PhysicalVehicleDrive; +import cz.cvut.fel.aic.agentpolis.simmodel.activity.Wait; import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.PhysicalVehicleDriveFactory; + +import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.WaitActivityFactory; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; import cz.cvut.fel.aic.agentpolis.simulator.visualization.visio.VisioPositionUtil; import cz.cvut.fel.aic.alite.common.event.Event; @@ -39,11 +42,7 @@ import cz.cvut.fel.aic.simod.event.OnDemandVehicleEvent; import cz.cvut.fel.aic.simod.event.OnDemandVehicleEventContent; import cz.cvut.fel.aic.simod.ridesharing.insertionheuristic.DriverPlan; -import cz.cvut.fel.aic.simod.ridesharing.model.PlanAction; -import cz.cvut.fel.aic.simod.ridesharing.model.PlanActionCurrentPosition; -import cz.cvut.fel.aic.simod.ridesharing.model.PlanActionDropoff; -import cz.cvut.fel.aic.simod.ridesharing.model.PlanActionPickup; -import cz.cvut.fel.aic.simod.ridesharing.model.PlanRequestAction; +import cz.cvut.fel.aic.simod.ridesharing.model.*; import cz.cvut.fel.aic.simod.statistics.PickupEventContent; import cz.cvut.fel.aic.simod.storage.PhysicalTransportVehicleStorage; import cz.cvut.fel.aic.simod.visio.PlanLayerTrip; @@ -67,10 +66,16 @@ public class RideSharingOnDemandVehicle extends OnDemandVehicle{ private IdGenerator tripIdGenerator; + private final WaitActivityFactory waitActivityFactory; + public DriverPlan getCurrentPlan() { currentPlan.updateCurrentPosition(getPosition()); return currentPlan; } + public void setCurrentPlan(DriverPlan driverPlan) { + currentPlan = driverPlan; + currentPlan.updateCurrentPosition(getPosition()); + } @@ -89,6 +94,7 @@ public RideSharingOnDemandVehicle( SimodConfig config, IdGenerator idGenerator, AgentpolisConfig agentpolisConfig, + WaitActivityFactory waitActivityFactory, @Assisted String vehicleId, @Assisted SimulationNode startPosition) { super( vehicleStorage, @@ -106,6 +112,7 @@ public RideSharingOnDemandVehicle( startPosition); this.positionUtil = positionUtil; this.tripIdGenerator = tripIdGenerator; + this.waitActivityFactory = waitActivityFactory; // empty plan LinkedList plan = new LinkedList<>(); @@ -238,6 +245,9 @@ private void driveToNextTask() { if(currentTask instanceof PlanActionPickup){ driveToDemandStartLocation(); } + else if(currentTask instanceof PlanActionWait) { + waitActivityFactory.runActivity(this, ((PlanActionWait) currentTask).getWaitTime()); + } else{ driveToTargetLocation(); } @@ -258,6 +268,7 @@ private void pickupAndContinue() { vehicle.pickUp(demandAgent); // statistics TODO demand tirp? + // demandTrip = tripsUtil.createTrip(currentTask.getDemandAgent().getPosition().id, // currentTask.getLocation().id, vehicle); // demand trip length 0 - need to find out where the statistic is used, does it make sense with rebalancing? diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java index dac42377..622baba0 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java @@ -1,36 +1,28 @@ package cz.cvut.fel.aic.simod.ridesharing.greedyTASeT; import com.google.inject.Inject; -import com.sun.xml.internal.xsom.impl.scd.Iterators; import cz.cvut.fel.aic.agentpolis.config.AgentpolisConfig; import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.TimeProvider; -import cz.cvut.fel.aic.agentpolis.simmodel.activity.Drive; import cz.cvut.fel.aic.agentpolis.simmodel.entity.AgentPolisEntity; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; -import cz.cvut.fel.aic.agentpolis.utils.Benchmark; import cz.cvut.fel.aic.agentpolis.utils.PositionUtil; import cz.cvut.fel.aic.alite.common.event.Event; import cz.cvut.fel.aic.alite.common.event.EventHandler; import cz.cvut.fel.aic.alite.common.event.EventProcessor; import cz.cvut.fel.aic.alite.common.event.typed.TypedSimulation; import cz.cvut.fel.aic.simod.config.SimodConfig; -import cz.cvut.fel.aic.simod.entity.DemandAgent; -import cz.cvut.fel.aic.simod.entity.OnDemandVehicleState; -import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicle; import cz.cvut.fel.aic.simod.event.OnDemandVehicleEvent; -import cz.cvut.fel.aic.simod.io.SimulationNodeArrayConstructor; import cz.cvut.fel.aic.simod.ridesharing.DARPSolver; import cz.cvut.fel.aic.simod.ridesharing.DroppedDemandsAnalyzer; import cz.cvut.fel.aic.simod.ridesharing.PlanCostProvider; import cz.cvut.fel.aic.simod.ridesharing.RideSharingOnDemandVehicle; import cz.cvut.fel.aic.simod.ridesharing.insertionheuristic.DriverPlan; -import cz.cvut.fel.aic.simod.ridesharing.insertionheuristic.InsertionHeuristicSolver; import cz.cvut.fel.aic.simod.ridesharing.model.*; -import cz.cvut.fel.aic.simod.ridesharing.vga.model.Plan; import cz.cvut.fel.aic.simod.storage.OnDemandVehicleStorage; import cz.cvut.fel.aic.simod.storage.OnDemandvehicleStationStorage; import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider; -import me.tongfei.progressbar.ProgressBar; +import jdk.internal.util.xml.impl.Pair; +import jdk.nashorn.internal.ir.RuntimeNode; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -56,6 +48,9 @@ public class GreedyTASeTSolver extends DARPSolver implements EventHandler { private final int maxDelayTime = 10; + private final List transferPoints; + + protected final DefaultPlanComputationRequest.DefaultPlanComputationRequestFactory requestFactory; //copied from insertionHeuristicSolver private GreedyTASeTSolver.PlanData bestPlan; @@ -76,7 +71,7 @@ public GreedyTASeTSolver( PositionUtil positionUtil, DroppedDemandsAnalyzer droppedDemandsAnalyzer, OnDemandvehicleStationStorage onDemandvehicleStationStorage, - AgentpolisConfig agentpolisConfig) { + AgentpolisConfig agentpolisConfig, List transferPoints) { super(vehicleStorage, travelTimeProvider, travelCostProvider, requestFactory); this.eventProcessor = eventProcessor; this.config = config; @@ -84,6 +79,8 @@ public GreedyTASeTSolver( this.positionUtil = positionUtil; this.droppedDemandsAnalyzer = droppedDemandsAnalyzer; this.onDemandvehicleStationStorage = onDemandvehicleStationStorage; + this.requestFactory = requestFactory; + this.transferPoints = transferPoints; //TODO: resolve // commented because config is null in test @@ -131,11 +128,12 @@ public Map solve(List driverPlans = dispatch(taxis, newRequests); for (int i = 0; i < driverPlans.size(); i++) { planMap.put(taxis.get(i), driverPlans.get(i)); } + return planMap; } @@ -144,27 +142,32 @@ public Map solve(List dispatch(List taxis, List requests) { - List lst1 = dispatchVacantTaxi(taxis, requests); + List lst1 = dispatchVacantTaxi(taxis, requests); List carpoolAcceptingTaxis = taxis; List carpoolAcceptingPassengers = requests; - List lst2 = heuristics(carpoolAcceptingTaxis, carpoolAcceptingPassengers); + List lst2 = heuristics(carpoolAcceptingTaxis, carpoolAcceptingPassengers); for(PlanComputationRequest request : requests) { // TODO: check duplicates - // wtf - // is request in lst? + // is request served by both lst? } - lst1.addAll(lst2); - return lst1; + // todo prevest na driver plany +// lst1.addAll(lst2); + List convertedlist = convertRequestPlansToDriverPlans(lst1, taxis); + return convertedlist; } /** * traditional taxi dispatch strategy that schedules taxis based on the shortest waiting time for the passengers * @return */ - private List dispatchVacantTaxi(List taxis, List requests) { + private List dispatchVacantTaxi(List taxis, List requests) { //taxi dispatch strategy that schedules taxis based on the shortest waiting time for the passengers //TODO: implement method //function can be changed to any dispatch strategy that a taxi company may currently be using (e.g., shortest waiting time and shortest cruising distance) +// taxis.get(0).getPosition() + // while mám volné taxíky + // najdu nejbližší taxík pro request + // pro ten request vytvorim return null; } @@ -173,10 +176,9 @@ private List dispatchVacantTaxi(List tax * Greedy TASeT heuristics function * @return */ - private List heuristics(List taxis, List requests) { + private List heuristics(List taxis, List requests) { //transfer points = charging stations - List transferPoints = new ArrayList<>(); - //TODO: fill transfer points + List transferPoints = this.transferPoints; //lookup table LT - LT [t][k] stores the earliest arrival time for taxi k to charging station t without violating the tolerable delay for k’s current passengers int stationsCount = transferPoints.size(); @@ -186,7 +188,15 @@ private List heuristics(List taxis, List for(int i = 0; i < taxisCount; i++) { RideSharingOnDemandVehicle taxi = taxis.get(i); SimulationNode taxiPosition = taxis.get(i).getPosition(); - List requestsOnBoard = taxi.getVehicle().getTransportedEntities(); + Set requestsOnBoardSet = new HashSet<>(); + DriverPlan actualPlan = taxi.getCurrentPlan(); + for(PlanAction action : actualPlan) { + if(action instanceof PlanRequestAction) { + PlanRequestAction requestAction = (PlanRequestAction) action; + requestsOnBoardSet.add(requestAction.request); + } + } + List requestsOnBoard = new ArrayList<>(requestsOnBoardSet); boolean taxiFree = taxi.hasFreeCapacity(); for(int j = 0; j < stationsCount; j++) { //timeProvider is set to null so getCurrentSimTime() wont work @@ -210,7 +220,7 @@ private List heuristics(List taxis, List } //itinerary list - List itinerarylist = new ArrayList<>(); + List itinerarylist = new ArrayList<>(); //we rank the requests in descending order by the number of taxis that are possible to pick them up in time (without considering transfer or destination) //get possible taxis for every request and number of possible taxis @@ -238,60 +248,409 @@ private List heuristics(List taxis, List for(PlanComputationRequest request : requests) { - List templist = new ArrayList<>(); - +// List> templist = new ArrayList<>(); // list planactionu pro auto + Map>, List>, List> templist = new HashMap<>(); //hashmapa RequestPlan : list driverplanu + List delays = new ArrayList<>(); + List transferTimes = new ArrayList<>(); List canPickupRequestTaxis = possiblePickupTaxisMap.get(request); - for(RideSharingOnDemandVehicle taxi : canPickupRequestTaxis) { - DriverPlan posbitnry = findPlanWithNoTransfer(request, taxi); - templist.add(posbitnry); + for (RideSharingOnDemandVehicle taxi : canPickupRequestTaxis) { + List posbitnry = findPlanWithNoTransfer(request, taxi); // pro auto + List posbitnryR = getActionsForRequestFromActionsForDriver(posbitnry, request, taxi); // pro request + List> tmp = new ArrayList<>(); + List tmpVehs = new ArrayList<>(); + tmpVehs.add(taxi); + tmp.add(posbitnry); + Map>, List> submap = new HashMap<>(); + submap.put(tmp, tmpVehs); + templist.put(submap, posbitnryR); + delays.add((long) 0); + transferTimes.add((long) 0); + long travelTimeNoTransfer = getTravelTime(request, posbitnry); //charge stations list = transferPoints int stationIndex = 0; - for(SimulationNode station : transferPoints) { + for (SimulationNode station : transferPoints) { // find k' = taxis that taxi k can transfer to at station - for(int k = 0; k < taxisCount; k++) - { + for (int k = 0; k < taxisCount; k++) { //not possible to transfer to - if(LT[stationIndex][k] == Long.MAX_VALUE) { + if (LT[stationIndex][k] == Long.MAX_VALUE) { continue; } else { - //TODO (check): get requestFactory and DemandAgent? - PlanActionPickup p = (PlanActionPickup) taxi.getCurrentTask(); // split request to two requests with transfer point DefaultPlanComputationRequest newRequest1 = requestFactory.create(0, request.getFrom(), - station, p.getRequest().getDemandAgent()); + station, request.getDemandAgent()); DefaultPlanComputationRequest newRequest2 = requestFactory.create(1, station, - request.getTo(), p.getRequest().getDemandAgent()); + request.getTo(), request.getDemandAgent()); //find optimal plans for these two requests - DriverPlan itryp1 = findPlanWithNoTransfer(newRequest1, taxi); - DriverPlan itnryp2 = findPlanWithNoTransfer(newRequest2, taxis.get(k)); - // TODO: create Charge plan (TransferPlan) from itnryp1 and itnryp2 - // idea: transfer time = zjistim z LT tabulky - // create DriverPlan from itnryp1 and itnryp2, add transfer time between - // check constraints for DriverPlan - // if ok, -// templist.add(ZKONTROLOVANY PLAN); + List itnryp1 = findPlanWithNoTransfer(newRequest1, taxi); // pro auto + //List itnryp1R = getActionsForRequestFromActionsForDriver(itnryp1, newRequest1, taxi); + List itnryp2 = findPlanWithNoTransfer(newRequest2, taxis.get(k)); // pro auto + //List itnryp2R = getActionsForRequestFromActionsForDriver(itnryp2, newRequest2, taxis.get(k)); + Map>, Long> m = createChargePlan(itnryp1, itnryp2, taxi, taxis.get(k), newRequest1, newRequest2); + if (m == null) { + // neni mozne prestoupit, takze neudelam nic + continue; + } else { + Map.Entry>, Long> entry = m.entrySet().iterator().next(); + List> itnrys = entry.getKey(); + itnryp1 = itnrys.get(0); + itnryp2 = itnrys.get(1); + List> tmp2 = new ArrayList<>(); + tmp2.add(itnryp1); + tmp2.add(itnryp2); + List tmpVehs2 = new ArrayList<>(); + tmpVehs2.add(taxi); + tmpVehs2.add(taxis.get(k)); + Map>, List> submap2 = new HashMap<>(); + submap2.put(tmp2, tmpVehs2); + List transferPlan = splittedRequestToPlanForRequest(itnryp1, itnryp2, newRequest1, newRequest2, request); + templist.put(submap2, transferPlan); + long travelTimeTransfer = getTravelTime(newRequest1, itnryp1) + getTravelTime(newRequest2, itnryp2); + delays.add(travelTimeNoTransfer - travelTimeTransfer); + long transferTime = entry.getValue(); + transferTimes.add(transferTime); + } } } stationIndex++; } } - // TODO: - // sort templist by delay and transfer time - // podobna funkce jako findItineraryWithMinimumDelay, akorat nevrati jeden DriverPlan, ale seradi je - // selected = itinerary with longest transfer time in the top β% shortest delay - // budu si nekde drzet transfer time pro kazdy DriverPlan (nebo request?) + + // potrebuji seradit delays + // a podle toho vybrat veci z hashmapy + + //create array of indices + List indices = new ArrayList<>(); + for(int q = 0; q < delays.size(); q++) + { + indices.add(q); + } + List beforeDelays = new ArrayList<>(); + List beforeIndices = new ArrayList<>(); + beforeDelays.addAll(delays); + beforeIndices.addAll(indices); + //seradim delays od nejkratsich + delays.sort(null); + for(int q = 0; q < beforeDelays.size(); q++) { + int index = beforeDelays.indexOf(delays.get(q)); + indices.set(q, beforeIndices.get(q)); + } + // ted mam serazene delays a indexy v indices + + //vezmu hornich beta procent + double beta = 0.2; + int numOfTaken = (int) (delays.size() * beta); + if (numOfTaken == 0) { + numOfTaken = 1; + } + List subsetIndices = new ArrayList<>(); + List subsetTransferTimes = new ArrayList<>(); + for (int q = 0; q < numOfTaken; q++) + { + subsetIndices.add(indices.get(q)); + subsetTransferTimes.add(transferTimes.get(indices.get(q))); + } + // v subsetIndices mam ted indexy tech vysledku, ktere chci vybrat pro porovnani podle transfer timu + // v subsetTransferTimes jsou casy prestupu, podle toho to ted budu chtit seradit + + // chci seradit subsetIndices podle subsetTransferTImes + List beforeSubsetTransferTimes = new ArrayList<>(); + List beforeSubsetIndices = new ArrayList<>(); + beforeSubsetTransferTimes.addAll(subsetTransferTimes); + beforeSubsetIndices.addAll(subsetIndices); + //seradim transfer times od nejkratsich + subsetTransferTimes.sort(null); + for(int q = 0; q < beforeSubsetTransferTimes.size(); q++) { + int index = beforeSubsetTransferTimes.indexOf(subsetTransferTimes.get(q)); + subsetIndices.set(q, beforeSubsetIndices.get(q)); + } + // ted mam serazene transferTimes a indexy v subsetIndices + + // ted bych mela chtit vybrat jeden entry z templistu podle toho subsetIndices + int indexOfFirst = subsetIndices.get(0); + int iterateOrder = 0; + Map.Entry>, List>, List> returnEntry = null; + + // ziskam entry ktery je nejlepsi podle heuristiky + for (Map.Entry>, List>, List> entry : templist.entrySet()) + { + if (iterateOrder == indexOfFirst) { + returnEntry = entry; + } + } + List selectedList = returnEntry.getValue(); + RequestPlan selected = new RequestPlan(selectedList, 0, 0); + selected.setRequest(request); + itinerarylist.add(selected); + Map>, List> key = returnEntry.getKey(); + for (Map.Entry>, List> entry : key.entrySet()) { + List> plansForVehicles = entry.getKey(); + List vehicles = entry.getValue(); + for (int q = 0; q < vehicles.size(); q++) { + RideSharingOnDemandVehicle veh = vehicles.get(q); + List vehPlan = plansForVehicles.get(q); + DriverPlan dp = new DriverPlan(vehPlan, 0, 0); + veh.setCurrentPlan(dp); + } + } + // update k, k′ and LT -// itinerarylist.add(selected) + //update LT - not efficient + for(int q = 0; q < taxisCount; q++) { + RideSharingOnDemandVehicle taxi = taxis.get(q); + SimulationNode taxiPosition = taxis.get(q).getPosition(); + Set requestsOnBoardSet = new HashSet<>(); + DriverPlan actualPlan = taxi.getCurrentPlan(); + for(PlanAction action : actualPlan) { + if(action instanceof PlanRequestAction) { + PlanRequestAction requestAction = (PlanRequestAction) action; + requestsOnBoardSet.add(requestAction.request); + } + } + List requestsOnBoard = new ArrayList<>(requestsOnBoardSet); + boolean taxiFree = taxi.hasFreeCapacity(); + for(int j = 0; j < stationsCount; j++) { + //timeProvider is set to null so getCurrentSimTime() wont work + //the idea is to fill LT with times of arrival of taxis +// LT[j][i] = this.timeProvider.getCurrentSimTime() + travelTime; + //check if taxi has free seat + if (!taxiFree) { + LT[j][q] = Long.MAX_VALUE; + } + else { + SimulationNode station = transferPoints.get(j); + long travelTime = this.travelTimeProvider.getExpectedTravelTime(taxiPosition, station); + //check if setting a new via point will exceed the tolerable delay for onboard passengers + if (checkTolerableDelay(requestsOnBoard, station, taxi)) { + LT[j][q] = travelTime; + } else { + LT[j][q] = Long.MAX_VALUE; + } + } + } + } + + //update k + for(PlanComputationRequest req : requests) { + int counter = 0; + List possiblePickupTaxisOneRequest = new ArrayList<>(); + for(RideSharingOnDemandVehicle t : taxis) { + if (canServeRequestTASeT(t, req)) { + counter++; + possiblePickupTaxisOneRequest.add(t); + } + } + possiblePickupTaxisCounts[i] = counter; + possiblePickupTaxisMap.put(req, possiblePickupTaxisOneRequest); + i++; + } + } return itinerarylist; } + private long getTravelTime(PlanComputationRequest request, List planOfCar) { + long time = 0; + int index = 0; + SimulationNode previousPosition = planOfCar.get(0).getPosition(); + PlanAction lastAction = null; + // find first action + for (int i = 0; i < planOfCar.size(); i++) { + PlanAction action = planOfCar.get(i); + if (action instanceof PlanRequestAction) { + PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); + previousPosition = action.getPosition(); + if (pcq == request) { + index = i; + break; + } + } + } + //find last action + for (int i = planOfCar.size()-1; i > 0; i--) { + PlanAction action = planOfCar.get(i); + if (action instanceof PlanRequestAction) { + PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); + previousPosition = action.getPosition(); + if (pcq == request) { + lastAction = action; + break; + } + } + } + for (int i = index+1; i < planOfCar.size(); i++) { + PlanAction action = planOfCar.get(i); + time = time + travelTimeProvider.getExpectedTravelTime(previousPosition, action.getPosition()); + previousPosition = action.getPosition(); + if (action == lastAction) { + break; + } + } + return time; + } + + private List splittedRequestToPlanForRequest(List itnryp1, List itnryp2, PlanComputationRequest newRequest1, + PlanComputationRequest newRequest2, PlanComputationRequest originalRequest) { + List listForOriginalRequest = new ArrayList<>(); + // iterate over first itnryp + //find actions that belongs to newrequest1 + //create similar action with originalrequest + //add to list + //do the same with the second itnryp + for (PlanAction action : itnryp1) { + if (action instanceof PlanRequestAction) { + PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); + if (action instanceof PlanActionPickup) { + if (pcq.getPickUpAction().request == newRequest1) { + PlanActionPickup pickup = (PlanActionPickup) pcq; + PlanActionPickup newPickup = new PlanActionPickup(originalRequest, pickup.getPosition(), pickup.getMaxTime()); + listForOriginalRequest.add(newPickup); + } + } else if (action instanceof PlanActionDropoff) { + if (pcq.getDropOffAction().request == newRequest1) { + PlanActionDropoff dropoff = (PlanActionDropoff) pcq; + PlanActionDropoff newDropoff = new PlanActionDropoff(originalRequest, dropoff.getPosition(), dropoff.getMaxTime()); + listForOriginalRequest.add(newDropoff); + } + } + } + } + for (PlanAction action : itnryp2) { + if (action instanceof PlanRequestAction) { + PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); + if (action instanceof PlanActionPickup) { + if (pcq.getPickUpAction().request == newRequest2) { + PlanActionPickup pickup = (PlanActionPickup) pcq; + PlanActionPickup newPickup = new PlanActionPickup(originalRequest, pickup.getPosition(), pickup.getMaxTime()); + listForOriginalRequest.add(newPickup); + } + } else if (action instanceof PlanActionDropoff) { + if (pcq.getDropOffAction().request == newRequest2) { + PlanActionDropoff dropoff = (PlanActionDropoff) pcq; + PlanActionDropoff newDropoff = new PlanActionDropoff(originalRequest, dropoff.getPosition(), dropoff.getMaxTime()); + listForOriginalRequest.add(newDropoff); + } + } + } + } + + return listForOriginalRequest; + + } + + private Map>, Long> createChargePlan(List itnryp1, List itnryp2, RideSharingOnDemandVehicle veh1, RideSharingOnDemandVehicle veh2, + DefaultPlanComputationRequest request1, DefaultPlanComputationRequest request2) { + long time1 = 0; + long time2 = 0; + long transferTime = 0; + SimulationNode previousDestination = veh1.getPosition(); + //expected arrival time of first car + for (PlanAction action : itnryp1) { + if (action instanceof PlanRequestAction) { + PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); + if (action instanceof PlanActionPickup) { + SimulationNode dest = pcq.getFrom(); + time1 = time1 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = dest; + } else if (action instanceof PlanActionDropoff) { + SimulationNode dest = pcq.getTo(); + time1 = time1 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (pcq.getDropOffAction().request == request1) { + break; + } + previousDestination = dest; + } else if (action instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) action; + time1 = time1 + wait.getWaitTime(); + } + } + } + // expected arrival of second car + int indexPickupSecondCar = 0; + PlanActionPickup pickup = null; + previousDestination = veh2.getPosition(); + for (PlanAction action : itnryp2) { + if (action instanceof PlanRequestAction) { + PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); + if (action instanceof PlanActionPickup) { + SimulationNode dest = pcq.getFrom(); + time2 = time2 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (pcq.getPickUpAction().request == request2) { + pickup = pcq.getPickUpAction(); + break; + } + previousDestination = dest; + } else if (action instanceof PlanActionDropoff) { + SimulationNode dest = pcq.getTo(); + time2 = time2 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = dest; + } else if (action instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) action; + time2 = time2 + wait.getWaitTime(); + } + indexPickupSecondCar++; + } + } + long waitTime = time2 - time1; + // pokud je zaporny, tak druhe auto bude muset cekat waitTime dlouho + // pokud je kladny, tak to znamena ze prvni auto prijede drive nez druhe - bude cekat cestujici + + boolean valid = true; + // pridam wait time do planu pro druhe auto pokud je wait time zaporny + if (waitTime < 0) { + //transfer time je -waitTime + PlanActionWait waitAction = new PlanActionWait(null, pickup.getPosition(), pickup.getMaxTime(), -waitTime); + transferTime = -waitTime; + itnryp2.add(indexPickupSecondCar, waitAction); + + //check tolerable delay for passengers in vehicle2 + long time = 0; + for (PlanAction action : itnryp2) { + if (action instanceof PlanRequestAction) { + PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); + if (action instanceof PlanActionPickup) { + SimulationNode dest = pcq.getFrom(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (!(time < pcq.getMaxPickupTime())) { + //not valid itinerary - check new driver plan + valid = false; + break; + } + previousDestination = dest; + } else if (action instanceof PlanActionDropoff) { + SimulationNode dest = pcq.getTo(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (!(time < pcq.getMaxDropoffTime())) { + //not valid itinerary - check new driver plan + valid = false; + break; + } + previousDestination = dest; + } else if (action instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) action; + time = time + wait.getWaitTime(); + } + } + } + } + if(valid) { + List> itnrys = new ArrayList<>(); + itnrys.add(itnryp1); + itnrys.add(itnryp2); + Map>, Long> map = new HashMap<>(); + map.put(itnrys, transferTime); + return map; + } + else { + return null; + } + } + /** * Find DriverPlan with smallest delay without transfer allowed. * @return valid DriverPlan with smallest delay. */ - private DriverPlan findPlanWithNoTransfer(PlanComputationRequest newRequest, RideSharingOnDemandVehicle taxi) { + private List findPlanWithNoTransfer(PlanComputationRequest newRequest, RideSharingOnDemandVehicle taxi) { int n = taxi.getOnBoardCount(); List lst = new ArrayList<>(); DriverPlan currentPlan = taxi.getCurrentPlan(); @@ -307,16 +666,141 @@ private DriverPlan findPlanWithNoTransfer(PlanComputationRequest newRequest, Rid for (List dropoffPlan : dropoffOrders) { lst.add(createItinerary(pickups, dropoffPlan)); } - DriverPlan bestPlan = findItineraryWithMinimumDelay(lst); + List bestPlan = findItineraryWithMinimumDelay(lst); return bestPlan; } + private List getActionsForRequestFromActionsForDriver(List planActionsVehicle, PlanComputationRequest request, RideSharingOnDemandVehicle vehicle) { + List actionsForRequest = new ArrayList<>(); + for (int i = 0; i < planActionsVehicle.size(); i++) { + PlanAction action = planActionsVehicle.get(i); + if (action instanceof PlanRequestAction) { + PlanRequestAction planRequestAction = (PlanRequestAction) action; + if(request == planRequestAction.getRequest()) { + if (action instanceof PlanActionPickup) { + PlanActionOnboard onboard = new PlanActionOnboard(request, action.getPosition(), planRequestAction.getMaxTime(), vehicle); + PlanAction currentAction = actionsForRequest.get(0); + PlanRequestAction currentRAction = (PlanRequestAction) currentAction; + int index = 0; + while(currentRAction.getMaxTime() <= onboard.getMaxTime()) { + index++; + currentAction = actionsForRequest.get(index); + currentRAction = (PlanRequestAction) currentAction; + } + actionsForRequest.add(index, onboard); + } + if (action instanceof PlanActionDropoff) { + PlanActionDropoff dropoff = new PlanActionDropoff(request, action.getPosition(), planRequestAction.getMaxTime()); + PlanAction currentAction = actionsForRequest.get(0); + PlanRequestAction currentRAction = (PlanRequestAction) currentAction; + int index = 0; + while(currentRAction.getMaxTime() <= dropoff.getMaxTime()) { + index++; + currentAction = actionsForRequest.get(index); + currentRAction = (PlanRequestAction) currentAction; + } + actionsForRequest.add(index, dropoff); + } + } + } + } + return actionsForRequest; + } + + private List convertDriverPlansToRequestPlans(List driverPlans, List requests) { + int lenRequests = requests.size(); + List requestPlans = new ArrayList<>(); + List emptyPlan = new ArrayList<>(); + RequestPlan empty = new RequestPlan(emptyPlan, 0, 0); + for (int i = 0; i < lenRequests; i++) { + requestPlans.add(empty); + } + + for(DriverPlan driverPlan : driverPlans) { + for (int i = 0; i < driverPlan.plan.size(); i++) { + PlanAction action = driverPlan.plan.get(i); + PlanRequestAction rAction = (PlanRequestAction) action; + PlanComputationRequest requestAssigned = rAction.getRequest(); + for(int j = 0; j < requests.size(); j++) { + if(requestAssigned == requests.get(j)) + { + if (action instanceof PlanActionPickup) { + PlanActionOnboard planActionOnboard = new PlanActionOnboard(requestAssigned, action.getPosition(), rAction.getMaxTime(), driverPlan.getVehicle()); +// TODO: iterate over existing actions and find a timestamp HOPEFULLY DONE + PlanAction currentAction = requestPlans.get(j).plan.get(0); + PlanRequestAction currentRAction = (PlanRequestAction) currentAction; + int index = 0; + while(currentRAction.getMaxTime() <= planActionOnboard.getMaxTime()) { + index++; + currentAction = requestPlans.get(j).plan.get(index); + currentRAction = (PlanRequestAction) currentAction; + } + requestPlans.get(j).plan.add(index, planActionOnboard); + } else if (action instanceof PlanActionDropoff) { + PlanActionOffboard planActionOffboard = new PlanActionOffboard(requestAssigned, action.getPosition(), rAction.getMaxTime(), driverPlan.getVehicle()); +// TODO: iterate over existing actions and find a timestamp + requestPlans.get(j).plan.add(planActionOffboard); + } else if (action instanceof PlanActionWait) { + + } +// TODO: add Wait Actions + } + } + } + } + + return requestPlans; + } + + private List convertRequestPlansToDriverPlans(List requestPlans, List vehicles) { + int lenVehicles = vehicles.size(); + List driverPlans = new ArrayList<>(); + List emptyPlan = new ArrayList<>(); + DriverPlan empty = new DriverPlan(emptyPlan, 0, 0); + for (int i = 0; i < lenVehicles; i++) { + driverPlans.add(empty); + } + + for(RequestPlan requestPlan : requestPlans) { + for(int i = 0; i < requestPlan.plan.size(); i++) { + PlanAction action = requestPlan.plan.get(i); + if (action instanceof PlanActionOffboard) { + PlanActionOffboard planActionOffboard = (PlanActionOffboard) action; + RideSharingOnDemandVehicle veh = planActionOffboard.getFromVehicle(); + PlanActionDropoff planActionDropoff = new PlanActionDropoff(requestPlan.getRequest(), planActionOffboard.getPosition(), planActionOffboard.getMaxTime()); + for (int j = 0; j < vehicles.size(); j++) { + if (veh == vehicles.get(i)) + { +// TODO: iterate over existing actions and find a timestamp + driverPlans.get(j).plan.add(planActionDropoff); + } + } + } + else if (action instanceof PlanActionOnboard) { + PlanActionOnboard planActionOnboard = (PlanActionOnboard) action; + RideSharingOnDemandVehicle veh = planActionOnboard.getToVehicle(); + PlanActionPickup planActionPickup = new PlanActionPickup(requestPlan.getRequest(), planActionOnboard.getPosition(), planActionOnboard.getMaxTime()); + for (int j = 0; j < vehicles.size(); j++) { + if (veh == vehicles.get(i)) + { + driverPlans.get(j).plan.add(planActionOnboard); + } + } + } +// TODO: resolve Wait Actions + } + } + + return driverPlans; + } + + /** * Checks time constraints and counts delay among DriverPlans. * @return valid DriverPlan with smallest delay. */ - private DriverPlan findItineraryWithMinimumDelay(List plans) + private List findItineraryWithMinimumDelay(List plans) { long[] delays = new long[plans.size()]; int index = 0; @@ -324,7 +808,9 @@ private DriverPlan findItineraryWithMinimumDelay(List plans) long time = 0; long delay = 0; // TODO: how to set (initialize) previousDestination? + // vychozi pozice, odkud auto vyjizdi SimulationNode previousDestination = driverPlan.plan.get(0).getPosition(); + previousDestination = driverPlan.vehicle.getPosition(); for (int i = 0; i < driverPlan.getLength(); i++) { PlanAction action = driverPlan.plan.get(i); @@ -355,18 +841,22 @@ else if (action instanceof PlanActionDropoff) { } previousDestination = dest; } + else if (action instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) action; + time = time + wait.getWaitTime(); + } } } // save delay to array delays[index] = delay; index++; } - //find max in delay + //find max in delays int maxAt = 0; for (int i = 0; i < delays.length; i++) { maxAt = delays[i] > delays[maxAt] ? i : maxAt; } - DriverPlan bestPlan = plans.get(maxAt); + List bestPlan = plans.get(maxAt).plan; return bestPlan; } @@ -420,12 +910,12 @@ private void permuteHelper(List> list, List resultL */ private boolean checkTolerableDelay(List requestsOnBoard, SimulationNode viaPoint, RideSharingOnDemandVehicle taxi) { //for every onboard passenger in taxi - for(PlanComputationRequest plan : requestsOnBoard) { - SimulationNode destination = plan.getTo(); + for(PlanComputationRequest request : requestsOnBoard) { + SimulationNode destination = request.getTo(); //get new time of arrival with new via point - //TODO (check): count new Arrival time - long newArrivalTime = timeProvider.getCurrentSimTime() + travelTimeProvider.getTravelTime(taxi, viaPoint) + travelTimeProvider.getTravelTime(taxi, viaPoint, destination); - if (newArrivalTime > plan.getMaxDropoffTime()) { +// long newArrivalTime = timeProvider.getCurrentSimTime() + travelTimeProvider.getTravelTime(taxi, viaPoint) + travelTimeProvider.getTravelTime(taxi, viaPoint, destination); + long newArrivalTime = travelTimeProvider.getTravelTime(taxi, viaPoint) + travelTimeProvider.getTravelTime(taxi, viaPoint, destination); + if (newArrivalTime > request.getMaxDropoffTime()) { return false; } } @@ -437,7 +927,6 @@ private boolean checkTolerableDelay(List requestsOnBoard * @return boolean. */ private boolean canServeRequestTASeT(RideSharingOnDemandVehicle vehicle, PlanComputationRequest request) { - //TODO (check): if taxi can pick request in time //wont work since timeProvider is set null in test // return travelTimeProvider.getTravelTime(vehicle, request.getFrom()) + timeProvider.getCurrentSimTime() // < request.getMaxPickupTime(); diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/RequestPlan.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/RequestPlan.java new file mode 100644 index 00000000..e19f8488 --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/RequestPlan.java @@ -0,0 +1,38 @@ +package cz.cvut.fel.aic.simod.ridesharing.greedyTASeT; + +import cz.cvut.fel.aic.simod.ridesharing.model.PlanAction; +import cz.cvut.fel.aic.simod.ridesharing.model.PlanComputationRequest; + +import java.util.Iterator; +import java.util.List; + +public class RequestPlan implements Iterable{ + public final List plan; + + public final long totalTime; + + public final double cost; + + public PlanComputationRequest getRequest() { + return request; + } + + public void setRequest(PlanComputationRequest request) { + this.request = request; + } + + public PlanComputationRequest request; + + public RequestPlan(List plan, long totalTime, double cost ) { + this.plan = plan; + this.totalTime = totalTime; + this.cost = cost; + } + + @Override + public Iterator iterator() { + return plan.iterator(); + } + + // plan for each request, contains onboarding / offboarding actions +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/insertionheuristic/DriverPlan.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/insertionheuristic/DriverPlan.java index bb814c9d..e3ae0872 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/insertionheuristic/DriverPlan.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/insertionheuristic/DriverPlan.java @@ -19,6 +19,7 @@ package cz.cvut.fel.aic.simod.ridesharing.insertionheuristic; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.simod.ridesharing.RideSharingOnDemandVehicle; import cz.cvut.fel.aic.simod.ridesharing.model.PlanAction; import cz.cvut.fel.aic.simod.ridesharing.model.PlanActionCurrentPosition; import cz.cvut.fel.aic.simod.ridesharing.model.PlanActionDropoff; @@ -39,6 +40,10 @@ public class DriverPlan implements Iterable{ public final double cost; + public int vehicleIndex = -1; + + public RideSharingOnDemandVehicle vehicle; + @@ -69,6 +74,24 @@ public void taskCompleted(){ plan.remove(1); } + public void setVehicleIndex(int vehicleIndex) { + this.vehicleIndex = vehicleIndex; + } + + public void setVehicle(RideSharingOnDemandVehicle vehicle) { + this.vehicle = vehicle; + } + + public RideSharingOnDemandVehicle getVehicle() { + return this.vehicle; + } + + public int getVehicleIndex() { + return this.vehicleIndex; + } + + + @Override public String toString() { StringBuilder sb = new StringBuilder("["); diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionOffboard.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionOffboard.java new file mode 100644 index 00000000..b92be184 --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionOffboard.java @@ -0,0 +1,22 @@ +package cz.cvut.fel.aic.simod.ridesharing.model; + +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.simod.ridesharing.RideSharingOnDemandVehicle; + +public class PlanActionOffboard extends PlanRequestAction{ + + private RideSharingOnDemandVehicle fromVehicle; + + public PlanActionOffboard(PlanComputationRequest request, SimulationNode location, int maxTime, RideSharingOnDemandVehicle fromVehicle) { + super(request, location, maxTime); + this.fromVehicle = fromVehicle; + } + + public RideSharingOnDemandVehicle getFromVehicle() { + return fromVehicle; + } + + public void setFromVehicle(RideSharingOnDemandVehicle fromVehicle) { + this.fromVehicle = fromVehicle; + } +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionOnboard.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionOnboard.java new file mode 100644 index 00000000..881bd78a --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionOnboard.java @@ -0,0 +1,22 @@ +package cz.cvut.fel.aic.simod.ridesharing.model; + +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.simod.ridesharing.RideSharingOnDemandVehicle; + +public class PlanActionOnboard extends PlanRequestAction { + + private RideSharingOnDemandVehicle toVehicle; + + public PlanActionOnboard(PlanComputationRequest request, SimulationNode location, int maxTime, RideSharingOnDemandVehicle toVehicle) { + super(request, location, maxTime); + this.toVehicle = toVehicle; + } + + public RideSharingOnDemandVehicle getToVehicle() { + return toVehicle; + } + + public void setToVehicle(RideSharingOnDemandVehicle toVehicle) { + this.toVehicle = toVehicle; + } +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionWait.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionWait.java new file mode 100644 index 00000000..af054dea --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionWait.java @@ -0,0 +1,27 @@ +package cz.cvut.fel.aic.simod.ridesharing.model; + +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; + +public class PlanActionWait extends PlanRequestAction { + + protected final long waitTime; + + + + public long getWaitTime(){ + return waitTime; + } + + + + public PlanActionWait(PlanComputationRequest request, SimulationNode node, int maxTime, long waitTime) { + super(request, node, maxTime); + this.waitTime = waitTime; + + } + + @Override + public String toString() { + return String.format("Wait demand %s at node %s", request.getDemandAgent().getId(), location.id); + } +} diff --git a/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java b/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java index 2ba3d6df..2e480a47 100644 --- a/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java +++ b/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java @@ -5,41 +5,29 @@ import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.TripsUtil; import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.TimeProvider; import cz.cvut.fel.aic.agentpolis.simmodel.MoveUtil; -import cz.cvut.fel.aic.agentpolis.simmodel.entity.MovingEntity; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.GraphType; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.NearestElementUtils; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.Utils; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationEdge; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.networks.HighwayNetwork; -import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.networks.TransportNetworks; import cz.cvut.fel.aic.agentpolis.utils.PositionUtil; -import cz.cvut.fel.aic.alite.common.event.Event; -import cz.cvut.fel.aic.alite.common.event.EventHandler; -import cz.cvut.fel.aic.alite.common.event.EventProcessor; import cz.cvut.fel.aic.alite.common.event.typed.TypedSimulation; import cz.cvut.fel.aic.geographtools.Graph; import cz.cvut.fel.aic.geographtools.util.Transformer; import cz.cvut.fel.aic.simod.config.SimodConfig; -import cz.cvut.fel.aic.simod.event.OnDemandVehicleEvent; -import cz.cvut.fel.aic.simod.ridesharing.DARPSolver; import cz.cvut.fel.aic.simod.ridesharing.DroppedDemandsAnalyzer; import cz.cvut.fel.aic.simod.ridesharing.PlanCostProvider; import cz.cvut.fel.aic.simod.ridesharing.RideSharingOnDemandVehicle; import cz.cvut.fel.aic.simod.ridesharing.insertionheuristic.DriverPlan; import cz.cvut.fel.aic.simod.ridesharing.model.DefaultPlanComputationRequest; -import cz.cvut.fel.aic.simod.ridesharing.model.PlanActionDropoff; -import cz.cvut.fel.aic.simod.ridesharing.model.PlanActionPickup; import cz.cvut.fel.aic.simod.ridesharing.model.PlanComputationRequest; -import cz.cvut.fel.aic.simod.ridesharing.vga.model.Plan; import cz.cvut.fel.aic.simod.storage.OnDemandVehicleStorage; import cz.cvut.fel.aic.simod.storage.OnDemandvehicleStationStorage; import cz.cvut.fel.aic.simod.traveltimecomputation.AstarTravelTimeProvider; import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider; import cz.cvut.fel.aic.simod.ridesharing.greedyTASeT.GreedyTASeTSolver; import cz.cvut.fel.aic.simod.visual.ridesharing.vga.mock.TestPlanRequest; -import jdk.nashorn.internal.runtime.Debug; -import org.apache.commons.lang.exception.ExceptionUtils; import org.junit.Test; import java.util.*; @@ -75,6 +63,8 @@ public long getCurrentSimTime() { Graph graph = Utils.getCompleteGraph(4, transformer); AgentpolisConfig agentpolisConfig = new AgentpolisConfig(); MoveUtil moveUtil = new MoveUtil(agentpolisConfig); +// AStarShortestPathPlanner astarShortestPathPlanner = + AstarTravelTimeProvider astarTravelTimeProvider = new AstarTravelTimeProvider(timeProvider1, null, graph, moveUtil); OnDemandvehicleStationStorage onDemandvehicleStationStorage = new OnDemandvehicleStationStorage(transformer); DroppedDemandsAnalyzer droppedDemandsAnalyzer = new DroppedDemandsAnalyzer(vehicleStorage, positionUtil, astarTravelTimeProvider, config, onDemandvehicleStationStorage, agentpolisConfig); @@ -82,7 +72,10 @@ public long getCurrentSimTime() { GreedyTASeTSolver solver = new GreedyTASeTSolver(vehicleStorage, astarTravelTimeProvider, null, null, eventProcessor, config, timeProvider1, positionUtil, null, - onDemandvehicleStationStorage, agentpolisConfig); + onDemandvehicleStationStorage, agentpolisConfig, transferPoints); + +// TODO idk +// requestFactory = SimulationNode origin = new SimulationNode(1, 2, 55, 45, 55, 45, 200, 0); SimulationNode destination = new SimulationNode(2, 3, 56, 46, 56, 46, 210, 0); @@ -97,7 +90,7 @@ public long getCurrentSimTime() { req.add(rp1); req.add(rp2); List rr = new ArrayList<>(); - +// Map retMap = solver.solve(req, rr); From 52c9f854e9c7f2b4c6bbf78a3367d6da7e85efdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kub=C3=ADkov=C3=A1=2C=20Ad=C3=A9la?= Date: Sat, 1 Jan 2022 22:42:28 +0100 Subject: [PATCH 03/21] Implementation of heuristics method. --- .../greedyTASeT/GreedyTASeTSolver.java | 52 ++++++++----------- 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java index 622baba0..5c88d4b8 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java @@ -21,7 +21,6 @@ import cz.cvut.fel.aic.simod.storage.OnDemandVehicleStorage; import cz.cvut.fel.aic.simod.storage.OnDemandvehicleStationStorage; import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider; -import jdk.internal.util.xml.impl.Pair; import jdk.nashorn.internal.ir.RuntimeNode; import java.util.*; @@ -57,8 +56,6 @@ public class GreedyTASeTSolver extends DARPSolver implements EventHandler { - - @Inject public GreedyTASeTSolver( OnDemandVehicleStorage vehicleStorage, @@ -113,8 +110,6 @@ private void setEventHandeling() { eventProcessor.addEventHandler(this, typesToHandle); } - - /** * Transfer-allowed scheduling solver * @return Map @@ -129,9 +124,10 @@ public Map solve(List driverPlans = dispatch(taxis, newRequests); - for (int i = 0; i < driverPlans.size(); i++) { - planMap.put(taxis.get(i), driverPlans.get(i)); + List vehiclesWithPlans = dispatch(taxis, newRequests); + + for (int i = 0; i < vehiclesWithPlans.size(); i++) { + planMap.put(vehiclesWithPlans.get(i), vehiclesWithPlans.get(i).getCurrentPlan()); } return planMap; @@ -141,19 +137,19 @@ public Map solve(List dispatch(List taxis, List requests) { - List lst1 = dispatchVacantTaxi(taxis, requests); + private List dispatch(List taxis, List requests) { + // because all passengers allow ridesharing, only greedy taset will be called +// List lst1 = dispatchVacantTaxi(taxis, requests); List carpoolAcceptingTaxis = taxis; List carpoolAcceptingPassengers = requests; - List lst2 = heuristics(carpoolAcceptingTaxis, carpoolAcceptingPassengers); - for(PlanComputationRequest request : requests) { - // TODO: check duplicates + List lst2 = heuristics(carpoolAcceptingTaxis, carpoolAcceptingPassengers); +// for(PlanComputationRequest request : requests) { // is request served by both lst? - } - // todo prevest na driver plany +// } + // lst1.addAll(lst2); - List convertedlist = convertRequestPlansToDriverPlans(lst1, taxis); - return convertedlist; + return lst2; +// return convertedlist; } /** @@ -162,7 +158,7 @@ private List dispatch(List taxis, List

dispatchVacantTaxi(List taxis, List requests) { //taxi dispatch strategy that schedules taxis based on the shortest waiting time for the passengers - //TODO: implement method + //TODO: implement method??? //function can be changed to any dispatch strategy that a taxi company may currently be using (e.g., shortest waiting time and shortest cruising distance) // taxis.get(0).getPosition() // while mám volné taxíky @@ -171,12 +167,12 @@ private List dispatchVacantTaxi(List ta return null; } - /** * Greedy TASeT heuristics function * @return */ - private List heuristics(List taxis, List requests) { +// private List heuristics(List taxis, List requests) { + private List heuristics(List taxis, List requests) { //transfer points = charging stations List transferPoints = this.transferPoints; @@ -185,7 +181,7 @@ private List heuristics(List taxis, Lis int taxisCount = taxis.size(); long[][] LT = new long[stationsCount][taxisCount]; //fill the LT table - for(int i = 0; i < taxisCount; i++) { + for (int i = 0; i < taxisCount; i++) { RideSharingOnDemandVehicle taxi = taxis.get(i); SimulationNode taxiPosition = taxis.get(i).getPosition(); Set requestsOnBoardSet = new HashSet<>(); @@ -386,10 +382,10 @@ private List heuristics(List taxis, Lis List> plansForVehicles = entry.getKey(); List vehicles = entry.getValue(); for (int q = 0; q < vehicles.size(); q++) { - RideSharingOnDemandVehicle veh = vehicles.get(q); +// RideSharingOnDemandVehicle veh = vehicles.get(q); List vehPlan = plansForVehicles.get(q); DriverPlan dp = new DriverPlan(vehPlan, 0, 0); - veh.setCurrentPlan(dp); + vehicles.get(q).setCurrentPlan(dp); } } @@ -411,7 +407,7 @@ private List heuristics(List taxis, Lis for(int j = 0; j < stationsCount; j++) { //timeProvider is set to null so getCurrentSimTime() wont work //the idea is to fill LT with times of arrival of taxis -// LT[j][i] = this.timeProvider.getCurrentSimTime() + travelTime; + //LT[j][i] = this.timeProvider.getCurrentSimTime() + travelTime; //check if taxi has free seat if (!taxiFree) { LT[j][q] = Long.MAX_VALUE; @@ -445,7 +441,8 @@ private List heuristics(List taxis, Lis } } - return itinerarylist; +// return itinerarylist; + return taxis; } private long getTravelTime(PlanComputationRequest request, List planOfCar) { @@ -645,7 +642,6 @@ private Map>, Long> createChargePlan(List itnr } } - /** * Find DriverPlan with smallest delay without transfer allowed. * @return valid DriverPlan with smallest delay. @@ -668,7 +664,6 @@ private List findPlanWithNoTransfer(PlanComputationRequest newReques } List bestPlan = findItineraryWithMinimumDelay(lst); return bestPlan; - } private List getActionsForRequestFromActionsForDriver(List planActionsVehicle, PlanComputationRequest request, RideSharingOnDemandVehicle vehicle) { @@ -749,7 +744,6 @@ private List convertDriverPlansToRequestPlans(List driv } } } - return requestPlans; } @@ -791,11 +785,9 @@ else if (action instanceof PlanActionOnboard) { // TODO: resolve Wait Actions } } - return driverPlans; } - /** * Checks time constraints and counts delay among DriverPlans. * @return valid DriverPlan with smallest delay. From 77df58c9f1b5e7ff9b543ac563f1e9b9a7b4cc46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kub=C3=ADkov=C3=A1=2C=20Ad=C3=A9la?= Date: Sun, 2 Jan 2022 02:25:37 +0100 Subject: [PATCH 04/21] Run first test with bugs --- .../RideSharingOnDemandVehicle.java | 17 +- .../greedyTASeT/GreedyTASeTSolver.java | 141 ++++++---- .../insertionheuristic/DriverPlan.java | 22 +- .../model/DefaultPlanComputationRequest.java | 2 +- .../greedyTASeT/GreedyTASeTSolverTest.java | 247 +++++++++++++++--- 5 files changed, 309 insertions(+), 120 deletions(-) diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java index 4f4f5b44..541b6cdc 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java @@ -66,15 +66,18 @@ public class RideSharingOnDemandVehicle extends OnDemandVehicle{ private IdGenerator tripIdGenerator; - private final WaitActivityFactory waitActivityFactory; +// private final WaitActivityFactory waitActivityFactory; public DriverPlan getCurrentPlan() { currentPlan.updateCurrentPosition(getPosition()); return currentPlan; } public void setCurrentPlan(DriverPlan driverPlan) { - currentPlan = driverPlan; + List newPlan = new ArrayList<>(); + newPlan.add(currentPlan.plan.get(0)); + currentPlan.plan = newPlan; currentPlan.updateCurrentPosition(getPosition()); + currentPlan.plan.addAll(driverPlan.plan); } @@ -94,7 +97,7 @@ public RideSharingOnDemandVehicle( SimodConfig config, IdGenerator idGenerator, AgentpolisConfig agentpolisConfig, - WaitActivityFactory waitActivityFactory, +// WaitActivityFactory waitActivityFactory, @Assisted String vehicleId, @Assisted SimulationNode startPosition) { super( vehicleStorage, @@ -112,7 +115,7 @@ public RideSharingOnDemandVehicle( startPosition); this.positionUtil = positionUtil; this.tripIdGenerator = tripIdGenerator; - this.waitActivityFactory = waitActivityFactory; +// this.waitActivityFactory = waitActivityFactory; // empty plan LinkedList plan = new LinkedList<>(); @@ -245,9 +248,9 @@ private void driveToNextTask() { if(currentTask instanceof PlanActionPickup){ driveToDemandStartLocation(); } - else if(currentTask instanceof PlanActionWait) { - waitActivityFactory.runActivity(this, ((PlanActionWait) currentTask).getWaitTime()); - } +// else if(currentTask instanceof PlanActionWait) { +// waitActivityFactory.runActivity(this, ((PlanActionWait) currentTask).getWaitTime()); +// } else{ driveToTargetLocation(); } diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java index 5c88d4b8..86490812 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java @@ -118,8 +118,9 @@ private void setEventHandeling() { public Map solve(List newRequests, List waitingRequests) { Map planMap = new ConcurrentHashMap<>(); List taxis = new ArrayList<>(); - AgentPolisEntity[] tVvehicles = vehicleStorage.getEntitiesForIteration(); - for(AgentPolisEntity tVvehicle: tVvehicles) { + +// AgentPolisEntity[] tVvehicles = vehicleStorage.getEntitiesForIteration(); + for(AgentPolisEntity tVvehicle: vehicleStorage.getEntitiesForIteration()) { RideSharingOnDemandVehicle vehicle = (RideSharingOnDemandVehicle) tVvehicle; taxis.add(vehicle); } @@ -272,10 +273,8 @@ private List heuristics(List itnryp1 = findPlanWithNoTransfer(newRequest1, taxi); // pro auto //List itnryp1R = getActionsForRequestFromActionsForDriver(itnryp1, newRequest1, taxi); @@ -300,6 +299,8 @@ private List heuristics(List transferPlan = splittedRequestToPlanForRequest(itnryp1, itnryp2, newRequest1, newRequest2, request); templist.put(submap2, transferPlan); + // TODO get travel time nefunguje dobre pro prestup + // asi kvuli traxi.getPosition() long travelTimeTransfer = getTravelTime(newRequest1, itnryp1) + getTravelTime(newRequest2, itnryp2); delays.add(travelTimeNoTransfer - travelTimeTransfer); long transferTime = entry.getValue(); @@ -425,20 +426,20 @@ private List heuristics(List possiblePickupTaxisOneRequest = new ArrayList<>(); - for(RideSharingOnDemandVehicle t : taxis) { - if (canServeRequestTASeT(t, req)) { - counter++; - possiblePickupTaxisOneRequest.add(t); - } - } - possiblePickupTaxisCounts[i] = counter; - possiblePickupTaxisMap.put(req, possiblePickupTaxisOneRequest); - i++; - } +// //update k +// for(PlanComputationRequest req : requests) { +// int counter = 0; +// List possiblePickupTaxisOneRequest = new ArrayList<>(); +// for(RideSharingOnDemandVehicle t : taxis) { +// if (canServeRequestTASeT(t, req)) { +// counter++; +// possiblePickupTaxisOneRequest.add(t); +// } +// } +// possiblePickupTaxisCounts[i] = counter; +// possiblePickupTaxisMap.put(req, possiblePickupTaxisOneRequest); +// i++; +// } } // return itinerarylist; @@ -495,17 +496,18 @@ private List splittedRequestToPlanForRequest(List itnryp //do the same with the second itnryp for (PlanAction action : itnryp1) { if (action instanceof PlanRequestAction) { + PlanRequestAction requestAction = (PlanRequestAction) action; PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); if (action instanceof PlanActionPickup) { if (pcq.getPickUpAction().request == newRequest1) { - PlanActionPickup pickup = (PlanActionPickup) pcq; - PlanActionPickup newPickup = new PlanActionPickup(originalRequest, pickup.getPosition(), pickup.getMaxTime()); +// PlanActionPickup pickup = (PlanActionPickup) pcq; + PlanActionPickup newPickup = new PlanActionPickup(originalRequest, action.getPosition(), requestAction.getMaxTime()); listForOriginalRequest.add(newPickup); } } else if (action instanceof PlanActionDropoff) { if (pcq.getDropOffAction().request == newRequest1) { - PlanActionDropoff dropoff = (PlanActionDropoff) pcq; - PlanActionDropoff newDropoff = new PlanActionDropoff(originalRequest, dropoff.getPosition(), dropoff.getMaxTime()); +// PlanActionDropoff dropoff = (PlanActionDropoff) pcq; + PlanActionDropoff newDropoff = new PlanActionDropoff(originalRequest, action.getPosition(), requestAction.getMaxTime()); listForOriginalRequest.add(newDropoff); } } @@ -513,17 +515,18 @@ private List splittedRequestToPlanForRequest(List itnryp } for (PlanAction action : itnryp2) { if (action instanceof PlanRequestAction) { + PlanRequestAction requestAction = (PlanRequestAction) action; PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); if (action instanceof PlanActionPickup) { if (pcq.getPickUpAction().request == newRequest2) { - PlanActionPickup pickup = (PlanActionPickup) pcq; - PlanActionPickup newPickup = new PlanActionPickup(originalRequest, pickup.getPosition(), pickup.getMaxTime()); +// PlanActionPickup pickup = (PlanActionPickup) pcq; + PlanActionPickup newPickup = new PlanActionPickup(originalRequest, action.getPosition(), requestAction.getMaxTime()); listForOriginalRequest.add(newPickup); } } else if (action instanceof PlanActionDropoff) { if (pcq.getDropOffAction().request == newRequest2) { - PlanActionDropoff dropoff = (PlanActionDropoff) pcq; - PlanActionDropoff newDropoff = new PlanActionDropoff(originalRequest, dropoff.getPosition(), dropoff.getMaxTime()); +// PlanActionDropoff dropoff = (PlanActionDropoff) pcq; + PlanActionDropoff newDropoff = new PlanActionDropoff(originalRequest, action.getPosition(), requestAction.getMaxTime()); listForOriginalRequest.add(newDropoff); } } @@ -593,7 +596,7 @@ private Map>, Long> createChargePlan(List itnr boolean valid = true; // pridam wait time do planu pro druhe auto pokud je wait time zaporny - if (waitTime < 0) { + if (waitTime <= 0) { //transfer time je -waitTime PlanActionWait waitAction = new PlanActionWait(null, pickup.getPosition(), pickup.getMaxTime(), -waitTime); transferTime = -waitTime; @@ -607,7 +610,7 @@ private Map>, Long> createChargePlan(List itnr if (action instanceof PlanActionPickup) { SimulationNode dest = pcq.getFrom(); time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); - if (!(time < pcq.getMaxPickupTime())) { + if (!(time < pcq.getMaxPickupTime()*1000)) { //not valid itinerary - check new driver plan valid = false; break; @@ -616,7 +619,7 @@ private Map>, Long> createChargePlan(List itnr } else if (action instanceof PlanActionDropoff) { SimulationNode dest = pcq.getTo(); time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); - if (!(time < pcq.getMaxDropoffTime())) { + if (!(time < pcq.getMaxDropoffTime()*1000)) { //not valid itinerary - check new driver plan valid = false; break; @@ -642,6 +645,26 @@ private Map>, Long> createChargePlan(List itnr } } + public List getPickupActions(List plan) { + List pickups = new ArrayList<>(); + for(PlanAction action : plan) { + if(action instanceof PlanActionPickup) { + pickups.add(action); + } + } + return pickups; + } + + public List getDropoffActions(List plan) { + List dropoffs = new ArrayList<>(); + for(PlanAction action : plan) { + if(action instanceof PlanActionDropoff) { + dropoffs.add(action); + } + } + return dropoffs; + } + /** * Find DriverPlan with smallest delay without transfer allowed. * @return valid DriverPlan with smallest delay. @@ -649,14 +672,18 @@ private Map>, Long> createChargePlan(List itnr private List findPlanWithNoTransfer(PlanComputationRequest newRequest, RideSharingOnDemandVehicle taxi) { int n = taxi.getOnBoardCount(); List lst = new ArrayList<>(); - DriverPlan currentPlan = taxi.getCurrentPlan(); + List currentPlan = taxi.getCurrentPlan().plan; + List newPlan = new ArrayList<>(); + for (PlanAction action : currentPlan) { + newPlan.add(action); + } //add pickup and dropoff for new request - currentPlan.plan.add(newRequest.getPickUpAction()); - currentPlan.plan.add(newRequest.getDropOffAction()); + newPlan.add(newRequest.getPickUpAction()); + newPlan.add(newRequest.getDropOffAction()); //get pickup order based on heuristic from TASeT paper - List pickups = currentPlan.getPickupActions(); + List pickups = getPickupActions(newPlan); //get dropoff actions in currentPlan - List dropoffs = currentPlan.getDropoffActions(); + List dropoffs = getDropoffActions(newPlan); //permute dropoff orders List> dropoffOrders = permute(dropoffs); for (List dropoffPlan : dropoffOrders) { @@ -675,25 +702,39 @@ private List getActionsForRequestFromActionsForDriver(List findItineraryWithMinimumDelay(List plans) // TODO: how to set (initialize) previousDestination? // vychozi pozice, odkud auto vyjizdi SimulationNode previousDestination = driverPlan.plan.get(0).getPosition(); - previousDestination = driverPlan.vehicle.getPosition(); +// previousDestination = driverPlan.vehicle.getPosition(); for (int i = 0; i < driverPlan.getLength(); i++) { PlanAction action = driverPlan.plan.get(i); @@ -922,7 +963,7 @@ private boolean canServeRequestTASeT(RideSharingOnDemandVehicle vehicle, PlanCom //wont work since timeProvider is set null in test // return travelTimeProvider.getTravelTime(vehicle, request.getFrom()) + timeProvider.getCurrentSimTime() // < request.getMaxPickupTime(); - return travelTimeProvider.getTravelTime(vehicle, request.getFrom()) < request.getMaxPickupTime(); + return travelTimeProvider.getTravelTime(vehicle, request.getFrom()) < request.getMaxPickupTime() * 1000; } diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/insertionheuristic/DriverPlan.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/insertionheuristic/DriverPlan.java index e3ae0872..df9ac88a 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/insertionheuristic/DriverPlan.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/insertionheuristic/DriverPlan.java @@ -34,7 +34,7 @@ * @author F.I.D.O. */ public class DriverPlan implements Iterable{ - public final List plan; + public List plan; public final long totalTime; @@ -104,26 +104,6 @@ public String toString() { return sb.toString(); } - // TODO: check if that works - public List getPickupActions() { - List pickups = new ArrayList<>(); - for(PlanAction action : plan) { - if(action instanceof PlanActionPickup) { - pickups.add(action); - } - } - return pickups; - } - - public List getDropoffActions() { - List dropoffs = new ArrayList<>(); - for(PlanAction action : plan) { - if(action instanceof PlanActionDropoff) { - dropoffs.add(action); - } - } - return dropoffs; - } } diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/DefaultPlanComputationRequest.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/DefaultPlanComputationRequest.java index 677cf48f..94336bf6 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/DefaultPlanComputationRequest.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/DefaultPlanComputationRequest.java @@ -86,7 +86,7 @@ public DemandAgent getDemandAgent() { @Inject - private DefaultPlanComputationRequest(TravelTimeProvider travelTimeProvider, @Assisted int id, + public DefaultPlanComputationRequest(TravelTimeProvider travelTimeProvider, @Assisted int id, SimodConfig SimodConfig, @Assisted("origin") SimulationNode origin, @Assisted("destination") SimulationNode destination, @Assisted DemandAgent demandAgent){ this.id = id; diff --git a/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java b/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java index 2e480a47..eea5d4f2 100644 --- a/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java +++ b/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java @@ -1,33 +1,45 @@ package cz.cvut.fel.aic.simod.visual.ridesharing.greedyTASeT; import cz.cvut.fel.aic.agentpolis.config.AgentpolisConfig; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.AStarShortestPathPlanner; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.EuclideanTraveltimeHeuristic; import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.ShortestPathPlanner; import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.TripsUtil; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.StandardTimeProvider; import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.TimeProvider; +import cz.cvut.fel.aic.agentpolis.simmodel.IdGenerator; import cz.cvut.fel.aic.agentpolis.simmodel.MoveUtil; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.EGraphType; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.GraphType; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.NearestElementUtils; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.Utils; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationEdge; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.networks.HighwayNetwork; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.networks.TransportNetworks; import cz.cvut.fel.aic.agentpolis.utils.PositionUtil; import cz.cvut.fel.aic.alite.common.event.typed.TypedSimulation; import cz.cvut.fel.aic.geographtools.Graph; import cz.cvut.fel.aic.geographtools.util.Transformer; import cz.cvut.fel.aic.simod.config.SimodConfig; +import cz.cvut.fel.aic.simod.entity.DemandAgent; +import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicle; +import cz.cvut.fel.aic.simod.io.TimeTrip; import cz.cvut.fel.aic.simod.ridesharing.DroppedDemandsAnalyzer; import cz.cvut.fel.aic.simod.ridesharing.PlanCostProvider; import cz.cvut.fel.aic.simod.ridesharing.RideSharingOnDemandVehicle; +import cz.cvut.fel.aic.simod.ridesharing.StandardPlanCostProvider; import cz.cvut.fel.aic.simod.ridesharing.insertionheuristic.DriverPlan; import cz.cvut.fel.aic.simod.ridesharing.model.DefaultPlanComputationRequest; import cz.cvut.fel.aic.simod.ridesharing.model.PlanComputationRequest; import cz.cvut.fel.aic.simod.storage.OnDemandVehicleStorage; import cz.cvut.fel.aic.simod.storage.OnDemandvehicleStationStorage; +import cz.cvut.fel.aic.simod.storage.PhysicalTransportVehicleStorage; import cz.cvut.fel.aic.simod.traveltimecomputation.AstarTravelTimeProvider; import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider; import cz.cvut.fel.aic.simod.ridesharing.greedyTASeT.GreedyTASeTSolver; import cz.cvut.fel.aic.simod.visual.ridesharing.vga.mock.TestPlanRequest; +import ninja.fido.config.Configuration; import org.junit.Test; import java.util.*; @@ -36,13 +48,13 @@ public class GreedyTASeTSolverTest { @Test public void run() { - OnDemandVehicleStorage vehicleStorage = new OnDemandVehicleStorage(); - TravelTimeProvider travelTimeProvider = null; - TimeProvider timeProvider = null; - PlanCostProvider travelCostProvider = null; - DefaultPlanComputationRequest.DefaultPlanComputationRequestFactory requestFactory = null; + TypedSimulation eventProcessor = new TypedSimulation(120); - SimodConfig config = new SimodConfig(); + SimodConfig simodConfig = new SimodConfig(); + IdGenerator tripIdGenerator = new IdGenerator(); + IdGenerator idGenerator2 = new IdGenerator(); + IdGenerator idGenerator3 = new IdGenerator(); + TimeProvider timeProvider1 = new TimeProvider() { @Override public long getCurrentSimTime() { @@ -50,49 +62,202 @@ public long getCurrentSimTime() { } }; PositionUtil positionUtil = new PositionUtil(); - TripsUtil tripsUtil = null; - // TripsUtil(ShortestPathPlanner pathPlanner, NearestElementUtils nearestElementUtils, HighwayNetwork network, IdGenerator tripIdGenerator) - ShortestPathPlanner pathPlanner = null; - NearestElementUtils nearestElementUtils = new NearestElementUtils(null, null); - HighwayNetwork highwayNetwork = new HighwayNetwork(null); - - Map> map = null; + // creating MAP of city: 4columns x 3rows grid int citySRID = 32618; Transformer transformer = new Transformer(citySRID); - Graph graph = Utils.getCompleteGraph(4, transformer); + Graph graph = Utils.getGridGraph(4, transformer, 3); + Map> gridMap = new HashMap<>(); + gridMap.put(EGraphType.HIGHWAY, graph); + + // setting up Agentpolis config AgentpolisConfig agentpolisConfig = new AgentpolisConfig(); + Configuration.load(agentpolisConfig, simodConfig, null, "agentpolis"); + + // TripsUtil initialization MoveUtil moveUtil = new MoveUtil(agentpolisConfig); -// AStarShortestPathPlanner astarShortestPathPlanner = + TransportNetworks transportNetworks = new TransportNetworks(gridMap); + AStarShortestPathPlanner aStarPlanner = new AStarShortestPathPlanner( + transportNetworks, + new EuclideanTraveltimeHeuristic(positionUtil), + agentpolisConfig, + moveUtil + ); + NearestElementUtils nearestElementUtils = new NearestElementUtils(transportNetworks, transformer); + TripsUtil tripsUtil = new TripsUtil( + aStarPlanner, + nearestElementUtils, + new HighwayNetwork(graph), + tripIdGenerator + ); + + // Time providers + AstarTravelTimeProvider astarTravelTimeProvider = new AstarTravelTimeProvider(timeProvider1, tripsUtil, graph, moveUtil); + StandardTimeProvider standardTimeProvider = new StandardTimeProvider(eventProcessor); + + StandardPlanCostProvider travelCostProvider = new StandardPlanCostProvider(simodConfig); - AstarTravelTimeProvider astarTravelTimeProvider = new AstarTravelTimeProvider(timeProvider1, null, graph, moveUtil); + // Storages + OnDemandVehicleStorage onDemandVehicleStorage = new OnDemandVehicleStorage(); + PhysicalTransportVehicleStorage physicalVehicleStorage = new PhysicalTransportVehicleStorage(); OnDemandvehicleStationStorage onDemandvehicleStationStorage = new OnDemandvehicleStationStorage(transformer); - DroppedDemandsAnalyzer droppedDemandsAnalyzer = new DroppedDemandsAnalyzer(vehicleStorage, positionUtil, astarTravelTimeProvider, config, onDemandvehicleStationStorage, agentpolisConfig); - - - GreedyTASeTSolver solver = new GreedyTASeTSolver(vehicleStorage, astarTravelTimeProvider, null, null, - eventProcessor, config, timeProvider1, positionUtil, null, - onDemandvehicleStationStorage, agentpolisConfig, transferPoints); - -// TODO idk -// requestFactory = - - SimulationNode origin = new SimulationNode(1, 2, 55, 45, 55, 45, 200, 0); - SimulationNode destination = new SimulationNode(2, 3, 56, 46, 56, 46, 210, 0); - // null pointer exception because trips util is null - TestPlanRequest r1 = new TestPlanRequest(2, config, origin, destination, 0, false, astarTravelTimeProvider); - SimulationNode origin2 = new SimulationNode(1, 2, 55, 46, 55, 46, 200, 0); - SimulationNode destination2 = new SimulationNode(2, 3, 56, 45, 56, 5, 210, 0); - TestPlanRequest r2 = new TestPlanRequest(2, config, origin2, destination2, 0, false, astarTravelTimeProvider); - List req = new ArrayList<>(); - PlanComputationRequest rp1 = (PlanComputationRequest)r1; - PlanComputationRequest rp2 = (PlanComputationRequest)r2; - req.add(rp1); - req.add(rp2); - List rr = new ArrayList<>(); + + DroppedDemandsAnalyzer droppedDemandsAnalyzer = null; // new DroppedDemandsAnalyzer( vehicleStorage, positionUtil, astarTravelTimeProvider, config, onDemandvehicleStationStorage, agentpolisConfig); + + // start position of 1st vehicle + SimulationNode startPos = graph.getNode(1); // top left corner + + RideSharingOnDemandVehicle vehicle_1 = new RideSharingOnDemandVehicle( + physicalVehicleStorage, + tripsUtil, + null, + null, + null, + tripIdGenerator, + eventProcessor, + standardTimeProvider, + idGenerator2, + simodConfig, + idGenerator3, + agentpolisConfig, + "1", + startPos + ); + onDemandVehicleStorage.addEntity(vehicle_1); + + SimulationNode transferPoint = graph.getNode(7); + List transferPoints = new ArrayList<>(); + transferPoints.add(transferPoint); + + GreedyTASeTSolver solver = new GreedyTASeTSolver( onDemandVehicleStorage, + astarTravelTimeProvider, + travelCostProvider, + null, + eventProcessor, + simodConfig, + timeProvider1, + positionUtil, + droppedDemandsAnalyzer, + onDemandvehicleStationStorage, + agentpolisConfig, + transferPoints + ); + + // create requests + SimulationNode origin_1 = graph.getNode(1); + SimulationNode destination_1 = graph.getNode(3); + long startTime = 0; + long endTime = 1000; + SimulationNode[] locations = {origin_1, destination_1}; + DemandAgent demandAgent_0 = new DemandAgent( + null, + eventProcessor, + null, + standardTimeProvider, + tripsUtil, + "agent_00", + 0, + new TimeTrip( + 0, + startTime, + endTime, + locations + ) + ); + + SimulationNode origin_2 = graph.getNode(3); + SimulationNode destination_2 = graph.getNode(6); + long startTime2 = 1050; + long endTime2 = 2500; + SimulationNode[] locations2 = {origin_2, destination_2}; + DemandAgent demandAgent_1 = new DemandAgent( + null, + eventProcessor, + null, + standardTimeProvider, + tripsUtil, + "agent_01", + 1, + new TimeTrip( + 0, + startTime2, + endTime2, + locations2 + ) + ); + + DefaultPlanComputationRequest request_1 = new DefaultPlanComputationRequest(astarTravelTimeProvider, 0, simodConfig, origin_1, destination_1, demandAgent_0); + DefaultPlanComputationRequest request_2 = new DefaultPlanComputationRequest(astarTravelTimeProvider, 1, simodConfig, origin_2, destination_2, demandAgent_1); + List requestsPeople = new ArrayList<>(); + requestsPeople.add(request_1); + requestsPeople.add(request_2); + + // call solve method + Map solution = solver.solve(requestsPeople, null); + System.out.println("Solution:"); + System.out.println(solution.values().toString()); + + + +// OnDemandVehicleStorage vehicleStorage = new OnDemandVehicleStorage(); +// TravelTimeProvider travelTimeProvider = null; +// TimeProvider timeProvider = null; +// PlanCostProvider travelCostProvider = null; +// DefaultPlanComputationRequest.DefaultPlanComputationRequestFactory requestFactory = null; +// TypedSimulation eventProcessor = new TypedSimulation(120); +// SimodConfig config = new SimodConfig(); +// TimeProvider timeProvider1 = new TimeProvider() { +// @Override +// public long getCurrentSimTime() { +// return 0; +// } +// }; +// PositionUtil positionUtil = new PositionUtil(); +// TripsUtil tripsUtil = null; +// // TripsUtil(ShortestPathPlanner pathPlanner, NearestElementUtils nearestElementUtils, HighwayNetwork network, IdGenerator tripIdGenerator) +// ShortestPathPlanner pathPlanner = null; +// NearestElementUtils nearestElementUtils = new NearestElementUtils(null, null); +// HighwayNetwork highwayNetwork = new HighwayNetwork(null); +// +// +// Map> map = null; +// int citySRID = 32618; +// Transformer transformer = new Transformer(citySRID); +// Graph graph = Utils.getCompleteGraph(4, transformer); +// AgentpolisConfig agentpolisConfig = new AgentpolisConfig(); +// MoveUtil moveUtil = new MoveUtil(agentpolisConfig); +//// AStarShortestPathPlanner astarShortestPathPlanner = +// +// AstarTravelTimeProvider astarTravelTimeProvider = new AstarTravelTimeProvider(timeProvider1, null, graph, moveUtil); +// OnDemandvehicleStationStorage onDemandvehicleStationStorage = new OnDemandvehicleStationStorage(transformer); +// DroppedDemandsAnalyzer droppedDemandsAnalyzer = new DroppedDemandsAnalyzer(vehicleStorage, positionUtil, astarTravelTimeProvider, config, onDemandvehicleStationStorage, agentpolisConfig); +// +// +// GreedyTASeTSolver solver = new GreedyTASeTSolver(vehicleStorage, astarTravelTimeProvider, null, null, +// eventProcessor, config, timeProvider1, positionUtil, null, +// onDemandvehicleStationStorage, agentpolisConfig, transferPoints); +// +//// TODO idk +//// requestFactory = +// +// SimulationNode origin = new SimulationNode(1, 2, 55, 45, 55, 45, 200, 0); +// SimulationNode destination = new SimulationNode(2, 3, 56, 46, 56, 46, 210, 0); +// // null pointer exception because trips util is null +// TestPlanRequest r1 = new TestPlanRequest(2, config, origin, destination, 0, false, astarTravelTimeProvider); +// SimulationNode origin2 = new SimulationNode(1, 2, 55, 46, 55, 46, 200, 0); +// SimulationNode destination2 = new SimulationNode(2, 3, 56, 45, 56, 5, 210, 0); +// TestPlanRequest r2 = new TestPlanRequest(2, config, origin2, destination2, 0, false, astarTravelTimeProvider); +// List req = new ArrayList<>(); +// PlanComputationRequest rp1 = (PlanComputationRequest)r1; +// PlanComputationRequest rp2 = (PlanComputationRequest)r2; +// req.add(rp1); +// req.add(rp2); +// List rr = new ArrayList<>(); +//// +// +// +// Map retMap = solver.solve(req, rr); // - Map retMap = solver.solve(req, rr); - } From f6c5d8a85abaa71b64b2dbe4be55505bbb191fda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kub=C3=ADkov=C3=A1=2C=20Ad=C3=A9la?= Date: Tue, 15 Feb 2022 10:23:28 +0100 Subject: [PATCH 05/21] Integration to simod --- .../cz/cvut/fel/aic/simod/MapVisualizer.java | 4 + .../aic/simod/OnDemandVehiclesSimulation.java | 7 + .../fel/aic/simod/config/SimodConfig.java | 3 + .../simod/init/TransferPointsInitializer.java | 138 ++++++++ .../greedyTASeT/GreedyTASeTSolver.java | 305 +++++------------- .../greedyTASeT/GreedyTASeTSolverTest.java | 7 +- 6 files changed, 231 insertions(+), 233 deletions(-) create mode 100644 src/main/java/cz/cvut/fel/aic/simod/init/TransferPointsInitializer.java diff --git a/src/main/java/cz/cvut/fel/aic/simod/MapVisualizer.java b/src/main/java/cz/cvut/fel/aic/simod/MapVisualizer.java index ad7c7820..900a1c7a 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/MapVisualizer.java +++ b/src/main/java/cz/cvut/fel/aic/simod/MapVisualizer.java @@ -25,6 +25,7 @@ import cz.cvut.fel.aic.agentpolis.system.AgentPolisInitializer; import cz.cvut.fel.aic.simod.config.SimodConfig; import cz.cvut.fel.aic.simod.init.StationsInitializer; +import cz.cvut.fel.aic.simod.init.TransferPointsInitializer; import cz.cvut.fel.aic.simod.mapVisualization.MapVisualiserModule; import cz.cvut.fel.aic.simod.mapVisualization.MapVisualizationCreator; import java.io.File; @@ -60,6 +61,9 @@ public void run(String[] args) { // load stations injector.getInstance(StationsInitializer.class).loadStations(); + // load transfer points + injector.getInstance(TransferPointsInitializer.class).loadTransferPoints(); + creator.startSimulation(); diff --git a/src/main/java/cz/cvut/fel/aic/simod/OnDemandVehiclesSimulation.java b/src/main/java/cz/cvut/fel/aic/simod/OnDemandVehiclesSimulation.java index 1454ace0..65048fd4 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/OnDemandVehiclesSimulation.java +++ b/src/main/java/cz/cvut/fel/aic/simod/OnDemandVehiclesSimulation.java @@ -27,8 +27,10 @@ import cz.cvut.fel.aic.simod.init.EventInitializer; import cz.cvut.fel.aic.simod.init.StationsInitializer; import cz.cvut.fel.aic.simod.init.StatisticInitializer; +import cz.cvut.fel.aic.simod.init.TransferPointsInitializer; import cz.cvut.fel.aic.simod.io.TripTransform; import cz.cvut.fel.aic.simod.rebalancing.ReactiveRebalancing; +import cz.cvut.fel.aic.simod.ridesharing.greedyTASeT.GreedyTASeTSolver; import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider; import cz.cvut.fel.aic.simod.statistics.Statistics; import cz.cvut.fel.aic.simod.tripUtil.TripsUtilCached; @@ -51,6 +53,7 @@ public static void checkPaths(SimodConfig config, AgentpolisConfig agentpolisCon String[] pathsForRead = { config.tripsPath, config.stationPositionFilepath, + config.transferPointsFilepath, agentpolisConfig.mapNodesFilepath, agentpolisConfig.mapEdgesFilepath }; @@ -109,6 +112,10 @@ public void run(String[] args) { // load stations injector.getInstance(StationsInitializer.class).loadStations(); + // load transfer points +// injector.getInstance(TransferPointsInitializer.class).loadTransferPoints(); + injector.getInstance(GreedyTASeTSolver.class).setTransferPoints(injector.getInstance(TransferPointsInitializer.class).loadTransferPoints()); + if(config.rebalancing.on){ // start rebalancing diff --git a/src/main/java/cz/cvut/fel/aic/simod/config/SimodConfig.java b/src/main/java/cz/cvut/fel/aic/simod/config/SimodConfig.java index ef16dedd..0521c112 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/config/SimodConfig.java +++ b/src/main/java/cz/cvut/fel/aic/simod/config/SimodConfig.java @@ -48,6 +48,8 @@ public class SimodConfig implements GeneratedConfig { public String stationPositionFilepath; + public String transferPointsFilepath; + public Rebalancing rebalancing; public Statistics statistics; @@ -76,6 +78,7 @@ public SimodConfig fill(Map simodConfig) { this.simplifyGraph = (Boolean) simodConfig.get("simplify_graph"); this.ridesharing = new Ridesharing((Map) simodConfig.get("ridesharing")); this.stationPositionFilepath = (String) simodConfig.get("station_position_filepath"); + this.transferPointsFilepath = (String) simodConfig.get("transfer_points_filepath"); this.rebalancing = new Rebalancing((Map) simodConfig.get("rebalancing")); this.statistics = new Statistics((Map) simodConfig.get("statistics")); return this; diff --git a/src/main/java/cz/cvut/fel/aic/simod/init/TransferPointsInitializer.java b/src/main/java/cz/cvut/fel/aic/simod/init/TransferPointsInitializer.java new file mode 100644 index 00000000..a109cde4 --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/init/TransferPointsInitializer.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2021 Czech Technical University in Prague. + * + * This file is part of the SiMoD project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package cz.cvut.fel.aic.simod.init; + +import com.google.inject.Inject; +import com.univocity.parsers.csv.CsvParser; +import com.univocity.parsers.csv.CsvParserSettings; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.networks.NodesMappedByIndex; +import cz.cvut.fel.aic.simod.config.SimodConfig; +import cz.cvut.fel.aic.simod.entity.OnDemandVehicleStation; +import cz.cvut.fel.aic.simod.entity.OnDemandVehicleStation.OnDemandVehicleStationFactory; +import cz.cvut.fel.aic.simod.traveltimecomputation.DistanceMatrixTravelTimeProvider; +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author david + */ +public class TransferPointsInitializer { + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(DistanceMatrixTravelTimeProvider.class); + + private final OnDemandVehicleStation.OnDemandVehicleStationFactory onDemandVehicleStationFactory; + + private final NodesMappedByIndex nodesMappedByIndex; + + private final SimodConfig config; + + + + @Inject + public TransferPointsInitializer(OnDemandVehicleStationFactory onDemandVehicleStationFactory, NodesMappedByIndex + nodesMappedByIndex, SimodConfig config) { + this.onDemandVehicleStationFactory = onDemandVehicleStationFactory; + this.nodesMappedByIndex = nodesMappedByIndex; + this.config = config; + } + + + public List loadTransferPoints(){ + List transferPoints = new ArrayList<>(); + List stationRows = loadTransferPointsRows(config.transferPointsFilepath); + LOGGER.info("{} Stations indexes loaded from {}", stationRows.size(), config.transferPointsFilepath); + + int counter = 0; + int discarded = 0; + for(String[] row: stationRows){ + int index = Integer.parseInt(row[0]); + SimulationNode node = nodesMappedByIndex.getNodeByIndex(index); + if(node == null){ + LOGGER.info("Station at node with index {} discarded as it is not in the Agentpolis road graph", index); + discarded++; + } + else{ +// int initCount = Integer.parseInt(row[1]) + 100; +// if(initCount < 500){ +// initCount += 100; +// } + transferPoints.add(node); + //createStation(node, initCount, counter++); + } + } + + LOGGER.info("{} Stations Discarded", discarded); + + return transferPoints; + + } + + private List loadTransferPointsRows(String filepath){ + LOGGER.info("Loading station positions from: {}", filepath); + + try { + Reader reader + = new BufferedReader(new InputStreamReader(new FileInputStream(filepath), "utf-8")); + CsvParserSettings settings = new CsvParserSettings(); + + settings.getFormat().setLineSeparator("\r\n"); + + //turning off features enabled by default + settings.setIgnoreLeadingWhitespaces(false); + settings.setIgnoreTrailingWhitespaces(false); + settings.setSkipEmptyLines(false); + settings.setColumnReorderingEnabled(false); + + CsvParser parser = new CsvParser(settings); + + Iterator it = parser.iterate(reader).iterator(); + + String[] row; + + // first row processing + List stationRows = new ArrayList<>(); + while (it.hasNext()) { + row = it.next(); + stationRows.add(row); + } + parser.stopParsing(); + return stationRows; + } + catch (FileNotFoundException | UnsupportedEncodingException ex) { + Logger.getLogger(DistanceMatrixTravelTimeProvider.class.getName()).log(Level.SEVERE, null, ex); + return null; + } + } + + // TODO: nahradit + private void createStation(SimulationNode position, int vehicleCount, int id){ + onDemandVehicleStationFactory.create(Integer.toString(id), position, vehicleCount); + } +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java index 86490812..5f9e7ccb 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java @@ -1,6 +1,7 @@ package cz.cvut.fel.aic.simod.ridesharing.greedyTASeT; import com.google.inject.Inject; +import com.google.inject.Singleton; import cz.cvut.fel.aic.agentpolis.config.AgentpolisConfig; import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.TimeProvider; import cz.cvut.fel.aic.agentpolis.simmodel.entity.AgentPolisEntity; @@ -26,6 +27,7 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; +@Singleton public class GreedyTASeTSolver extends DARPSolver implements EventHandler { @@ -47,12 +49,10 @@ public class GreedyTASeTSolver extends DARPSolver implements EventHandler { private final int maxDelayTime = 10; - private final List transferPoints; + private List transferPoints; protected final DefaultPlanComputationRequest.DefaultPlanComputationRequestFactory requestFactory; - //copied from insertionHeuristicSolver - private GreedyTASeTSolver.PlanData bestPlan; @@ -68,7 +68,15 @@ public GreedyTASeTSolver( PositionUtil positionUtil, DroppedDemandsAnalyzer droppedDemandsAnalyzer, OnDemandvehicleStationStorage onDemandvehicleStationStorage, - AgentpolisConfig agentpolisConfig, List transferPoints) { + AgentpolisConfig agentpolisConfig) { + // late binding na prestupni stanice + // vyhodit transfer points z konstruktoru + // vytvorit metodu sem do toho solveru get station s parametrem List + + // zkompirovat tridu StationsInitializer a jenom poupravit + // v greedyTASeT solveru udelat metodu - setter na list transfer stations kde si je vezmu z parametru a jenom je hodim na this.trasnferpoints = + + super(vehicleStorage, travelTimeProvider, travelCostProvider, requestFactory); this.eventProcessor = eventProcessor; this.config = config; @@ -77,9 +85,8 @@ public GreedyTASeTSolver( this.droppedDemandsAnalyzer = droppedDemandsAnalyzer; this.onDemandvehicleStationStorage = onDemandvehicleStationStorage; this.requestFactory = requestFactory; - this.transferPoints = transferPoints; - //TODO: resolve + //TODO: // commented because config is null in test // // max distance in meters between vehicle and request for the vehicle to be considered to serve the request // maxDistance = (double) config.ridesharing.maxProlongationInSeconds @@ -93,6 +100,10 @@ public GreedyTASeTSolver( setEventHandeling(); } + public void setTransferPoints(List transferPoints) { + this.transferPoints = transferPoints; + } + @Override public EventProcessor getEventProcessor() { return eventProcessor; @@ -103,6 +114,7 @@ public void handleEvent(Event event) { } + private void setEventHandeling() { List typesToHandle = new LinkedList<>(); @@ -140,17 +152,14 @@ public Map solve(List dispatch(List taxis, List requests) { // because all passengers allow ridesharing, only greedy taset will be called -// List lst1 = dispatchVacantTaxi(taxis, requests); List carpoolAcceptingTaxis = taxis; List carpoolAcceptingPassengers = requests; List lst2 = heuristics(carpoolAcceptingTaxis, carpoolAcceptingPassengers); // for(PlanComputationRequest request : requests) { // is request served by both lst? // } - // lst1.addAll(lst2); return lst2; -// return convertedlist; } /** @@ -159,12 +168,8 @@ private List dispatch(List dispatchVacantTaxi(List taxis, List requests) { //taxi dispatch strategy that schedules taxis based on the shortest waiting time for the passengers - //TODO: implement method??? + //TODO //function can be changed to any dispatch strategy that a taxi company may currently be using (e.g., shortest waiting time and shortest cruising distance) -// taxis.get(0).getPosition() - // while mám volné taxíky - // najdu nejbližší taxík pro request - // pro ten request vytvorim return null; } @@ -273,9 +278,39 @@ private List heuristics(List itnryp1 = findPlanWithNoTransferActions(request.getPickUpAction(), dropoffActionTransfer, taxi); // pro auto +// List itnryp2 = findPlanWithNoTransferActions(pickupActionTransfer, request.getDropOffAction(), taxis.get(k)); List itnryp1 = findPlanWithNoTransfer(newRequest1, taxi); // pro auto //List itnryp1R = getActionsForRequestFromActionsForDriver(itnryp1, newRequest1, taxi); List itnryp2 = findPlanWithNoTransfer(newRequest2, taxis.get(k)); // pro auto @@ -670,7 +705,6 @@ public List getDropoffActions(List plan) { * @return valid DriverPlan with smallest delay. */ private List findPlanWithNoTransfer(PlanComputationRequest newRequest, RideSharingOnDemandVehicle taxi) { - int n = taxi.getOnBoardCount(); List lst = new ArrayList<>(); List currentPlan = taxi.getCurrentPlan().plan; List newPlan = new ArrayList<>(); @@ -693,6 +727,29 @@ private List findPlanWithNoTransfer(PlanComputationRequest newReques return bestPlan; } + private List findPlanWithNoTransferActions(PlanActionPickup pickup, PlanActionDropoff dropoff, RideSharingOnDemandVehicle taxi) { + List lst = new ArrayList<>(); + List currentPlan = taxi.getCurrentPlan().plan; + List newPlan = new ArrayList<>(); + for (PlanAction action : currentPlan) { + newPlan.add(action); + } + //add pickup and dropoff for new request + newPlan.add(pickup); + newPlan.add(dropoff); + //get pickup order based on heuristic from TASeT paper + List pickups = getPickupActions(newPlan); + //get dropoff actions in currentPlan + List dropoffs = getDropoffActions(newPlan); + //permute dropoff orders + List> dropoffOrders = permute(dropoffs); + for (List dropoffPlan : dropoffOrders) { + lst.add(createItinerary(pickups, dropoffPlan)); + } + List bestPlan = findItineraryWithMinimumDelay(lst); + return bestPlan; + } + private List getActionsForRequestFromActionsForDriver(List planActionsVehicle, PlanComputationRequest request, RideSharingOnDemandVehicle vehicle) { List actionsForRequest = new ArrayList<>(); for (int i = 0; i < planActionsVehicle.size(); i++) { @@ -853,7 +910,7 @@ private List findItineraryWithMinimumDelay(List plans) PlanActionPickup pickup = (PlanActionPickup) action; SimulationNode dest = pcq.getFrom(); time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); - if(!(time < pcq.getMaxPickupTime())) { + if(!(time <= pcq.getMaxPickupTime())) { //not valid itinerary - check new driver plan break; } else { @@ -866,7 +923,7 @@ else if (action instanceof PlanActionDropoff) { PlanActionDropoff dropoff = (PlanActionDropoff) action; SimulationNode dest = pcq.getTo(); time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); - if(!(time < pcq.getMaxDropoffTime())) { + if(!(time <= pcq.getMaxDropoffTime())) { //not valid itinerary - check new driver plan break; } else { @@ -898,7 +955,7 @@ else if (action instanceof PlanActionWait) { * @return new DriverPlan */ private DriverPlan createItinerary(List pickupOrder, List dropoffOrder) { - List listOfActionsOrdered = new LinkedList<>(pickupOrder); + List listOfActionsOrdered = new ArrayList<>(pickupOrder); listOfActionsOrdered.addAll(dropoffOrder); return new DriverPlan(listOfActionsOrdered, 0, 0); } @@ -965,217 +1022,5 @@ private boolean canServeRequestTASeT(RideSharingOnDemandVehicle vehicle, PlanCom // < request.getMaxPickupTime(); return travelTimeProvider.getTravelTime(vehicle, request.getFrom()) < request.getMaxPickupTime() * 1000; } - - - - - - - - - - - - - - - - - - - //copied from InsertionHeuristicSolver - private void computeOptimalPlan(RideSharingOnDemandVehicle vehicle, DriverPlan currentPlan, PlanComputationRequest planComputationRequest) { - - int freeCapacity = vehicle.getFreeCapacity(); - - for(int pickupOptionIndex = 1; pickupOptionIndex <= currentPlan.getLength(); pickupOptionIndex++){ - - // continue if the vehicle is full - if(freeCapacity == 0){ - continue; - } - - for(int dropoffOptionIndex = pickupOptionIndex + 1; dropoffOptionIndex <= currentPlan.getLength() + 1; - dropoffOptionIndex++){ - DriverPlan potentialPlan = insertIntoPlan(currentPlan, pickupOptionIndex, dropoffOptionIndex, - vehicle, planComputationRequest); - if(potentialPlan != null){ - double costIncrement = potentialPlan.cost - currentPlan.cost; - GreedyTASeTSolver.PlanData bestPlanData = new PlanData(vehicle, potentialPlan, costIncrement); - tryUpdateBestPlan(bestPlanData); - } - } - - // change free capacity for next index - if(pickupOptionIndex < currentPlan.getLength()){ - if(currentPlan.plan.get(pickupOptionIndex) instanceof PlanActionPickup){ - freeCapacity--; - } - else{ - freeCapacity++; - } - } - } - } - - //copied from InsertionHeuristicSolver - /** - * Returns list of plan tasks with new request actions added at specified indexes or null if the plan is infeasible. - * @param currentPlan Current plan, starting with the current position action - * @param pickupOptionIndex Pick up index: 1 - current plan length - * @param dropoffOptionIndex Drop off index: 2 - current plan length + 1 - * @param vehicle - * @param planComputationRequest - * @return list of plan tasks with new request actions added at specified indexes or null if the plan is infeasible. - */ - private DriverPlan insertIntoPlan(final DriverPlan currentPlan, final int pickupOptionIndex, - final int dropoffOptionIndex, final RideSharingOnDemandVehicle vehicle, - final PlanComputationRequest planComputationRequest) { - - List newPlanTasks = new LinkedList<>(); - - - // travel time of the new plan in milliseconds - int newPlanTravelTime = 0; - - // discomfort of the new plan in milliseconds - int newPlanDiscomfort = 0; - - PlanAction previousTask = null; - - // index of the lastly added action from the old plan (not considering current position action) - int indexInOldPlan = -1; - - Iterator oldPlanIterator = currentPlan.iterator(); - int freeCapacity = vehicle.getFreeCapacity(); - - for(int newPlanIndex = 0; newPlanIndex <= currentPlan.getLength() + 1; newPlanIndex++){ - - /* get new task */ - PlanAction newTask = null; - if(newPlanIndex == pickupOptionIndex){ - newTask = planComputationRequest.getPickUpAction(); -// new PlanActionPickup(request.getDemandAgent(), request.getDemandAgent().getPosition()); - } - else if(newPlanIndex == dropoffOptionIndex){ - newTask = planComputationRequest.getDropOffAction(); -// = new DriverPlanTask(DriverPlanTaskType.DROPOFF, request.getDemandAgent(), -// request.getTargetLocation()); - } - else{ - newTask = oldPlanIterator.next(); - } - - // travel time increment - if(previousTask != null){ - if(previousTask instanceof PlanActionCurrentPosition){ - newPlanTravelTime += travelTimeProvider.getTravelTime(vehicle, newTask.getPosition()); - } - else{ - newPlanTravelTime += travelTimeProvider.getTravelTime(vehicle, previousTask.getPosition(), - newTask.getPosition()); - } - } - long currentTaskTimeInSeconds = (timeProvider.getCurrentSimTime() + newPlanTravelTime) / 1000; -// LOGGER.debug("currentTaskTimeInSeconds: {}", currentTaskTimeInSeconds); - - /* check max time for all unfinished demands */ - - // check max time check for the new action - if(newTask instanceof PlanRequestAction){ - int maxTime = ((PlanRequestAction) newTask).getMaxTime(); - if(maxTime < currentTaskTimeInSeconds){ -// LOGGER.debug("currentTaskTimeInSeconds {} \n> maxTime {}",currentTaskTimeInSeconds, maxTime); - return null; - } - } - - // check max time for actions in the current plan - for(int index = indexInOldPlan + 1; index < currentPlan.getLength(); index++){ - PlanAction remainingAction = currentPlan.plan.get(index); - if(!(remainingAction instanceof PlanActionCurrentPosition)){ - PlanRequestAction remainingRequestAction = (PlanRequestAction) remainingAction; - if(remainingRequestAction.getMaxTime() < currentTaskTimeInSeconds){ - return null; - } - } - } - - // check max time for pick up action - if(newPlanIndex <= pickupOptionIndex){ - if(planComputationRequest.getPickUpAction().getMaxTime() < currentTaskTimeInSeconds){ - return null; - } - } - - // check max time for drop off action - if(newPlanIndex <= dropoffOptionIndex){ - if(planComputationRequest.getDropOffAction().getMaxTime() < currentTaskTimeInSeconds){ - return null; - } - } - - - /* pickup and drop off handeling */ - if(newTask instanceof PlanActionDropoff){ - freeCapacity++; - - // discomfort increment - PlanComputationRequest newRequest = ((PlanActionDropoff) newTask).getRequest(); - long taskExecutionTime = timeProvider.getCurrentSimTime() + newPlanTravelTime; - newPlanDiscomfort += taskExecutionTime - newRequest.getOriginTime() * 1000 - - newRequest.getMinTravelTime() * 1000; - } - else if(newTask instanceof PlanActionPickup){ - // capacity check - if(freeCapacity == 0){ - return null; - } - freeCapacity--; - } - - - // index in old plan if the action was not new - if(newPlanIndex != pickupOptionIndex && newPlanIndex != dropoffOptionIndex){ - indexInOldPlan++; - } - - newPlanTasks.add(newTask); - previousTask = newTask; - } - - // cost computation - double newPlanCost = planCostProvider.calculatePlanCost(newPlanDiscomfort, newPlanTravelTime); - - return new DriverPlan(newPlanTasks, newPlanTravelTime, newPlanCost); - } - //copied from InsertionHeuristicSolver - private class PlanData{ - final DriverPlan plan; - - final double increment; - - final RideSharingOnDemandVehicle vehicle; - - public PlanData(RideSharingOnDemandVehicle vehicle, DriverPlan plan, double increment) { - this.vehicle = vehicle; - this.plan = plan; - this.increment = increment; - } - } - - //copied from InsertionHeuristicSolver - edited - private synchronized void tryUpdateBestPlan(GreedyTASeTSolver.PlanData newPlanData){ - if(newPlanData != null){ - bestPlan = newPlanData; - } - } } - - - - - - - diff --git a/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java b/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java index eea5d4f2..d9d2d794 100644 --- a/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java +++ b/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java @@ -139,10 +139,11 @@ public long getCurrentSimTime() { positionUtil, droppedDemandsAnalyzer, onDemandvehicleStationStorage, - agentpolisConfig, - transferPoints + agentpolisConfig ); + solver.setTransferPoints(transferPoints); + // create requests SimulationNode origin_1 = graph.getNode(1); SimulationNode destination_1 = graph.getNode(3); @@ -189,8 +190,8 @@ public long getCurrentSimTime() { DefaultPlanComputationRequest request_1 = new DefaultPlanComputationRequest(astarTravelTimeProvider, 0, simodConfig, origin_1, destination_1, demandAgent_0); DefaultPlanComputationRequest request_2 = new DefaultPlanComputationRequest(astarTravelTimeProvider, 1, simodConfig, origin_2, destination_2, demandAgent_1); List requestsPeople = new ArrayList<>(); - requestsPeople.add(request_1); requestsPeople.add(request_2); + requestsPeople.add(request_1); // call solve method Map solution = solver.solve(requestsPeople, null); From ad5e97e8a7b35ba8b6372ba08a02b1e3b5a6652d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kub=C3=ADkov=C3=A1=2C=20Ad=C3=A9la?= Date: Fri, 8 Apr 2022 00:50:40 +0200 Subject: [PATCH 06/21] Fixed solver working with only small demand --- .../cz/cvut/fel/aic/simod/MainModule.java | 2 +- .../cz/cvut/fel/aic/simod/WaitTransfer.java | 94 ++ .../simod/WaitTransferActivityFactory.java | 20 + .../config/OnDemandVehicleStatistic.java | 3 + .../fel/aic/simod/entity/DemandAgent.java | 34 +- .../simod/entity/OnDemandVehicleState.java | 3 + .../simod/entity/OnDemandVehicleStation.java | 6 +- .../simod/entity/vehicle/OnDemandVehicle.java | 34 +- .../vehicle/OnDemandVehicleFactory.java | 11 + .../aic/simod/event/OnDemandVehicleEvent.java | 3 +- .../aic/simod/init/StationsInitializer.java | 9 +- .../RideSharingOnDemandVehicle.java | 197 ++- .../ridesharing/RidesharingDispatcher.java | 15 +- .../RidesharingOnDemandVehicleFactory.java | 31 +- .../greedyTASeT/GreedyTASeTSolver.java | 1105 +++++++++++++---- .../ridesharing/greedyTASeT/TransferPlan.java | 30 + .../model/PlanActionDropoffTransfer.java | 44 + .../model/PlanActionPickupTransfer.java | 43 + .../ridesharing/model/PlanActionWait.java | 2 +- .../fel/aic/simod/statistics/Statistics.java | 2 + .../cz/cvut/fel/aic/simod/config/config.cfg | 3 +- .../aic/simod/system/TestOnDemandVehicle.java | 7 + .../greedyTASeT/GreedyTASeTSolverTest.java | 184 +-- 23 files changed, 1533 insertions(+), 349 deletions(-) create mode 100644 src/main/java/cz/cvut/fel/aic/simod/WaitTransfer.java create mode 100644 src/main/java/cz/cvut/fel/aic/simod/WaitTransferActivityFactory.java create mode 100644 src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/TransferPlan.java create mode 100644 src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionDropoffTransfer.java create mode 100644 src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionPickupTransfer.java diff --git a/src/main/java/cz/cvut/fel/aic/simod/MainModule.java b/src/main/java/cz/cvut/fel/aic/simod/MainModule.java index 7b52d3eb..ee18a795 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/MainModule.java +++ b/src/main/java/cz/cvut/fel/aic/simod/MainModule.java @@ -149,7 +149,7 @@ protected void configureNext() { break; case "greedy-taset": bind(DARPSolver.class).to(GreedyTASeTSolver.class); - // nabindovat i nove tridy (treba waiting akci) + // nabindovat i nove tridy break; } } diff --git a/src/main/java/cz/cvut/fel/aic/simod/WaitTransfer.java b/src/main/java/cz/cvut/fel/aic/simod/WaitTransfer.java new file mode 100644 index 00000000..41993da5 --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/WaitTransfer.java @@ -0,0 +1,94 @@ +package cz.cvut.fel.aic.simod; + +import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.trip.Trip; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.StandardTimeProvider; +import cz.cvut.fel.aic.agentpolis.simmodel.Activity; +import cz.cvut.fel.aic.agentpolis.simmodel.ActivityInitializer; +import cz.cvut.fel.aic.agentpolis.simmodel.Agent; +import cz.cvut.fel.aic.agentpolis.simmodel.TimeConsumingActivity; +import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.VehicleMoveActivityFactory; +import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.WaitActivityFactory; +import cz.cvut.fel.aic.agentpolis.simmodel.agent.Driver; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.vehicle.Vehicle; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.EGraphType; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationEdge; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.networks.TransportNetworks; +import cz.cvut.fel.aic.agentpolis.simmodel.eventType.DriveEvent; +import cz.cvut.fel.aic.agentpolis.simmodel.eventType.Transit; +import cz.cvut.fel.aic.alite.common.event.EventProcessor; +import cz.cvut.fel.aic.alite.common.event.typed.TypedSimulation; +import cz.cvut.fel.aic.geographtools.Graph; + +public class WaitTransfer extends TimeConsumingActivity { + + private final long waitTime; + + private final WaitActivityFactory waitActivityFactory; + +// private final Trip trip; +// +// private final VehicleMoveActivityFactory moveActivityFactory; +// +// private final Vehicle vehicle; +// +// private final Graph graph; +// +// private final EventProcessor eventProcessor; +// +// private final StandardTimeProvider timeProvider; + + +// private SimulationNode from; +// +// private SimulationNode to; + + public WaitTransfer(ActivityInitializer activityInitializer, A agent, long waitTime, WaitActivityFactory waitActivityFactory +// , VehicleMoveActivityFactory moveActivityFactory, +// TypedSimulation eventProcessor, StandardTimeProvider timeProvider, Trip trip, Vehicle vehicle, TransportNetworks transportNetworks + ) { + super(activityInitializer, agent); + this.waitTime = waitTime; + this.waitActivityFactory = waitActivityFactory; +// this.moveActivityFactory = moveActivityFactory; +// this.timeProvider = timeProvider; +// this.eventProcessor = eventProcessor; +// this.trip = trip; +// this.vehicle = vehicle; +// graph = transportNetworks.getGraph(EGraphType.HIGHWAY); + + } + + @Override + protected long performPreDelayActions() { + return waitTime; + } + + @Override + protected void performAction() { + waitTransfer(); + +// finish(); + } + +// @Override +// protected void onChildActivityFinish(Activity activity) { +//// if (trip.isEmpty()) { +//// vehicle.setLastFromPosition(from); +//// finish(); +//// } else { +// from = to; +// move(); +//// } +// } + +// private void move() { +// +// } + + private void waitTransfer() { + runChildActivity(waitActivityFactory.create(agent, waitTime)); + } + + +} \ No newline at end of file diff --git a/src/main/java/cz/cvut/fel/aic/simod/WaitTransferActivityFactory.java b/src/main/java/cz/cvut/fel/aic/simod/WaitTransferActivityFactory.java new file mode 100644 index 00000000..464a6199 --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/WaitTransferActivityFactory.java @@ -0,0 +1,20 @@ +package cz.cvut.fel.aic.simod; + +import com.google.inject.Singleton; +import cz.cvut.fel.aic.agentpolis.simmodel.Activity; +import cz.cvut.fel.aic.agentpolis.simmodel.ActivityFactory; +import cz.cvut.fel.aic.agentpolis.simmodel.Agent; +import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.WaitActivityFactory; + +@Singleton +public class WaitTransferActivityFactory extends ActivityFactory { + + + public void runActivity(A agent, long waitTime, WaitActivityFactory waitActivityFactory) { + create(agent, waitTime, waitActivityFactory).run(); + } + + public WaitTransfer create(A agent, long waitTime, WaitActivityFactory waitActivityFactory) { + return new WaitTransfer<>(activityInitializer, agent, waitTime, waitActivityFactory); + } +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/config/OnDemandVehicleStatistic.java b/src/main/java/cz/cvut/fel/aic/simod/config/OnDemandVehicleStatistic.java index 92759ce7..788b452f 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/config/OnDemandVehicleStatistic.java +++ b/src/main/java/cz/cvut/fel/aic/simod/config/OnDemandVehicleStatistic.java @@ -14,6 +14,8 @@ public class OnDemandVehicleStatistic { public String finishRebalancingFilePath; + public String waitFilePath; + public String dirPath; public String startRebalancingFilePath; @@ -26,5 +28,6 @@ public OnDemandVehicleStatistic(Map onDemandVehicleStatistic) { this.finishRebalancingFilePath = (String) onDemandVehicleStatistic.get("finish_rebalancing_file_path"); this.dirPath = (String) onDemandVehicleStatistic.get("dir_path"); this.startRebalancingFilePath = (String) onDemandVehicleStatistic.get("start_rebalancing_file_path"); + this.waitFilePath = (String) onDemandVehicleStatistic.get("wait_file_path"); } } diff --git a/src/main/java/cz/cvut/fel/aic/simod/entity/DemandAgent.java b/src/main/java/cz/cvut/fel/aic/simod/entity/DemandAgent.java index 3683eb32..bd78d319 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/entity/DemandAgent.java +++ b/src/main/java/cz/cvut/fel/aic/simod/entity/DemandAgent.java @@ -205,6 +205,36 @@ public void tripEnded() { die(); } + public void tripPaused() { + if (state == DemandAgentState.WAITING) { + try { + throw new Exception(String.format("Demand Agent %s already stopped", this)); + } catch (Exception ex) { + Logger.getLogger(DemandAgent.class.getName()).log(Level.SEVERE, null, ex); + } + } + else{ + state = DemandAgentState.TRANSFERING; +// this.onDemandVehicle = null; + } + } + + public void tripRePaused(OnDemandVehicle vehicle) { +// if(state == DemandAgentState.DRIVING){ +// try { +// throw new Exception(String.format("Demand Agent %s already repaused in vehicle %s, it cannot be picked up by" +// + "another vehicle %s", this, onDemandVehicle, vehicle)); +// } catch (Exception ex) { +// Logger.getLogger(DemandAgent.class.getName()).log(Level.SEVERE, null, ex); +// } +// } +// else{ + state = DemandAgentState.DRIVING; + realPickupTime = timeProvider.getCurrentSimTime(); + this.onDemandVehicle = vehicle; +// } + } + public void tripStarted(OnDemandVehicle vehicle) { if(state == DemandAgentState.DRIVING){ try { @@ -214,10 +244,6 @@ public void tripStarted(OnDemandVehicle vehicle) { Logger.getLogger(DemandAgent.class.getName()).log(Level.SEVERE, null, ex); } } -// TODO to do -// else if(state == DemandAgentState.TRANSFERING) { -// -// } else{ state = DemandAgentState.DRIVING; realPickupTime = timeProvider.getCurrentSimTime(); diff --git a/src/main/java/cz/cvut/fel/aic/simod/entity/OnDemandVehicleState.java b/src/main/java/cz/cvut/fel/aic/simod/entity/OnDemandVehicleState.java index 4e989e5d..bcebbc41 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/entity/OnDemandVehicleState.java +++ b/src/main/java/cz/cvut/fel/aic/simod/entity/OnDemandVehicleState.java @@ -24,8 +24,11 @@ */ public enum OnDemandVehicleState { WAITING, + WAITINGFORTRANSFER, DRIVING_TO_START_LOCATION, DRIVING_TO_TARGET_LOCATION, DRIVING_TO_STATION, + DRIVING_TO_TRANSFER_POINT_TARGET, + DRIVING_TO_TRANSFER_POINT_START, REBALANCING; } diff --git a/src/main/java/cz/cvut/fel/aic/simod/entity/OnDemandVehicleStation.java b/src/main/java/cz/cvut/fel/aic/simod/entity/OnDemandVehicleStation.java index e25fd5e3..0aea69b4 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/entity/OnDemandVehicleStation.java +++ b/src/main/java/cz/cvut/fel/aic/simod/entity/OnDemandVehicleStation.java @@ -204,9 +204,11 @@ public int getIndex(){ } private OnDemandVehicle getAndRemoveVehicle() { - OnDemandVehicle nearestVehicle; + OnDemandVehicle nearestVehicle = null; - nearestVehicle = parkedVehicles.remove(0); + if (parkedVehicles.size() > 0) { + nearestVehicle = parkedVehicles.remove(0); + } return nearestVehicle; } diff --git a/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicle.java b/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicle.java index 465675d1..32238eff 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicle.java +++ b/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicle.java @@ -28,7 +28,9 @@ import cz.cvut.fel.aic.agentpolis.simmodel.Agent; import cz.cvut.fel.aic.agentpolis.simmodel.IdGenerator; import cz.cvut.fel.aic.agentpolis.simmodel.activity.PhysicalVehicleDrive; +import cz.cvut.fel.aic.agentpolis.simmodel.activity.Wait; import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.PhysicalVehicleDriveFactory; +import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.WaitActivityFactory; import cz.cvut.fel.aic.agentpolis.simmodel.agent.DelayData; import cz.cvut.fel.aic.agentpolis.simmodel.agent.Driver; import cz.cvut.fel.aic.agentpolis.simmodel.entity.EntityType; @@ -42,6 +44,7 @@ import cz.cvut.fel.aic.simod.DemandData; import cz.cvut.fel.aic.simod.DemandSimulationEntityType; import cz.cvut.fel.aic.simod.StationsDispatcher; +import cz.cvut.fel.aic.simod.WaitTransferActivityFactory; import cz.cvut.fel.aic.simod.config.SimodConfig; import cz.cvut.fel.aic.simod.entity.DemandAgent; import cz.cvut.fel.aic.simod.entity.OnDemandVehicleState; @@ -50,6 +53,8 @@ import cz.cvut.fel.aic.simod.event.OnDemandVehicleEvent; import cz.cvut.fel.aic.simod.event.OnDemandVehicleEventContent; import cz.cvut.fel.aic.simod.event.RebalancingEventContent; +import cz.cvut.fel.aic.simod.ridesharing.RideSharingOnDemandVehicle; +import cz.cvut.fel.aic.simod.ridesharing.model.PlanActionWait; import cz.cvut.fel.aic.simod.statistics.PickupEventContent; import cz.cvut.fel.aic.simod.storage.PhysicalTransportVehicleStorage; import cz.cvut.fel.aic.geographtools.Node; @@ -122,6 +127,10 @@ public class OnDemandVehicle extends Agent implements EventHandler, PlanningAgen protected OnDemandVehicleStation parkedIn; + public WaitTransferActivityFactory waitTransferActivityFactory; + + private WaitActivityFactory waitActivityFactory; + @@ -187,6 +196,8 @@ public OnDemandVehicle( SimodConfig config, IdGenerator idGenerator, AgentpolisConfig agentpolisConfig, + WaitTransferActivityFactory waitTransferActivityFactory, + WaitActivityFactory waitActivityFactory, @Assisted String vehicleId, @Assisted SimulationNode startPosition) { super(vehicleId, startPosition); this.tripsUtil = tripsUtil; @@ -197,6 +208,8 @@ public OnDemandVehicle( this.timeProvider = timeProvider; this.rebalancingIdGenerator = rebalancingIdGenerator; this.config = config; + this.waitTransferActivityFactory = waitTransferActivityFactory; + this.waitActivityFactory = waitActivityFactory; index = idGenerator.getId(); @@ -252,11 +265,12 @@ public void finishedDriving(boolean wasStopped) { case REBALANCING: finishRebalancing(); break; +// case WAITINGFORTRANSFER: +// waitForTransfer(); +// break; } } -// TODO add method with wait activity - protected void driveToDemandStartLocation() { if(getPosition() == demandNodes.get(0)){ @@ -422,10 +436,22 @@ protected void dropOffDemand() { @Override protected void onActivityFinish(Activity activity) { super.onActivityFinish(activity); - PhysicalVehicleDrive drive = (PhysicalVehicleDrive) activity; - finishedDriving(drive.isStoped()); + if (activity instanceof PhysicalVehicleDrive) { + PhysicalVehicleDrive drive = (PhysicalVehicleDrive) activity; + finishedDriving(drive.isStoped()); + } + else if (activity instanceof Wait) { + finishedWaiting(); + } + else { + finishedDriving(true); + } } + public void finishedWaiting() { + + }; + @Override public EntityType getType() { return DemandSimulationEntityType.ON_DEMAND_VEHICLE; diff --git a/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicleFactory.java b/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicleFactory.java index 03d31815..a374a486 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicleFactory.java +++ b/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicleFactory.java @@ -25,10 +25,12 @@ import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.StandardTimeProvider; import cz.cvut.fel.aic.agentpolis.simmodel.IdGenerator; import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.PhysicalVehicleDriveFactory; +import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.WaitActivityFactory; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; import cz.cvut.fel.aic.agentpolis.simulator.visualization.visio.VisioPositionUtil; import cz.cvut.fel.aic.alite.common.event.EventProcessor; import cz.cvut.fel.aic.simod.StationsDispatcher; +import cz.cvut.fel.aic.simod.WaitTransferActivityFactory; import cz.cvut.fel.aic.simod.config.SimodConfig; import cz.cvut.fel.aic.simod.storage.PhysicalTransportVehicleStorage; @@ -62,6 +64,9 @@ public class OnDemandVehicleFactory implements OnDemandVehicleFactorySpec{ protected final AgentpolisConfig agentpolisConfig; + protected final WaitTransferActivityFactory waitTransferActivityFactory; + + protected final WaitActivityFactory waitActivityFactory; @@ -75,6 +80,8 @@ public OnDemandVehicleFactory( StandardTimeProvider timeProvider, IdGenerator rebalancingIdGenerator, SimodConfig config, + WaitTransferActivityFactory waitTransferActivityFactory, + WaitActivityFactory waitActivityFactory, IdGenerator idGenerator, AgentpolisConfig agentpolisConfig) { this.tripsUtil = tripsUtil; @@ -87,6 +94,8 @@ public OnDemandVehicleFactory( this.config = config; this.idGenerator = idGenerator; this.agentpolisConfig = agentpolisConfig; + this.waitTransferActivityFactory = waitTransferActivityFactory; + this.waitActivityFactory = waitActivityFactory; } @@ -105,6 +114,8 @@ public OnDemandVehicle create(String vehicleId, SimulationNode startPosition){ config, idGenerator, agentpolisConfig, + waitTransferActivityFactory, + waitActivityFactory, vehicleId, startPosition); } diff --git a/src/main/java/cz/cvut/fel/aic/simod/event/OnDemandVehicleEvent.java b/src/main/java/cz/cvut/fel/aic/simod/event/OnDemandVehicleEvent.java index d8ce076d..ddcf97ae 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/event/OnDemandVehicleEvent.java +++ b/src/main/java/cz/cvut/fel/aic/simod/event/OnDemandVehicleEvent.java @@ -28,5 +28,6 @@ public enum OnDemandVehicleEvent{ DROP_OFF, REACH_NEAREST_STATION, START_REBALANCING, - FINISH_REBALANCING + FINISH_REBALANCING, + WAIT } diff --git a/src/main/java/cz/cvut/fel/aic/simod/init/StationsInitializer.java b/src/main/java/cz/cvut/fel/aic/simod/init/StationsInitializer.java index 6f43e17d..62ea4225 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/init/StationsInitializer.java +++ b/src/main/java/cz/cvut/fel/aic/simod/init/StationsInitializer.java @@ -78,10 +78,11 @@ public void loadStations(){ discarded++; } else{ - int initCount = Integer.parseInt(row[1]) + 100; - if(initCount < 500){ - initCount += 100; - } + // tady vznika tech 200 aut v kazde stanici + int initCount = Integer.parseInt(row[1]); +// if(initCount < 500){ +// initCount += 100; +// } createStation(node, initCount, counter++); } } diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java index 541b6cdc..780f8410 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java @@ -27,25 +27,35 @@ import cz.cvut.fel.aic.agentpolis.simmodel.IdGenerator; import cz.cvut.fel.aic.agentpolis.simmodel.activity.PhysicalVehicleDrive; import cz.cvut.fel.aic.agentpolis.simmodel.activity.Wait; +import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.CongestedDriveFactory; import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.PhysicalVehicleDriveFactory; import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.WaitActivityFactory; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.init.SimpleMapInitializer; +import cz.cvut.fel.aic.agentpolis.simulator.creator.SimulationCreator; import cz.cvut.fel.aic.agentpolis.simulator.visualization.visio.VisioPositionUtil; +import cz.cvut.fel.aic.agentpolis.system.AgentPolisInitializer; import cz.cvut.fel.aic.alite.common.event.Event; import cz.cvut.fel.aic.alite.common.event.EventProcessor; +import cz.cvut.fel.aic.simod.MainModule; import cz.cvut.fel.aic.simod.StationsDispatcher; +import cz.cvut.fel.aic.simod.WaitTransferActivityFactory; import cz.cvut.fel.aic.simod.config.SimodConfig; import cz.cvut.fel.aic.simod.entity.DemandAgent; import cz.cvut.fel.aic.simod.entity.OnDemandVehicleState; import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicle; import cz.cvut.fel.aic.simod.event.OnDemandVehicleEvent; import cz.cvut.fel.aic.simod.event.OnDemandVehicleEventContent; +import cz.cvut.fel.aic.simod.mapVisualization.MapVisualiserModule; import cz.cvut.fel.aic.simod.ridesharing.insertionheuristic.DriverPlan; import cz.cvut.fel.aic.simod.ridesharing.model.*; import cz.cvut.fel.aic.simod.statistics.PickupEventContent; import cz.cvut.fel.aic.simod.storage.PhysicalTransportVehicleStorage; import cz.cvut.fel.aic.simod.visio.PlanLayerTrip; +import org.opengis.filter.PropertyIsGreaterThanOrEqualTo; + +import java.io.File; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -66,12 +76,19 @@ public class RideSharingOnDemandVehicle extends OnDemandVehicle{ private IdGenerator tripIdGenerator; -// private final WaitActivityFactory waitActivityFactory; + private WaitTransferActivityFactory waitTransferActivityFactory; + + private WaitActivityFactory waitActivityFactory; public DriverPlan getCurrentPlan() { currentPlan.updateCurrentPosition(getPosition()); return currentPlan; } + + public DriverPlan getCurrentPlanNoUpdate() { + return currentPlan; + } + public void setCurrentPlan(DriverPlan driverPlan) { List newPlan = new ArrayList<>(); newPlan.add(currentPlan.plan.get(0)); @@ -97,7 +114,8 @@ public RideSharingOnDemandVehicle( SimodConfig config, IdGenerator idGenerator, AgentpolisConfig agentpolisConfig, -// WaitActivityFactory waitActivityFactory, + WaitTransferActivityFactory waitTransferActivityFactory, + WaitActivityFactory waitActivityFactory, @Assisted String vehicleId, @Assisted SimulationNode startPosition) { super( vehicleStorage, @@ -111,11 +129,16 @@ public RideSharingOnDemandVehicle( config, idGenerator, agentpolisConfig, + waitTransferActivityFactory, + waitActivityFactory, vehicleId, startPosition); this.positionUtil = positionUtil; this.tripIdGenerator = tripIdGenerator; -// this.waitActivityFactory = waitActivityFactory; + + this.waitTransferActivityFactory = waitTransferActivityFactory; + this.waitActivityFactory = waitActivityFactory; + // empty plan LinkedList plan = new LinkedList<>(); @@ -158,20 +181,57 @@ else if( } +// +// protected void driveToDemandTransferStartLocation() { +// // safety check that prevents request from being picked up twice because of the delayed pickup event +// if(((PlanActionPickupTransfer) currentTask).request.isOnboard()){ +// currentPlan.taskCompleted(); +// driveToNextTask(); +// } +// state = OnDemandVehicleState.DRIVING_TO_TRANSFER_POINT_START; +// if(getPosition().id == currentTask.getPosition().id){ +// pickupAndContinue(); +// } +// else{ +// currentTrip = tripsUtil.createTrip(getPosition(), currentTask.getPosition(), vehicle); +// DemandAgent demandAgent = ((PlanActionPickupTransfer) currentTask).getRequest().getDemandAgent(); +// driveFactory.runActivity(this, vehicle, currentTrip); +// } +// } +// +// protected void driveToDemandTransferTargetLocation() { +// state = OnDemandVehicleState.DRIVING_TO_TRANSFER_POINT_TARGET; +// if(getPosition().id == currentTask.getPosition().id){ +// dropoffTransferAndContinue(); +// } +// else{ +// currentTrip = tripsUtil.createTrip(getPosition(), currentTask.getPosition(), vehicle); +// driveFactory.runActivity(this, vehicle, currentTrip); +// } +// } + @Override protected void driveToDemandStartLocation() { // safety check that prevents request from being picked up twice because of the delayed pickup event - if(((PlanActionPickup) currentTask).request.isOnboard()){ - currentPlan.taskCompleted(); - driveToNextTask(); + if (currentTask instanceof PlanActionPickup) { + if(((PlanActionPickup) currentTask).request.isOnboard()){ + currentPlan.taskCompleted(); + driveToNextTask(); + } + } else { + if(((PlanActionPickupTransfer) currentTask).request.isOnboard()){ + currentPlan.taskCompleted(); + driveToNextTask(); + } } + state = OnDemandVehicleState.DRIVING_TO_START_LOCATION; if(getPosition().id == currentTask.getPosition().id){ pickupAndContinue(); } else{ currentTrip = tripsUtil.createTrip(getPosition(), currentTask.getPosition(), vehicle); - DemandAgent demandAgent = ((PlanActionPickup) currentTask).getRequest().getDemandAgent(); +// DemandAgent demandAgent = ((PlanActionPickup) currentTask).getRequest().getDemandAgent(); driveFactory.runActivity(this, vehicle, currentTrip); } } @@ -180,7 +240,12 @@ protected void driveToDemandStartLocation() { protected void driveToTargetLocation() { state = OnDemandVehicleState.DRIVING_TO_TARGET_LOCATION; if(getPosition().id == currentTask.getPosition().id){ - dropOffAndContinue(); + if (currentTask instanceof PlanActionDropoff) { + dropOffAndContinue(); + } else if (currentTask instanceof PlanActionDropoffTransfer) { +// dropoffTransferAndContinue(); + dropOffAndContinue(); + } } else{ currentTrip = tripsUtil.createTrip(getPosition(), currentTask.getPosition(), vehicle); @@ -201,28 +266,52 @@ protected void driveToNearestStation() { driveFactory.runActivity(this, vehicle, currentTrip); } } + @Override + public void finishedWaiting() { + currentPlan.taskCompleted(); + currentTask = currentPlan.getNextTask(); +// driveToNextTask(); + pickupAndContinue(); + } + + public void startWaiting() { + waitActivityFactory.runActivity(this, ((PlanActionWait) currentTask).getWaitTime()); + state = OnDemandVehicleState.WAITINGFORTRANSFER; +// currentPlan.taskCompleted(); +// currentTask = currentPlan.getNextTask(); + } @Override public void finishedDriving(boolean wasStopped) { - logTraveledDistance(wasStopped); +// logTraveledDistance(wasStopped); if(wasStopped){ driveToNextTask(); } else{ switch(state){ + // start location agenta - pickup misto case DRIVING_TO_START_LOCATION: + logTraveledDistance(wasStopped); pickupAndContinue(); break; + // dropoff misto agenta case DRIVING_TO_TARGET_LOCATION: + logTraveledDistance(wasStopped); dropOffAndContinue(); break; + // stanice auta case DRIVING_TO_STATION: + logTraveledDistance(wasStopped); finishDrivingToStation(); break; case REBALANCING: + logTraveledDistance(wasStopped); finishRebalancing(); break; +// case WAITINGFORTRANSFER: +// waitForTransfer(); +// break; } } } @@ -248,10 +337,17 @@ private void driveToNextTask() { if(currentTask instanceof PlanActionPickup){ driveToDemandStartLocation(); } -// else if(currentTask instanceof PlanActionWait) { -// waitActivityFactory.runActivity(this, ((PlanActionWait) currentTask).getWaitTime()); -// } - else{ + else if(currentTask instanceof PlanActionWait) { + startWaiting(); + } + else if(currentTask instanceof PlanActionPickupTransfer) { + driveToDemandStartLocation(); + } + else if(currentTask instanceof PlanActionDropoffTransfer) { + driveToTargetLocation(); + } + else // dropoff + { driveToTargetLocation(); } } @@ -259,15 +355,38 @@ private void driveToNextTask() { private void pickupAndContinue() { try { - DemandAgent demandAgent = ((PlanActionPickup) currentTask).getRequest().getDemandAgent(); - if(demandAgent.isDropped()){ - long currentTime = timeProvider.getCurrentSimTime(); - long droppTime = demandAgent.getDemandTime() + config.ridesharing.maxProlongationInSeconds * 1000; - throw new Exception( - String.format("Demand agent %s cannot be picked up, he is already dropped! Current simulation " - + "time: %s, dropp time: %s", demandAgent, currentTime, droppTime)); + DemandAgent demandAgent; + if (currentTask instanceof PlanActionPickup) { + demandAgent = ((PlanActionPickup) currentTask).getRequest().getDemandAgent(); + if(demandAgent.isDropped()){ + long currentTime = timeProvider.getCurrentSimTime(); + long droppTime = demandAgent.getDemandTime() + config.ridesharing.maxProlongationInSeconds * 1000; + throw new Exception( + String.format("Demand agent %s cannot be picked up, he is already dropped! Current simulation " + + "time: %s, dropp time: %s", demandAgent, currentTime, droppTime)); + } + demandAgent.tripStarted(this); + } + else { + demandAgent = ((PlanActionPickupTransfer) currentTask).getRequest().getDemandAgent(); + if(demandAgent.isDropped()){ + long currentTime = timeProvider.getCurrentSimTime(); + long droppTime = demandAgent.getDemandTime() + config.ridesharing.maxProlongationInSeconds * 1000; + throw new Exception( + String.format("Demand agent %s cannot be picked up, he is already dropped! Current simulation " + + "time: %s, dropp time: %s", demandAgent, currentTime, droppTime)); + } + demandAgent.tripRePaused(this); } - demandAgent.tripStarted(this); + +// if(demandAgent.isDropped()){ +// long currentTime = timeProvider.getCurrentSimTime(); +// long droppTime = demandAgent.getDemandTime() + config.ridesharing.maxProlongationInSeconds * 1000; +// throw new Exception( +// String.format("Demand agent %s cannot be picked up, he is already dropped! Current simulation " +// + "time: %s, dropp time: %s", demandAgent, currentTime, droppTime)); +// } +// demandAgent.tripStarted(this); vehicle.pickUp(demandAgent); // statistics TODO demand tirp? @@ -288,8 +407,16 @@ private void pickupAndContinue() { } private void dropOffAndContinue() { - DemandAgent demandAgent = ((PlanActionDropoff) currentTask).getRequest().getDemandAgent(); - demandAgent.tripEnded(); + DemandAgent demandAgent = null; + if (currentTask instanceof PlanActionDropoff) { + demandAgent = ((PlanActionDropoff) currentTask).getRequest().getDemandAgent(); + demandAgent.tripEnded(); + } else + { + demandAgent = ((PlanActionDropoffTransfer) currentTask).getRequest().getDemandAgent(); + demandAgent.tripPaused(); + } + vehicle.dropOff(demandAgent); // statistics @@ -300,6 +427,30 @@ private void dropOffAndContinue() { driveToNextTask(); } + private void pickupTransferAndContinue() { + try { + DemandAgent demandAgent = ((PlanActionPickupTransfer) currentTask).getRequest().getDemandAgent(); + + vehicle.pickUp(demandAgent); + demandAgent.tripRePaused(this); + currentPlan.taskCompleted(); + driveToNextTask(); + + } catch (Exception ex) { + Logger.getLogger(RideSharingOnDemandVehicle.class.getName()).log(Level.SEVERE, null, ex); + } + } + + private void dropoffTransferAndContinue() { + DemandAgent demandAgent = ((PlanActionDropoffTransfer) currentTask).getRequest().getDemandAgent(); + vehicle.dropOff(demandAgent); + demandAgent.tripPaused(); + + currentPlan.taskCompleted(); + driveToNextTask(); + + } + @Override protected void leavingStationEvent() { eventProcessor.addEvent(OnDemandVehicleEvent.LEAVE_STATION, null, null, diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RidesharingDispatcher.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RidesharingDispatcher.java index edf88420..95562631 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RidesharingDispatcher.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RidesharingDispatcher.java @@ -253,13 +253,16 @@ public void handleEvent(Event event) { if(eventType == OnDemandVehicleEvent.PICKUP){ OnDemandVehicleEventContent eventContent = (OnDemandVehicleEventContent) event.getContent(); PlanComputationRequest request = requestsMapByDemandAgents.get(eventContent.getDemandId()); - if(!waitingRequests.remove(request)){ - try { - throw new SimodException("Request picked up but it is not present in the waiting request queue!"); - } catch (Exception ex) { - Logger.getLogger(VehicleGroupAssignmentSolver.class.getName()).log(Level.SEVERE, null, ex); + if (waitingRequests.contains(request)) { + if (!waitingRequests.remove(request)) { + try { + throw new SimodException("Request picked up but it is not present in the waiting request queue!"); + } catch (Exception ex) { + Logger.getLogger(VehicleGroupAssignmentSolver.class.getName()).log(Level.SEVERE, null, ex); + } } - }; + ; + } request.setOnboard(true); } } diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RidesharingOnDemandVehicleFactory.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RidesharingOnDemandVehicleFactory.java index a44247de..ea308407 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RidesharingOnDemandVehicleFactory.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RidesharingOnDemandVehicleFactory.java @@ -24,10 +24,12 @@ import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.TripsUtil; import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.StandardTimeProvider; import cz.cvut.fel.aic.agentpolis.simmodel.IdGenerator; +import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.WaitActivityFactory; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; import cz.cvut.fel.aic.agentpolis.simulator.visualization.visio.VisioPositionUtil; import cz.cvut.fel.aic.alite.common.event.EventProcessor; import cz.cvut.fel.aic.simod.StationsDispatcher; +import cz.cvut.fel.aic.simod.WaitTransferActivityFactory; import cz.cvut.fel.aic.simod.config.SimodConfig; import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicle; import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicleFactory; @@ -39,19 +41,24 @@ */ @Singleton public class RidesharingOnDemandVehicleFactory extends OnDemandVehicleFactory{ + + WaitTransferActivityFactory waitTransferActivityFactory; @Inject public RidesharingOnDemandVehicleFactory( - PhysicalTransportVehicleStorage vehicleStorage, - TripsUtil tripsUtil, + PhysicalTransportVehicleStorage vehicleStorage, + TripsUtil tripsUtil, StationsDispatcher onDemandVehicleStationsCentral, - VisioPositionUtil positionUtil, - EventProcessor eventProcessor, - StandardTimeProvider timeProvider, - IdGenerator rebalancingIdGenerator, + VisioPositionUtil positionUtil, + EventProcessor eventProcessor, + StandardTimeProvider timeProvider, + IdGenerator rebalancingIdGenerator, SimodConfig config, IdGenerator idGenerator, - AgentpolisConfig agentpolisConfig) { + AgentpolisConfig agentpolisConfig, + WaitTransferActivityFactory waitTransferActivityFactory, + WaitActivityFactory waitActivityFactory + ) { super( vehicleStorage, tripsUtil, @@ -60,9 +67,12 @@ public RidesharingOnDemandVehicleFactory( eventProcessor, timeProvider, rebalancingIdGenerator, - config, + config, + waitTransferActivityFactory, + waitActivityFactory, idGenerator, agentpolisConfig); + this.waitTransferActivityFactory = waitTransferActivityFactory; } @Override @@ -80,8 +90,11 @@ public OnDemandVehicle create(String vehicleId, SimulationNode startPosition) { config, idGenerator, agentpolisConfig, + waitTransferActivityFactory, + waitActivityFactory, vehicleId, - startPosition); + startPosition) + ; } diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java index 5f9e7ccb..92484e6a 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java @@ -22,7 +22,7 @@ import cz.cvut.fel.aic.simod.storage.OnDemandVehicleStorage; import cz.cvut.fel.aic.simod.storage.OnDemandvehicleStationStorage; import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider; -import jdk.nashorn.internal.ir.RuntimeNode; +import org.jgrapht.alg.util.Pair; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -69,13 +69,6 @@ public GreedyTASeTSolver( DroppedDemandsAnalyzer droppedDemandsAnalyzer, OnDemandvehicleStationStorage onDemandvehicleStationStorage, AgentpolisConfig agentpolisConfig) { - // late binding na prestupni stanice - // vyhodit transfer points z konstruktoru - // vytvorit metodu sem do toho solveru get station s parametrem List - - // zkompirovat tridu StationsInitializer a jenom poupravit - // v greedyTASeT solveru udelat metodu - setter na list transfer stations kde si je vezmu z parametru a jenom je hodim na this.trasnferpoints = - super(vehicleStorage, travelTimeProvider, travelCostProvider, requestFactory); this.eventProcessor = eventProcessor; @@ -86,8 +79,6 @@ public GreedyTASeTSolver( this.onDemandvehicleStationStorage = onDemandvehicleStationStorage; this.requestFactory = requestFactory; - //TODO: - // commented because config is null in test // // max distance in meters between vehicle and request for the vehicle to be considered to serve the request // maxDistance = (double) config.ridesharing.maxProlongationInSeconds // * agentpolisConfig.maxVehicleSpeedInMeters; @@ -131,16 +122,15 @@ public Map solve(List planMap = new ConcurrentHashMap<>(); List taxis = new ArrayList<>(); -// AgentPolisEntity[] tVvehicles = vehicleStorage.getEntitiesForIteration(); for(AgentPolisEntity tVvehicle: vehicleStorage.getEntitiesForIteration()) { RideSharingOnDemandVehicle vehicle = (RideSharingOnDemandVehicle) tVvehicle; taxis.add(vehicle); } - // TODO + List vehiclesWithPlans = dispatch(taxis, newRequests); for (int i = 0; i < vehiclesWithPlans.size(); i++) { - planMap.put(vehiclesWithPlans.get(i), vehiclesWithPlans.get(i).getCurrentPlan()); + planMap.put(vehiclesWithPlans.get(i), vehiclesWithPlans.get(i).getCurrentPlanNoUpdate()); } return planMap; @@ -155,29 +145,135 @@ private List dispatch(List carpoolAcceptingTaxis = taxis; List carpoolAcceptingPassengers = requests; List lst2 = heuristics(carpoolAcceptingTaxis, carpoolAcceptingPassengers); -// for(PlanComputationRequest request : requests) { - // is request served by both lst? -// } -// lst1.addAll(lst2); return lst2; } - /** - * traditional taxi dispatch strategy that schedules taxis based on the shortest waiting time for the passengers - * @return - */ - private List dispatchVacantTaxi(List taxis, List requests) { - //taxi dispatch strategy that schedules taxis based on the shortest waiting time for the passengers - //TODO - //function can be changed to any dispatch strategy that a taxi company may currently be using (e.g., shortest waiting time and shortest cruising distance) - return null; + + private boolean isWithTransfer(DriverPlan plan) { + for(PlanAction action : plan.plan) { + if(action instanceof PlanRequestAction) { + if (action instanceof PlanActionDropoffTransfer || action instanceof PlanActionPickupTransfer || action instanceof PlanActionWait) { + return true; + } + } + } + return false; + } + + private int findLastPickupIndex(DriverPlan plan) { + int index = -1; + for (int i = 0; i < plan.getLength(); i++) { + if (plan.plan.get(i) instanceof PlanActionPickup) { + index = i; + } + } + return index; + } + + private int findLastPickupIndexList(List plan) { + int index = -1; + for (int i = 0; i < plan.size(); i++) { + if (plan.get(i) instanceof PlanActionPickup) { + index = i; + } + } + return index; + } + + private int findLastTransferActionIndex(DriverPlan plan) { + int index = -1; + for (int i = 0; i < plan.getLength(); i++) { + if (plan.plan.get(i) instanceof PlanActionDropoffTransfer || plan.plan.get(i) instanceof PlanActionPickupTransfer || plan.plan.get(i) instanceof PlanActionWait) { + index = i; + } + } + return index; + } + + private long countTimeToNewPickup(RideSharingOnDemandVehicle taxi, PlanComputationRequest request, List requestsOnBoard) { + if (isWithTransfer(taxi.getCurrentPlanNoUpdate())) { + // nekdo prestupuje + int indexLastTransferAction = findLastTransferActionIndex(taxi.getCurrentPlanNoUpdate()); + long timeToFinishCurrentEdge = 0; + SimulationNode previousPos = taxi.getPosition(); + if (taxi.getCurrentTask() != null) { + timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(taxi, taxi.getCurrentTask().getPosition()); + previousPos = taxi.getCurrentTask().getPosition(); + } + long timeToLastTransferAction = 0; + for (int q = 0; q < indexLastTransferAction + 1; q++) { + if (taxi.getCurrentPlanNoUpdate().plan.get(q) instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) taxi.getCurrentPlanNoUpdate().plan.get(q); + timeToLastTransferAction = timeToLastTransferAction + wait.getWaitTime(); + } else { + timeToLastTransferAction = timeToLastTransferAction + travelTimeProvider.getExpectedTravelTime(previousPos, taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition()); + } + previousPos = taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition(); + } + // ted potrebuju najit posledni pickup ve zbyvajicim driver planu po prestupu + List segmentAfterTransfer = taxi.getCurrentPlanNoUpdate().plan.subList(indexLastTransferAction+1, taxi.getCurrentPlanNoUpdate().plan.size()); + int indexLastPickupSegment = findLastPickupIndexList(segmentAfterTransfer); + long timeToLastPickup = 0; + SimulationNode previousPos2 = taxi.getCurrentPlanNoUpdate().plan.get(taxi.getCurrentPlanNoUpdate().plan.size()-1).getPosition(); + if (segmentAfterTransfer.size() > 0) { + previousPos2 = segmentAfterTransfer.get(0).getPosition(); + for (int q = 0; q < indexLastPickupSegment + 1; q++) { + timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos2, segmentAfterTransfer.get(q).getPosition()); + previousPos2 = segmentAfterTransfer.get(q).getPosition(); + } + } + SimulationNode newPickupFrom = request.getFrom(); + long timeToNewPick = travelTimeProvider.getExpectedTravelTime(previousPos, newPickupFrom); + long estimatedArrivalToPickup = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastTransferAction + timeToLastPickup + timeToNewPick; + // zkontrolovat, zda arrival je v pohode z hlediska delay - kontroluju pro requesty po ukonceni prestupu + Set requestsInSegmentSet = new HashSet<>(); + for(PlanAction action : segmentAfterTransfer) { + if(action instanceof PlanRequestAction) { + PlanRequestAction requestAction = (PlanRequestAction) action; + requestsInSegmentSet.add(requestAction.request); + } + } + List requestsInSegment = new ArrayList<>(requestsInSegmentSet); + for (PlanComputationRequest req : requestsInSegment) { + long maxTime = req.getMaxDropoffTime() * 1000; + if (estimatedArrivalToPickup > maxTime) { + return Long.MAX_VALUE; + } + } + return estimatedArrivalToPickup; + } + else { + //neprestupuje nikdo + int indexLastPickup = findLastPickupIndex(taxi.getCurrentPlanNoUpdate()); + long timeToFinishCurrentEdge = 0; + SimulationNode previousPos = taxi.getPosition(); + if (taxi.getCurrentTask() != null) { + timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(taxi, taxi.getCurrentTask().getPosition()); + previousPos = taxi.getCurrentTask().getPosition(); + } + long timeToLastPickup = 0; + for (int q = 0; q < indexLastPickup + 1; q++) { + timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos, taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition()); + previousPos = taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition(); + } + SimulationNode newPickupFrom = request.getFrom(); + long timeToNewPick = travelTimeProvider.getExpectedTravelTime(previousPos, newPickupFrom); + long estimatedArrivalToNewPickup = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastPickup + timeToNewPick; + // zkontrolovat, zda arrival je v pohode z hlediska delay + for (PlanComputationRequest req : requestsOnBoard) { + long maxTime = request.getMaxDropoffTime() * 1000; + if (estimatedArrivalToNewPickup > maxTime) { + return Long.MAX_VALUE; + } + } + return estimatedArrivalToNewPickup; + } } /** * Greedy TASeT heuristics function * @return */ -// private List heuristics(List taxis, List requests) { private List heuristics(List taxis, List requests) { //transfer points = charging stations List transferPoints = this.transferPoints; @@ -191,7 +287,7 @@ private List heuristics(List requestsOnBoardSet = new HashSet<>(); - DriverPlan actualPlan = taxi.getCurrentPlan(); + DriverPlan actualPlan = taxi.getCurrentPlanNoUpdate(); for(PlanAction action : actualPlan) { if(action instanceof PlanRequestAction) { PlanRequestAction requestAction = (PlanRequestAction) action; @@ -199,31 +295,103 @@ private List heuristics(List requestsOnBoard = new ArrayList<>(requestsOnBoardSet); - boolean taxiFree = taxi.hasFreeCapacity(); + // kolik lidi je prave ted v aute + boolean taxiFree = true; + int taxiCapacity = taxi.getCapacity(); + if (requestsOnBoardSet.size() >= taxiCapacity) { + taxiFree = false; + } for(int j = 0; j < stationsCount; j++) { - //timeProvider is set to null so getCurrentSimTime() wont work - //the idea is to fill LT with times of arrival of taxis -// LT[j][i] = this.timeProvider.getCurrentSimTime() + travelTime; //check if taxi has free seat if (!taxiFree) { LT[j][i] = Long.MAX_VALUE; } else { - SimulationNode station = transferPoints.get(j); - long travelTime = this.travelTimeProvider.getExpectedTravelTime(taxiPosition, station); - //check if setting a new via point will exceed the tolerable delay for onboard passengers - if (checkTolerableDelay(requestsOnBoard, station, taxi)) { - LT[j][i] = travelTime; - } else { - LT[j][i] = Long.MAX_VALUE; + if (isWithTransfer(taxi.getCurrentPlanNoUpdate())) { + // nekdo prestupuje + int indexLastTransferAction = findLastTransferActionIndex(taxi.getCurrentPlanNoUpdate()); + long timeToFinishCurrentEdge = 0; + SimulationNode previousPos = taxi.getPosition(); + if (taxi.getCurrentTask() != null) { + timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(taxi, taxi.getCurrentTask().getPosition()); + previousPos = taxi.getCurrentTask().getPosition(); + } + long timeToLastTransferAction = 0; + for (int q = 0; q < indexLastTransferAction + 1; q++) { + if (taxi.getCurrentPlanNoUpdate().plan.get(q) instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) taxi.getCurrentPlanNoUpdate().plan.get(q); + timeToLastTransferAction = timeToLastTransferAction + wait.getWaitTime(); + } else { + timeToLastTransferAction = timeToLastTransferAction + travelTimeProvider.getExpectedTravelTime(previousPos, taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition()); + } + previousPos = taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition(); + } + // ted potrebuju najit posledni pickup ve zbyvajicim driver planu po prestupu + List segmentAfterTransfer = taxi.getCurrentPlanNoUpdate().plan.subList(indexLastTransferAction+1, taxi.getCurrentPlanNoUpdate().plan.size()); + int indexLastPickupSegment = findLastPickupIndexList(segmentAfterTransfer); + long timeToLastPickup = 0; + SimulationNode previousPos2 = taxi.getCurrentPlanNoUpdate().plan.get(taxi.getCurrentPlanNoUpdate().plan.size()-1).getPosition(); + if (segmentAfterTransfer.size() > 0) { + previousPos2 = segmentAfterTransfer.get(0).getPosition(); + for (int q = 0; q < indexLastPickupSegment + 1; q++) { + timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos2, segmentAfterTransfer.get(q).getPosition()); + previousPos2 = segmentAfterTransfer.get(q).getPosition(); + } + } + SimulationNode station = transferPoints.get(j); + long timeToStation = travelTimeProvider.getExpectedTravelTime(previousPos, station); + long estimatedArrivalToStation = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastTransferAction + timeToLastPickup + timeToStation; + LT[j][i] = estimatedArrivalToStation; + // zkontrolovat, zda arrival je v pohode z hlediska delay - kontroluju pro requesty po ukonceni prestupu + Set requestsInSegmentSet = new HashSet<>(); + for(PlanAction action : segmentAfterTransfer) { + if(action instanceof PlanRequestAction) { + PlanRequestAction requestAction = (PlanRequestAction) action; + requestsInSegmentSet.add(requestAction.request); + } + } + List requestsInSegment = new ArrayList<>(requestsInSegmentSet); + for (PlanComputationRequest request : requestsInSegment) { + long maxTime = request.getMaxDropoffTime() * 1000; + if (LT[j][i] > maxTime) { + LT[j][i] = Long.MAX_VALUE; + break; + } + } + } + else { + //neprestupuje nikdo + int indexLastPickup = findLastPickupIndex(taxi.getCurrentPlanNoUpdate()); + long timeToFinishCurrentEdge = 0; + SimulationNode previousPos = taxi.getPosition(); + if (taxi.getCurrentTask() != null) { + timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(taxi, taxi.getCurrentTask().getPosition()); + previousPos = taxi.getCurrentTask().getPosition(); + } +// long timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(taxi, taxi.getCurrentTask().getPosition()); + long timeToLastPickup = 0; +// SimulationNode previousPos = taxi.getCurrentTask().getPosition(); + for (int q = 0; q < indexLastPickup + 1; q++) { + timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos, taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition()); + previousPos = taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition(); + } + SimulationNode station = transferPoints.get(j); + long timeToStation = travelTimeProvider.getExpectedTravelTime(previousPos, station); + long estimatedArrivalToStation = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastPickup + timeToStation; + LT[j][i] = estimatedArrivalToStation; + // zkontrolovat, zda arrival je v pohode z hlediska delay + for (PlanComputationRequest request : requestsOnBoard) { + long maxTime = request.getMaxDropoffTime() * 1000; + if (LT[j][i] > maxTime) { + LT[j][i] = Long.MAX_VALUE; + break; + } + } } } } } - //itinerary list - List itinerarylist = new ArrayList<>(); - //we rank the requests in descending order by the number of taxis that are possible to pick them up in time (without considering transfer or destination) //get possible taxis for every request and number of possible taxis int[] possiblePickupTaxisCounts = new int[requests.size()]; @@ -233,7 +401,7 @@ private List heuristics(List possiblePickupTaxisOneRequest = new ArrayList<>(); for(RideSharingOnDemandVehicle t : taxis) { - if (canServeRequestTASeT(t, request)) { + if (canServeRequestTASeT2(t, request)) { counter++; possiblePickupTaxisOneRequest.add(t); } @@ -242,6 +410,8 @@ private List heuristics(List requestsCopy = new ArrayList<>(requests); requests.sort(Comparator.comparing(x -> possiblePickupTaxisCounts[requestsCopy.indexOf(x)])); @@ -250,78 +420,78 @@ private List heuristics(List> templist = new ArrayList<>(); // list planactionu pro auto - Map>, List>, List> templist = new HashMap<>(); //hashmapa RequestPlan : list driverplanu + List>, List>> templistP = new ArrayList<>(); + // list ve kterem je list dvojic - list dvojic, protoze dvojice muze byt jen jedna (neni prestup) nebo dve (je prestup) List delays = new ArrayList<>(); List transferTimes = new ArrayList<>(); List canPickupRequestTaxis = possiblePickupTaxisMap.get(request); for (RideSharingOnDemandVehicle taxi : canPickupRequestTaxis) { - List posbitnry = findPlanWithNoTransfer(request, taxi); // pro auto - List posbitnryR = getActionsForRequestFromActionsForDriver(posbitnry, request, taxi); // pro request - List> tmp = new ArrayList<>(); - List tmpVehs = new ArrayList<>(); - tmpVehs.add(taxi); - tmp.add(posbitnry); - Map>, List> submap = new HashMap<>(); - submap.put(tmp, tmpVehs); - templist.put(submap, posbitnryR); - delays.add((long) 0); - transferTimes.add((long) 0); - long travelTimeNoTransfer = getTravelTime(request, posbitnry); - //charge stations list = transferPoints + List posbitnry = findPlanWithNoTransferNew(request, taxi); + // pokud neexistuje ani jeden validni itinerar, tak je posbitnry null + // tehdy ho nebudu pridavat do templistu + if (posbitnry != null) { + List> tmp = new ArrayList<>(); + List tmpVehs = new ArrayList<>(); + tmpVehs.add(taxi); + tmp.add(posbitnry); + Pair>, List> pair = new Pair<>(tmp, tmpVehs); + templistP.add(pair); + long minimalArrivalTime = timeProvider.getCurrentSimTime() + travelTimeProvider.getExpectedTravelTime(request.getFrom(), request.getTo()); + HashMap dropoffs = getEstimatedTimesOfDropoff(posbitnry, taxi); + long realArrivalTime = dropoffs.get(request); + long delay = realArrivalTime - minimalArrivalTime; + delays.add(delay); + transferTimes.add((long) 0); + } + Set requestsOnBoardSet = new HashSet<>(); + DriverPlan actualPlan = taxi.getCurrentPlanNoUpdate(); + for(PlanAction action : actualPlan) { + if(action instanceof PlanRequestAction) { + PlanRequestAction requestAction = (PlanRequestAction) action; + requestsOnBoardSet.add(requestAction.request); + } + } + List requestsOnBoard = new ArrayList<>(requestsOnBoardSet); + + long timeToNewPickup = countTimeToNewPickup(taxi, request, requestsOnBoard); int stationIndex = 0; for (SimulationNode station : transferPoints) { + // je stanice potencialne vhodna pro prestup? + if (timeToNewPickup + travelTimeProvider.getExpectedTravelTime(request.getFrom(), station) > + request.getMaxDropoffTime() * 1000 - travelTimeProvider.getExpectedTravelTime(station, request.getTo())) { + continue; + } + // find k' = taxis that taxi k can transfer to at station for (int k = 0; k < taxisCount; k++) { + // minimalni cas na druhy usek + int minimalTimeFromStation = (int) Math.round(travelTimeProvider.getExpectedTravelTime(station, request.getFrom()) / 1000.0); //not possible to transfer to if (LT[stationIndex][k] == Long.MAX_VALUE) { continue; + } else if(LT[stationIndex][k] > request.getMaxDropoffTime() * 1000 - travelTimeProvider.getExpectedTravelTime(station, request.getTo())) { + continue; + } else if(taxi.equals(taxis.get(k))) { + continue; } else { // split request to two requests with transfer point - int originTime = (int) Math.round(request.getDemandAgent().getDemandTime() / 1000.0); - int minTravelTime = (int) Math.round( - travelTimeProvider.getExpectedTravelTime(request.getFrom(), station) / 1000.0); - int maxProlongation; - if(config.ridesharing.discomfortConstraint.equals("absolute")){ - maxProlongation = config.ridesharing.maxProlongationInSeconds; - } - else{ - maxProlongation = (int) Math.round( - config.ridesharing.maximumRelativeDiscomfort * minTravelTime); - } - int maxPickUpTime = originTime + maxProlongation; - int maxDropOffTime = originTime + minTravelTime + maxProlongation; - - PlanActionDropoff dropoffActionTransfer = new PlanActionDropoff(request, station, maxDropOffTime); - originTime = (int) Math.round(request.getDemandAgent().getDemandTime() / 1000.0); - minTravelTime = (int) Math.round( - travelTimeProvider.getExpectedTravelTime(station, request.getTo()) / 1000.0); - if(config.ridesharing.discomfortConstraint.equals("absolute")){ - maxProlongation = config.ridesharing.maxProlongationInSeconds; - } - else{ - maxProlongation = (int) Math.round( - config.ridesharing.maximumRelativeDiscomfort * minTravelTime); + long travelTimeFromStationToDest = travelTimeProvider.getExpectedTravelTime(station, request.getTo()); + int maxDropOffTime = request.getMaxDropoffTime() - (int) Math.round(travelTimeFromStationToDest / 1000.0); + PlanActionDropoffTransfer dropoffActionTransfer = new PlanActionDropoffTransfer(request, station, maxDropOffTime); + PlanActionPickupTransfer pickupActionTransfer = new PlanActionPickupTransfer(request, station, maxDropOffTime); + + List itnryp1 = findPlanWithNoTransferActionsNew(request.getPickUpAction(), dropoffActionTransfer, taxi); // pro auto + List itnryp2 = findPlanWithNoTransferActionsNew(pickupActionTransfer, request.getDropOffAction(), taxis.get(k)); + if (itnryp1 == null || itnryp2 == null) { + // neexistuje plan + continue; } - maxPickUpTime = originTime + maxProlongation; - PlanActionPickup pickupActionTransfer = new PlanActionPickup(request, station, maxPickUpTime); - - DefaultPlanComputationRequest newRequest1 = new DefaultPlanComputationRequest(travelTimeProvider, 0, config, request.getFrom(), station, request.getDemandAgent()); - DefaultPlanComputationRequest newRequest2 = new DefaultPlanComputationRequest(travelTimeProvider, 1, config, station, request.getTo(), request.getDemandAgent()); - //find optimal plans for these two requests -// List itnryp1 = findPlanWithNoTransferActions(request.getPickUpAction(), dropoffActionTransfer, taxi); // pro auto -// List itnryp2 = findPlanWithNoTransferActions(pickupActionTransfer, request.getDropOffAction(), taxis.get(k)); - List itnryp1 = findPlanWithNoTransfer(newRequest1, taxi); // pro auto - //List itnryp1R = getActionsForRequestFromActionsForDriver(itnryp1, newRequest1, taxi); - List itnryp2 = findPlanWithNoTransfer(newRequest2, taxis.get(k)); // pro auto - //List itnryp2R = getActionsForRequestFromActionsForDriver(itnryp2, newRequest2, taxis.get(k)); - Map>, Long> m = createChargePlan(itnryp1, itnryp2, taxi, taxis.get(k), newRequest1, newRequest2); - if (m == null) { - // neni mozne prestoupit, takze neudelam nic + Pair>, Long> p = createChargePlanNoNewRequests(itnryp1, itnryp2, taxi, taxis.get(k), request); + if (p == null) { + // neni zadny validni plan a tedy neni mozne prestoupit, takze neudelam nic continue; } else { - Map.Entry>, Long> entry = m.entrySet().iterator().next(); - List> itnrys = entry.getKey(); + List> itnrys = p.getFirst(); itnryp1 = itnrys.get(0); itnryp2 = itnrys.get(1); List> tmp2 = new ArrayList<>(); @@ -330,15 +500,25 @@ private List heuristics(List tmpVehs2 = new ArrayList<>(); tmpVehs2.add(taxi); tmpVehs2.add(taxis.get(k)); - Map>, List> submap2 = new HashMap<>(); - submap2.put(tmp2, tmpVehs2); - List transferPlan = splittedRequestToPlanForRequest(itnryp1, itnryp2, newRequest1, newRequest2, request); - templist.put(submap2, transferPlan); - // TODO get travel time nefunguje dobre pro prestup - // asi kvuli traxi.getPosition() - long travelTimeTransfer = getTravelTime(newRequest1, itnryp1) + getTravelTime(newRequest2, itnryp2); - delays.add(travelTimeNoTransfer - travelTimeTransfer); - long transferTime = entry.getValue(); + Pair>, List> pair2 = new Pair<>(tmp2, tmpVehs2); + templistP.add(pair2); + // travel time daneho requestu s prestupem spocitam jako: + // cas nez prvni auto dojede pro request a vyzvedne ho + // + cas jizdy v prvnim vozidle + // + pokud druhe auto prijede pozdeji nez to prvni tak k tomu prictu rozdil + // + doba jizdy v druhem aute + HashMap drops = getEstimatedTimesOfDropoff(itnryp2, taxis.get(k)); + if (drops == null) { + // not valid + delays.add(Long.MAX_VALUE); + transferTimes.add((long) -1); + continue; + } + long minimalArrivalTime = timeProvider.getCurrentSimTime() + travelTimeProvider.getExpectedTravelTime(request.getFrom(), request.getTo()); + long realArrivalTime = drops.get(request); + long delay = realArrivalTime - minimalArrivalTime; + delays.add(delay); + long transferTime = p.getSecond(); transferTimes.add(transferTime); } } @@ -346,27 +526,12 @@ private List heuristics(List indices = new ArrayList<>(); - for(int q = 0; q < delays.size(); q++) - { - indices.add(q); + List listTransferPlans = new ArrayList<>(); + for (int j = 0; j < templistP.size(); j++) { + TransferPlan t = new TransferPlan(transferTimes.get(j), delays.get(j), templistP.get(j)); + listTransferPlans.add(t); } - List beforeDelays = new ArrayList<>(); - List beforeIndices = new ArrayList<>(); - beforeDelays.addAll(delays); - beforeIndices.addAll(indices); - //seradim delays od nejkratsich - delays.sort(null); - for(int q = 0; q < beforeDelays.size(); q++) { - int index = beforeDelays.indexOf(delays.get(q)); - indices.set(q, beforeIndices.get(q)); - } - // ted mam serazene delays a indexy v indices + listTransferPlans.sort(TransferPlan::compareByDelay); //vezmu hornich beta procent double beta = 0.2; @@ -374,51 +539,27 @@ private List heuristics(List subsetIndices = new ArrayList<>(); - List subsetTransferTimes = new ArrayList<>(); + List sublistTransferPlans = new ArrayList<>(); for (int q = 0; q < numOfTaken; q++) { - subsetIndices.add(indices.get(q)); - subsetTransferTimes.add(transferTimes.get(indices.get(q))); - } - // v subsetIndices mam ted indexy tech vysledku, ktere chci vybrat pro porovnani podle transfer timu - // v subsetTransferTimes jsou casy prestupu, podle toho to ted budu chtit seradit - - // chci seradit subsetIndices podle subsetTransferTImes - List beforeSubsetTransferTimes = new ArrayList<>(); - List beforeSubsetIndices = new ArrayList<>(); - beforeSubsetTransferTimes.addAll(subsetTransferTimes); - beforeSubsetIndices.addAll(subsetIndices); - //seradim transfer times od nejkratsich - subsetTransferTimes.sort(null); - for(int q = 0; q < beforeSubsetTransferTimes.size(); q++) { - int index = beforeSubsetTransferTimes.indexOf(subsetTransferTimes.get(q)); - subsetIndices.set(q, beforeSubsetIndices.get(q)); + if(!listTransferPlans.isEmpty()) { + sublistTransferPlans.add(listTransferPlans.get(q)); + } } - // ted mam serazene transferTimes a indexy v subsetIndices - - // ted bych mela chtit vybrat jeden entry z templistu podle toho subsetIndices - int indexOfFirst = subsetIndices.get(0); - int iterateOrder = 0; - Map.Entry>, List>, List> returnEntry = null; + sublistTransferPlans.sort(TransferPlan::compareByTransferTime); + Collections.reverse(sublistTransferPlans); - // ziskam entry ktery je nejlepsi podle heuristiky - for (Map.Entry>, List>, List> entry : templist.entrySet()) - { - if (iterateOrder == indexOfFirst) { - returnEntry = entry; - } + // ted mam serazene transferTimes + if (sublistTransferPlans.isEmpty()) { + continue; } - List selectedList = returnEntry.getValue(); - RequestPlan selected = new RequestPlan(selectedList, 0, 0); - selected.setRequest(request); - itinerarylist.add(selected); - Map>, List> key = returnEntry.getKey(); - for (Map.Entry>, List> entry : key.entrySet()) { - List> plansForVehicles = entry.getKey(); - List vehicles = entry.getValue(); + else + { + // ziskam entry ktery je nejlepsi podle heuristiky + Pair>, List> key = sublistTransferPlans.get(0).pair; + List> plansForVehicles = key.getFirst(); + List vehicles = key.getSecond(); for (int q = 0; q < vehicles.size(); q++) { -// RideSharingOnDemandVehicle veh = vehicles.get(q); List vehPlan = plansForVehicles.get(q); DriverPlan dp = new DriverPlan(vehPlan, 0, 0); vehicles.get(q).setCurrentPlan(dp); @@ -427,11 +568,11 @@ private List heuristics(List requestsOnBoardSet = new HashSet<>(); - DriverPlan actualPlan = taxi.getCurrentPlan(); + DriverPlan actualPlan = taxi.getCurrentPlanNoUpdate(); for(PlanAction action : actualPlan) { if(action instanceof PlanRequestAction) { PlanRequestAction requestAction = (PlanRequestAction) action; @@ -439,45 +580,99 @@ private List heuristics(List requestsOnBoard = new ArrayList<>(requestsOnBoardSet); - boolean taxiFree = taxi.hasFreeCapacity(); + // kolik lidi je prave ted v aute + boolean taxiFree = true; + int taxiCapacity = taxi.getCapacity(); + if (requestsOnBoardSet.size() >= taxiCapacity) { + taxiFree = false; + } for(int j = 0; j < stationsCount; j++) { - //timeProvider is set to null so getCurrentSimTime() wont work - //the idea is to fill LT with times of arrival of taxis - //LT[j][i] = this.timeProvider.getCurrentSimTime() + travelTime; //check if taxi has free seat if (!taxiFree) { - LT[j][q] = Long.MAX_VALUE; - } - else { - SimulationNode station = transferPoints.get(j); - long travelTime = this.travelTimeProvider.getExpectedTravelTime(taxiPosition, station); - //check if setting a new via point will exceed the tolerable delay for onboard passengers - if (checkTolerableDelay(requestsOnBoard, station, taxi)) { - LT[j][q] = travelTime; + LT[j][z] = Long.MAX_VALUE; + } else { + if (isWithTransfer(taxi.getCurrentPlanNoUpdate())) { + // nekdo prestupuje + int indexLastTransferAction = findLastTransferActionIndex(taxi.getCurrentPlanNoUpdate()); + long timeToFinishCurrentEdge = 0; + SimulationNode previousPos = taxi.getPosition(); + if (taxi.getCurrentTask() != null) { + timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(taxi, taxi.getCurrentTask().getPosition()); + previousPos = taxi.getCurrentTask().getPosition(); + } + long timeToLastTransferAction = 0; + for (int q = 0; q < indexLastTransferAction + 1; q++) { + if (taxi.getCurrentPlanNoUpdate().plan.get(q) instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) taxi.getCurrentPlanNoUpdate().plan.get(q); + timeToLastTransferAction = timeToLastTransferAction + wait.getWaitTime(); + } else { + timeToLastTransferAction = timeToLastTransferAction + travelTimeProvider.getExpectedTravelTime(previousPos, taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition()); + } + previousPos = taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition(); + } + // ted potrebuju najit posledni pickup ve zbyvajicim driver planu po prestupu + List segmentAfterTransfer = taxi.getCurrentPlanNoUpdate().plan.subList(indexLastTransferAction + 1, taxi.getCurrentPlanNoUpdate().plan.size()); + int indexLastPickupSegment = findLastPickupIndexList(segmentAfterTransfer); + long timeToLastPickup = 0; + SimulationNode previousPos2 = taxi.getCurrentPlanNoUpdate().plan.get(taxi.getCurrentPlanNoUpdate().plan.size()-1).getPosition(); + if (segmentAfterTransfer.size() > 0) { + previousPos2 = segmentAfterTransfer.get(0).getPosition(); + for (int q = 0; q < indexLastPickupSegment + 1; q++) { + timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos2, segmentAfterTransfer.get(q).getPosition()); + previousPos2 = segmentAfterTransfer.get(q).getPosition(); + } + } + SimulationNode station = transferPoints.get(j); + long timeToStation = travelTimeProvider.getExpectedTravelTime(previousPos, station); + long estimatedArrivalToStation = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastTransferAction + timeToLastPickup + timeToStation; + LT[j][z] = estimatedArrivalToStation; + // zkontrolovat, zda arrival je v pohode z hlediska delay - kontroluju pro requesty po ukonceni prestupu + Set requestsInSegmentSet = new HashSet<>(); + for (PlanAction action : segmentAfterTransfer) { + if (action instanceof PlanRequestAction) { + PlanRequestAction requestAction = (PlanRequestAction) action; + requestsInSegmentSet.add(requestAction.request); + } + } + List requestsInSegment = new ArrayList<>(requestsInSegmentSet); + for (PlanComputationRequest r : requestsInSegment) { + long maxTime = r.getMaxDropoffTime() * 1000; + if (LT[j][z] > maxTime) { + LT[j][z] = Long.MAX_VALUE; + break; + } + } } else { - LT[j][q] = Long.MAX_VALUE; + //neprestupuje nikdo + int indexLastPickup = findLastPickupIndex(taxi.getCurrentPlanNoUpdate()); + long timeToFinishCurrentEdge = 0; + SimulationNode previousPos = taxi.getPosition(); + if (taxi.getCurrentTask() != null) { + timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(taxi, taxi.getCurrentTask().getPosition()); + previousPos = taxi.getCurrentTask().getPosition(); + } + long timeToLastPickup = 0; + for (int q = 0; q < indexLastPickup + 1; q++) { + timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos, taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition()); + previousPos = taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition(); + } + SimulationNode station = transferPoints.get(j); + long timeToStation = travelTimeProvider.getExpectedTravelTime(previousPos, station); + long estimatedArrivalToStation = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastPickup + timeToStation; + LT[j][z] = estimatedArrivalToStation; + // zkontrolovat, zda arrival je v pohode z hlediska delay + for (PlanComputationRequest r : requestsOnBoard) { + long maxTime = r.getMaxDropoffTime() * 1000; + if (LT[j][z] > maxTime) { + LT[j][z] = Long.MAX_VALUE; + break; + } + } } } } } - -// //update k -// for(PlanComputationRequest req : requests) { -// int counter = 0; -// List possiblePickupTaxisOneRequest = new ArrayList<>(); -// for(RideSharingOnDemandVehicle t : taxis) { -// if (canServeRequestTASeT(t, req)) { -// counter++; -// possiblePickupTaxisOneRequest.add(t); -// } -// } -// possiblePickupTaxisCounts[i] = counter; -// possiblePickupTaxisMap.put(req, possiblePickupTaxisOneRequest); -// i++; -// } - } -// return itinerarylist; return taxis; } @@ -503,7 +698,6 @@ private long getTravelTime(PlanComputationRequest request, List plan PlanAction action = planOfCar.get(i); if (action instanceof PlanRequestAction) { PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); - previousPosition = action.getPosition(); if (pcq == request) { lastAction = action; break; @@ -572,6 +766,164 @@ private List splittedRequestToPlanForRequest(List itnryp } + private Pair>, Long> createChargePlanNoNewRequests(List itnryp1, List itnryp2, RideSharingOnDemandVehicle veh1, RideSharingOnDemandVehicle veh2, PlanComputationRequest request) { + long time1 = 0; + long timeToFinishEdge1 = 0; + SimulationNode previousDestination = veh1.getPosition(); + if (veh1.getCurrentTask() != null) { + timeToFinishEdge1 = travelTimeProvider.getTravelTime(veh1, veh1.getCurrentTask().getPosition()); + previousDestination = veh1.getCurrentTask().getPosition(); + } + time1 = timeToFinishEdge1; + long time2 = 0; + long timeToFinishEdge2 = 0; + if (veh2.getCurrentTask() != null) { + timeToFinishEdge2 = travelTimeProvider.getTravelTime(veh2, veh2.getCurrentTask().getPosition()); + } + time2 = timeToFinishEdge2; + // nemusim pricitat current sim time, protoze budu od sebe oba casy odecitat, jde mi jen o jejich rozdil + long transferTime = 0; + //expected arrival time of first car + int indexDropoffFirstCar = 0; + for (PlanAction action : itnryp1) { + if (action instanceof PlanRequestAction) { + PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); + if (action instanceof PlanActionPickup) { + SimulationNode dest = pcq.getFrom(); + time1 = time1 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = dest; + } else if(action instanceof PlanActionPickupTransfer) { + PlanActionPickupTransfer pickupTransfer = (PlanActionPickupTransfer) action; + SimulationNode dest = pickupTransfer.getPosition(); + time1 = time1 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = dest; + } else if(action instanceof PlanActionDropoffTransfer) { + PlanActionDropoffTransfer dropoffTransfer = (PlanActionDropoffTransfer) action; + SimulationNode dest = dropoffTransfer.getPosition(); + time1 = time1 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (dropoffTransfer.request == request) { + break; + } + previousDestination = dest; + } else if (action instanceof PlanActionDropoff) { + SimulationNode dest = pcq.getTo(); + time1 = time1 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = dest; + } else if (action instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) action; + time1 = time1 + wait.getWaitTime(); + } + indexDropoffFirstCar++; + } + } + // expected arrival of second car + int indexPickupSecondCar = 0; + PlanActionPickupTransfer pickup = null; + previousDestination = veh2.getPosition(); + for (PlanAction action : itnryp2) { + if (action instanceof PlanRequestAction) { + PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); + if (action instanceof PlanActionPickup) { + SimulationNode dest = pcq.getFrom(); + time2 = time2 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = dest; + } else if(action instanceof PlanActionPickupTransfer) { + PlanActionPickupTransfer pickupTransfer = (PlanActionPickupTransfer) action; + SimulationNode dest = pickupTransfer.getPosition(); + time2 = time2 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (pickupTransfer.request == request) { + pickup = pickupTransfer; + break; + } + previousDestination = dest; + } else if(action instanceof PlanActionDropoffTransfer) { + PlanActionDropoffTransfer dropoffTransfer = (PlanActionDropoffTransfer) action; + SimulationNode dest = dropoffTransfer.getPosition(); + time2 = time2 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = dest; + } else if (action instanceof PlanActionDropoff) { + SimulationNode dest = pcq.getTo(); + time2 = time2 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = dest; + } else if (action instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) action; + time2 = time2 + wait.getWaitTime(); + } + } + indexPickupSecondCar++; + } + long waitTime = time2 - time1; // k wait time prictu navic rezervu + + // pokud je zaporny, tak druhe auto bude muset cekat waitTime dlouho + // pokud je kladny, tak to znamena ze prvni auto prijede drive nez druhe - bude cekat cestujici + + boolean valid = true; + // pridam wait time do planu pro druhe auto pokud je wait time zaporny + if (waitTime < 0) { + waitTime = waitTime - 5000; + //transfer time je -waitTime + PlanActionWait waitAction = new PlanActionWait(request, pickup.getPosition(), pickup.getMaxTime(), -waitTime); + transferTime = -waitTime; + itnryp2.add(indexPickupSecondCar, waitAction); + + //check tolerable delay for passengers in vehicle2 + long time = 0; + time = timeToFinishEdge2; + previousDestination = veh2.getPosition(); + if (veh2.getCurrentTask() != null) { + previousDestination = veh2.getCurrentTask().getPosition(); + } + for (PlanAction action : itnryp2) { + if (action instanceof PlanRequestAction) { + PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); + if (action instanceof PlanActionPickup) { + SimulationNode dest = pcq.getFrom(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (!(time < pcq.getMaxPickupTime()*1000)) { + //not valid itinerary - check new driver plan + valid = false; + break; + } + previousDestination = dest; + } else if (action instanceof PlanActionDropoff) { + SimulationNode dest = pcq.getTo(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (!(time < pcq.getMaxDropoffTime()*1000)) { + //not valid itinerary - check new driver plan + valid = false; + break; + } + previousDestination = dest; + } else if (action instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) action; + time = time + wait.getWaitTime(); + previousDestination = wait.getPosition(); + } else if (action instanceof PlanActionPickupTransfer) { + PlanActionPickupTransfer p = (PlanActionPickupTransfer) action; + SimulationNode dest = p.getPosition(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = dest; + } else if(action instanceof PlanActionDropoffTransfer) { + PlanActionDropoffTransfer p = (PlanActionDropoffTransfer) action; + SimulationNode dest = p.getPosition(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = dest; + } + } + } + } + if(valid) { + List> itnrys = new ArrayList<>(); + itnrys.add(itnryp1); + itnrys.add(itnryp2); + Pair>, Long> ret = new Pair<>(itnrys, transferTime); + return ret; + } + else { + return null; + } + } + private Map>, Long> createChargePlan(List itnryp1, List itnryp2, RideSharingOnDemandVehicle veh1, RideSharingOnDemandVehicle veh2, DefaultPlanComputationRequest request1, DefaultPlanComputationRequest request2) { long time1 = 0; @@ -633,7 +985,7 @@ private Map>, Long> createChargePlan(List itnr // pridam wait time do planu pro druhe auto pokud je wait time zaporny if (waitTime <= 0) { //transfer time je -waitTime - PlanActionWait waitAction = new PlanActionWait(null, pickup.getPosition(), pickup.getMaxTime(), -waitTime); + PlanActionWait waitAction = new PlanActionWait(request2, pickup.getPosition(), pickup.getMaxTime(), -waitTime); transferTime = -waitTime; itnryp2.add(indexPickupSecondCar, waitAction); @@ -671,7 +1023,7 @@ private Map>, Long> createChargePlan(List itnr List> itnrys = new ArrayList<>(); itnrys.add(itnryp1); itnrys.add(itnryp2); - Map>, Long> map = new HashMap<>(); + Map>, Long> map = new LinkedHashMap<>(); map.put(itnrys, transferTime); return map; } @@ -683,7 +1035,7 @@ private Map>, Long> createChargePlan(List itnr public List getPickupActions(List plan) { List pickups = new ArrayList<>(); for(PlanAction action : plan) { - if(action instanceof PlanActionPickup) { + if(action instanceof PlanActionPickup || action instanceof PlanActionPickupTransfer) { pickups.add(action); } } @@ -693,7 +1045,7 @@ public List getPickupActions(List plan) { public List getDropoffActions(List plan) { List dropoffs = new ArrayList<>(); for(PlanAction action : plan) { - if(action instanceof PlanActionDropoff) { + if(action instanceof PlanActionDropoff || action instanceof PlanActionDropoffTransfer) { dropoffs.add(action); } } @@ -706,7 +1058,7 @@ public List getDropoffActions(List plan) { */ private List findPlanWithNoTransfer(PlanComputationRequest newRequest, RideSharingOnDemandVehicle taxi) { List lst = new ArrayList<>(); - List currentPlan = taxi.getCurrentPlan().plan; + List currentPlan = taxi.getCurrentPlanNoUpdate().plan; List newPlan = new ArrayList<>(); for (PlanAction action : currentPlan) { newPlan.add(action); @@ -719,6 +1071,7 @@ private List findPlanWithNoTransfer(PlanComputationRequest newReques //get dropoff actions in currentPlan List dropoffs = getDropoffActions(newPlan); //permute dropoff orders + // TODO fix tady se mi ztrati wait akce, pokud tam nejake jsou! List> dropoffOrders = permute(dropoffs); for (List dropoffPlan : dropoffOrders) { lst.add(createItinerary(pickups, dropoffPlan)); @@ -727,13 +1080,14 @@ private List findPlanWithNoTransfer(PlanComputationRequest newReques return bestPlan; } - private List findPlanWithNoTransferActions(PlanActionPickup pickup, PlanActionDropoff dropoff, RideSharingOnDemandVehicle taxi) { + private List findPlanWithNoTransferActions(PlanAction pickup, PlanAction dropoff, RideSharingOnDemandVehicle taxi) { List lst = new ArrayList<>(); - List currentPlan = taxi.getCurrentPlan().plan; + List currentPlan = taxi.getCurrentPlanNoUpdate().plan; List newPlan = new ArrayList<>(); for (PlanAction action : currentPlan) { newPlan.add(action); } + //add pickup and dropoff for new request newPlan.add(pickup); newPlan.add(dropoff); @@ -750,6 +1104,201 @@ private List findPlanWithNoTransferActions(PlanActionPickup pickup, return bestPlan; } + private HashMap getEstimatedTimesOfDropoff(List itinerary, RideSharingOnDemandVehicle vehicle) { + long time = timeProvider.getCurrentSimTime(); + long timeToFinishEdge = travelTimeProvider.getTravelTime(vehicle, itinerary.get(0).getPosition()); + time = time + timeToFinishEdge; + HashMap times = new HashMap<>(); + SimulationNode previousPosition = itinerary.get(0).getPosition(); + for (PlanAction action : itinerary) { + if (action instanceof PlanActionPickup || action instanceof PlanActionPickupTransfer) { + time = time + travelTimeProvider.getExpectedTravelTime(previousPosition, action.getPosition()); + if (time > ((PlanRequestAction) action).request.getMaxPickupTime() * 1000) { + //not valid + return null; + } + } else if (action instanceof PlanActionDropoff || action instanceof PlanActionDropoffTransfer) { + time = time + travelTimeProvider.getExpectedTravelTime(previousPosition, action.getPosition()); + if (time > ((PlanRequestAction) action).request.getMaxDropoffTime() * 1000) { + //not valid + return null; + } + times.put(((PlanRequestAction) action).getRequest(), time); + } else if (action instanceof PlanActionWait) { + time = time + ((PlanActionWait) action).getWaitTime(); + } + previousPosition = action.getPosition(); + } + return times; + } + + private List findItineraryWithMinimumDelayNew(List> lst, List originalPlan, RideSharingOnDemandVehicle vehicle) { + HashMap timesOfDropOriginal = getEstimatedTimesOfDropoff(originalPlan, vehicle); + if (timesOfDropOriginal == null) { + //plan neni validni + // to je chyba, puvodni plan by mel byt validni vzdy + return null; + //TODO throw exception + } + List delays = new ArrayList<>(); + for (List itnry : lst) { + HashMap timesOfDropNew = getEstimatedTimesOfDropoff(itnry, vehicle); + if (timesOfDropNew == null) { + //plan neni validni + delays.add(Long.MAX_VALUE); + } else { + // plan je validni, spocitam zpozdeni + long delay = countDelayDifference(timesOfDropOriginal, timesOfDropNew); + delays.add(delay); + } + } + //find max in delays + int maxAt = 0; + for (int i = 0; i < delays.size(); i++) { + maxAt = delays.get(i) > delays.get(maxAt) ? i : maxAt; + } + if (delays.get(maxAt) == Long.MAX_VALUE) { + return null; + } + List bestPlan = lst.get(maxAt); + return bestPlan; + } + + private long countDelayDifference(HashMap originalMap, HashMap newMap) { + long time = 0; + for (Map.Entry entry : originalMap.entrySet()) { + long difference = Math.abs(entry.getValue() - newMap.get(entry.getKey())); + time = time + difference; + } + return time; + } + + private List removeCurrentPositionActions(List listOfActionsWithPositions) { + List copyOfList = new ArrayList<>(); + copyOfList.addAll(listOfActionsWithPositions); + for (PlanAction action : listOfActionsWithPositions) { + if (action instanceof PlanActionCurrentPosition) { + copyOfList.remove(action); + } + } + return copyOfList; + } + + + private List findPlanWithNoTransferNew(PlanComputationRequest newRequest, RideSharingOnDemandVehicle vehicle) { + if (isWithTransfer(vehicle.getCurrentPlanNoUpdate())) { + // v aute nekdo prestupuje + // musim oddelit segment s prestupem + // ze zbytku vezmu pickups, pridam novy a potom hledam permutace dropoff akci + int indexLastTransfer = findLastTransferActionIndex(vehicle.getCurrentPlanNoUpdate()); + List segmentWithTransfer = vehicle.getCurrentPlanNoUpdate().plan.subList(0, indexLastTransfer+1); + List segmentWithTransferWithoutPositionAction = removeCurrentPositionActions(segmentWithTransfer); + + List segmentAfterTransfer = vehicle.getCurrentPlanNoUpdate().plan.subList(indexLastTransfer+1, vehicle.getCurrentPlanNoUpdate().plan.size()); + List> lstTemp = new ArrayList<>(); + List> lst = new ArrayList<>(); + List newPlan = new ArrayList<>(); + for (PlanAction action : segmentAfterTransfer) { + newPlan.add(action); + } + //add pickup and dropoff for new request + newPlan.add(newRequest.getPickUpAction()); + newPlan.add(newRequest.getDropOffAction()); + //get pickup order based on heuristic from TASeT paper + List pickups = getPickupActions(newPlan); + List dropoffs = getDropoffActions(newPlan); + //permute dropoff orders + List> dropoffOrders = permute(dropoffs); + for (List dropoffPlan : dropoffOrders) { + lstTemp.add(createItineraryList(pickups, dropoffPlan)); + } + // ted spojit puvodni segment a kadzy itinerare z lst + for (List itnry : lstTemp) { + List newList = new ArrayList<>(segmentWithTransferWithoutPositionAction); + newList.addAll(itnry); + lst.add(newList); + } + return findItineraryWithMinimumDelayNew(lst, vehicle.getCurrentPlanNoUpdate().plan, vehicle); + + } else { + //neni prestup v aute + List> lst = new ArrayList<>(); + List newPlan = new ArrayList<>(); + for (PlanAction action : vehicle.getCurrentPlanNoUpdate().plan) { + newPlan.add(action); + } + //add pickup and dropoff for new request + newPlan.add(newRequest.getPickUpAction()); + newPlan.add(newRequest.getDropOffAction()); + //get pickup order based on heuristic from TASeT paper + List pickups = getPickupActions(newPlan); + List dropoffs = getDropoffActions(newPlan); + //permute dropoff orders + List> dropoffOrders = permute(dropoffs); + for (List dropoffPlan : dropoffOrders) { + lst.add(createItineraryList(pickups, dropoffPlan)); + } + return findItineraryWithMinimumDelayNew(lst, vehicle.getCurrentPlanNoUpdate().plan, vehicle); + } + } + + private List findPlanWithNoTransferActionsNew(PlanAction pickup, PlanAction dropoff, RideSharingOnDemandVehicle vehicle) { + if (isWithTransfer(vehicle.getCurrentPlanNoUpdate())) { + // v aute nekdo prestupuje + // musim oddelit segment s prestupem + // ze zbytku vezmu pickups, pridam novy a potom hledam permutace dropoff akci + int indexLastTransfer = findLastTransferActionIndex(vehicle.getCurrentPlanNoUpdate()); + List segmentWithTransfer = vehicle.getCurrentPlanNoUpdate().plan.subList(0, indexLastTransfer+1); + List segmentWithTransferWithoutPositionAction = removeCurrentPositionActions(segmentWithTransfer); + + List segmentAfterTransfer = vehicle.getCurrentPlanNoUpdate().plan.subList(indexLastTransfer+1, vehicle.getCurrentPlanNoUpdate().plan.size()); + List> lstTemp = new ArrayList<>(); + List> lst = new ArrayList<>(); + List newPlan = new ArrayList<>(); + for (PlanAction action : segmentAfterTransfer) { + newPlan.add(action); + } + //add pickup and dropoff for new request + newPlan.add(pickup); + newPlan.add(dropoff); + //get pickup order based on heuristic from TASeT paper + List pickups = getPickupActions(newPlan); + List dropoffs = getDropoffActions(newPlan); + //permute dropoff orders + List> dropoffOrders = permute(dropoffs); + for (List dropoffPlan : dropoffOrders) { + lstTemp.add(createItineraryList(pickups, dropoffPlan)); + } + // ted spojit puvodni segment a kadzy itinerare z lst + for (List itnry : lstTemp) { + List newList = new ArrayList<>(segmentWithTransferWithoutPositionAction); + newList.addAll(itnry); + lst.add(newList); + } + return findItineraryWithMinimumDelayNew(lst, vehicle.getCurrentPlanNoUpdate().plan, vehicle); + + } else { + //neni prestup v aute + List> lst = new ArrayList<>(); + List newPlan = new ArrayList<>(); + for (PlanAction action : vehicle.getCurrentPlanNoUpdate().plan) { + newPlan.add(action); + } + //add pickup and dropoff for new request + newPlan.add(pickup); + newPlan.add(dropoff); + //get pickup order based on heuristic from TASeT paper + List pickups = getPickupActions(newPlan); + List dropoffs = getDropoffActions(newPlan); + //permute dropoff orders + List> dropoffOrders = permute(dropoffs); + for (List dropoffPlan : dropoffOrders) { + lst.add(createItineraryList(pickups, dropoffPlan)); + } + return findItineraryWithMinimumDelayNew(lst, vehicle.getCurrentPlanNoUpdate().plan, vehicle); + } + } + private List getActionsForRequestFromActionsForDriver(List planActionsVehicle, PlanComputationRequest request, RideSharingOnDemandVehicle vehicle) { List actionsForRequest = new ArrayList<>(); for (int i = 0; i < planActionsVehicle.size(); i++) { @@ -801,6 +1350,7 @@ private List getActionsForRequestFromActionsForDriver(List convertDriverPlansToRequestPlans(List driverPlans, List requests) { int lenRequests = requests.size(); List requestPlans = new ArrayList<>(); @@ -820,7 +1370,7 @@ private List convertDriverPlansToRequestPlans(List driv { if (action instanceof PlanActionPickup) { PlanActionOnboard planActionOnboard = new PlanActionOnboard(requestAssigned, action.getPosition(), rAction.getMaxTime(), driverPlan.getVehicle()); -// TODO: iterate over existing actions and find a timestamp HOPEFULLY DONE +// iterate over existing actions and find a timestamp HOPEFULLY DONE PlanAction currentAction = requestPlans.get(j).plan.get(0); PlanRequestAction currentRAction = (PlanRequestAction) currentAction; int index = 0; @@ -832,19 +1382,19 @@ private List convertDriverPlansToRequestPlans(List driv requestPlans.get(j).plan.add(index, planActionOnboard); } else if (action instanceof PlanActionDropoff) { PlanActionOffboard planActionOffboard = new PlanActionOffboard(requestAssigned, action.getPosition(), rAction.getMaxTime(), driverPlan.getVehicle()); -// TODO: iterate over existing actions and find a timestamp +// : iterate over existing actions and find a timestamp requestPlans.get(j).plan.add(planActionOffboard); } else if (action instanceof PlanActionWait) { } -// TODO: add Wait Actions +// : add Wait Actions } } } } return requestPlans; } - + // neni dodelana ale nepouzivam ji private List convertRequestPlansToDriverPlans(List requestPlans, List vehicles) { int lenVehicles = vehicles.size(); List driverPlans = new ArrayList<>(); @@ -864,7 +1414,7 @@ private List convertRequestPlansToDriverPlans(List requ for (int j = 0; j < vehicles.size(); j++) { if (veh == vehicles.get(i)) { -// TODO: iterate over existing actions and find a timestamp +// : iterate over existing actions and find a timestamp driverPlans.get(j).plan.add(planActionDropoff); } } @@ -880,7 +1430,7 @@ else if (action instanceof PlanActionOnboard) { } } } -// TODO: resolve Wait Actions +// : resolve Wait Actions } } return driverPlans; @@ -960,6 +1510,12 @@ private DriverPlan createItinerary(List pickupOrder, List createItineraryList(List pickupOrder, List dropoffOrder) { + List listOfActionsOrdered = new ArrayList<>(pickupOrder); + listOfActionsOrdered.addAll(dropoffOrder); + return listOfActionsOrdered; + } + /** * @return new list with all permutations of PlanActrions from lst List. */ @@ -999,12 +1555,17 @@ private void permuteHelper(List> list, List resultL * @return boolean */ private boolean checkTolerableDelay(List requestsOnBoard, SimulationNode viaPoint, RideSharingOnDemandVehicle taxi) { + //TODO + // uvazuju ze auto se ted rozhodne jet do stanice + // potrebuju zjistit jestli to nebude vadit ostatnim cestujicim + + //for every onboard passenger in taxi for(PlanComputationRequest request : requestsOnBoard) { SimulationNode destination = request.getTo(); //get new time of arrival with new via point -// long newArrivalTime = timeProvider.getCurrentSimTime() + travelTimeProvider.getTravelTime(taxi, viaPoint) + travelTimeProvider.getTravelTime(taxi, viaPoint, destination); - long newArrivalTime = travelTimeProvider.getTravelTime(taxi, viaPoint) + travelTimeProvider.getTravelTime(taxi, viaPoint, destination); + long newArrivalTime = timeProvider.getCurrentSimTime() + travelTimeProvider.getTravelTime(taxi, viaPoint) + travelTimeProvider.getTravelTime(taxi, viaPoint, destination); +// long newArrivalTime = travelTimeProvider.getTravelTime(taxi, viaPoint) + travelTimeProvider.getTravelTime(taxi, viaPoint, destination); if (newArrivalTime > request.getMaxDropoffTime()) { return false; } @@ -1017,10 +1578,112 @@ private boolean checkTolerableDelay(List requestsOnBoard * @return boolean. */ private boolean canServeRequestTASeT(RideSharingOnDemandVehicle vehicle, PlanComputationRequest request) { - //wont work since timeProvider is set null in test -// return travelTimeProvider.getTravelTime(vehicle, request.getFrom()) + timeProvider.getCurrentSimTime() -// < request.getMaxPickupTime(); - return travelTimeProvider.getTravelTime(vehicle, request.getFrom()) < request.getMaxPickupTime() * 1000; + return travelTimeProvider.getTravelTime(vehicle, request.getFrom()) + timeProvider.getCurrentSimTime() + < request.getMaxPickupTime() * 1000; + + //TODO upravit + // pokud je taxik prazdny, tak se podivam jestli taxik prijede do cile driv nez je max dropoff time + // dojede do cile? + // = expectedTravelTime(aktualni pozice taxiku, zacatek) + expected(zacatek, cil) + currentSimTime + // tohle zaokrouhlene na integer musi byt <= maxDropoff + // neboli expectedTravelTime(aktualni, zacatek) + currentSimTime <= maxPickUpTime + + // kdyz taxik neni prazdny, tak krome vyse uvedene podminky musi splnovat podminku i pro ostatni cestujici + // tento constraint se ale kontroluje v findPlanWithMinimumDelay - az to opravim teda xD + } + + private boolean canServeRequestTASeT2(RideSharingOnDemandVehicle vehicle, PlanComputationRequest request) { + Set requestsOnBoardSet = new HashSet<>(); + DriverPlan actualPlan = vehicle.getCurrentPlanNoUpdate(); + for(PlanAction action : actualPlan) { + if(action instanceof PlanRequestAction) { + PlanRequestAction requestAction = (PlanRequestAction) action; + requestsOnBoardSet.add(requestAction.request); + } + } + List requestsOnBoard = new ArrayList<>(requestsOnBoardSet); + // kolik lidi je prave ted v aute + boolean taxiFree = true; + int taxiCapacity = vehicle.getCapacity(); + if (requestsOnBoardSet.size() >= taxiCapacity) { + taxiFree = false; + } + if (!taxiFree) { + return false; + } + else { + if (requestsOnBoard.size() == 0) { + long timeToNewRequest = travelTimeProvider.getTravelTime(vehicle, request.getFrom()); + if (timeToNewRequest <= request.getMaxPickupTime() * 1000) { + return true; + } + return false; + } + if (isWithTransfer(vehicle.getCurrentPlanNoUpdate())) { + // nekdo prestupuje + int indexLastTransferAction = findLastTransferActionIndex(vehicle.getCurrentPlanNoUpdate()); + long timeToFinishCurrentEdge = 0; + SimulationNode previousPos = vehicle.getPosition(); + if (vehicle.getCurrentTask() != null) { + timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(vehicle, vehicle.getCurrentTask().getPosition()); + previousPos = vehicle.getCurrentTask().getPosition(); + } + long timeToLastTransferAction = 0; + for (int q = 0; q < indexLastTransferAction + 1; q++) { + if (vehicle.getCurrentPlanNoUpdate().plan.get(q) instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) vehicle.getCurrentPlanNoUpdate().plan.get(q); + timeToLastTransferAction = timeToLastTransferAction + wait.getWaitTime(); + } else { + timeToLastTransferAction = timeToLastTransferAction + travelTimeProvider.getExpectedTravelTime(previousPos, vehicle.getCurrentPlanNoUpdate().plan.get(q).getPosition()); + } + previousPos = vehicle.getCurrentPlanNoUpdate().plan.get(q).getPosition(); + } + // ted potrebuju najit posledni pickup ve zbyvajicim driver planu po prestupu + List segmentAfterTransfer = vehicle.getCurrentPlanNoUpdate().plan.subList(indexLastTransferAction+1, vehicle.getCurrentPlanNoUpdate().plan.size()); + int indexLastPickupSegment = findLastPickupIndexList(segmentAfterTransfer); + long timeToLastPickup = 0; + SimulationNode previousPos2 = vehicle.getCurrentPlanNoUpdate().plan.get(vehicle.getCurrentPlanNoUpdate().plan.size()-1).getPosition(); + if (segmentAfterTransfer.size() > 0) { + previousPos2 = segmentAfterTransfer.get(0).getPosition(); + for (int q = 0; q < indexLastPickupSegment + 1; q++) { + timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos2, segmentAfterTransfer.get(q).getPosition()); + previousPos2 = segmentAfterTransfer.get(q).getPosition(); + } + } + + //odtud jestli muze dojet k requestu - tj. cas od mista kde skoncil k vyzvednuti requestu + long timeToNewRequest = travelTimeProvider.getExpectedTravelTime(previousPos2, request.getFrom()); + long estimatedArrival = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastTransferAction + timeToLastPickup + timeToNewRequest; + if (estimatedArrival <= request.getMaxPickupTime() * 1000) { + return true; + } else { + return false; + } + } + else { + //neprestupuje nikdo + int indexLastPickup = findLastPickupIndex(vehicle.getCurrentPlanNoUpdate()); + long timeToFinishCurrentEdge = 0; + SimulationNode previousPos = vehicle.getPosition(); + if (vehicle.getCurrentTask() != null) { + timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(vehicle, vehicle.getCurrentTask().getPosition()); + previousPos = vehicle.getCurrentTask().getPosition(); + } + long timeToLastPickup = 0; + for (int q = 0; q < indexLastPickup + 1; q++) { + timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos, vehicle.getCurrentPlanNoUpdate().plan.get(q).getPosition()); + previousPos = vehicle.getCurrentPlanNoUpdate().plan.get(q).getPosition(); + } + long timeToNewRequest = travelTimeProvider.getExpectedTravelTime(previousPos, request.getFrom()); + long estimatedArrival = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastPickup + timeToNewRequest; + if (estimatedArrival <= request.getMaxPickupTime() * 1000) { + return true; + } else { + return false; + } + } + + } } } diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/TransferPlan.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/TransferPlan.java new file mode 100644 index 00000000..be378d2d --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/TransferPlan.java @@ -0,0 +1,30 @@ +package cz.cvut.fel.aic.simod.ridesharing.greedyTASeT; + +import cz.cvut.fel.aic.simod.ridesharing.RideSharingOnDemandVehicle; +import cz.cvut.fel.aic.simod.ridesharing.model.PlanAction; +import org.jgrapht.alg.util.Pair; + +import java.util.List; + +public class TransferPlan { + + public final long trasferTime; + public final long delay; + public final Pair>, List> pair; + + TransferPlan(long trasferTime, long delay, Pair>, List> pair) { + this.trasferTime = trasferTime; + this.delay = delay; + this.pair = pair; + } + + public int compareByDelay(TransferPlan o2) { + return Long.compare(this.delay, o2.delay); + } + + public int compareByTransferTime(TransferPlan o2) { + return Long.compare(this.trasferTime, o2.trasferTime); + } +} + + diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionDropoffTransfer.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionDropoffTransfer.java new file mode 100644 index 00000000..d8886027 --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionDropoffTransfer.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021 Czech Technical University in Prague. + * + * This file is part of the SiMoD project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package cz.cvut.fel.aic.simod.ridesharing.model; + +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; + +public class PlanActionDropoffTransfer extends PlanRequestAction { + + /** + * DropoffTransfer action. + * @param request Request + * @param node Position where action takes place. + * @param maxTime Time constraint in seconds. + */ + public PlanActionDropoffTransfer(PlanComputationRequest request, SimulationNode node, int maxTime) { + super(request, node, maxTime); + } + + + + @Override + public String toString() { + return String.format("Drop off demand %s at node %s", request.getDemandAgent().getId(), location.id); + } + + + +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionPickupTransfer.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionPickupTransfer.java new file mode 100644 index 00000000..49150438 --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionPickupTransfer.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021 Czech Technical University in Prague. + * + * This file is part of the SiMoD project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package cz.cvut.fel.aic.simod.ridesharing.model; + +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; + +public class PlanActionPickupTransfer extends PlanRequestAction { + + /** + * PickupTransfer action. + * @param request Request + * @param node Position where action takes place. + * @param maxTime Time constraint in seconds. + */ + public PlanActionPickupTransfer(PlanComputationRequest request, SimulationNode node, int maxTime) { + super(request, node, maxTime); + } + + + + @Override + public String toString() { + return String.format("Pick up demand %s at node %s", request.getDemandAgent().getId(), location.id); + } + + +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionWait.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionWait.java index af054dea..7f6030e1 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionWait.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionWait.java @@ -22,6 +22,6 @@ public PlanActionWait(PlanComputationRequest request, SimulationNode node, int m @Override public String toString() { - return String.format("Wait demand %s at node %s", request.getDemandAgent().getId(), location.id); + return String.format("Wait for demand %s at node %s", request.getDemandAgent().getId(), location.id); } } diff --git a/src/main/java/cz/cvut/fel/aic/simod/statistics/Statistics.java b/src/main/java/cz/cvut/fel/aic/simod/statistics/Statistics.java index 1a562e7a..653c78e7 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/statistics/Statistics.java +++ b/src/main/java/cz/cvut/fel/aic/simod/statistics/Statistics.java @@ -548,6 +548,8 @@ private void saveOnDemandVehicleEvents() { case FINISH_REBALANCING: filepath = config.statistics.onDemandVehicleStatistic.finishRebalancingFilePath; break; + case WAIT: + filepath = config.statistics.onDemandVehicleStatistic.waitFilePath; } try { diff --git a/src/main/resources/cz/cvut/fel/aic/simod/config/config.cfg b/src/main/resources/cz/cvut/fel/aic/simod/config/config.cfg index 43dd59f6..c57e7d70 100644 --- a/src/main/resources/cz/cvut/fel/aic/simod/config/config.cfg +++ b/src/main/resources/cz/cvut/fel/aic/simod/config/config.cfg @@ -14,7 +14,7 @@ map_dir: $simod_data_dir + 'maps/' trips_filename: 'trips' trips_path: $simod_data_dir + $trips_filename + '.txt' -trips_multiplier: 3.433 +trips_multiplier: 1.0 #~ trips_multiplier: 1.0 @@ -159,6 +159,7 @@ statistics: reach_nearest_station_file_path: $statistics.on_demand_vehicle_statistic.dir_path + 'reach_nearest_station.csv' start_rebalancing_file_path: $statistics.on_demand_vehicle_statistic.dir_path + 'start_rebalancing.csv' finish_rebalancing_file_path: $statistics.on_demand_vehicle_statistic.dir_path + 'finish_rebalancing.csv' + wait_file_path: $statistics.on_demand_vehicle_statistic.dir_path + 'wait.csv' } trip_distances_file_path: $simod_experiment_dir + 'demand_trip_lengths.csv' occupancies_file_name: 'vehicle_occupancy.csv' diff --git a/src/test/java/cz/cvut/fel/aic/simod/system/TestOnDemandVehicle.java b/src/test/java/cz/cvut/fel/aic/simod/system/TestOnDemandVehicle.java index e8494980..ecec74f8 100644 --- a/src/test/java/cz/cvut/fel/aic/simod/system/TestOnDemandVehicle.java +++ b/src/test/java/cz/cvut/fel/aic/simod/system/TestOnDemandVehicle.java @@ -24,11 +24,14 @@ import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.TripsUtil; import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.StandardTimeProvider; import cz.cvut.fel.aic.agentpolis.simmodel.IdGenerator; +import cz.cvut.fel.aic.agentpolis.simmodel.activity.Wait; import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.StandardDriveFactory; +import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.WaitActivityFactory; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; import cz.cvut.fel.aic.agentpolis.simulator.visualization.visio.VisioPositionUtil; import cz.cvut.fel.aic.alite.common.event.EventProcessor; import cz.cvut.fel.aic.simod.StationsDispatcher; +import cz.cvut.fel.aic.simod.WaitTransferActivityFactory; import cz.cvut.fel.aic.simod.config.SimodConfig; import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicle; import cz.cvut.fel.aic.simod.storage.PhysicalTransportVehicleStorage; @@ -53,6 +56,8 @@ public TestOnDemandVehicle( SimodConfig config, IdGenerator idGenerator, AgentpolisConfig agentpolisConfig, + WaitTransferActivityFactory waitTransferActivityFactory, + WaitActivityFactory waitActivityFactory, @Assisted String vehicleId, @Assisted SimulationNode startPosition) { super(vehicleStorage, @@ -66,6 +71,8 @@ public TestOnDemandVehicle( config, idGenerator, agentpolisConfig, + waitTransferActivityFactory, + waitActivityFactory, vehicleId, startPosition); diff --git a/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java b/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java index d9d2d794..7a26e0cd 100644 --- a/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java +++ b/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java @@ -9,6 +9,7 @@ import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.TimeProvider; import cz.cvut.fel.aic.agentpolis.simmodel.IdGenerator; import cz.cvut.fel.aic.agentpolis.simmodel.MoveUtil; +import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.WaitActivityFactory; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.EGraphType; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.GraphType; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.NearestElementUtils; @@ -21,6 +22,7 @@ import cz.cvut.fel.aic.alite.common.event.typed.TypedSimulation; import cz.cvut.fel.aic.geographtools.Graph; import cz.cvut.fel.aic.geographtools.util.Transformer; +import cz.cvut.fel.aic.simod.WaitTransferActivityFactory; import cz.cvut.fel.aic.simod.config.SimodConfig; import cz.cvut.fel.aic.simod.entity.DemandAgent; import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicle; @@ -30,8 +32,7 @@ import cz.cvut.fel.aic.simod.ridesharing.RideSharingOnDemandVehicle; import cz.cvut.fel.aic.simod.ridesharing.StandardPlanCostProvider; import cz.cvut.fel.aic.simod.ridesharing.insertionheuristic.DriverPlan; -import cz.cvut.fel.aic.simod.ridesharing.model.DefaultPlanComputationRequest; -import cz.cvut.fel.aic.simod.ridesharing.model.PlanComputationRequest; +import cz.cvut.fel.aic.simod.ridesharing.model.*; import cz.cvut.fel.aic.simod.storage.OnDemandVehicleStorage; import cz.cvut.fel.aic.simod.storage.OnDemandvehicleStationStorage; import cz.cvut.fel.aic.simod.storage.PhysicalTransportVehicleStorage; @@ -105,7 +106,11 @@ public long getCurrentSimTime() { DroppedDemandsAnalyzer droppedDemandsAnalyzer = null; // new DroppedDemandsAnalyzer( vehicleStorage, positionUtil, astarTravelTimeProvider, config, onDemandvehicleStationStorage, agentpolisConfig); // start position of 1st vehicle - SimulationNode startPos = graph.getNode(1); // top left corner + SimulationNode startPos = graph.getNode(6); // top left corner + + WaitTransferActivityFactory waitTransferActivityFactory = new WaitTransferActivityFactory(); + WaitActivityFactory waitActivityFactory = new WaitActivityFactory(); + RideSharingOnDemandVehicle vehicle_1 = new RideSharingOnDemandVehicle( physicalVehicleStorage, @@ -120,12 +125,35 @@ public long getCurrentSimTime() { simodConfig, idGenerator3, agentpolisConfig, + waitTransferActivityFactory, + waitActivityFactory, "1", startPos + + ); + RideSharingOnDemandVehicle vehicle_2 = new RideSharingOnDemandVehicle( + physicalVehicleStorage, + tripsUtil, + null, + null, + null, + tripIdGenerator, + eventProcessor, + standardTimeProvider, + idGenerator2, + simodConfig, + idGenerator3, + agentpolisConfig, + waitTransferActivityFactory, + waitActivityFactory, + "2", + startPos ); + onDemandVehicleStorage.addEntity(vehicle_1); + onDemandVehicleStorage.addEntity(vehicle_2); - SimulationNode transferPoint = graph.getNode(7); + SimulationNode transferPoint = graph.getNode(6); List transferPoints = new ArrayList<>(); transferPoints.add(transferPoint); @@ -145,10 +173,10 @@ public long getCurrentSimTime() { solver.setTransferPoints(transferPoints); // create requests - SimulationNode origin_1 = graph.getNode(1); - SimulationNode destination_1 = graph.getNode(3); + SimulationNode origin_1 = graph.getNode(2); + SimulationNode destination_1 = graph.getNode(8); long startTime = 0; - long endTime = 1000; + long endTime = 100; SimulationNode[] locations = {origin_1, destination_1}; DemandAgent demandAgent_0 = new DemandAgent( null, @@ -166,10 +194,10 @@ public long getCurrentSimTime() { ) ); - SimulationNode origin_2 = graph.getNode(3); - SimulationNode destination_2 = graph.getNode(6); - long startTime2 = 1050; - long endTime2 = 2500; + SimulationNode origin_2 = graph.getNode(5); + SimulationNode destination_2 = graph.getNode(10); + long startTime2 = 0; + long endTime2 = 100; SimulationNode[] locations2 = {origin_2, destination_2}; DemandAgent demandAgent_1 = new DemandAgent( null, @@ -187,79 +215,68 @@ public long getCurrentSimTime() { ) ); + SimulationNode origin_3 = graph.getNode(2); + SimulationNode destination_3 = graph.getNode(10); + long startTime3 = 0; + long endTime3 = 100; + SimulationNode[] locations3 = {origin_3, destination_3}; + DemandAgent demandAgent_2 = new DemandAgent( + null, + eventProcessor, + null, + standardTimeProvider, + tripsUtil, + "agent_02", + 1, + new TimeTrip( + 0, + startTime3, + endTime3, + locations3 + ) + ); + + SimulationNode origin_4 = graph.getNode(5); + SimulationNode destination_4 = graph.getNode(8); + long startTime4 = 0; + long endTime4 = 100; + SimulationNode[] locations4 = {origin_4, destination_4}; + DemandAgent demandAgent_3 = new DemandAgent( + null, + eventProcessor, + null, + standardTimeProvider, + tripsUtil, + "agent_03", + 1, + new TimeTrip( + 0, + startTime4, + endTime4, + locations4 + ) + ); + + + + DefaultPlanComputationRequest request_1 = new DefaultPlanComputationRequest(astarTravelTimeProvider, 0, simodConfig, origin_1, destination_1, demandAgent_0); DefaultPlanComputationRequest request_2 = new DefaultPlanComputationRequest(astarTravelTimeProvider, 1, simodConfig, origin_2, destination_2, demandAgent_1); + DefaultPlanComputationRequest request_3 = new DefaultPlanComputationRequest(astarTravelTimeProvider, 1, simodConfig, origin_3, destination_3, demandAgent_2); + DefaultPlanComputationRequest request_4 = new DefaultPlanComputationRequest(astarTravelTimeProvider, 1, simodConfig, origin_4, destination_4, demandAgent_3); List requestsPeople = new ArrayList<>(); requestsPeople.add(request_2); requestsPeople.add(request_1); + requestsPeople.add(request_3); + requestsPeople.add(request_4); // call solve method - Map solution = solver.solve(requestsPeople, null); + Map solution = solver.solve(requestsPeople, null); System.out.println("Solution:"); System.out.println(solution.values().toString()); -// OnDemandVehicleStorage vehicleStorage = new OnDemandVehicleStorage(); -// TravelTimeProvider travelTimeProvider = null; -// TimeProvider timeProvider = null; -// PlanCostProvider travelCostProvider = null; -// DefaultPlanComputationRequest.DefaultPlanComputationRequestFactory requestFactory = null; -// TypedSimulation eventProcessor = new TypedSimulation(120); -// SimodConfig config = new SimodConfig(); -// TimeProvider timeProvider1 = new TimeProvider() { -// @Override -// public long getCurrentSimTime() { -// return 0; -// } -// }; -// PositionUtil positionUtil = new PositionUtil(); -// TripsUtil tripsUtil = null; -// // TripsUtil(ShortestPathPlanner pathPlanner, NearestElementUtils nearestElementUtils, HighwayNetwork network, IdGenerator tripIdGenerator) -// ShortestPathPlanner pathPlanner = null; -// NearestElementUtils nearestElementUtils = new NearestElementUtils(null, null); -// HighwayNetwork highwayNetwork = new HighwayNetwork(null); -// -// -// Map> map = null; -// int citySRID = 32618; -// Transformer transformer = new Transformer(citySRID); -// Graph graph = Utils.getCompleteGraph(4, transformer); -// AgentpolisConfig agentpolisConfig = new AgentpolisConfig(); -// MoveUtil moveUtil = new MoveUtil(agentpolisConfig); -//// AStarShortestPathPlanner astarShortestPathPlanner = -// -// AstarTravelTimeProvider astarTravelTimeProvider = new AstarTravelTimeProvider(timeProvider1, null, graph, moveUtil); -// OnDemandvehicleStationStorage onDemandvehicleStationStorage = new OnDemandvehicleStationStorage(transformer); -// DroppedDemandsAnalyzer droppedDemandsAnalyzer = new DroppedDemandsAnalyzer(vehicleStorage, positionUtil, astarTravelTimeProvider, config, onDemandvehicleStationStorage, agentpolisConfig); -// -// -// GreedyTASeTSolver solver = new GreedyTASeTSolver(vehicleStorage, astarTravelTimeProvider, null, null, -// eventProcessor, config, timeProvider1, positionUtil, null, -// onDemandvehicleStationStorage, agentpolisConfig, transferPoints); -// -//// TODO idk -//// requestFactory = -// -// SimulationNode origin = new SimulationNode(1, 2, 55, 45, 55, 45, 200, 0); -// SimulationNode destination = new SimulationNode(2, 3, 56, 46, 56, 46, 210, 0); -// // null pointer exception because trips util is null -// TestPlanRequest r1 = new TestPlanRequest(2, config, origin, destination, 0, false, astarTravelTimeProvider); -// SimulationNode origin2 = new SimulationNode(1, 2, 55, 46, 55, 46, 200, 0); -// SimulationNode destination2 = new SimulationNode(2, 3, 56, 45, 56, 5, 210, 0); -// TestPlanRequest r2 = new TestPlanRequest(2, config, origin2, destination2, 0, false, astarTravelTimeProvider); -// List req = new ArrayList<>(); -// PlanComputationRequest rp1 = (PlanComputationRequest)r1; -// PlanComputationRequest rp2 = (PlanComputationRequest)r2; -// req.add(rp1); -// req.add(rp2); -// List rr = new ArrayList<>(); -//// -// -// -// Map retMap = solver.solve(req, rr); -// - } @Test @@ -285,4 +302,27 @@ public void testSort() { System.out.println(list); } + + @Test + public void removeCurrentPositionActions() { + + List listOfActionsWithPositions = new ArrayList<>(); + + PlanActionCurrentPosition a1 = new PlanActionCurrentPosition(null); + PlanActionPickup a2 = new PlanActionPickup(null, null, 0); + PlanActionDropoffTransfer a3 = new PlanActionDropoffTransfer(null, null, 0); + + listOfActionsWithPositions.add(a1); + listOfActionsWithPositions.add(a2); + listOfActionsWithPositions.add(a3); + + List copyOfList = new ArrayList<>(); + copyOfList.addAll(listOfActionsWithPositions); + for (PlanAction action : listOfActionsWithPositions) { + if (action instanceof PlanActionCurrentPosition) { + copyOfList.remove(action); + } + } + System.out.println(copyOfList.size()); + } } From 702eb4939e7f34d64c9acb9d74019447dc7c4542 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kub=C3=ADkov=C3=A1=2C=20Ad=C3=A9la?= Date: Thu, 21 Apr 2022 04:48:43 +0200 Subject: [PATCH 07/21] Running TASeT solver without errors. --- .../fel/aic/simod/DriveToTransferStation.java | 104 ++++ ...DriveToTransferStationActivityFactory.java | 66 +++ .../cz/cvut/fel/aic/simod/TransferPickUp.java | 41 ++ .../simod/entity/OnDemandVehicleState.java | 2 - .../simod/entity/vehicle/OnDemandVehicle.java | 21 +- .../RideSharingOnDemandVehicle.java | 117 ++-- .../RidesharingOnDemandVehicleFactory.java | 10 +- .../greedyTASeT/GreedyTASeTSolver.java | 531 ++++++++++++++---- .../ridesharing/model/PlanActionWait.java | 6 +- .../greedyTASeT/GreedyTASeTSolverTest.java | 6 +- 10 files changed, 723 insertions(+), 181 deletions(-) create mode 100644 src/main/java/cz/cvut/fel/aic/simod/DriveToTransferStation.java create mode 100644 src/main/java/cz/cvut/fel/aic/simod/DriveToTransferStationActivityFactory.java create mode 100644 src/main/java/cz/cvut/fel/aic/simod/TransferPickUp.java diff --git a/src/main/java/cz/cvut/fel/aic/simod/DriveToTransferStation.java b/src/main/java/cz/cvut/fel/aic/simod/DriveToTransferStation.java new file mode 100644 index 00000000..6fc5b857 --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/DriveToTransferStation.java @@ -0,0 +1,104 @@ +package cz.cvut.fel.aic.simod; + +import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.trip.Trip; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.StandardTimeProvider; +import cz.cvut.fel.aic.agentpolis.simmodel.Activity; +import cz.cvut.fel.aic.agentpolis.simmodel.ActivityInitializer; +import cz.cvut.fel.aic.agentpolis.simmodel.Agent; +import cz.cvut.fel.aic.agentpolis.simmodel.activity.PhysicalVehicleDrive; +import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.VehicleMoveActivityFactory; +import cz.cvut.fel.aic.agentpolis.simmodel.agent.Driver; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.vehicle.Vehicle; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.EGraphType; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationEdge; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.networks.TransportNetworks; +import cz.cvut.fel.aic.agentpolis.simmodel.eventType.DriveEvent; +import cz.cvut.fel.aic.agentpolis.simmodel.eventType.Transit; +import cz.cvut.fel.aic.alite.common.event.EventProcessor; +import cz.cvut.fel.aic.alite.common.event.typed.TypedSimulation; +import cz.cvut.fel.aic.geographtools.Graph; +import cz.cvut.fel.aic.simod.ridesharing.RideSharingOnDemandVehicle; + + +/** + * @param + * @author fido + */ +public class DriveToTransferStation extends PhysicalVehicleDrive { + + private final Vehicle vehicle; + + private final Trip trip; + + private final VehicleMoveActivityFactory moveActivityFactory; + + private final Graph graph; + + private final EventProcessor eventProcessor; + + private final StandardTimeProvider timeProvider; + + + private SimulationNode from; + + private SimulationNode to; + + + + + public DriveToTransferStation(ActivityInitializer activityInitializer, TransportNetworks transportNetworks, + VehicleMoveActivityFactory moveActivityFactory, TypedSimulation eventProcessor, + StandardTimeProvider timeProvider, + A agent, Vehicle vehicle, Trip trip) { + super(activityInitializer, agent); + this.vehicle = vehicle; + this.trip = trip; + this.moveActivityFactory = moveActivityFactory; + this.eventProcessor = eventProcessor; + this.timeProvider = timeProvider; + graph = transportNetworks.getGraph(EGraphType.HIGHWAY); + } + + @Override + protected void performAction() { + agent.startDriving(vehicle); + from = trip.removeFirstLocation(); + move(); + } + + @Override + protected void onChildActivityFinish(Activity activity) { + if (trip.isEmpty() || stoped) { + agent.endDriving(); + // todo: nastavit tripalreadyplanned na false + if (agent instanceof RideSharingOnDemandVehicle) { + ((RideSharingOnDemandVehicle) agent).tripAlreadyPlanned = false; + } + vehicle.setLastFromPosition(from); + finish(); + } else { + from = to; + move(); + } + } + + + private void move() { + to = trip.removeFirstLocation(); + SimulationEdge edge = graph.getEdge(from, to); + + runChildActivity(moveActivityFactory.create(agent, edge, from, to)); + triggerVehicleEnteredEdgeEvent(); + } + + private void triggerVehicleEnteredEdgeEvent() { + SimulationEdge edge = graph.getEdge(from, to); + Transit transit = new Transit(timeProvider.getCurrentSimTime(), edge.getStaticId(),trip.getTripId(), agent); + eventProcessor.addEvent(DriveEvent.VEHICLE_ENTERED_EDGE, null, null, transit); + } + + public Trip getTrip() { + return trip; + } +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/DriveToTransferStationActivityFactory.java b/src/main/java/cz/cvut/fel/aic/simod/DriveToTransferStationActivityFactory.java new file mode 100644 index 00000000..0b4d7e26 --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/DriveToTransferStationActivityFactory.java @@ -0,0 +1,66 @@ +package cz.cvut.fel.aic.simod; + +import com.google.inject.Inject; +import com.google.inject.Singleton; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.TripsUtil; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.trip.Trip; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.StandardTimeProvider; +import cz.cvut.fel.aic.agentpolis.simmodel.ActivityFactory; +import cz.cvut.fel.aic.agentpolis.simmodel.Agent; +import cz.cvut.fel.aic.agentpolis.simmodel.activity.Drive; +import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.PhysicalVehicleDriveFactory; +import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.VehicleMoveActivityFactory; +import cz.cvut.fel.aic.agentpolis.simmodel.agent.Driver; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.vehicle.PhysicalVehicle; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.networks.TransportNetworks; +import cz.cvut.fel.aic.alite.common.event.typed.TypedSimulation; + +/** + * @author fido + */ +@Singleton +public class DriveToTransferStationActivityFactory extends ActivityFactory implements PhysicalVehicleDriveFactory { + + private final TransportNetworks transportNetworks; + + private final VehicleMoveActivityFactory moveActivityFactory; + + private final TypedSimulation eventProcessor; + + private final StandardTimeProvider timeProvider; + + private final TripsUtil tripsUtil; + + + @Inject + public DriveToTransferStationActivityFactory(TransportNetworks transportNetworks, VehicleMoveActivityFactory moveActivityFactory, + TypedSimulation eventProcessor, StandardTimeProvider timeProvider,TripsUtil tripsUtil) { + this.transportNetworks = transportNetworks; + this.moveActivityFactory = moveActivityFactory; + this.eventProcessor = eventProcessor; + this.timeProvider = timeProvider; + this.tripsUtil = tripsUtil; + } + + + @Override + public void runActivity(A agent, PhysicalVehicle vehicle, Trip trip) { + create(agent, vehicle, trip).run(); + } + + + public DriveToTransferStation create(A agent, PhysicalVehicle vehicle, Trip trip) { + return new DriveToTransferStation<>(activityInitializer, transportNetworks, moveActivityFactory, eventProcessor, + timeProvider, agent, vehicle, trip); + } + + @Override + public DriveToTransferStation create(A agent, PhysicalVehicle vehicle, SimulationNode target) { + Trip trip = tripsUtil.createTrip(agent.getPosition(), target); + + return new DriveToTransferStation<>(activityInitializer, transportNetworks, moveActivityFactory, eventProcessor, timeProvider, + agent, vehicle, trip); + } + +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/TransferPickUp.java b/src/main/java/cz/cvut/fel/aic/simod/TransferPickUp.java new file mode 100644 index 00000000..3241f980 --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/TransferPickUp.java @@ -0,0 +1,41 @@ +package cz.cvut.fel.aic.simod; + +import cz.cvut.fel.aic.agentpolis.simmodel.agent.TransportEntity; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.TransportableEntity; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.vehicle.PhysicalTransportVehicle; + +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +public final class TransferPickUp { + + public static void pickUp(T entity, + boolean isVehicleFull, E transportingEntity, List transportedEntities) { + if (isVehicleFull) { + try { + throw new Exception( + String.format("Cannot pick up entity, the vehicle is full! [%s]", entity)); + } catch (Exception ex) { + Logger.getLogger(PhysicalTransportVehicle.class.getName()).log(Level.SEVERE, null, ex); + } + } + if(entity.getTransportingEntity() != null) { + // auto se snazi zavolat pickup na demand, ktery jeste nedojel do cilove stanice + // ale nez by toto auto dojelo na stanici, demand uz by tam byl vylozeny + // proto podminka entity.getTransportingEntity() != null neni spravne + +// try { +// throw new Exception( +// String.format("Cannot pick up entity, it's already being transported! [%s]", entity)); +// } catch (Exception ex) { +// Logger.getLogger(PhysicalTransportVehicle.class.getName()).log(Level.SEVERE, null, ex); +// } + } + else{ + transportedEntities.add(entity); + entity.setTransportingEntity(transportingEntity); + } + } + +} \ No newline at end of file diff --git a/src/main/java/cz/cvut/fel/aic/simod/entity/OnDemandVehicleState.java b/src/main/java/cz/cvut/fel/aic/simod/entity/OnDemandVehicleState.java index bcebbc41..d8c56f6e 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/entity/OnDemandVehicleState.java +++ b/src/main/java/cz/cvut/fel/aic/simod/entity/OnDemandVehicleState.java @@ -28,7 +28,5 @@ public enum OnDemandVehicleState { DRIVING_TO_START_LOCATION, DRIVING_TO_TARGET_LOCATION, DRIVING_TO_STATION, - DRIVING_TO_TRANSFER_POINT_TARGET, - DRIVING_TO_TRANSFER_POINT_START, REBALANCING; } diff --git a/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicle.java b/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicle.java index 32238eff..026e79cf 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicle.java +++ b/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicle.java @@ -41,10 +41,7 @@ import cz.cvut.fel.aic.alite.common.event.Event; import cz.cvut.fel.aic.alite.common.event.EventHandler; import cz.cvut.fel.aic.alite.common.event.EventProcessor; -import cz.cvut.fel.aic.simod.DemandData; -import cz.cvut.fel.aic.simod.DemandSimulationEntityType; -import cz.cvut.fel.aic.simod.StationsDispatcher; -import cz.cvut.fel.aic.simod.WaitTransferActivityFactory; +import cz.cvut.fel.aic.simod.*; import cz.cvut.fel.aic.simod.config.SimodConfig; import cz.cvut.fel.aic.simod.entity.DemandAgent; import cz.cvut.fel.aic.simod.entity.OnDemandVehicleState; @@ -433,9 +430,24 @@ protected void dropOffDemand() { currentlyServedDemmand.demandAgent.getSimpleId(), getId())); } + public void startWaiting() { + // pokud je auto jinde nez ve stanici, tak chcu vytvorit trip ke stanici, spustit jizdu a az dojede, + // tak spustit cekani, ktere je kratsi o cas dojezdu na stanici +// waitActivityFactory.runActivity(this, ((PlanActionWait) currentTask).getWaitTime()); + state = OnDemandVehicleState.WAITINGFORTRANSFER; +// currentPlan.taskCompleted(); +// currentTask = currentPlan.getNextTask(); + } + @Override protected void onActivityFinish(Activity activity) { super.onActivityFinish(activity); + if (activity instanceof DriveToTransferStation) { + startWaiting(); + return; + + // try to do nothing + } if (activity instanceof PhysicalVehicleDrive) { PhysicalVehicleDrive drive = (PhysicalVehicleDrive) activity; finishedDriving(drive.isStoped()); @@ -443,6 +455,7 @@ protected void onActivityFinish(Activity activity) { else if (activity instanceof Wait) { finishedWaiting(); } + else { finishedDriving(true); } diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java index 780f8410..523eda28 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java @@ -22,8 +22,10 @@ import com.google.inject.assistedinject.Assisted; import cz.cvut.fel.aic.agentpolis.config.AgentpolisConfig; import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.TripsUtil; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.trip.Trip; import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.trip.VehicleTrip; import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.StandardTimeProvider; +import cz.cvut.fel.aic.agentpolis.simmodel.Activity; import cz.cvut.fel.aic.agentpolis.simmodel.IdGenerator; import cz.cvut.fel.aic.agentpolis.simmodel.activity.PhysicalVehicleDrive; import cz.cvut.fel.aic.agentpolis.simmodel.activity.Wait; @@ -31,6 +33,7 @@ import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.PhysicalVehicleDriveFactory; import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.WaitActivityFactory; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.vehicle.PickUp; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.init.SimpleMapInitializer; import cz.cvut.fel.aic.agentpolis.simulator.creator.SimulationCreator; @@ -38,9 +41,7 @@ import cz.cvut.fel.aic.agentpolis.system.AgentPolisInitializer; import cz.cvut.fel.aic.alite.common.event.Event; import cz.cvut.fel.aic.alite.common.event.EventProcessor; -import cz.cvut.fel.aic.simod.MainModule; -import cz.cvut.fel.aic.simod.StationsDispatcher; -import cz.cvut.fel.aic.simod.WaitTransferActivityFactory; +import cz.cvut.fel.aic.simod.*; import cz.cvut.fel.aic.simod.config.SimodConfig; import cz.cvut.fel.aic.simod.entity.DemandAgent; import cz.cvut.fel.aic.simod.entity.OnDemandVehicleState; @@ -52,6 +53,7 @@ import cz.cvut.fel.aic.simod.ridesharing.model.*; import cz.cvut.fel.aic.simod.statistics.PickupEventContent; import cz.cvut.fel.aic.simod.storage.PhysicalTransportVehicleStorage; +import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider; import cz.cvut.fel.aic.simod.visio.PlanLayerTrip; import org.opengis.filter.PropertyIsGreaterThanOrEqualTo; @@ -76,10 +78,14 @@ public class RideSharingOnDemandVehicle extends OnDemandVehicle{ private IdGenerator tripIdGenerator; - private WaitTransferActivityFactory waitTransferActivityFactory; - private WaitActivityFactory waitActivityFactory; + private TravelTimeProvider travelTimeProvider; + + private DriveToTransferStationActivityFactory driveToTransferStationActivityFactory; + + public boolean tripAlreadyPlanned = false; + public DriverPlan getCurrentPlan() { currentPlan.updateCurrentPosition(getPosition()); return currentPlan; @@ -116,6 +122,7 @@ public RideSharingOnDemandVehicle( AgentpolisConfig agentpolisConfig, WaitTransferActivityFactory waitTransferActivityFactory, WaitActivityFactory waitActivityFactory, + DriveToTransferStationActivityFactory driveToTransferStationActivityFactory, @Assisted String vehicleId, @Assisted SimulationNode startPosition) { super( vehicleStorage, @@ -138,7 +145,7 @@ public RideSharingOnDemandVehicle( this.waitTransferActivityFactory = waitTransferActivityFactory; this.waitActivityFactory = waitActivityFactory; - + this.driveToTransferStationActivityFactory = driveToTransferStationActivityFactory; // empty plan LinkedList plan = new LinkedList<>(); @@ -181,35 +188,6 @@ else if( } -// -// protected void driveToDemandTransferStartLocation() { -// // safety check that prevents request from being picked up twice because of the delayed pickup event -// if(((PlanActionPickupTransfer) currentTask).request.isOnboard()){ -// currentPlan.taskCompleted(); -// driveToNextTask(); -// } -// state = OnDemandVehicleState.DRIVING_TO_TRANSFER_POINT_START; -// if(getPosition().id == currentTask.getPosition().id){ -// pickupAndContinue(); -// } -// else{ -// currentTrip = tripsUtil.createTrip(getPosition(), currentTask.getPosition(), vehicle); -// DemandAgent demandAgent = ((PlanActionPickupTransfer) currentTask).getRequest().getDemandAgent(); -// driveFactory.runActivity(this, vehicle, currentTrip); -// } -// } -// -// protected void driveToDemandTransferTargetLocation() { -// state = OnDemandVehicleState.DRIVING_TO_TRANSFER_POINT_TARGET; -// if(getPosition().id == currentTask.getPosition().id){ -// dropoffTransferAndContinue(); -// } -// else{ -// currentTrip = tripsUtil.createTrip(getPosition(), currentTask.getPosition(), vehicle); -// driveFactory.runActivity(this, vehicle, currentTrip); -// } -// } - @Override protected void driveToDemandStartLocation() { // safety check that prevents request from being picked up twice because of the delayed pickup event @@ -218,12 +196,13 @@ protected void driveToDemandStartLocation() { currentPlan.taskCompleted(); driveToNextTask(); } - } else { - if(((PlanActionPickupTransfer) currentTask).request.isOnboard()){ - currentPlan.taskCompleted(); - driveToNextTask(); - } } +// else { +// if(((PlanActionPickupTransfer) currentTask).request.isOnboard()){ +// currentPlan.taskCompleted(); +// driveToNextTask(); +// } +// } state = OnDemandVehicleState.DRIVING_TO_START_LOCATION; if(getPosition().id == currentTask.getPosition().id){ @@ -270,15 +249,16 @@ protected void driveToNearestStation() { public void finishedWaiting() { currentPlan.taskCompleted(); currentTask = currentPlan.getNextTask(); -// driveToNextTask(); pickupAndContinue(); } + @Override public void startWaiting() { + // pokud je auto jinde nez ve stanici, tak chcu vytvorit trip ke stanici, spustit jizdu a az dojede, + // tak spustit cekani, ktere je kratsi o cas dojezdu na stanici +// state = OnDemandVehicleState.WAITINGFORTRANSFER; waitActivityFactory.runActivity(this, ((PlanActionWait) currentTask).getWaitTime()); - state = OnDemandVehicleState.WAITINGFORTRANSFER; -// currentPlan.taskCompleted(); -// currentTask = currentPlan.getNextTask(); + } @Override @@ -338,7 +318,23 @@ private void driveToNextTask() { driveToDemandStartLocation(); } else if(currentTask instanceof PlanActionWait) { - startWaiting(); + if (currentTask.getPosition() == this.getPosition()) { + startWaiting(); + } else { + // drive to station and begin waiting + if (this.tripAlreadyPlanned) { + return; + } + // else make new trip and start driving with edited wait time + VehicleTrip newTrip = tripsUtil.createTrip(this.getPosition(), currentTask.getPosition(), vehicle); + this.currentTrip = newTrip; + driveToTransferStationActivityFactory.create(this, vehicle, currentTrip).run(); + this.tripAlreadyPlanned = true; + + + + } + } else if(currentTask instanceof PlanActionPickupTransfer) { driveToDemandStartLocation(); @@ -354,6 +350,7 @@ else if(currentTask instanceof PlanActionDropoffTransfer) { } private void pickupAndContinue() { +// state = OnDemandVehicleState.DRIVING_TO_TARGET_LOCATION; try { DemandAgent demandAgent; if (currentTask instanceof PlanActionPickup) { @@ -367,7 +364,7 @@ private void pickupAndContinue() { } demandAgent.tripStarted(this); } - else { + else if (currentTask instanceof PlanActionPickupTransfer) { demandAgent = ((PlanActionPickupTransfer) currentTask).getRequest().getDemandAgent(); if(demandAgent.isDropped()){ long currentTime = timeProvider.getCurrentSimTime(); @@ -377,6 +374,10 @@ private void pickupAndContinue() { + "time: %s, dropp time: %s", demandAgent, currentTime, droppTime)); } demandAgent.tripRePaused(this); + } else { + // should not be + throw new Exception(String.format("Wrong action order in plan")); + } // if(demandAgent.isDropped()){ @@ -427,30 +428,6 @@ private void dropOffAndContinue() { driveToNextTask(); } - private void pickupTransferAndContinue() { - try { - DemandAgent demandAgent = ((PlanActionPickupTransfer) currentTask).getRequest().getDemandAgent(); - - vehicle.pickUp(demandAgent); - demandAgent.tripRePaused(this); - currentPlan.taskCompleted(); - driveToNextTask(); - - } catch (Exception ex) { - Logger.getLogger(RideSharingOnDemandVehicle.class.getName()).log(Level.SEVERE, null, ex); - } - } - - private void dropoffTransferAndContinue() { - DemandAgent demandAgent = ((PlanActionDropoffTransfer) currentTask).getRequest().getDemandAgent(); - vehicle.dropOff(demandAgent); - demandAgent.tripPaused(); - - currentPlan.taskCompleted(); - driveToNextTask(); - - } - @Override protected void leavingStationEvent() { eventProcessor.addEvent(OnDemandVehicleEvent.LEAVE_STATION, null, null, diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RidesharingOnDemandVehicleFactory.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RidesharingOnDemandVehicleFactory.java index ea308407..0a1a531d 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RidesharingOnDemandVehicleFactory.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RidesharingOnDemandVehicleFactory.java @@ -28,6 +28,8 @@ import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; import cz.cvut.fel.aic.agentpolis.simulator.visualization.visio.VisioPositionUtil; import cz.cvut.fel.aic.alite.common.event.EventProcessor; +import cz.cvut.fel.aic.simod.DriveToTransferStation; +import cz.cvut.fel.aic.simod.DriveToTransferStationActivityFactory; import cz.cvut.fel.aic.simod.StationsDispatcher; import cz.cvut.fel.aic.simod.WaitTransferActivityFactory; import cz.cvut.fel.aic.simod.config.SimodConfig; @@ -43,6 +45,8 @@ public class RidesharingOnDemandVehicleFactory extends OnDemandVehicleFactory{ WaitTransferActivityFactory waitTransferActivityFactory; + + DriveToTransferStationActivityFactory driveToTransferStationActivityFactory; @Inject public RidesharingOnDemandVehicleFactory( @@ -57,7 +61,8 @@ public RidesharingOnDemandVehicleFactory( IdGenerator idGenerator, AgentpolisConfig agentpolisConfig, WaitTransferActivityFactory waitTransferActivityFactory, - WaitActivityFactory waitActivityFactory + WaitActivityFactory waitActivityFactory, + DriveToTransferStationActivityFactory driveToTransferStationActivityFactory ) { super( vehicleStorage, @@ -73,6 +78,8 @@ public RidesharingOnDemandVehicleFactory( idGenerator, agentpolisConfig); this.waitTransferActivityFactory = waitTransferActivityFactory; + this.driveToTransferStationActivityFactory = driveToTransferStationActivityFactory; + } @Override @@ -92,6 +99,7 @@ public OnDemandVehicle create(String vehicleId, SimulationNode startPosition) { agentpolisConfig, waitTransferActivityFactory, waitActivityFactory, + driveToTransferStationActivityFactory, vehicleId, startPosition) ; diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java index 92484e6a..47655df8 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java @@ -3,6 +3,7 @@ import com.google.inject.Inject; import com.google.inject.Singleton; import cz.cvut.fel.aic.agentpolis.config.AgentpolisConfig; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.trip.VehicleTrip; import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.TimeProvider; import cz.cvut.fel.aic.agentpolis.simmodel.entity.AgentPolisEntity; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; @@ -53,6 +54,8 @@ public class GreedyTASeTSolver extends DARPSolver implements EventHandler { protected final DefaultPlanComputationRequest.DefaultPlanComputationRequestFactory requestFactory; + private Map planMap; + @@ -120,6 +123,7 @@ private void setEventHandeling() { @Override public Map solve(List newRequests, List waitingRequests) { Map planMap = new ConcurrentHashMap<>(); + Map planMapReturn = new ConcurrentHashMap<>(); List taxis = new ArrayList<>(); for(AgentPolisEntity tVvehicle: vehicleStorage.getEntitiesForIteration()) { @@ -127,11 +131,9 @@ public Map solve(List vehiclesWithPlans = dispatch(taxis, newRequests); + planMap = dispatch(taxis, newRequests); + - for (int i = 0; i < vehiclesWithPlans.size(); i++) { - planMap.put(vehiclesWithPlans.get(i), vehiclesWithPlans.get(i).getCurrentPlanNoUpdate()); - } return planMap; } @@ -140,12 +142,12 @@ public Map solve(List dispatch(List taxis, List requests) { + private Map dispatch(List taxis, List requests) { // because all passengers allow ridesharing, only greedy taset will be called List carpoolAcceptingTaxis = taxis; List carpoolAcceptingPassengers = requests; - List lst2 = heuristics(carpoolAcceptingTaxis, carpoolAcceptingPassengers); - return lst2; + Map map = heuristics(carpoolAcceptingTaxis, carpoolAcceptingPassengers); + return map; } @@ -191,9 +193,15 @@ private int findLastTransferActionIndex(DriverPlan plan) { } private long countTimeToNewPickup(RideSharingOnDemandVehicle taxi, PlanComputationRequest request, List requestsOnBoard) { - if (isWithTransfer(taxi.getCurrentPlanNoUpdate())) { + DriverPlan taxiPlan; + if (planMap.containsKey(taxi)) { + taxiPlan = planMap.get(taxi); + } else { + taxiPlan = taxi.getCurrentPlanNoUpdate(); + } + if (isWithTransfer(taxiPlan)) { // nekdo prestupuje - int indexLastTransferAction = findLastTransferActionIndex(taxi.getCurrentPlanNoUpdate()); + int indexLastTransferAction = findLastTransferActionIndex(taxiPlan); long timeToFinishCurrentEdge = 0; SimulationNode previousPos = taxi.getPosition(); if (taxi.getCurrentTask() != null) { @@ -202,19 +210,19 @@ private long countTimeToNewPickup(RideSharingOnDemandVehicle taxi, PlanComputati } long timeToLastTransferAction = 0; for (int q = 0; q < indexLastTransferAction + 1; q++) { - if (taxi.getCurrentPlanNoUpdate().plan.get(q) instanceof PlanActionWait) { - PlanActionWait wait = (PlanActionWait) taxi.getCurrentPlanNoUpdate().plan.get(q); + if (taxiPlan.plan.get(q) instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) taxiPlan.plan.get(q); timeToLastTransferAction = timeToLastTransferAction + wait.getWaitTime(); } else { - timeToLastTransferAction = timeToLastTransferAction + travelTimeProvider.getExpectedTravelTime(previousPos, taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition()); + timeToLastTransferAction = timeToLastTransferAction + travelTimeProvider.getExpectedTravelTime(previousPos, taxiPlan.plan.get(q).getPosition()); } - previousPos = taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition(); + previousPos = taxiPlan.plan.get(q).getPosition(); } // ted potrebuju najit posledni pickup ve zbyvajicim driver planu po prestupu - List segmentAfterTransfer = taxi.getCurrentPlanNoUpdate().plan.subList(indexLastTransferAction+1, taxi.getCurrentPlanNoUpdate().plan.size()); + List segmentAfterTransfer = taxiPlan.plan.subList(indexLastTransferAction+1, taxiPlan.plan.size()); int indexLastPickupSegment = findLastPickupIndexList(segmentAfterTransfer); long timeToLastPickup = 0; - SimulationNode previousPos2 = taxi.getCurrentPlanNoUpdate().plan.get(taxi.getCurrentPlanNoUpdate().plan.size()-1).getPosition(); + SimulationNode previousPos2 = taxiPlan.plan.get(taxiPlan.plan.size()-1).getPosition(); if (segmentAfterTransfer.size() > 0) { previousPos2 = segmentAfterTransfer.get(0).getPosition(); for (int q = 0; q < indexLastPickupSegment + 1; q++) { @@ -223,28 +231,28 @@ private long countTimeToNewPickup(RideSharingOnDemandVehicle taxi, PlanComputati } } SimulationNode newPickupFrom = request.getFrom(); - long timeToNewPick = travelTimeProvider.getExpectedTravelTime(previousPos, newPickupFrom); + long timeToNewPick = travelTimeProvider.getExpectedTravelTime(previousPos2, newPickupFrom); long estimatedArrivalToPickup = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastTransferAction + timeToLastPickup + timeToNewPick; // zkontrolovat, zda arrival je v pohode z hlediska delay - kontroluju pro requesty po ukonceni prestupu - Set requestsInSegmentSet = new HashSet<>(); - for(PlanAction action : segmentAfterTransfer) { - if(action instanceof PlanRequestAction) { - PlanRequestAction requestAction = (PlanRequestAction) action; - requestsInSegmentSet.add(requestAction.request); - } - } - List requestsInSegment = new ArrayList<>(requestsInSegmentSet); - for (PlanComputationRequest req : requestsInSegment) { - long maxTime = req.getMaxDropoffTime() * 1000; +// Set requestsInSegmentSet = new HashSet<>(); +// for(PlanAction action : segmentAfterTransfer) { +// if(action instanceof PlanRequestAction) { +// PlanRequestAction requestAction = (PlanRequestAction) action; +// requestsInSegmentSet.add(requestAction.request); +// } +// } +// List requestsInSegment = new ArrayList<>(requestsInSegmentSet); +// for (PlanComputationRequest req : requestsInSegment) { + long maxTime = request.getMaxDropoffTime() * 1000; if (estimatedArrivalToPickup > maxTime) { return Long.MAX_VALUE; - } +// } } return estimatedArrivalToPickup; } else { //neprestupuje nikdo - int indexLastPickup = findLastPickupIndex(taxi.getCurrentPlanNoUpdate()); + int indexLastPickup = findLastPickupIndex(taxiPlan); long timeToFinishCurrentEdge = 0; SimulationNode previousPos = taxi.getPosition(); if (taxi.getCurrentTask() != null) { @@ -253,19 +261,19 @@ private long countTimeToNewPickup(RideSharingOnDemandVehicle taxi, PlanComputati } long timeToLastPickup = 0; for (int q = 0; q < indexLastPickup + 1; q++) { - timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos, taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition()); - previousPos = taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition(); + timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos, taxiPlan.plan.get(q).getPosition()); + previousPos = taxiPlan.plan.get(q).getPosition(); } SimulationNode newPickupFrom = request.getFrom(); long timeToNewPick = travelTimeProvider.getExpectedTravelTime(previousPos, newPickupFrom); long estimatedArrivalToNewPickup = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastPickup + timeToNewPick; // zkontrolovat, zda arrival je v pohode z hlediska delay - for (PlanComputationRequest req : requestsOnBoard) { +// for (PlanComputationRequest req : requestsOnBoard) { long maxTime = request.getMaxDropoffTime() * 1000; if (estimatedArrivalToNewPickup > maxTime) { return Long.MAX_VALUE; } - } +// } return estimatedArrivalToNewPickup; } } @@ -274,7 +282,7 @@ private long countTimeToNewPickup(RideSharingOnDemandVehicle taxi, PlanComputati * Greedy TASeT heuristics function * @return */ - private List heuristics(List taxis, List requests) { + private Map heuristics(List taxis, List requests) { //transfer points = charging stations List transferPoints = this.transferPoints; @@ -418,6 +426,8 @@ private List heuristics(List(); + for(PlanComputationRequest request : requests) { List>, List>> templistP = new ArrayList<>(); @@ -430,21 +440,28 @@ private List heuristics(List> tmp = new ArrayList<>(); - List tmpVehs = new ArrayList<>(); - tmpVehs.add(taxi); - tmp.add(posbitnry); - Pair>, List> pair = new Pair<>(tmp, tmpVehs); - templistP.add(pair); - long minimalArrivalTime = timeProvider.getCurrentSimTime() + travelTimeProvider.getExpectedTravelTime(request.getFrom(), request.getTo()); - HashMap dropoffs = getEstimatedTimesOfDropoff(posbitnry, taxi); - long realArrivalTime = dropoffs.get(request); - long delay = realArrivalTime - minimalArrivalTime; - delays.add(delay); - transferTimes.add((long) 0); + if (checkValidItinerary(posbitnry, taxi)) { + List> tmp = new ArrayList<>(); + List tmpVehs = new ArrayList<>(); + tmpVehs.add(taxi); + tmp.add(posbitnry); + Pair>, List> pair = new Pair<>(tmp, tmpVehs); + templistP.add(pair); + long minimalArrivalTime = timeProvider.getCurrentSimTime() + travelTimeProvider.getExpectedTravelTime(request.getFrom(), request.getTo()); + HashMap dropoffs = getEstimatedTimesOfDropoff(posbitnry, taxi); + long realArrivalTime = dropoffs.get(request); + long delay = realArrivalTime - minimalArrivalTime; + delays.add(delay); + transferTimes.add((long) 0); + } } Set requestsOnBoardSet = new HashSet<>(); - DriverPlan actualPlan = taxi.getCurrentPlanNoUpdate(); + DriverPlan actualPlan; + if (planMap.containsKey(taxi)) { + actualPlan = planMap.get(taxi); + } else { + actualPlan = taxi.getCurrentPlanNoUpdate(); + } for(PlanAction action : actualPlan) { if(action instanceof PlanRequestAction) { PlanRequestAction requestAction = (PlanRequestAction) action; @@ -473,6 +490,10 @@ private List heuristics(List heuristics(List>, List> key = sublistTransferPlans.get(0).pair; List> plansForVehicles = key.getFirst(); List vehicles = key.getSecond(); for (int q = 0; q < vehicles.size(); q++) { List vehPlan = plansForVehicles.get(q); - DriverPlan dp = new DriverPlan(vehPlan, 0, 0); - vehicles.get(q).setCurrentPlan(dp); + List planWithPos = new ArrayList<>(); + planWithPos.add(vehicles.get(q).getCurrentPlanNoUpdate().plan.get(0)); + planWithPos.addAll(vehPlan); + DriverPlan dp = new DriverPlan(planWithPos, 0, 0); +// vehicles.get(q).setCurrentPlan(dp); +// dp.plan.set(0, new PlanActionCurrentPosition(vehicles.get(q).getPosition())); +// dp.plan.addAll(vehPlan); +// dp.updateCurrentPosition(vehicles.get(q).getPosition()); + + planMap.put(vehicles.get(q), dp); } } @@ -572,7 +604,12 @@ private List heuristics(List requestsOnBoardSet = new HashSet<>(); - DriverPlan actualPlan = taxi.getCurrentPlanNoUpdate(); + DriverPlan actualPlan; + if (planMap.containsKey(taxis.get(z))) { + actualPlan = planMap.get(taxi); + } else { + actualPlan = taxi.getCurrentPlanNoUpdate(); + } for(PlanAction action : actualPlan) { if(action instanceof PlanRequestAction) { PlanRequestAction requestAction = (PlanRequestAction) action; @@ -591,9 +628,9 @@ private List heuristics(List heuristics(List segmentAfterTransfer = taxi.getCurrentPlanNoUpdate().plan.subList(indexLastTransferAction + 1, taxi.getCurrentPlanNoUpdate().plan.size()); + List segmentAfterTransfer = actualPlan.plan.subList(indexLastTransferAction + 1, actualPlan.plan.size()); int indexLastPickupSegment = findLastPickupIndexList(segmentAfterTransfer); long timeToLastPickup = 0; - SimulationNode previousPos2 = taxi.getCurrentPlanNoUpdate().plan.get(taxi.getCurrentPlanNoUpdate().plan.size()-1).getPosition(); + SimulationNode previousPos2 = actualPlan.plan.get(actualPlan.plan.size()-1).getPosition(); if (segmentAfterTransfer.size() > 0) { previousPos2 = segmentAfterTransfer.get(0).getPosition(); for (int q = 0; q < indexLastPickupSegment + 1; q++) { @@ -623,7 +660,7 @@ private List heuristics(List heuristics(List heuristics(List heuristics(List itinerary, RideSharingOnDemandVehicle vehicle) { + SimulationNode previousDestination = vehicle.getPosition(); + boolean ret = true; + long time = timeProvider.getCurrentSimTime(); + long timeToFinishEdge = 0; + previousDestination = vehicle.getPosition(); + + // podivam se na trip plan + if (vehicle.getCurrentTripPlan() != null) { + if (vehicle.getCurrentTripPlan().getSize() == 0) { + SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getLastLocation(); + // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu + // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu + timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, stopLoc); + previousDestination = stopLoc; + } + else if (vehicle.getCurrentTripPlan().getSize() > 0) { + SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getFirstLocation(); + SimulationNode currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[0]; + boolean currLocIsVehiclePosition = false; + int curridx = 0; + while (currLoc != stopLoc) { + if (currLocIsVehiclePosition) { + timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, currLoc); + } + if (currLoc == vehicle.getPosition()) { + currLocIsVehiclePosition = true; + } + previousDestination = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx]; + curridx++; + currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx]; + } + } + } + time += timeToFinishEdge; + + for (PlanAction action : itinerary) { + if (action instanceof PlanRequestAction) { + PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); + if (action instanceof PlanActionPickup) { + SimulationNode dest = pcq.getFrom(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (!(time < pcq.getMaxPickupTime()*1000)) { + //not valid itinerary + ret = false; + break; + } + previousDestination = dest; + } else if(action instanceof PlanActionPickupTransfer) { + PlanActionPickupTransfer pickupTransfer = (PlanActionPickupTransfer) action; + SimulationNode dest = pickupTransfer.getPosition(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = dest; + } else if(action instanceof PlanActionDropoffTransfer) { + PlanActionDropoffTransfer dropoffTransfer = (PlanActionDropoffTransfer) action; + SimulationNode dest = dropoffTransfer.getPosition(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = dest; + } else if (action instanceof PlanActionDropoff) { + SimulationNode dest = pcq.getTo(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (!(time < pcq.getMaxDropoffTime()*1000)) { + //not valid itinerary + ret = false; + break; + } + previousDestination = dest; + } else if (action instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) action; + time = time + wait.getWaitTime(); + } + } + } + return ret; } private long getTravelTime(PlanComputationRequest request, List planOfCar) { @@ -770,17 +884,39 @@ private Pair>, Long> createChargePlanNoNewRequests(List 0) { + SimulationNode stopLoc = (SimulationNode) veh1.getCurrentTripPlan().getFirstLocation(); + SimulationNode currLoc = (SimulationNode) veh1.getCurrentTripPlan().getAllLocations()[0]; + boolean currLocIsVehiclePosition = false; + int curridx = 0; + while (currLoc != stopLoc) { + if (currLocIsVehiclePosition) { + timeToFinishEdge1 += travelTimeProvider.getTravelTime(veh1, currLoc); + } + if (currLoc == veh1.getPosition()) { + currLocIsVehiclePosition = true; + } + previousDestination = (SimulationNode) veh1.getCurrentTripPlan().getAllLocations()[curridx]; + curridx++; + currLoc = (SimulationNode) veh1.getCurrentTripPlan().getAllLocations()[curridx]; + } + } } time1 = timeToFinishEdge1; - long time2 = 0; - long timeToFinishEdge2 = 0; - if (veh2.getCurrentTask() != null) { - timeToFinishEdge2 = travelTimeProvider.getTravelTime(veh2, veh2.getCurrentTask().getPosition()); - } - time2 = timeToFinishEdge2; + // nemusim pricitat current sim time, protoze budu od sebe oba casy odecitat, jde mi jen o jejich rozdil long transferTime = 0; //expected arrival time of first car @@ -818,8 +954,40 @@ private Pair>, Long> createChargePlanNoNewRequests(List 0) { + SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getFirstLocation(); + SimulationNode currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[0]; + boolean currLocIsVehiclePosition = false; + int curridx = 0; + while (currLoc != stopLoc) { + if (currLocIsVehiclePosition) { + timeToFinishEdge2 += travelTimeProvider.getTravelTime(veh2, currLoc); + } + if (currLoc == veh2.getPosition()) { + currLocIsVehiclePosition = true; + } + previousDestination = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx]; + curridx++; + currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx]; + } + } + } + time2 = timeToFinishEdge2; +// previousDestination = veh2.getPosition(); + for (PlanAction action : itnryp2) { if (action instanceof PlanRequestAction) { PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); @@ -858,21 +1026,129 @@ private Pair>, Long> createChargePlanNoNewRequests(List 0 && waitTime < 5000) { + // ceka aspon 5 sekund + long newWait = 5000 - waitTime; + PlanActionWait waitAction = new PlanActionWait(request, pickup.getPosition(), pickup.getMaxTime(), newWait); + transferTime = newWait; + itnryp2.add(indexPickupSecondCar, waitAction); + + //check tolerable delay for passengers in vehicle2 + long time = 0; + previousDestination = veh2.getPosition(); + // podivam se na trip plan + if (veh2.getCurrentTripPlan() != null) { + if (veh2.getCurrentTripPlan().getSize() == 0) { + SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getLastLocation(); + // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu + // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu + time += travelTimeProvider.getTravelTime(veh2, stopLoc); + previousDestination = stopLoc; + } + else if (veh2.getCurrentTripPlan().getSize() > 0) { + SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getFirstLocation(); + SimulationNode currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[0]; + boolean currLocIsVehiclePosition = false; + int curridx = 0; + while (currLoc != stopLoc) { + if (currLocIsVehiclePosition) { + time += travelTimeProvider.getTravelTime(veh2, currLoc); + } + if (currLoc == veh2.getPosition()) { + currLocIsVehiclePosition = true; + } + previousDestination = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx]; + curridx++; + currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx]; + } + } + } + + for (PlanAction action : itnryp2) { + if (action instanceof PlanRequestAction) { + PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); + if (action instanceof PlanActionPickup) { + SimulationNode dest = pcq.getFrom(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (!(time < pcq.getMaxPickupTime()*1000)) { + //not valid itinerary - check new driver plan + valid = false; + break; + } + previousDestination = dest; + } else if (action instanceof PlanActionDropoff) { + SimulationNode dest = pcq.getTo(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (!(time < pcq.getMaxDropoffTime()*1000)) { + //not valid itinerary - check new driver plan + valid = false; + break; + } + previousDestination = dest; + } else if (action instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) action; + time = time + wait.getWaitTime(); + previousDestination = wait.getPosition(); + } else if (action instanceof PlanActionPickupTransfer) { + PlanActionPickupTransfer p = (PlanActionPickupTransfer) action; + SimulationNode dest = p.getPosition(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = dest; + } else if(action instanceof PlanActionDropoffTransfer) { + PlanActionDropoffTransfer p = (PlanActionDropoffTransfer) action; + SimulationNode dest = p.getPosition(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = dest; + } + } + } + } // pridam wait time do planu pro druhe auto pokud je wait time zaporny - if (waitTime < 0) { + // pozor, pokud bych chtela smazat casovou rezervu 5 s, tak je tam nekde problem s wait akci s casem 0 + // - tak na to by bylo potreba udelat zvlast podminku a nejaky minimalni wait time tam nastavit, aby bylo zajistene poradi pri pruchodu algoritmem + if (waitTime <= 0) { waitTime = waitTime - 5000; //transfer time je -waitTime + // pickup by nemel byt null protoze se nastavi v predeslem loopu + assert pickup != null; PlanActionWait waitAction = new PlanActionWait(request, pickup.getPosition(), pickup.getMaxTime(), -waitTime); transferTime = -waitTime; itnryp2.add(indexPickupSecondCar, waitAction); //check tolerable delay for passengers in vehicle2 long time = 0; - time = timeToFinishEdge2; previousDestination = veh2.getPosition(); - if (veh2.getCurrentTask() != null) { - previousDestination = veh2.getCurrentTask().getPosition(); + // podivam se na trip plan + if (veh2.getCurrentTripPlan() != null) { + if (veh2.getCurrentTripPlan().getSize() == 0) { + SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getLastLocation(); + // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu + // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu + time += travelTimeProvider.getTravelTime(veh2, stopLoc); + previousDestination = stopLoc; + } + else if (veh2.getCurrentTripPlan().getSize() > 0) { + SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getFirstLocation(); + SimulationNode currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[0]; + boolean currLocIsVehiclePosition = false; + int curridx = 0; + while (currLoc != stopLoc) { + if (currLocIsVehiclePosition) { + time += travelTimeProvider.getTravelTime(veh2, currLoc); + } + if (currLoc == veh2.getPosition()) { + currLocIsVehiclePosition = true; + } + previousDestination = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx]; + curridx++; + currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx]; + } + } } + for (PlanAction action : itnryp2) { if (action instanceof PlanRequestAction) { PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); @@ -1104,30 +1380,75 @@ private List findPlanWithNoTransferActions(PlanAction pickup, PlanAc return bestPlan; } + private SimulationNode getStopLocFromTripPlan(VehicleTrip trip, RideSharingOnDemandVehicle vehicle) { + SimulationNode currentLoc; + int stopIdx = 0; + SimulationNode stopLoc; + for (int i = 0; i < trip.getAllLocations().length; i++) { + currentLoc = (SimulationNode) trip.getAllLocations()[i]; + if (currentLoc == vehicle.getPosition()) { + stopIdx = i; + break; + } + } + stopLoc = (SimulationNode) trip.getAllLocations()[stopIdx+1]; + return stopLoc; + } + private HashMap getEstimatedTimesOfDropoff(List itinerary, RideSharingOnDemandVehicle vehicle) { long time = timeProvider.getCurrentSimTime(); - long timeToFinishEdge = travelTimeProvider.getTravelTime(vehicle, itinerary.get(0).getPosition()); + long timeToFinishEdge = 0; + SimulationNode previousDestination = vehicle.getPosition(); + if (vehicle.getCurrentTripPlan() != null) { + if (vehicle.getCurrentTripPlan().getSize() == 0) { + SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getLastLocation(); + // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu + // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu + timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, stopLoc); + previousDestination = stopLoc; + } + else if (vehicle.getCurrentTripPlan().getSize() > 0) { + SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getFirstLocation(); + SimulationNode currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[0]; + boolean currLocIsVehiclePosition = false; + int curridx = 0; + while (currLoc != stopLoc) { + if (currLocIsVehiclePosition) { + timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, currLoc); + } + if (currLoc == vehicle.getPosition()) { + currLocIsVehiclePosition = true; + } + previousDestination = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx]; + curridx++; + currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx]; + } + } + } + time = time + timeToFinishEdge; + HashMap times = new HashMap<>(); - SimulationNode previousPosition = itinerary.get(0).getPosition(); for (PlanAction action : itinerary) { if (action instanceof PlanActionPickup || action instanceof PlanActionPickupTransfer) { - time = time + travelTimeProvider.getExpectedTravelTime(previousPosition, action.getPosition()); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, action.getPosition()); if (time > ((PlanRequestAction) action).request.getMaxPickupTime() * 1000) { //not valid return null; } + previousDestination = action.getPosition(); } else if (action instanceof PlanActionDropoff || action instanceof PlanActionDropoffTransfer) { - time = time + travelTimeProvider.getExpectedTravelTime(previousPosition, action.getPosition()); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, action.getPosition()); if (time > ((PlanRequestAction) action).request.getMaxDropoffTime() * 1000) { //not valid return null; } times.put(((PlanRequestAction) action).getRequest(), time); + previousDestination = action.getPosition(); } else if (action instanceof PlanActionWait) { time = time + ((PlanActionWait) action).getWaitTime(); } - previousPosition = action.getPosition(); + } return times; } @@ -1170,6 +1491,7 @@ private long countDelayDifference(HashMap original long difference = Math.abs(entry.getValue() - newMap.get(entry.getKey())); time = time + difference; } + // todo maybe add delay for a new passenger? return time; } @@ -1186,15 +1508,21 @@ private List removeCurrentPositionActions(List listOfAct private List findPlanWithNoTransferNew(PlanComputationRequest newRequest, RideSharingOnDemandVehicle vehicle) { - if (isWithTransfer(vehicle.getCurrentPlanNoUpdate())) { + DriverPlan vehiclePlan; + if (planMap.containsKey(vehicle)) { + vehiclePlan = planMap.get(vehicle); + } else { + vehiclePlan = vehicle.getCurrentPlanNoUpdate(); + } + if (isWithTransfer(vehiclePlan)) { // v aute nekdo prestupuje // musim oddelit segment s prestupem // ze zbytku vezmu pickups, pridam novy a potom hledam permutace dropoff akci - int indexLastTransfer = findLastTransferActionIndex(vehicle.getCurrentPlanNoUpdate()); - List segmentWithTransfer = vehicle.getCurrentPlanNoUpdate().plan.subList(0, indexLastTransfer+1); + int indexLastTransfer = findLastTransferActionIndex(vehiclePlan); + List segmentWithTransfer = vehiclePlan.plan.subList(0, indexLastTransfer+1); List segmentWithTransferWithoutPositionAction = removeCurrentPositionActions(segmentWithTransfer); - List segmentAfterTransfer = vehicle.getCurrentPlanNoUpdate().plan.subList(indexLastTransfer+1, vehicle.getCurrentPlanNoUpdate().plan.size()); + List segmentAfterTransfer = vehiclePlan.plan.subList(indexLastTransfer+1, vehiclePlan.plan.size()); List> lstTemp = new ArrayList<>(); List> lst = new ArrayList<>(); List newPlan = new ArrayList<>(); @@ -1218,15 +1546,13 @@ private List findPlanWithNoTransferNew(PlanComputationRequest newReq newList.addAll(itnry); lst.add(newList); } - return findItineraryWithMinimumDelayNew(lst, vehicle.getCurrentPlanNoUpdate().plan, vehicle); + return findItineraryWithMinimumDelayNew(lst, vehiclePlan.plan, vehicle); } else { //neni prestup v aute List> lst = new ArrayList<>(); List newPlan = new ArrayList<>(); - for (PlanAction action : vehicle.getCurrentPlanNoUpdate().plan) { - newPlan.add(action); - } + newPlan.addAll(vehiclePlan.plan); //add pickup and dropoff for new request newPlan.add(newRequest.getPickUpAction()); newPlan.add(newRequest.getDropOffAction()); @@ -1238,26 +1564,30 @@ private List findPlanWithNoTransferNew(PlanComputationRequest newReq for (List dropoffPlan : dropoffOrders) { lst.add(createItineraryList(pickups, dropoffPlan)); } - return findItineraryWithMinimumDelayNew(lst, vehicle.getCurrentPlanNoUpdate().plan, vehicle); + return findItineraryWithMinimumDelayNew(lst, vehiclePlan.plan, vehicle); } } private List findPlanWithNoTransferActionsNew(PlanAction pickup, PlanAction dropoff, RideSharingOnDemandVehicle vehicle) { - if (isWithTransfer(vehicle.getCurrentPlanNoUpdate())) { + DriverPlan vehiclePlan; + if (planMap.containsKey(vehicle)) { + vehiclePlan = planMap.get(vehicle); + } else { + vehiclePlan = vehicle.getCurrentPlanNoUpdate(); + } + if (isWithTransfer(vehiclePlan)) { // v aute nekdo prestupuje // musim oddelit segment s prestupem // ze zbytku vezmu pickups, pridam novy a potom hledam permutace dropoff akci - int indexLastTransfer = findLastTransferActionIndex(vehicle.getCurrentPlanNoUpdate()); - List segmentWithTransfer = vehicle.getCurrentPlanNoUpdate().plan.subList(0, indexLastTransfer+1); + int indexLastTransfer = findLastTransferActionIndex(vehiclePlan); + List segmentWithTransfer = vehiclePlan.plan.subList(0, indexLastTransfer+1); List segmentWithTransferWithoutPositionAction = removeCurrentPositionActions(segmentWithTransfer); - List segmentAfterTransfer = vehicle.getCurrentPlanNoUpdate().plan.subList(indexLastTransfer+1, vehicle.getCurrentPlanNoUpdate().plan.size()); + List segmentAfterTransfer = vehiclePlan.plan.subList(indexLastTransfer+1, vehiclePlan.plan.size()); List> lstTemp = new ArrayList<>(); List> lst = new ArrayList<>(); List newPlan = new ArrayList<>(); - for (PlanAction action : segmentAfterTransfer) { - newPlan.add(action); - } + newPlan.addAll(segmentAfterTransfer); //add pickup and dropoff for new request newPlan.add(pickup); newPlan.add(dropoff); @@ -1275,15 +1605,13 @@ private List findPlanWithNoTransferActionsNew(PlanAction pickup, Pla newList.addAll(itnry); lst.add(newList); } - return findItineraryWithMinimumDelayNew(lst, vehicle.getCurrentPlanNoUpdate().plan, vehicle); + return findItineraryWithMinimumDelayNew(lst, vehiclePlan.plan, vehicle); } else { //neni prestup v aute List> lst = new ArrayList<>(); List newPlan = new ArrayList<>(); - for (PlanAction action : vehicle.getCurrentPlanNoUpdate().plan) { - newPlan.add(action); - } + newPlan.addAll(vehiclePlan.plan); //add pickup and dropoff for new request newPlan.add(pickup); newPlan.add(dropoff); @@ -1295,7 +1623,7 @@ private List findPlanWithNoTransferActionsNew(PlanAction pickup, Pla for (List dropoffPlan : dropoffOrders) { lst.add(createItineraryList(pickups, dropoffPlan)); } - return findItineraryWithMinimumDelayNew(lst, vehicle.getCurrentPlanNoUpdate().plan, vehicle); + return findItineraryWithMinimumDelayNew(lst, vehiclePlan.plan, vehicle); } } @@ -1440,6 +1768,7 @@ else if (action instanceof PlanActionOnboard) { * Checks time constraints and counts delay among DriverPlans. * @return valid DriverPlan with smallest delay. */ + // pouziva se jenom v metodach ktere nepouzivam private List findItineraryWithMinimumDelay(List plans) { long[] delays = new long[plans.size()]; diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionWait.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionWait.java index 7f6030e1..112df16e 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionWait.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionWait.java @@ -4,7 +4,7 @@ public class PlanActionWait extends PlanRequestAction { - protected final long waitTime; + protected long waitTime; @@ -12,6 +12,10 @@ public long getWaitTime(){ return waitTime; } + public void setWaitTime(long waitTime) { + this.waitTime = waitTime; + } + public PlanActionWait(PlanComputationRequest request, SimulationNode node, int maxTime, long waitTime) { diff --git a/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java b/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java index 7a26e0cd..19798b6a 100644 --- a/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java +++ b/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java @@ -22,6 +22,7 @@ import cz.cvut.fel.aic.alite.common.event.typed.TypedSimulation; import cz.cvut.fel.aic.geographtools.Graph; import cz.cvut.fel.aic.geographtools.util.Transformer; +import cz.cvut.fel.aic.simod.DriveToTransferStationActivityFactory; import cz.cvut.fel.aic.simod.WaitTransferActivityFactory; import cz.cvut.fel.aic.simod.config.SimodConfig; import cz.cvut.fel.aic.simod.entity.DemandAgent; @@ -110,7 +111,7 @@ public long getCurrentSimTime() { WaitTransferActivityFactory waitTransferActivityFactory = new WaitTransferActivityFactory(); WaitActivityFactory waitActivityFactory = new WaitActivityFactory(); - + DriveToTransferStationActivityFactory driveToTransferStationActivityFactory = null; RideSharingOnDemandVehicle vehicle_1 = new RideSharingOnDemandVehicle( physicalVehicleStorage, @@ -127,9 +128,9 @@ public long getCurrentSimTime() { agentpolisConfig, waitTransferActivityFactory, waitActivityFactory, + null, "1", startPos - ); RideSharingOnDemandVehicle vehicle_2 = new RideSharingOnDemandVehicle( physicalVehicleStorage, @@ -146,6 +147,7 @@ public long getCurrentSimTime() { agentpolisConfig, waitTransferActivityFactory, waitActivityFactory, + null, "2", startPos ); From 353984398cc3f597b6d0cbacff79dcc46100b756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kub=C3=ADkov=C3=A1=2C=20Ad=C3=A9la?= Date: Thu, 21 Apr 2022 15:34:13 +0200 Subject: [PATCH 08/21] Replace hardcoded values with config values. --- .../ridesharing/DroppedDemandsAnalyzer.java | 47 ++++--------------- 1 file changed, 10 insertions(+), 37 deletions(-) diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/DroppedDemandsAnalyzer.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/DroppedDemandsAnalyzer.java index 71d240b6..a554bc2f 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/DroppedDemandsAnalyzer.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/DroppedDemandsAnalyzer.java @@ -46,41 +46,17 @@ public class DroppedDemandsAnalyzer { private final PositionUtil positionUtil; -// private final double maxDistance; - private final double maxDistance = 1000; + private final double maxDistance; protected final TravelTimeProvider travelTimeProvider; -// private final int maxDelayTime; - private final int maxDelayTime = 10; + private final int maxDelayTime; private final OnDemandvehicleStationStorage onDemandvehicleStationStorage; -// @Inject -// public DroppedDemandsAnalyzer( -// OnDemandVehicleStorage vehicleStorage, -// PositionUtil positionUtil, -// TravelTimeProvider travelTimeProvider, -// SimodConfig config, -// OnDemandvehicleStationStorage onDemandvehicleStationStorage, -// AgentpolisConfig agentpolisConfig) { -// this.vehicleStorage = vehicleStorage; -// this.positionUtil = positionUtil; -// this.travelTimeProvider = travelTimeProvider; -// this.onDemandvehicleStationStorage = onDemandvehicleStationStorage; -// this.config = config; -// -// // max distance in meters between vehicle and request for the vehicle to be considered to serve the request -// maxDistance = (double) config.ridesharing.maxProlongationInSeconds -// * agentpolisConfig.maxVehicleSpeedInMeters; -// -// // the traveltime from vehicle to request cannot be greater than max prolongation in milliseconds for the -// // vehicle to be considered to serve the request -// maxDelayTime = config.ridesharing.maxProlongationInSeconds * 1000; -// } @Inject public DroppedDemandsAnalyzer( OnDemandVehicleStorage vehicleStorage, @@ -93,21 +69,18 @@ public DroppedDemandsAnalyzer( this.positionUtil = positionUtil; this.travelTimeProvider = travelTimeProvider; this.onDemandvehicleStationStorage = onDemandvehicleStationStorage; - this.config = config; + this.config = config; -// // max distance in meters between vehicle and request for the vehicle to be considered to serve the request -// maxDistance = (double) config.ridesharing.maxProlongationInSeconds -// * agentpolisConfig.maxVehicleSpeedInMeters; -// -// // the traveltime from vehicle to request cannot be greater than max prolongation in milliseconds for the -// // vehicle to be considered to serve the request -// maxDelayTime = config.ridesharing.maxProlongationInSeconds * 1000; + // max distance in meters between vehicle and request for the vehicle to be considered to serve the request + maxDistance = (double) config.ridesharing.maxProlongationInSeconds + * agentpolisConfig.maxVehicleSpeedInMeters; + + // the traveltime from vehicle to request cannot be greater than max prolongation in milliseconds for the + // vehicle to be considered to serve the request + maxDelayTime = config.ridesharing.maxProlongationInSeconds * 1000; } - - - public void debugFail(PlanComputationRequest request, int[] usedVehiclesPerStation) { boolean freeVehicle = false; double bestEuclideanDistance = Double.MAX_VALUE; From d6084644d7e4c9d44a1cf0124ccca417bba18c97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kub=C3=ADkov=C3=A1=2C=20Ad=C3=A9la?= Date: Sun, 24 Apr 2022 16:55:55 +0200 Subject: [PATCH 09/21] Delete old methods without usage --- .../greedyTASeT/GreedyTASeTSolver.java | 547 +----------------- 1 file changed, 1 insertion(+), 546 deletions(-) diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java index 47655df8..9b09a1e0 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java @@ -233,20 +233,9 @@ private long countTimeToNewPickup(RideSharingOnDemandVehicle taxi, PlanComputati SimulationNode newPickupFrom = request.getFrom(); long timeToNewPick = travelTimeProvider.getExpectedTravelTime(previousPos2, newPickupFrom); long estimatedArrivalToPickup = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastTransferAction + timeToLastPickup + timeToNewPick; - // zkontrolovat, zda arrival je v pohode z hlediska delay - kontroluju pro requesty po ukonceni prestupu -// Set requestsInSegmentSet = new HashSet<>(); -// for(PlanAction action : segmentAfterTransfer) { -// if(action instanceof PlanRequestAction) { -// PlanRequestAction requestAction = (PlanRequestAction) action; -// requestsInSegmentSet.add(requestAction.request); -// } -// } -// List requestsInSegment = new ArrayList<>(requestsInSegmentSet); -// for (PlanComputationRequest req : requestsInSegment) { long maxTime = request.getMaxDropoffTime() * 1000; if (estimatedArrivalToPickup > maxTime) { return Long.MAX_VALUE; -// } } return estimatedArrivalToPickup; } @@ -267,13 +256,10 @@ private long countTimeToNewPickup(RideSharingOnDemandVehicle taxi, PlanComputati SimulationNode newPickupFrom = request.getFrom(); long timeToNewPick = travelTimeProvider.getExpectedTravelTime(previousPos, newPickupFrom); long estimatedArrivalToNewPickup = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastPickup + timeToNewPick; - // zkontrolovat, zda arrival je v pohode z hlediska delay -// for (PlanComputationRequest req : requestsOnBoard) { long maxTime = request.getMaxDropoffTime() * 1000; if (estimatedArrivalToNewPickup > maxTime) { return Long.MAX_VALUE; } -// } return estimatedArrivalToNewPickup; } } @@ -376,9 +362,7 @@ private Map heuristics(List heuristics(List heuristics(List heuristics(List 0) { return ret; } - private long getTravelTime(PlanComputationRequest request, List planOfCar) { - long time = 0; - int index = 0; - SimulationNode previousPosition = planOfCar.get(0).getPosition(); - PlanAction lastAction = null; - // find first action - for (int i = 0; i < planOfCar.size(); i++) { - PlanAction action = planOfCar.get(i); - if (action instanceof PlanRequestAction) { - PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); - previousPosition = action.getPosition(); - if (pcq == request) { - index = i; - break; - } - } - } - //find last action - for (int i = planOfCar.size()-1; i > 0; i--) { - PlanAction action = planOfCar.get(i); - if (action instanceof PlanRequestAction) { - PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); - if (pcq == request) { - lastAction = action; - break; - } - } - } - for (int i = index+1; i < planOfCar.size(); i++) { - PlanAction action = planOfCar.get(i); - time = time + travelTimeProvider.getExpectedTravelTime(previousPosition, action.getPosition()); - previousPosition = action.getPosition(); - if (action == lastAction) { - break; - } - } - return time; - } - - private List splittedRequestToPlanForRequest(List itnryp1, List itnryp2, PlanComputationRequest newRequest1, - PlanComputationRequest newRequest2, PlanComputationRequest originalRequest) { - List listForOriginalRequest = new ArrayList<>(); - // iterate over first itnryp - //find actions that belongs to newrequest1 - //create similar action with originalrequest - //add to list - //do the same with the second itnryp - for (PlanAction action : itnryp1) { - if (action instanceof PlanRequestAction) { - PlanRequestAction requestAction = (PlanRequestAction) action; - PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); - if (action instanceof PlanActionPickup) { - if (pcq.getPickUpAction().request == newRequest1) { -// PlanActionPickup pickup = (PlanActionPickup) pcq; - PlanActionPickup newPickup = new PlanActionPickup(originalRequest, action.getPosition(), requestAction.getMaxTime()); - listForOriginalRequest.add(newPickup); - } - } else if (action instanceof PlanActionDropoff) { - if (pcq.getDropOffAction().request == newRequest1) { -// PlanActionDropoff dropoff = (PlanActionDropoff) pcq; - PlanActionDropoff newDropoff = new PlanActionDropoff(originalRequest, action.getPosition(), requestAction.getMaxTime()); - listForOriginalRequest.add(newDropoff); - } - } - } - } - for (PlanAction action : itnryp2) { - if (action instanceof PlanRequestAction) { - PlanRequestAction requestAction = (PlanRequestAction) action; - PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); - if (action instanceof PlanActionPickup) { - if (pcq.getPickUpAction().request == newRequest2) { -// PlanActionPickup pickup = (PlanActionPickup) pcq; - PlanActionPickup newPickup = new PlanActionPickup(originalRequest, action.getPosition(), requestAction.getMaxTime()); - listForOriginalRequest.add(newPickup); - } - } else if (action instanceof PlanActionDropoff) { - if (pcq.getDropOffAction().request == newRequest2) { -// PlanActionDropoff dropoff = (PlanActionDropoff) pcq; - PlanActionDropoff newDropoff = new PlanActionDropoff(originalRequest, action.getPosition(), requestAction.getMaxTime()); - listForOriginalRequest.add(newDropoff); - } - } - } - } - - return listForOriginalRequest; - - } - private Pair>, Long> createChargePlanNoNewRequests(List itnryp1, List itnryp2, RideSharingOnDemandVehicle veh1, RideSharingOnDemandVehicle veh2, PlanComputationRequest request) { long time1 = 0; long timeToFinishEdge1 = 0; @@ -920,7 +807,6 @@ else if (veh1.getCurrentTripPlan().getSize() > 0) { // nemusim pricitat current sim time, protoze budu od sebe oba casy odecitat, jde mi jen o jejich rozdil long transferTime = 0; //expected arrival time of first car - int indexDropoffFirstCar = 0; for (PlanAction action : itnryp1) { if (action instanceof PlanRequestAction) { PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); @@ -949,7 +835,6 @@ else if (veh1.getCurrentTripPlan().getSize() > 0) { PlanActionWait wait = (PlanActionWait) action; time1 = time1 + wait.getWaitTime(); } - indexDropoffFirstCar++; } } // expected arrival of second car @@ -986,7 +871,6 @@ else if (veh1.getCurrentTripPlan().getSize() > 0) { } } time2 = timeToFinishEdge2; -// previousDestination = veh2.getPosition(); for (PlanAction action : itnryp2) { if (action instanceof PlanRequestAction) { @@ -1027,7 +911,7 @@ else if (veh1.getCurrentTripPlan().getSize() > 0) { boolean valid = true; // todo edit -// pridat wait i pro druhe auto tam, kde je rozdil mensi nez 10 s +// pridat wait i pro druhe auto tam, kde je rozdil mensi nez 5 s // aby tam byla rezerva if (waitTime > 0 && waitTime < 5000) { // ceka aspon 5 sekund @@ -1200,114 +1084,6 @@ else if (veh2.getCurrentTripPlan().getSize() > 0) { } } - private Map>, Long> createChargePlan(List itnryp1, List itnryp2, RideSharingOnDemandVehicle veh1, RideSharingOnDemandVehicle veh2, - DefaultPlanComputationRequest request1, DefaultPlanComputationRequest request2) { - long time1 = 0; - long time2 = 0; - long transferTime = 0; - SimulationNode previousDestination = veh1.getPosition(); - //expected arrival time of first car - for (PlanAction action : itnryp1) { - if (action instanceof PlanRequestAction) { - PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); - if (action instanceof PlanActionPickup) { - SimulationNode dest = pcq.getFrom(); - time1 = time1 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); - previousDestination = dest; - } else if (action instanceof PlanActionDropoff) { - SimulationNode dest = pcq.getTo(); - time1 = time1 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); - if (pcq.getDropOffAction().request == request1) { - break; - } - previousDestination = dest; - } else if (action instanceof PlanActionWait) { - PlanActionWait wait = (PlanActionWait) action; - time1 = time1 + wait.getWaitTime(); - } - } - } - // expected arrival of second car - int indexPickupSecondCar = 0; - PlanActionPickup pickup = null; - previousDestination = veh2.getPosition(); - for (PlanAction action : itnryp2) { - if (action instanceof PlanRequestAction) { - PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); - if (action instanceof PlanActionPickup) { - SimulationNode dest = pcq.getFrom(); - time2 = time2 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); - if (pcq.getPickUpAction().request == request2) { - pickup = pcq.getPickUpAction(); - break; - } - previousDestination = dest; - } else if (action instanceof PlanActionDropoff) { - SimulationNode dest = pcq.getTo(); - time2 = time2 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); - previousDestination = dest; - } else if (action instanceof PlanActionWait) { - PlanActionWait wait = (PlanActionWait) action; - time2 = time2 + wait.getWaitTime(); - } - indexPickupSecondCar++; - } - } - long waitTime = time2 - time1; - // pokud je zaporny, tak druhe auto bude muset cekat waitTime dlouho - // pokud je kladny, tak to znamena ze prvni auto prijede drive nez druhe - bude cekat cestujici - - boolean valid = true; - // pridam wait time do planu pro druhe auto pokud je wait time zaporny - if (waitTime <= 0) { - //transfer time je -waitTime - PlanActionWait waitAction = new PlanActionWait(request2, pickup.getPosition(), pickup.getMaxTime(), -waitTime); - transferTime = -waitTime; - itnryp2.add(indexPickupSecondCar, waitAction); - - //check tolerable delay for passengers in vehicle2 - long time = 0; - for (PlanAction action : itnryp2) { - if (action instanceof PlanRequestAction) { - PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); - if (action instanceof PlanActionPickup) { - SimulationNode dest = pcq.getFrom(); - time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); - if (!(time < pcq.getMaxPickupTime()*1000)) { - //not valid itinerary - check new driver plan - valid = false; - break; - } - previousDestination = dest; - } else if (action instanceof PlanActionDropoff) { - SimulationNode dest = pcq.getTo(); - time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); - if (!(time < pcq.getMaxDropoffTime()*1000)) { - //not valid itinerary - check new driver plan - valid = false; - break; - } - previousDestination = dest; - } else if (action instanceof PlanActionWait) { - PlanActionWait wait = (PlanActionWait) action; - time = time + wait.getWaitTime(); - } - } - } - } - if(valid) { - List> itnrys = new ArrayList<>(); - itnrys.add(itnryp1); - itnrys.add(itnryp2); - Map>, Long> map = new LinkedHashMap<>(); - map.put(itnrys, transferTime); - return map; - } - else { - return null; - } - } - public List getPickupActions(List plan) { List pickups = new ArrayList<>(); for(PlanAction action : plan) { @@ -1328,73 +1104,6 @@ public List getDropoffActions(List plan) { return dropoffs; } - /** - * Find DriverPlan with smallest delay without transfer allowed. - * @return valid DriverPlan with smallest delay. - */ - private List findPlanWithNoTransfer(PlanComputationRequest newRequest, RideSharingOnDemandVehicle taxi) { - List lst = new ArrayList<>(); - List currentPlan = taxi.getCurrentPlanNoUpdate().plan; - List newPlan = new ArrayList<>(); - for (PlanAction action : currentPlan) { - newPlan.add(action); - } - //add pickup and dropoff for new request - newPlan.add(newRequest.getPickUpAction()); - newPlan.add(newRequest.getDropOffAction()); - //get pickup order based on heuristic from TASeT paper - List pickups = getPickupActions(newPlan); - //get dropoff actions in currentPlan - List dropoffs = getDropoffActions(newPlan); - //permute dropoff orders - // TODO fix tady se mi ztrati wait akce, pokud tam nejake jsou! - List> dropoffOrders = permute(dropoffs); - for (List dropoffPlan : dropoffOrders) { - lst.add(createItinerary(pickups, dropoffPlan)); - } - List bestPlan = findItineraryWithMinimumDelay(lst); - return bestPlan; - } - - private List findPlanWithNoTransferActions(PlanAction pickup, PlanAction dropoff, RideSharingOnDemandVehicle taxi) { - List lst = new ArrayList<>(); - List currentPlan = taxi.getCurrentPlanNoUpdate().plan; - List newPlan = new ArrayList<>(); - for (PlanAction action : currentPlan) { - newPlan.add(action); - } - - //add pickup and dropoff for new request - newPlan.add(pickup); - newPlan.add(dropoff); - //get pickup order based on heuristic from TASeT paper - List pickups = getPickupActions(newPlan); - //get dropoff actions in currentPlan - List dropoffs = getDropoffActions(newPlan); - //permute dropoff orders - List> dropoffOrders = permute(dropoffs); - for (List dropoffPlan : dropoffOrders) { - lst.add(createItinerary(pickups, dropoffPlan)); - } - List bestPlan = findItineraryWithMinimumDelay(lst); - return bestPlan; - } - - private SimulationNode getStopLocFromTripPlan(VehicleTrip trip, RideSharingOnDemandVehicle vehicle) { - SimulationNode currentLoc; - int stopIdx = 0; - SimulationNode stopLoc; - for (int i = 0; i < trip.getAllLocations().length; i++) { - currentLoc = (SimulationNode) trip.getAllLocations()[i]; - if (currentLoc == vehicle.getPosition()) { - stopIdx = i; - break; - } - } - stopLoc = (SimulationNode) trip.getAllLocations()[stopIdx+1]; - return stopLoc; - } - private HashMap getEstimatedTimesOfDropoff(List itinerary, RideSharingOnDemandVehicle vehicle) { long time = timeProvider.getCurrentSimTime(); long timeToFinishEdge = 0; @@ -1627,218 +1336,6 @@ private List findPlanWithNoTransferActionsNew(PlanAction pickup, Pla } } - private List getActionsForRequestFromActionsForDriver(List planActionsVehicle, PlanComputationRequest request, RideSharingOnDemandVehicle vehicle) { - List actionsForRequest = new ArrayList<>(); - for (int i = 0; i < planActionsVehicle.size(); i++) { - PlanAction action = planActionsVehicle.get(i); - if (action instanceof PlanRequestAction) { - PlanRequestAction planRequestAction = (PlanRequestAction) action; - if(request == planRequestAction.getRequest()) { - if (action instanceof PlanActionPickup) { - PlanActionOnboard onboard = new PlanActionOnboard(request, action.getPosition(), planRequestAction.getMaxTime(), vehicle); - int index = 0; - if (actionsForRequest.size() != 0) { - PlanAction currentAction = actionsForRequest.get(0); - PlanRequestAction currentRAction = (PlanRequestAction) currentAction; - while(currentRAction.getMaxTime() <= onboard.getMaxTime()) { - index++; - if (index < actionsForRequest.size()) { - currentAction = actionsForRequest.get(index); - currentRAction = (PlanRequestAction) currentAction; - } - else { - break; - } - } - } - actionsForRequest.add(index, onboard); - } - if (action instanceof PlanActionDropoff) { - PlanActionDropoff dropoff = new PlanActionDropoff(request, action.getPosition(), planRequestAction.getMaxTime()); - int index = 0; - if (actionsForRequest.size() != 0) { - PlanAction currentAction = actionsForRequest.get(0); - PlanRequestAction currentRAction = (PlanRequestAction) currentAction; - while(currentRAction.getMaxTime() <= dropoff.getMaxTime()) { - index++; - if (index < actionsForRequest.size()) { - currentAction = actionsForRequest.get(index); - currentRAction = (PlanRequestAction) currentAction; - } - else { - break; - } - } - } - actionsForRequest.add(index, dropoff); - } - } - } - } - return actionsForRequest; - } - - // neni dodelana ale nepouzivam ji - private List convertDriverPlansToRequestPlans(List driverPlans, List requests) { - int lenRequests = requests.size(); - List requestPlans = new ArrayList<>(); - List emptyPlan = new ArrayList<>(); - RequestPlan empty = new RequestPlan(emptyPlan, 0, 0); - for (int i = 0; i < lenRequests; i++) { - requestPlans.add(empty); - } - - for(DriverPlan driverPlan : driverPlans) { - for (int i = 0; i < driverPlan.plan.size(); i++) { - PlanAction action = driverPlan.plan.get(i); - PlanRequestAction rAction = (PlanRequestAction) action; - PlanComputationRequest requestAssigned = rAction.getRequest(); - for(int j = 0; j < requests.size(); j++) { - if(requestAssigned == requests.get(j)) - { - if (action instanceof PlanActionPickup) { - PlanActionOnboard planActionOnboard = new PlanActionOnboard(requestAssigned, action.getPosition(), rAction.getMaxTime(), driverPlan.getVehicle()); -// iterate over existing actions and find a timestamp HOPEFULLY DONE - PlanAction currentAction = requestPlans.get(j).plan.get(0); - PlanRequestAction currentRAction = (PlanRequestAction) currentAction; - int index = 0; - while(currentRAction.getMaxTime() <= planActionOnboard.getMaxTime()) { - index++; - currentAction = requestPlans.get(j).plan.get(index); - currentRAction = (PlanRequestAction) currentAction; - } - requestPlans.get(j).plan.add(index, planActionOnboard); - } else if (action instanceof PlanActionDropoff) { - PlanActionOffboard planActionOffboard = new PlanActionOffboard(requestAssigned, action.getPosition(), rAction.getMaxTime(), driverPlan.getVehicle()); -// : iterate over existing actions and find a timestamp - requestPlans.get(j).plan.add(planActionOffboard); - } else if (action instanceof PlanActionWait) { - - } -// : add Wait Actions - } - } - } - } - return requestPlans; - } - // neni dodelana ale nepouzivam ji - private List convertRequestPlansToDriverPlans(List requestPlans, List vehicles) { - int lenVehicles = vehicles.size(); - List driverPlans = new ArrayList<>(); - List emptyPlan = new ArrayList<>(); - DriverPlan empty = new DriverPlan(emptyPlan, 0, 0); - for (int i = 0; i < lenVehicles; i++) { - driverPlans.add(empty); - } - - for(RequestPlan requestPlan : requestPlans) { - for(int i = 0; i < requestPlan.plan.size(); i++) { - PlanAction action = requestPlan.plan.get(i); - if (action instanceof PlanActionOffboard) { - PlanActionOffboard planActionOffboard = (PlanActionOffboard) action; - RideSharingOnDemandVehicle veh = planActionOffboard.getFromVehicle(); - PlanActionDropoff planActionDropoff = new PlanActionDropoff(requestPlan.getRequest(), planActionOffboard.getPosition(), planActionOffboard.getMaxTime()); - for (int j = 0; j < vehicles.size(); j++) { - if (veh == vehicles.get(i)) - { -// : iterate over existing actions and find a timestamp - driverPlans.get(j).plan.add(planActionDropoff); - } - } - } - else if (action instanceof PlanActionOnboard) { - PlanActionOnboard planActionOnboard = (PlanActionOnboard) action; - RideSharingOnDemandVehicle veh = planActionOnboard.getToVehicle(); - PlanActionPickup planActionPickup = new PlanActionPickup(requestPlan.getRequest(), planActionOnboard.getPosition(), planActionOnboard.getMaxTime()); - for (int j = 0; j < vehicles.size(); j++) { - if (veh == vehicles.get(i)) - { - driverPlans.get(j).plan.add(planActionOnboard); - } - } - } -// : resolve Wait Actions - } - } - return driverPlans; - } - - /** - * Checks time constraints and counts delay among DriverPlans. - * @return valid DriverPlan with smallest delay. - */ - // pouziva se jenom v metodach ktere nepouzivam - private List findItineraryWithMinimumDelay(List plans) - { - long[] delays = new long[plans.size()]; - int index = 0; - for(DriverPlan driverPlan : plans) { - long time = 0; - long delay = 0; - // TODO: how to set (initialize) previousDestination? - // vychozi pozice, odkud auto vyjizdi - SimulationNode previousDestination = driverPlan.plan.get(0).getPosition(); -// previousDestination = driverPlan.vehicle.getPosition(); - - for (int i = 0; i < driverPlan.getLength(); i++) { - PlanAction action = driverPlan.plan.get(i); - if (action instanceof PlanRequestAction) { - PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); - if(action instanceof PlanActionPickup) { - PlanActionPickup pickup = (PlanActionPickup) action; - SimulationNode dest = pcq.getFrom(); - time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); - if(!(time <= pcq.getMaxPickupTime())) { - //not valid itinerary - check new driver plan - break; - } else { - //valid itinerary - delay = delay + (pcq.getMaxPickupTime() - time); - } - previousDestination = dest; - } - else if (action instanceof PlanActionDropoff) { - PlanActionDropoff dropoff = (PlanActionDropoff) action; - SimulationNode dest = pcq.getTo(); - time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); - if(!(time <= pcq.getMaxDropoffTime())) { - //not valid itinerary - check new driver plan - break; - } else { - delay = delay + (pcq.getMaxDropoffTime() - time); - } - previousDestination = dest; - } - else if (action instanceof PlanActionWait) { - PlanActionWait wait = (PlanActionWait) action; - time = time + wait.getWaitTime(); - } - } - } - // save delay to array - delays[index] = delay; - index++; - } - //find max in delays - int maxAt = 0; - for (int i = 0; i < delays.length; i++) { - maxAt = delays[i] > delays[maxAt] ? i : maxAt; - } - List bestPlan = plans.get(maxAt).plan; - return bestPlan; - } - - /** - * Creates new DriverPlan with pickups and dropoffs. - * @return new DriverPlan - */ - private DriverPlan createItinerary(List pickupOrder, List dropoffOrder) { - List listOfActionsOrdered = new ArrayList<>(pickupOrder); - listOfActionsOrdered.addAll(dropoffOrder); - return new DriverPlan(listOfActionsOrdered, 0, 0); - } - private List createItineraryList(List pickupOrder, List dropoffOrder) { List listOfActionsOrdered = new ArrayList<>(pickupOrder); listOfActionsOrdered.addAll(dropoffOrder); @@ -1879,48 +1376,6 @@ private void permuteHelper(List> list, List resultL } } - /** - * Checks if setting a new via point will exceed the tolerable delay for onboard passengers - * @return boolean - */ - private boolean checkTolerableDelay(List requestsOnBoard, SimulationNode viaPoint, RideSharingOnDemandVehicle taxi) { - //TODO - // uvazuju ze auto se ted rozhodne jet do stanice - // potrebuju zjistit jestli to nebude vadit ostatnim cestujicim - - - //for every onboard passenger in taxi - for(PlanComputationRequest request : requestsOnBoard) { - SimulationNode destination = request.getTo(); - //get new time of arrival with new via point - long newArrivalTime = timeProvider.getCurrentSimTime() + travelTimeProvider.getTravelTime(taxi, viaPoint) + travelTimeProvider.getTravelTime(taxi, viaPoint, destination); -// long newArrivalTime = travelTimeProvider.getTravelTime(taxi, viaPoint) + travelTimeProvider.getTravelTime(taxi, viaPoint, destination); - if (newArrivalTime > request.getMaxDropoffTime()) { - return false; - } - } - return true; - } - - /** - * counts arrival time of taxi to pickup location and check if is smaller than MaxPickupTime - * @return boolean. - */ - private boolean canServeRequestTASeT(RideSharingOnDemandVehicle vehicle, PlanComputationRequest request) { - return travelTimeProvider.getTravelTime(vehicle, request.getFrom()) + timeProvider.getCurrentSimTime() - < request.getMaxPickupTime() * 1000; - - //TODO upravit - // pokud je taxik prazdny, tak se podivam jestli taxik prijede do cile driv nez je max dropoff time - // dojede do cile? - // = expectedTravelTime(aktualni pozice taxiku, zacatek) + expected(zacatek, cil) + currentSimTime - // tohle zaokrouhlene na integer musi byt <= maxDropoff - // neboli expectedTravelTime(aktualni, zacatek) + currentSimTime <= maxPickUpTime - - // kdyz taxik neni prazdny, tak krome vyse uvedene podminky musi splnovat podminku i pro ostatni cestujici - // tento constraint se ale kontroluje v findPlanWithMinimumDelay - az to opravim teda xD - } - private boolean canServeRequestTASeT2(RideSharingOnDemandVehicle vehicle, PlanComputationRequest request) { Set requestsOnBoardSet = new HashSet<>(); DriverPlan actualPlan = vehicle.getCurrentPlanNoUpdate(); From 3a391ece1ea4c56099bd64482a2ae5ef240fe37f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kub=C3=ADkov=C3=A1=2C=20Ad=C3=A9la?= Date: Sat, 30 Apr 2022 19:27:38 +0200 Subject: [PATCH 10/21] Imlementation of TransferInsertionSolver --- .../fel/aic/simod/DriveToTransferStation.java | 5 +- .../cz/cvut/fel/aic/simod/MainModule.java | 8 + .../aic/simod/OnDemandVehiclesSimulation.java | 7 + .../cz/cvut/fel/aic/simod/WaitWithStop.java | 38 + .../simod/WaitWithStopActivityFactory.java | 19 + .../aic/simod/config/GreedyTASeTNoFreeze.java | 10 + .../fel/aic/simod/config/Ridesharing.java | 7 +- .../aic/simod/config/TransferInsertion.java | 10 + .../simod/entity/OnDemandVehicleState.java | 1 + .../simod/entity/vehicle/OnDemandVehicle.java | 23 +- .../vehicle/OnDemandVehicleFactory.java | 10 +- .../RideSharingOnDemandVehicle.java | 76 +- .../RidesharingOnDemandVehicleFactory.java | 15 +- .../GreedyTASeTNoFreezeSolver.java | 1503 +++++++++++++++++ .../greedyTASeT/GreedyTASeTSolver.java | 17 +- .../ridesharing/greedyTASeT/TransferPlan.java | 2 +- .../ridesharing/model/PlanActionWait.java | 39 + .../ridesharing/model/PlanRequestAction.java | 6 +- .../TransferInsertionSolver.java | 728 ++++++++ .../aic/simod/system/TestOnDemandVehicle.java | 5 +- .../greedyTASeT/GreedyTASeTSolverTest.java | 8 +- 21 files changed, 2479 insertions(+), 58 deletions(-) create mode 100644 src/main/java/cz/cvut/fel/aic/simod/WaitWithStop.java create mode 100644 src/main/java/cz/cvut/fel/aic/simod/WaitWithStopActivityFactory.java create mode 100644 src/main/java/cz/cvut/fel/aic/simod/config/GreedyTASeTNoFreeze.java create mode 100644 src/main/java/cz/cvut/fel/aic/simod/config/TransferInsertion.java create mode 100644 src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTNoFreezeSolver.java create mode 100644 src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java diff --git a/src/main/java/cz/cvut/fel/aic/simod/DriveToTransferStation.java b/src/main/java/cz/cvut/fel/aic/simod/DriveToTransferStation.java index 6fc5b857..7754ab7c 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/DriveToTransferStation.java +++ b/src/main/java/cz/cvut/fel/aic/simod/DriveToTransferStation.java @@ -29,7 +29,7 @@ public class DriveToTransferStation extends PhysicalVe private final Vehicle vehicle; - private final Trip trip; + public final Trip trip; private final VehicleMoveActivityFactory moveActivityFactory; @@ -42,7 +42,7 @@ public class DriveToTransferStation extends PhysicalVe private SimulationNode from; - private SimulationNode to; + public SimulationNode to; @@ -71,7 +71,6 @@ protected void performAction() { protected void onChildActivityFinish(Activity activity) { if (trip.isEmpty() || stoped) { agent.endDriving(); - // todo: nastavit tripalreadyplanned na false if (agent instanceof RideSharingOnDemandVehicle) { ((RideSharingOnDemandVehicle) agent).tripAlreadyPlanned = false; } diff --git a/src/main/java/cz/cvut/fel/aic/simod/MainModule.java b/src/main/java/cz/cvut/fel/aic/simod/MainModule.java index ee18a795..3a9fc356 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/MainModule.java +++ b/src/main/java/cz/cvut/fel/aic/simod/MainModule.java @@ -18,7 +18,9 @@ */ package cz.cvut.fel.aic.simod; +import cz.cvut.fel.aic.simod.ridesharing.greedyTASeT.GreedyTASeTNoFreezeSolver; import cz.cvut.fel.aic.simod.ridesharing.greedyTASeT.GreedyTASeTSolver; +import cz.cvut.fel.aic.simod.ridesharing.transferinsertion.TransferInsertionSolver; import cz.cvut.fel.aic.simod.traveltimecomputation.DistanceMatrixTravelTimeProvider; import cz.cvut.fel.aic.simod.traveltimecomputation.TNRTravelTimeProvider; import cz.cvut.fel.aic.simod.traveltimecomputation.TNRAFTravelTimeProvider; @@ -151,6 +153,12 @@ protected void configureNext() { bind(DARPSolver.class).to(GreedyTASeTSolver.class); // nabindovat i nove tridy break; + case "greedy-taset-no-freeze": + bind(DARPSolver.class).to(GreedyTASeTNoFreezeSolver.class); + break; + case "transfer-insertion": + bind(DARPSolver.class).to(TransferInsertionSolver.class); + break; } } else{ diff --git a/src/main/java/cz/cvut/fel/aic/simod/OnDemandVehiclesSimulation.java b/src/main/java/cz/cvut/fel/aic/simod/OnDemandVehiclesSimulation.java index 65048fd4..1e2bd4ca 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/OnDemandVehiclesSimulation.java +++ b/src/main/java/cz/cvut/fel/aic/simod/OnDemandVehiclesSimulation.java @@ -24,6 +24,7 @@ import cz.cvut.fel.aic.agentpolis.simulator.creator.SimulationCreator; import cz.cvut.fel.aic.agentpolis.system.AgentPolisInitializer; import cz.cvut.fel.aic.simod.config.SimodConfig; +import cz.cvut.fel.aic.simod.config.TransferInsertion; import cz.cvut.fel.aic.simod.init.EventInitializer; import cz.cvut.fel.aic.simod.init.StationsInitializer; import cz.cvut.fel.aic.simod.init.StatisticInitializer; @@ -31,6 +32,8 @@ import cz.cvut.fel.aic.simod.io.TripTransform; import cz.cvut.fel.aic.simod.rebalancing.ReactiveRebalancing; import cz.cvut.fel.aic.simod.ridesharing.greedyTASeT.GreedyTASeTSolver; +import cz.cvut.fel.aic.simod.ridesharing.greedyTASeT.GreedyTASeTNoFreezeSolver; +import cz.cvut.fel.aic.simod.ridesharing.transferinsertion.TransferInsertionSolver; import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider; import cz.cvut.fel.aic.simod.statistics.Statistics; import cz.cvut.fel.aic.simod.tripUtil.TripsUtilCached; @@ -116,6 +119,10 @@ public void run(String[] args) { // injector.getInstance(TransferPointsInitializer.class).loadTransferPoints(); injector.getInstance(GreedyTASeTSolver.class).setTransferPoints(injector.getInstance(TransferPointsInitializer.class).loadTransferPoints()); + injector.getInstance(GreedyTASeTNoFreezeSolver.class).setTransferPoints(injector.getInstance(TransferPointsInitializer.class).loadTransferPoints()); + + injector.getInstance(TransferInsertionSolver.class).setTransferPoints(injector.getInstance(TransferPointsInitializer.class).loadTransferPoints()); + if(config.rebalancing.on){ // start rebalancing diff --git a/src/main/java/cz/cvut/fel/aic/simod/WaitWithStop.java b/src/main/java/cz/cvut/fel/aic/simod/WaitWithStop.java new file mode 100644 index 00000000..3c714afd --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/WaitWithStop.java @@ -0,0 +1,38 @@ +package cz.cvut.fel.aic.simod; + +import cz.cvut.fel.aic.agentpolis.simmodel.ActivityInitializer; +import cz.cvut.fel.aic.agentpolis.simmodel.Agent; +import cz.cvut.fel.aic.agentpolis.simmodel.TimeConsumingActivity; + +public class WaitWithStop extends TimeConsumingActivity{ + + private final long waitTime; + + protected boolean stoped; + + + public WaitWithStop(ActivityInitializer activityInitializer, A agent, long waitTime) { + super(activityInitializer, agent); + this.waitTime = waitTime; + this.stoped = false; + } + + public boolean isStoped() { + return stoped; + } + + public void end(){ + stoped = true; + } + + @Override + protected long performPreDelayActions() { + return waitTime; + } + + @Override + protected void performAction() { + finish(); + } + +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/WaitWithStopActivityFactory.java b/src/main/java/cz/cvut/fel/aic/simod/WaitWithStopActivityFactory.java new file mode 100644 index 00000000..ac33db49 --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/WaitWithStopActivityFactory.java @@ -0,0 +1,19 @@ +package cz.cvut.fel.aic.simod; + +import com.google.inject.Singleton; +import cz.cvut.fel.aic.agentpolis.simmodel.ActivityFactory; +import cz.cvut.fel.aic.agentpolis.simmodel.Agent; +import cz.cvut.fel.aic.agentpolis.simmodel.activity.Wait; + +@Singleton +public class WaitWithStopActivityFactory extends ActivityFactory { + + + public void runActivity(A agent, long waitTime) { + create(agent, waitTime).run(); + } + + public WaitWithStop create(A agent, long waitTime) { + return new WaitWithStop<>(activityInitializer, agent, waitTime); + } +} \ No newline at end of file diff --git a/src/main/java/cz/cvut/fel/aic/simod/config/GreedyTASeTNoFreeze.java b/src/main/java/cz/cvut/fel/aic/simod/config/GreedyTASeTNoFreeze.java new file mode 100644 index 00000000..e4d7058a --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/config/GreedyTASeTNoFreeze.java @@ -0,0 +1,10 @@ +package cz.cvut.fel.aic.simod.config; + +import java.util.Map; + +public class GreedyTASeTNoFreeze { + + public GreedyTASeTNoFreeze(Map greedytaset) { + + } +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/config/Ridesharing.java b/src/main/java/cz/cvut/fel/aic/simod/config/Ridesharing.java index 6a33f8f5..def4fd8c 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/config/Ridesharing.java +++ b/src/main/java/cz/cvut/fel/aic/simod/config/Ridesharing.java @@ -1,6 +1,5 @@ package cz.cvut.fel.aic.simod.config; -import cz.cvut.fel.aic.simod.ridesharing.greedyTASeT.GreedyTASeTSolver; import java.lang.Boolean; import java.lang.Double; @@ -9,6 +8,10 @@ import java.util.Map; public class Ridesharing { + public TransferInsertion transferInsertion; + + public GreedyTASeTNoFreeze greedyTASeTNoFreeze; + public GreedyTASeT greedytaset; public Vga vga; @@ -32,6 +35,8 @@ public class Ridesharing { public Boolean on; public Ridesharing(Map ridesharing) { + this.transferInsertion = new TransferInsertion((Map) ridesharing.get("transfer-insertion")); + this.greedyTASeTNoFreeze = new GreedyTASeTNoFreeze((Map) ridesharing.get("greedy_taset_no_freeze")); this.greedytaset = new GreedyTASeT((Map) ridesharing.get("greedy_taset")); this.vga = new Vga((Map) ridesharing.get("vga")); this.batchPeriod = (Integer) ridesharing.get("batch_period"); diff --git a/src/main/java/cz/cvut/fel/aic/simod/config/TransferInsertion.java b/src/main/java/cz/cvut/fel/aic/simod/config/TransferInsertion.java new file mode 100644 index 00000000..c64bf85a --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/config/TransferInsertion.java @@ -0,0 +1,10 @@ +package cz.cvut.fel.aic.simod.config; + +import java.util.Map; + +public class TransferInsertion { + + public TransferInsertion(Map transferinsertion) { + + } +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/entity/OnDemandVehicleState.java b/src/main/java/cz/cvut/fel/aic/simod/entity/OnDemandVehicleState.java index d8c56f6e..1aaf3aa4 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/entity/OnDemandVehicleState.java +++ b/src/main/java/cz/cvut/fel/aic/simod/entity/OnDemandVehicleState.java @@ -28,5 +28,6 @@ public enum OnDemandVehicleState { DRIVING_TO_START_LOCATION, DRIVING_TO_TARGET_LOCATION, DRIVING_TO_STATION, + DRIVING_TO_TRANSFER_STATION_TO_WAIT, REBALANCING; } diff --git a/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicle.java b/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicle.java index 026e79cf..037ecadd 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicle.java +++ b/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicle.java @@ -124,7 +124,7 @@ public class OnDemandVehicle extends Agent implements EventHandler, PlanningAgen protected OnDemandVehicleStation parkedIn; - public WaitTransferActivityFactory waitTransferActivityFactory; + public WaitWithStopActivityFactory waitWithStopActivityFactory; private WaitActivityFactory waitActivityFactory; @@ -193,7 +193,7 @@ public OnDemandVehicle( SimodConfig config, IdGenerator idGenerator, AgentpolisConfig agentpolisConfig, - WaitTransferActivityFactory waitTransferActivityFactory, + WaitWithStopActivityFactory waitWithStopActivityFactory, WaitActivityFactory waitActivityFactory, @Assisted String vehicleId, @Assisted SimulationNode startPosition) { super(vehicleId, startPosition); @@ -205,7 +205,7 @@ public OnDemandVehicle( this.timeProvider = timeProvider; this.rebalancingIdGenerator = rebalancingIdGenerator; this.config = config; - this.waitTransferActivityFactory = waitTransferActivityFactory; + this.waitWithStopActivityFactory = waitWithStopActivityFactory; this.waitActivityFactory = waitActivityFactory; index = idGenerator.getId(); @@ -442,8 +442,14 @@ public void startWaiting() { @Override protected void onActivityFinish(Activity activity) { super.onActivityFinish(activity); - if (activity instanceof DriveToTransferStation) { - startWaiting(); + if (activity instanceof DriveToTransferStation && ((DriveToTransferStation) activity).trip.isEmpty()) { + PhysicalVehicleDrive drive = (PhysicalVehicleDrive) activity; + if (drive.isStoped()) { + finishedDriving(drive.isStoped()); + } + else { + startWaiting(); + } return; // try to do nothing @@ -452,8 +458,9 @@ protected void onActivityFinish(Activity activity) { PhysicalVehicleDrive drive = (PhysicalVehicleDrive) activity; finishedDriving(drive.isStoped()); } - else if (activity instanceof Wait) { - finishedWaiting(); + else if (activity instanceof WaitWithStop) { + WaitWithStop wait = (WaitWithStop) activity; + finishedWaiting(wait.isStoped()); } else { @@ -461,7 +468,7 @@ else if (activity instanceof Wait) { } } - public void finishedWaiting() { + public void finishedWaiting(boolean wasStopped) { }; diff --git a/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicleFactory.java b/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicleFactory.java index a374a486..98b9fc59 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicleFactory.java +++ b/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicleFactory.java @@ -31,6 +31,8 @@ import cz.cvut.fel.aic.alite.common.event.EventProcessor; import cz.cvut.fel.aic.simod.StationsDispatcher; import cz.cvut.fel.aic.simod.WaitTransferActivityFactory; +import cz.cvut.fel.aic.simod.WaitWithStop; +import cz.cvut.fel.aic.simod.WaitWithStopActivityFactory; import cz.cvut.fel.aic.simod.config.SimodConfig; import cz.cvut.fel.aic.simod.storage.PhysicalTransportVehicleStorage; @@ -64,7 +66,7 @@ public class OnDemandVehicleFactory implements OnDemandVehicleFactorySpec{ protected final AgentpolisConfig agentpolisConfig; - protected final WaitTransferActivityFactory waitTransferActivityFactory; + protected final WaitWithStopActivityFactory waitWithStopActivityFactory; protected final WaitActivityFactory waitActivityFactory; @@ -80,7 +82,7 @@ public OnDemandVehicleFactory( StandardTimeProvider timeProvider, IdGenerator rebalancingIdGenerator, SimodConfig config, - WaitTransferActivityFactory waitTransferActivityFactory, + WaitWithStopActivityFactory waitWithStopActivityFactory, WaitActivityFactory waitActivityFactory, IdGenerator idGenerator, AgentpolisConfig agentpolisConfig) { @@ -94,7 +96,7 @@ public OnDemandVehicleFactory( this.config = config; this.idGenerator = idGenerator; this.agentpolisConfig = agentpolisConfig; - this.waitTransferActivityFactory = waitTransferActivityFactory; + this.waitWithStopActivityFactory = waitWithStopActivityFactory; this.waitActivityFactory = waitActivityFactory; } @@ -114,7 +116,7 @@ public OnDemandVehicle create(String vehicleId, SimulationNode startPosition){ config, idGenerator, agentpolisConfig, - waitTransferActivityFactory, + waitWithStopActivityFactory, waitActivityFactory, vehicleId, startPosition); diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java index 523eda28..27238f62 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java @@ -120,7 +120,7 @@ public RideSharingOnDemandVehicle( SimodConfig config, IdGenerator idGenerator, AgentpolisConfig agentpolisConfig, - WaitTransferActivityFactory waitTransferActivityFactory, + WaitWithStopActivityFactory waitWithStopActivityFactory, WaitActivityFactory waitActivityFactory, DriveToTransferStationActivityFactory driveToTransferStationActivityFactory, @Assisted String vehicleId, @Assisted SimulationNode startPosition) { @@ -136,14 +136,14 @@ public RideSharingOnDemandVehicle( config, idGenerator, agentpolisConfig, - waitTransferActivityFactory, + waitWithStopActivityFactory, waitActivityFactory, vehicleId, startPosition); this.positionUtil = positionUtil; this.tripIdGenerator = tripIdGenerator; - this.waitTransferActivityFactory = waitTransferActivityFactory; + this.waitWithStopActivityFactory = waitWithStopActivityFactory; this.waitActivityFactory = waitActivityFactory; this.driveToTransferStationActivityFactory = driveToTransferStationActivityFactory; @@ -167,11 +167,35 @@ public int getFreeCapacity(){ } public void replan(DriverPlan plan){ - currentPlan = plan; + currentPlan = plan; // The vehicle now waits, we have to start moving. if(state == OnDemandVehicleState.WAITING && plan.getLength() > 1){ driveToNextTask(); } + if (state == OnDemandVehicleState.WAITINGFORTRANSFER) { + // if top akce neni stejna jako currentTask (currentTask je cekani) + if (currentPlan.getNextTask() != currentTask) { + ((PlanActionWait) currentTask).setWaitingPaused(true); + ((PlanActionWait) currentTask).setWaitingPausedAt(timeProvider.getCurrentSimTime()); + ((WaitWithStop) getCurrentTopLevelActivity()).end(); + // ted potrebuji aktivitu ukoncit, ona ale stale bezi + driveToNextTask(); + } + // jinak pokracovat v aktivite + // todo priradit stop time + // a ukoncit aktivitu + // todo tam kde se spousti cekani, tak reagovat na start a stop time + // auto je v prubehu vykonavani wait akce + } + if (state == OnDemandVehicleState.DRIVING_TO_TRANSFER_STATION_TO_WAIT) { + if (currentPlan.getNextTask() != currentTask) { + // pokud se zmenila current task, tak ukoncim cestu na stanici + ((PhysicalVehicleDrive) getCurrentTopLevelActivity()).end(); + } + // jinak necham aktivitu pokracovat + +// driveToNextTask(); + } // SPECIAL CASES - we don't have to do anything and let the current Drive action continue. else if( @@ -245,26 +269,49 @@ protected void driveToNearestStation() { driveFactory.runActivity(this, vehicle, currentTrip); } } + @Override - public void finishedWaiting() { - currentPlan.taskCompleted(); - currentTask = currentPlan.getNextTask(); - pickupAndContinue(); + public void finishedWaiting(boolean wasStopped) { + if (wasStopped) { +// driveToNextTask(); + } else { + currentPlan.taskCompleted(); + currentTask = currentPlan.getNextTask(); + if (currentTask instanceof PlanActionWait) { + startWaiting(); + } else if (currentTask instanceof PlanActionPickup || currentTask instanceof PlanActionPickupTransfer) { + pickupAndContinue(); + } else if (currentTask instanceof PlanActionDropoff || currentTask instanceof PlanActionDropoffTransfer) { + dropOffAndContinue(); + } + } } @Override public void startWaiting() { // pokud je auto jinde nez ve stanici, tak chcu vytvorit trip ke stanici, spustit jizdu a az dojede, // tak spustit cekani, ktere je kratsi o cas dojezdu na stanici -// state = OnDemandVehicleState.WAITINGFORTRANSFER; - waitActivityFactory.runActivity(this, ((PlanActionWait) currentTask).getWaitTime()); + state = OnDemandVehicleState.WAITINGFORTRANSFER; + if (currentTask instanceof PlanActionWait) { + long substractTime = 0; + if (((PlanActionWait) currentTask).isWaitingPaused()) { + substractTime = ((PlanActionWait) currentTask).getWaitingPausedAt() - ((PlanActionWait) currentTask).getWaitingStartedAt(); + } + ((PlanActionWait) currentTask).setWaitingStarted(true); + ((PlanActionWait) currentTask).setWaitingStartedAt(timeProvider.getCurrentSimTime()); + ((PlanActionWait) currentTask).setWaitingPaused(false); + long waitTime = ((PlanActionWait) currentTask).getWaitTime(); + waitWithStopActivityFactory.runActivity(this, waitTime - substractTime); + } else { + driveToNextTask(); + } + } @Override public void finishedDriving(boolean wasStopped) { -// logTraveledDistance(wasStopped); - + if(wasStopped){ driveToNextTask(); } @@ -289,9 +336,6 @@ public void finishedDriving(boolean wasStopped) { logTraveledDistance(wasStopped); finishRebalancing(); break; -// case WAITINGFORTRANSFER: -// waitForTransfer(); -// break; } } } @@ -328,6 +372,8 @@ else if(currentTask instanceof PlanActionWait) { // else make new trip and start driving with edited wait time VehicleTrip newTrip = tripsUtil.createTrip(this.getPosition(), currentTask.getPosition(), vehicle); this.currentTrip = newTrip; + state = OnDemandVehicleState.DRIVING_TO_TRANSFER_STATION_TO_WAIT; +// driveFactory.create(this, vehicle, currentTrip).run(); driveToTransferStationActivityFactory.create(this, vehicle, currentTrip).run(); this.tripAlreadyPlanned = true; diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RidesharingOnDemandVehicleFactory.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RidesharingOnDemandVehicleFactory.java index 0a1a531d..939dbe61 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RidesharingOnDemandVehicleFactory.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RidesharingOnDemandVehicleFactory.java @@ -28,10 +28,7 @@ import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; import cz.cvut.fel.aic.agentpolis.simulator.visualization.visio.VisioPositionUtil; import cz.cvut.fel.aic.alite.common.event.EventProcessor; -import cz.cvut.fel.aic.simod.DriveToTransferStation; -import cz.cvut.fel.aic.simod.DriveToTransferStationActivityFactory; -import cz.cvut.fel.aic.simod.StationsDispatcher; -import cz.cvut.fel.aic.simod.WaitTransferActivityFactory; +import cz.cvut.fel.aic.simod.*; import cz.cvut.fel.aic.simod.config.SimodConfig; import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicle; import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicleFactory; @@ -44,7 +41,7 @@ @Singleton public class RidesharingOnDemandVehicleFactory extends OnDemandVehicleFactory{ - WaitTransferActivityFactory waitTransferActivityFactory; + WaitWithStopActivityFactory waitWithStopActivityFactory; DriveToTransferStationActivityFactory driveToTransferStationActivityFactory; @@ -60,7 +57,7 @@ public RidesharingOnDemandVehicleFactory( SimodConfig config, IdGenerator idGenerator, AgentpolisConfig agentpolisConfig, - WaitTransferActivityFactory waitTransferActivityFactory, + WaitWithStopActivityFactory waitWithStopActivityFactory, WaitActivityFactory waitActivityFactory, DriveToTransferStationActivityFactory driveToTransferStationActivityFactory ) { @@ -73,11 +70,11 @@ public RidesharingOnDemandVehicleFactory( timeProvider, rebalancingIdGenerator, config, - waitTransferActivityFactory, + waitWithStopActivityFactory, waitActivityFactory, idGenerator, agentpolisConfig); - this.waitTransferActivityFactory = waitTransferActivityFactory; + this.waitWithStopActivityFactory = waitWithStopActivityFactory; this.driveToTransferStationActivityFactory = driveToTransferStationActivityFactory; } @@ -97,7 +94,7 @@ public OnDemandVehicle create(String vehicleId, SimulationNode startPosition) { config, idGenerator, agentpolisConfig, - waitTransferActivityFactory, + waitWithStopActivityFactory, waitActivityFactory, driveToTransferStationActivityFactory, vehicleId, diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTNoFreezeSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTNoFreezeSolver.java new file mode 100644 index 00000000..bad8e87d --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTNoFreezeSolver.java @@ -0,0 +1,1503 @@ +package cz.cvut.fel.aic.simod.ridesharing.greedyTASeT; + +import com.google.inject.Inject; +import com.google.inject.Singleton; +import cz.cvut.fel.aic.agentpolis.config.AgentpolisConfig; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.trip.VehicleTrip; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.TimeProvider; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.AgentPolisEntity; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.agentpolis.utils.PositionUtil; +import cz.cvut.fel.aic.alite.common.event.Event; +import cz.cvut.fel.aic.alite.common.event.EventHandler; +import cz.cvut.fel.aic.alite.common.event.EventProcessor; +import cz.cvut.fel.aic.alite.common.event.typed.TypedSimulation; +import cz.cvut.fel.aic.simod.config.SimodConfig; +import cz.cvut.fel.aic.simod.event.OnDemandVehicleEvent; +import cz.cvut.fel.aic.simod.ridesharing.DARPSolver; +import cz.cvut.fel.aic.simod.ridesharing.DroppedDemandsAnalyzer; +import cz.cvut.fel.aic.simod.ridesharing.PlanCostProvider; +import cz.cvut.fel.aic.simod.ridesharing.RideSharingOnDemandVehicle; +import cz.cvut.fel.aic.simod.ridesharing.insertionheuristic.DriverPlan; +import cz.cvut.fel.aic.simod.ridesharing.model.*; +import cz.cvut.fel.aic.simod.storage.OnDemandVehicleStorage; +import cz.cvut.fel.aic.simod.storage.OnDemandvehicleStationStorage; +import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider; +import org.jgrapht.alg.util.Pair; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +@Singleton +public class GreedyTASeTNoFreezeSolver extends DARPSolver implements EventHandler { + + + private final TypedSimulation eventProcessor; + + private final SimodConfig config; + + private final TimeProvider timeProvider; + + private final PositionUtil positionUtil; + + private final DroppedDemandsAnalyzer droppedDemandsAnalyzer; + + private final OnDemandvehicleStationStorage onDemandvehicleStationStorage; + + private final double maxDistance = 100; + + private final double maxDistanceSquared = 10000; + + private final int maxDelayTime = 10; + + private List transferPoints; + + protected final DefaultPlanComputationRequest.DefaultPlanComputationRequestFactory requestFactory; + + private Map planMap; + + + + + @Inject + public GreedyTASeTNoFreezeSolver( + OnDemandVehicleStorage vehicleStorage, + TravelTimeProvider travelTimeProvider, + PlanCostProvider travelCostProvider, + DefaultPlanComputationRequest.DefaultPlanComputationRequestFactory requestFactory, + TypedSimulation eventProcessor, + SimodConfig config, + TimeProvider timeProvider, + PositionUtil positionUtil, + DroppedDemandsAnalyzer droppedDemandsAnalyzer, + OnDemandvehicleStationStorage onDemandvehicleStationStorage, + AgentpolisConfig agentpolisConfig) { + + super(vehicleStorage, travelTimeProvider, travelCostProvider, requestFactory); + this.eventProcessor = eventProcessor; + this.config = config; + this.timeProvider = timeProvider; + this.positionUtil = positionUtil; + this.droppedDemandsAnalyzer = droppedDemandsAnalyzer; + this.onDemandvehicleStationStorage = onDemandvehicleStationStorage; + this.requestFactory = requestFactory; + + setEventHandeling(); + } + + public void setTransferPoints(List transferPoints) { + this.transferPoints = transferPoints; + } + + @Override + public EventProcessor getEventProcessor() { + return eventProcessor; + } + + @Override + public void handleEvent(Event event) { + + } + + + private void setEventHandeling() { + List typesToHandle = new LinkedList<>(); + + typesToHandle.add(OnDemandVehicleEvent.PICKUP); + eventProcessor.addEventHandler(this, typesToHandle); + } + + /** + * Transfer-allowed scheduling solver + * @return Map + */ + @Override + public Map solve(List newRequests, List waitingRequests) { + Map planMap = new ConcurrentHashMap<>(); + Map planMapReturn = new ConcurrentHashMap<>(); + List taxis = new ArrayList<>(); + + for(AgentPolisEntity tVvehicle: vehicleStorage.getEntitiesForIteration()) { + RideSharingOnDemandVehicle vehicle = (RideSharingOnDemandVehicle) tVvehicle; + taxis.add(vehicle); + } + + planMap = dispatch(taxis, newRequests); + + + + return planMap; + } + + /** + * Transfer-allowed scheduling function + * @return + */ + private Map dispatch(List taxis, List requests) { + // because all passengers allow ridesharing, only greedy taset will be called + List carpoolAcceptingTaxis = taxis; + List carpoolAcceptingPassengers = requests; + Map map = heuristics(carpoolAcceptingTaxis, carpoolAcceptingPassengers); + return map; + } + + + private boolean isWithTransfer(DriverPlan plan) { + for(PlanAction action : plan.plan) { + if(action instanceof PlanRequestAction) { + if (action instanceof PlanActionDropoffTransfer || action instanceof PlanActionPickupTransfer || action instanceof PlanActionWait) { + return true; + } + } + } + return false; + } + + private int findLastPickupIndex(DriverPlan plan) { + int index = -1; + for (int i = 0; i < plan.getLength(); i++) { + if (plan.plan.get(i) instanceof PlanActionPickup) { + index = i; + } + } + return index; + } + + private int findLastPickupIndexList(List plan) { + int index = -1; + for (int i = 0; i < plan.size(); i++) { + if (plan.get(i) instanceof PlanActionPickup) { + index = i; + } + } + return index; + } + + private int findLastTransferActionIndex(DriverPlan plan) { + int index = -1; + for (int i = 0; i < plan.getLength(); i++) { + if (plan.plan.get(i) instanceof PlanActionDropoffTransfer || plan.plan.get(i) instanceof PlanActionPickupTransfer || plan.plan.get(i) instanceof PlanActionWait) { + index = i; + } + } + return index; + } + + private long countTimeToNewPickup(RideSharingOnDemandVehicle taxi, PlanComputationRequest request, List requestsOnBoard) { + DriverPlan taxiPlan; + if (planMap.containsKey(taxi)) { + taxiPlan = planMap.get(taxi); + } else { + taxiPlan = taxi.getCurrentPlanNoUpdate(); + } + if (isWithTransfer(taxiPlan)) { + // nekdo prestupuje + int indexLastTransferAction = findLastTransferActionIndex(taxiPlan); + long timeToFinishCurrentEdge = 0; + SimulationNode previousPos = taxi.getPosition(); + if (taxi.getCurrentTask() != null) { + timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(taxi, taxi.getCurrentTask().getPosition()); + previousPos = taxi.getCurrentTask().getPosition(); + } + long timeToLastTransferAction = 0; + for (int q = 0; q < indexLastTransferAction + 1; q++) { + if (taxiPlan.plan.get(q) instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) taxiPlan.plan.get(q); + timeToLastTransferAction = timeToLastTransferAction + wait.getWaitTime(); + } else { + timeToLastTransferAction = timeToLastTransferAction + travelTimeProvider.getExpectedTravelTime(previousPos, taxiPlan.plan.get(q).getPosition()); + } + previousPos = taxiPlan.plan.get(q).getPosition(); + } + // ted potrebuju najit posledni pickup ve zbyvajicim driver planu po prestupu + List segmentAfterTransfer = taxiPlan.plan.subList(indexLastTransferAction+1, taxiPlan.plan.size()); + int indexLastPickupSegment = findLastPickupIndexList(segmentAfterTransfer); + long timeToLastPickup = 0; + SimulationNode previousPos2 = taxiPlan.plan.get(taxiPlan.plan.size()-1).getPosition(); + if (segmentAfterTransfer.size() > 0) { + previousPos2 = segmentAfterTransfer.get(0).getPosition(); + for (int q = 0; q < indexLastPickupSegment + 1; q++) { + timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos2, segmentAfterTransfer.get(q).getPosition()); + previousPos2 = segmentAfterTransfer.get(q).getPosition(); + } + } + SimulationNode newPickupFrom = request.getFrom(); + long timeToNewPick = travelTimeProvider.getExpectedTravelTime(previousPos2, newPickupFrom); + long estimatedArrivalToPickup = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastTransferAction + timeToLastPickup + timeToNewPick; + long maxTime = request.getMaxDropoffTime() * 1000; + if (estimatedArrivalToPickup > maxTime) { + return Long.MAX_VALUE; + } + return estimatedArrivalToPickup; + } + else { + //neprestupuje nikdo + int indexLastPickup = findLastPickupIndex(taxiPlan); + long timeToFinishCurrentEdge = 0; + SimulationNode previousPos = taxi.getPosition(); + if (taxi.getCurrentTask() != null) { + timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(taxi, taxi.getCurrentTask().getPosition()); + previousPos = taxi.getCurrentTask().getPosition(); + } + long timeToLastPickup = 0; + for (int q = 0; q < indexLastPickup + 1; q++) { + timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos, taxiPlan.plan.get(q).getPosition()); + previousPos = taxiPlan.plan.get(q).getPosition(); + } + SimulationNode newPickupFrom = request.getFrom(); + long timeToNewPick = travelTimeProvider.getExpectedTravelTime(previousPos, newPickupFrom); + long estimatedArrivalToNewPickup = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastPickup + timeToNewPick; + long maxTime = request.getMaxDropoffTime() * 1000; + if (estimatedArrivalToNewPickup > maxTime) { + return Long.MAX_VALUE; + } + return estimatedArrivalToNewPickup; + } + } + + /** + * Greedy TASeT heuristics function + * @return + */ + private Map heuristics(List taxis, List requests) { + //transfer points = charging stations + List transferPoints = this.transferPoints; + + //lookup table LT - LT [t][k] stores the earliest arrival time for taxi k to charging station t without violating the tolerable delay for k’s current passengers + int stationsCount = transferPoints.size(); + int taxisCount = taxis.size(); + long[][] LT = new long[stationsCount][taxisCount]; + //fill the LT table + for (int i = 0; i < taxisCount; i++) { + RideSharingOnDemandVehicle taxi = taxis.get(i); + SimulationNode taxiPosition = taxis.get(i).getPosition(); + Set requestsOnBoardSet = new HashSet<>(); + DriverPlan actualPlan = taxi.getCurrentPlanNoUpdate(); + for(PlanAction action : actualPlan) { + if(action instanceof PlanRequestAction) { + PlanRequestAction requestAction = (PlanRequestAction) action; + requestsOnBoardSet.add(requestAction.request); + } + } + List requestsOnBoard = new ArrayList<>(requestsOnBoardSet); + // kolik lidi je prave ted v aute + boolean taxiFree = true; + int taxiCapacity = taxi.getCapacity(); + if (requestsOnBoardSet.size() >= taxiCapacity) { + taxiFree = false; + } + for(int j = 0; j < stationsCount; j++) { + //check if taxi has free seat + if (!taxiFree) { + LT[j][i] = Long.MAX_VALUE; + } + else { + if (isWithTransfer(taxi.getCurrentPlanNoUpdate())) { + // nekdo prestupuje + int indexLastTransferAction = findLastTransferActionIndex(taxi.getCurrentPlanNoUpdate()); + long timeToFinishCurrentEdge = 0; + SimulationNode previousPos = taxi.getPosition(); + if (taxi.getCurrentTask() != null) { + timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(taxi, taxi.getCurrentTask().getPosition()); + previousPos = taxi.getCurrentTask().getPosition(); + } + long timeToLastTransferAction = 0; + for (int q = 0; q < indexLastTransferAction + 1; q++) { + if (taxi.getCurrentPlanNoUpdate().plan.get(q) instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) taxi.getCurrentPlanNoUpdate().plan.get(q); + timeToLastTransferAction = timeToLastTransferAction + wait.getWaitTime(); + } else { + timeToLastTransferAction = timeToLastTransferAction + travelTimeProvider.getExpectedTravelTime(previousPos, taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition()); + } + previousPos = taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition(); + } + // ted potrebuju najit posledni pickup ve zbyvajicim driver planu po prestupu + List segmentAfterTransfer = taxi.getCurrentPlanNoUpdate().plan.subList(indexLastTransferAction+1, taxi.getCurrentPlanNoUpdate().plan.size()); + int indexLastPickupSegment = findLastPickupIndexList(segmentAfterTransfer); + long timeToLastPickup = 0; + SimulationNode previousPos2 = taxi.getCurrentPlanNoUpdate().plan.get(taxi.getCurrentPlanNoUpdate().plan.size()-1).getPosition(); + if (segmentAfterTransfer.size() > 0) { + previousPos2 = segmentAfterTransfer.get(0).getPosition(); + for (int q = 0; q < indexLastPickupSegment + 1; q++) { + timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos2, segmentAfterTransfer.get(q).getPosition()); + previousPos2 = segmentAfterTransfer.get(q).getPosition(); + } + } + SimulationNode station = transferPoints.get(j); + long timeToStation = travelTimeProvider.getExpectedTravelTime(previousPos, station); + long estimatedArrivalToStation = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastTransferAction + timeToLastPickup + timeToStation; + LT[j][i] = estimatedArrivalToStation; + // zkontrolovat, zda arrival je v pohode z hlediska delay - kontroluju pro requesty po ukonceni prestupu + Set requestsInSegmentSet = new HashSet<>(); + for(PlanAction action : segmentAfterTransfer) { + if(action instanceof PlanRequestAction) { + PlanRequestAction requestAction = (PlanRequestAction) action; + requestsInSegmentSet.add(requestAction.request); + } + } + List requestsInSegment = new ArrayList<>(requestsInSegmentSet); + for (PlanComputationRequest request : requestsInSegment) { + long maxTime = request.getMaxDropoffTime() * 1000; + if (LT[j][i] > maxTime) { + LT[j][i] = Long.MAX_VALUE; + break; + } + } + } + else { + //neprestupuje nikdo + int indexLastPickup = findLastPickupIndex(taxi.getCurrentPlanNoUpdate()); + long timeToFinishCurrentEdge = 0; + SimulationNode previousPos = taxi.getPosition(); + if (taxi.getCurrentTask() != null) { + timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(taxi, taxi.getCurrentTask().getPosition()); + previousPos = taxi.getCurrentTask().getPosition(); + } + long timeToLastPickup = 0; + for (int q = 0; q < indexLastPickup + 1; q++) { + timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos, taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition()); + previousPos = taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition(); + } + SimulationNode station = transferPoints.get(j); + long timeToStation = travelTimeProvider.getExpectedTravelTime(previousPos, station); + long estimatedArrivalToStation = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastPickup + timeToStation; + LT[j][i] = estimatedArrivalToStation; + // zkontrolovat, zda arrival je v pohode z hlediska delay + for (PlanComputationRequest request : requestsOnBoard) { + long maxTime = request.getMaxDropoffTime() * 1000; + if (LT[j][i] > maxTime) { + LT[j][i] = Long.MAX_VALUE; + break; + } + } + } + } + } + } + + //we rank the requests in descending order by the number of taxis that are possible to pick them up in time (without considering transfer or destination) + //get possible taxis for every request and number of possible taxis + int[] possiblePickupTaxisCounts = new int[requests.size()]; + int i = 0; + Map> possiblePickupTaxisMap = new HashMap<>(); + for(PlanComputationRequest request : requests) { + int counter = 0; + List possiblePickupTaxisOneRequest = new ArrayList<>(); + for(RideSharingOnDemandVehicle t : taxis) { + if (canServeRequestTASeT2(t, request)) { + counter++; + possiblePickupTaxisOneRequest.add(t); + } + } + possiblePickupTaxisCounts[i] = counter; + possiblePickupTaxisMap.put(request, possiblePickupTaxisOneRequest); + i++; + } + + + //sort R by the number of possible pickup taxis + List requestsCopy = new ArrayList<>(requests); + requests.sort(Comparator.comparing(x -> possiblePickupTaxisCounts[requestsCopy.indexOf(x)])); + //order to descending order + Collections.reverse(requests); + + planMap = new ConcurrentHashMap<>(); + + + for(PlanComputationRequest request : requests) { + List>, List>> templistP = new ArrayList<>(); + // list ve kterem je list dvojic - list dvojic, protoze dvojice muze byt jen jedna (neni prestup) nebo dve (je prestup) + List delays = new ArrayList<>(); + List transferTimes = new ArrayList<>(); + List canPickupRequestTaxis = possiblePickupTaxisMap.get(request); + for (RideSharingOnDemandVehicle taxi : canPickupRequestTaxis) { + List posbitnry = findPlanWithNoTransferNew(request, taxi); + // pokud neexistuje ani jeden validni itinerar, tak je posbitnry null + // tehdy ho nebudu pridavat do templistu + if (posbitnry != null) { + if (checkValidItinerary(posbitnry, taxi)) { + List> tmp = new ArrayList<>(); + List tmpVehs = new ArrayList<>(); + tmpVehs.add(taxi); + tmp.add(posbitnry); + Pair>, List> pair = new Pair<>(tmp, tmpVehs); + templistP.add(pair); + long minimalArrivalTime = timeProvider.getCurrentSimTime() + travelTimeProvider.getExpectedTravelTime(request.getFrom(), request.getTo()); + HashMap dropoffs = getEstimatedTimesOfDropoff(posbitnry, taxi); + long realArrivalTime = dropoffs.get(request); + long delay = realArrivalTime - minimalArrivalTime; + delays.add(delay); + transferTimes.add((long) 0); + } + } + Set requestsOnBoardSet = new HashSet<>(); + DriverPlan actualPlan; + if (planMap.containsKey(taxi)) { + actualPlan = planMap.get(taxi); + } else { + actualPlan = taxi.getCurrentPlanNoUpdate(); + } + for(PlanAction action : actualPlan) { + if(action instanceof PlanRequestAction) { + PlanRequestAction requestAction = (PlanRequestAction) action; + requestsOnBoardSet.add(requestAction.request); + } + } + List requestsOnBoard = new ArrayList<>(requestsOnBoardSet); + + long timeToNewPickup = countTimeToNewPickup(taxi, request, requestsOnBoard); + int stationIndex = 0; + for (SimulationNode station : transferPoints) { + // je stanice potencialne vhodna pro prestup? + if (timeToNewPickup + travelTimeProvider.getExpectedTravelTime(request.getFrom(), station) > + request.getMaxDropoffTime() * 1000 - travelTimeProvider.getExpectedTravelTime(station, request.getTo())) { + continue; + } + + // find k' = taxis that taxi k can transfer to at station + for (int k = 0; k < taxisCount; k++) { + // minimalni cas na druhy usek + //not possible to transfer to + if (LT[stationIndex][k] == Long.MAX_VALUE) { + continue; + } else if(LT[stationIndex][k] > request.getMaxDropoffTime() * 1000 - travelTimeProvider.getExpectedTravelTime(station, request.getTo())) { + continue; + } else if(taxi.equals(taxis.get(k))) { + continue; + } else if (station == request.getTo()) { + continue; + } else if (station == request.getFrom()) { + continue; + } else { + // split request to two requests with transfer point + long travelTimeFromStationToDest = travelTimeProvider.getExpectedTravelTime(station, request.getTo()); + int maxDropOffTime = request.getMaxDropoffTime() - (int) Math.round(travelTimeFromStationToDest / 1000.0); + PlanActionDropoffTransfer dropoffActionTransfer = new PlanActionDropoffTransfer(request, station, maxDropOffTime); + PlanActionPickupTransfer pickupActionTransfer = new PlanActionPickupTransfer(request, station, maxDropOffTime); + + List itnryp1 = findPlanWithNoTransferActionsNew(request.getPickUpAction(), dropoffActionTransfer, taxi); // pro auto + List itnryp2 = findPlanWithNoTransferActionsNew(pickupActionTransfer, request.getDropOffAction(), taxis.get(k)); + if (itnryp1 == null || itnryp2 == null) { + // neexistuje plan + continue; + } + Pair>, Long> p = createChargePlanNoNewRequests(itnryp1, itnryp2, taxi, taxis.get(k), request); + if (p == null) { + // neni zadny validni plan a tedy neni mozne prestoupit, takze neudelam nic + continue; + } else { + List> itnrys = p.getFirst(); + itnryp1 = itnrys.get(0); + itnryp2 = itnrys.get(1); + List> tmp2 = new ArrayList<>(); + tmp2.add(itnryp1); + tmp2.add(itnryp2); + List tmpVehs2 = new ArrayList<>(); + tmpVehs2.add(taxi); + tmpVehs2.add(taxis.get(k)); + Pair>, List> pair2 = new Pair<>(tmp2, tmpVehs2); + templistP.add(pair2); + // travel time daneho requestu s prestupem spocitam jako: + // cas nez prvni auto dojede pro request a vyzvedne ho + // + cas jizdy v prvnim vozidle + // + pokud druhe auto prijede pozdeji nez to prvni tak k tomu prictu rozdil + // + doba jizdy v druhem aute + HashMap drops = getEstimatedTimesOfDropoff(itnryp2, taxis.get(k)); + if (drops == null) { + // not valid + delays.add(Long.MAX_VALUE); + transferTimes.add((long) -1); + continue; + } + long minimalArrivalTime = timeProvider.getCurrentSimTime() + travelTimeProvider.getExpectedTravelTime(request.getFrom(), request.getTo()); + long realArrivalTime = drops.get(request); + long delay = realArrivalTime - minimalArrivalTime; + delays.add(delay); + long transferTime = p.getSecond(); + transferTimes.add(transferTime); + } + } + } + stationIndex++; + } + } + List listTransferPlans = new ArrayList<>(); + for (int j = 0; j < templistP.size(); j++) { + TransferPlan t = new TransferPlan(transferTimes.get(j), delays.get(j), templistP.get(j)); + listTransferPlans.add(t); + } + listTransferPlans.sort(TransferPlan::compareByDelay); + + //vezmu hornich beta procent + double beta = 0.2; + int numOfTaken = (int) (delays.size() * beta); + if (numOfTaken == 0) { + numOfTaken = 1; + } + List sublistTransferPlans = new ArrayList<>(); + for (int q = 0; q < numOfTaken; q++) + { + if(!listTransferPlans.isEmpty()) { + sublistTransferPlans.add(listTransferPlans.get(q)); + } + } + sublistTransferPlans.sort(TransferPlan::compareByTransferTime); + Collections.reverse(sublistTransferPlans); + + // ted mam serazene transferTimes + if (sublistTransferPlans.isEmpty()) { + continue; + } + else + { + // ziskam entry ktery je nejlepsi podle heuristiky + if (sublistTransferPlans.get(0).delay == Long.MAX_VALUE || sublistTransferPlans.get(0).trasferTime < 0) { + continue; + } + Pair>, List> key = sublistTransferPlans.get(0).pair; + List> plansForVehicles = key.getFirst(); + List vehicles = key.getSecond(); + for (int q = 0; q < vehicles.size(); q++) { + List vehPlan = plansForVehicles.get(q); + List planWithPos = new ArrayList<>(); + planWithPos.add(vehicles.get(q).getCurrentPlanNoUpdate().plan.get(0)); + planWithPos.addAll(vehPlan); + DriverPlan dp = new DriverPlan(planWithPos, 0, 0); + planMap.put(vehicles.get(q), dp); + } + } + + // update k, k′ and LT + //update LT - not efficient + for (int z = 0; z < taxisCount; z++) { + RideSharingOnDemandVehicle taxi = taxis.get(z); + SimulationNode taxiPosition = taxis.get(z).getPosition(); + Set requestsOnBoardSet = new HashSet<>(); + DriverPlan actualPlan; + if (planMap.containsKey(taxis.get(z))) { + actualPlan = planMap.get(taxi); + } else { + actualPlan = taxi.getCurrentPlanNoUpdate(); + } + for(PlanAction action : actualPlan) { + if(action instanceof PlanRequestAction) { + PlanRequestAction requestAction = (PlanRequestAction) action; + requestsOnBoardSet.add(requestAction.request); + } + } + List requestsOnBoard = new ArrayList<>(requestsOnBoardSet); + // kolik lidi je prave ted v aute + boolean taxiFree = true; + int taxiCapacity = taxi.getCapacity(); + if (requestsOnBoardSet.size() >= taxiCapacity) { + taxiFree = false; + } + for(int j = 0; j < stationsCount; j++) { + //check if taxi has free seat + if (!taxiFree) { + LT[j][z] = Long.MAX_VALUE; + } else { + if (isWithTransfer(actualPlan)) { + // nekdo prestupuje + int indexLastTransferAction = findLastTransferActionIndex(actualPlan); + long timeToFinishCurrentEdge = 0; + SimulationNode previousPos = taxi.getPosition(); + if (taxi.getCurrentTask() != null) { + timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(taxi, taxi.getCurrentTask().getPosition()); + previousPos = taxi.getCurrentTask().getPosition(); + } + long timeToLastTransferAction = 0; + for (int q = 0; q < indexLastTransferAction + 1; q++) { + if (actualPlan.plan.get(q) instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) actualPlan.plan.get(q); + timeToLastTransferAction = timeToLastTransferAction + wait.getWaitTime(); + } else { + timeToLastTransferAction = timeToLastTransferAction + travelTimeProvider.getExpectedTravelTime(previousPos, actualPlan.plan.get(q).getPosition()); + } + previousPos = actualPlan.plan.get(q).getPosition(); + } + // ted potrebuju najit posledni pickup ve zbyvajicim driver planu po prestupu + List segmentAfterTransfer = actualPlan.plan.subList(indexLastTransferAction + 1, actualPlan.plan.size()); + int indexLastPickupSegment = findLastPickupIndexList(segmentAfterTransfer); + long timeToLastPickup = 0; + SimulationNode previousPos2 = actualPlan.plan.get(actualPlan.plan.size()-1).getPosition(); + if (segmentAfterTransfer.size() > 0) { + previousPos2 = segmentAfterTransfer.get(0).getPosition(); + for (int q = 0; q < indexLastPickupSegment + 1; q++) { + timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos2, segmentAfterTransfer.get(q).getPosition()); + previousPos2 = segmentAfterTransfer.get(q).getPosition(); + } + } + SimulationNode station = transferPoints.get(j); + long timeToStation = travelTimeProvider.getExpectedTravelTime(previousPos2, station); + long estimatedArrivalToStation = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastTransferAction + timeToLastPickup + timeToStation; + LT[j][z] = estimatedArrivalToStation; + // zkontrolovat, zda arrival je v pohode z hlediska delay - kontroluju pro requesty po ukonceni prestupu + Set requestsInSegmentSet = new HashSet<>(); + for (PlanAction action : segmentAfterTransfer) { + if (action instanceof PlanRequestAction) { + PlanRequestAction requestAction = (PlanRequestAction) action; + requestsInSegmentSet.add(requestAction.request); + } + } + List requestsInSegment = new ArrayList<>(requestsInSegmentSet); + for (PlanComputationRequest r : requestsInSegment) { + long maxTime = r.getMaxDropoffTime() * 1000; + if (LT[j][z] > maxTime) { + LT[j][z] = Long.MAX_VALUE; + break; + } + } + } else { + //neprestupuje nikdo + int indexLastPickup = findLastPickupIndex(actualPlan); + long timeToFinishCurrentEdge = 0; + SimulationNode previousPos = taxi.getPosition(); + if (taxi.getCurrentTask() != null) { + timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(taxi, taxi.getCurrentTask().getPosition()); + previousPos = taxi.getCurrentTask().getPosition(); + } + long timeToLastPickup = 0; + for (int q = 0; q < indexLastPickup + 1; q++) { + timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos, actualPlan.plan.get(q).getPosition()); + previousPos = actualPlan.plan.get(q).getPosition(); + } + SimulationNode station = transferPoints.get(j); + long timeToStation = travelTimeProvider.getExpectedTravelTime(previousPos, station); + long estimatedArrivalToStation = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastPickup + timeToStation; + LT[j][z] = estimatedArrivalToStation; + // zkontrolovat, zda arrival je v pohode z hlediska delay + for (PlanComputationRequest r : requestsOnBoard) { + long maxTime = r.getMaxDropoffTime() * 1000; + if (LT[j][z] > maxTime) { + LT[j][z] = Long.MAX_VALUE; + break; + } + } + } + } + } + } + } + return planMap; + } + + private boolean checkValidItinerary(List itinerary, RideSharingOnDemandVehicle vehicle) { + SimulationNode previousDestination = vehicle.getPosition(); + boolean ret = true; + long time = timeProvider.getCurrentSimTime(); + long timeToFinishEdge = 0; + previousDestination = vehicle.getPosition(); + + // podivam se na trip plan + if (vehicle.getCurrentTripPlan() != null) { + if (vehicle.getCurrentTripPlan().getSize() == 0) { + SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getLastLocation(); + // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu + // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu + timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, stopLoc); + previousDestination = stopLoc; + } + else if (vehicle.getCurrentTripPlan().getSize() > 0) { + SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getFirstLocation(); + SimulationNode currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[0]; + boolean currLocIsVehiclePosition = false; + int curridx = 0; + while (currLoc != stopLoc) { + if (currLocIsVehiclePosition) { + timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, currLoc); + } + if (currLoc == vehicle.getPosition()) { + currLocIsVehiclePosition = true; + } + previousDestination = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx]; + curridx++; + currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx]; + } + } + } + time += timeToFinishEdge; + + for (PlanAction action : itinerary) { + if (action instanceof PlanRequestAction) { + PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); + if (action instanceof PlanActionPickup) { + SimulationNode dest = pcq.getFrom(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (!(time < pcq.getMaxPickupTime()*1000)) { + //not valid itinerary + ret = false; + break; + } + previousDestination = dest; + } else if(action instanceof PlanActionPickupTransfer) { + PlanActionPickupTransfer pickupTransfer = (PlanActionPickupTransfer) action; + SimulationNode dest = pickupTransfer.getPosition(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = dest; + } else if(action instanceof PlanActionDropoffTransfer) { + PlanActionDropoffTransfer dropoffTransfer = (PlanActionDropoffTransfer) action; + SimulationNode dest = dropoffTransfer.getPosition(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = dest; + } else if (action instanceof PlanActionDropoff) { + SimulationNode dest = pcq.getTo(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (!(time < pcq.getMaxDropoffTime()*1000)) { + //not valid itinerary + ret = false; + break; + } + previousDestination = dest; + } else if (action instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) action; + time = time + wait.getWaitTime(); + } + } + } + return ret; + } + + private Pair>, Long> createChargePlanNoNewRequests(List itnryp1, List itnryp2, RideSharingOnDemandVehicle veh1, RideSharingOnDemandVehicle veh2, PlanComputationRequest request) { + long time1 = 0; + long timeToFinishEdge1 = 0; + SimulationNode previousDestination = veh1.getPosition(); + + // podivam se na trip plan + if (veh1.getCurrentTripPlan() != null) { + // pokud je get size u current trip planu vetsi nez nula, tak get first location vybere nejblizsi node kde se auto muze zastavit a je to spravne + // pokud je ale delka current trip nula, tak vyberu posledni akci z tripu - auto tam jeste nemuselo dojet a to zpusobuje chybku + // proto demand 298 neni vyzvednut vcas, protoze se tam neuvazuje cas ktere auto potrebuje na dokonceni trupu + if (veh1.getCurrentTripPlan().getSize() == 0) { + SimulationNode stopLoc = (SimulationNode) veh1.getCurrentTripPlan().getLastLocation(); + // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu + // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu + timeToFinishEdge1 += travelTimeProvider.getTravelTime(veh1, stopLoc); + previousDestination = stopLoc; + } + else if (veh1.getCurrentTripPlan().getSize() > 0) { + SimulationNode stopLoc = (SimulationNode) veh1.getCurrentTripPlan().getFirstLocation(); + SimulationNode currLoc = (SimulationNode) veh1.getCurrentTripPlan().getAllLocations()[0]; + boolean currLocIsVehiclePosition = false; + int curridx = 0; + while (currLoc != stopLoc) { + if (currLocIsVehiclePosition) { + timeToFinishEdge1 += travelTimeProvider.getTravelTime(veh1, currLoc); + } + if (currLoc == veh1.getPosition()) { + currLocIsVehiclePosition = true; + } + previousDestination = (SimulationNode) veh1.getCurrentTripPlan().getAllLocations()[curridx]; + curridx++; + currLoc = (SimulationNode) veh1.getCurrentTripPlan().getAllLocations()[curridx]; + } + } + } + time1 = timeToFinishEdge1; + + // nemusim pricitat current sim time, protoze budu od sebe oba casy odecitat, jde mi jen o jejich rozdil + long transferTime = 0; + //expected arrival time of first car + for (PlanAction action : itnryp1) { + if (action instanceof PlanRequestAction) { + PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); + if (action instanceof PlanActionPickup) { + SimulationNode dest = pcq.getFrom(); + time1 = time1 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = dest; + } else if(action instanceof PlanActionPickupTransfer) { + PlanActionPickupTransfer pickupTransfer = (PlanActionPickupTransfer) action; + SimulationNode dest = pickupTransfer.getPosition(); + time1 = time1 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = dest; + } else if(action instanceof PlanActionDropoffTransfer) { + PlanActionDropoffTransfer dropoffTransfer = (PlanActionDropoffTransfer) action; + SimulationNode dest = dropoffTransfer.getPosition(); + time1 = time1 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (dropoffTransfer.request == request) { + break; + } + previousDestination = dest; + } else if (action instanceof PlanActionDropoff) { + SimulationNode dest = pcq.getTo(); + time1 = time1 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = dest; + } else if (action instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) action; + time1 = time1 + wait.getWaitTime(); + } + } + } + // expected arrival of second car + int indexPickupSecondCar = 0; + long time2 = 0; + long timeToFinishEdge2 = 0; + PlanActionPickupTransfer pickup = null; + previousDestination = veh2.getPosition(); + + // podivam se na trip plan + if (veh2.getCurrentTripPlan() != null) { + if (veh2.getCurrentTripPlan().getSize() == 0) { + SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getLastLocation(); + // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu + // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu + timeToFinishEdge2 += travelTimeProvider.getTravelTime(veh2, stopLoc); + previousDestination = stopLoc; + } else if (veh2.getCurrentTripPlan().getSize() > 0) { + SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getFirstLocation(); + SimulationNode currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[0]; + boolean currLocIsVehiclePosition = false; + int curridx = 0; + while (currLoc != stopLoc) { + if (currLocIsVehiclePosition) { + timeToFinishEdge2 += travelTimeProvider.getTravelTime(veh2, currLoc); + } + if (currLoc == veh2.getPosition()) { + currLocIsVehiclePosition = true; + } + previousDestination = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx]; + curridx++; + currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx]; + } + } + } + time2 = timeToFinishEdge2; + + for (PlanAction action : itnryp2) { + if (action instanceof PlanRequestAction) { + PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); + if (action instanceof PlanActionPickup) { + SimulationNode dest = pcq.getFrom(); + time2 = time2 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = dest; + } else if(action instanceof PlanActionPickupTransfer) { + PlanActionPickupTransfer pickupTransfer = (PlanActionPickupTransfer) action; + SimulationNode dest = pickupTransfer.getPosition(); + time2 = time2 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (pickupTransfer.request == request) { + pickup = pickupTransfer; + break; + } + previousDestination = dest; + } else if(action instanceof PlanActionDropoffTransfer) { + PlanActionDropoffTransfer dropoffTransfer = (PlanActionDropoffTransfer) action; + SimulationNode dest = dropoffTransfer.getPosition(); + time2 = time2 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = dest; + } else if (action instanceof PlanActionDropoff) { + SimulationNode dest = pcq.getTo(); + time2 = time2 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = dest; + } else if (action instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) action; + time2 = time2 + wait.getWaitTime(); + } + } + indexPickupSecondCar++; + } + long waitTime = time2 - time1; // k wait time prictu navic rezervu + + // pokud je zaporny, tak druhe auto bude muset cekat waitTime dlouho + // pokud je kladny, tak to znamena ze prvni auto prijede drive nez druhe - bude cekat cestujici + + boolean valid = true; + long maxTransferTime; + +// pridat wait i pro druhe auto tam, kde je rozdil mensi nez 5 s +// aby tam byla rezerva + if (waitTime > 0 && waitTime < 2000) { + maxTransferTime = time1; + // ceka aspon 2 s + long newWait = 2000 - waitTime; + setMaxTransferTimeForDropoffTransferAction(maxTransferTime, itnryp1, request); + PlanActionWait waitAction = new PlanActionWait(request, pickup.getPosition(), pickup.getMaxTime(), newWait); + transferTime = newWait; + itnryp2.add(indexPickupSecondCar, waitAction); + + //check tolerable delay for passengers in vehicle2 + long time = 0; + previousDestination = veh2.getPosition(); + // podivam se na trip plan + if (veh2.getCurrentTripPlan() != null) { + if (veh2.getCurrentTripPlan().getSize() == 0) { + SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getLastLocation(); + // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu + // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu + time += travelTimeProvider.getTravelTime(veh2, stopLoc); + previousDestination = stopLoc; + } + else if (veh2.getCurrentTripPlan().getSize() > 0) { + SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getFirstLocation(); + SimulationNode currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[0]; + boolean currLocIsVehiclePosition = false; + int curridx = 0; + while (currLoc != stopLoc) { + if (currLocIsVehiclePosition) { + time += travelTimeProvider.getTravelTime(veh2, currLoc); + } + if (currLoc == veh2.getPosition()) { + currLocIsVehiclePosition = true; + } + previousDestination = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx]; + curridx++; + currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx]; + } + } + } + + for (PlanAction action : itnryp2) { + if (action instanceof PlanRequestAction) { + PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); + if (action instanceof PlanActionPickup) { + SimulationNode dest = pcq.getFrom(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (!(time <= pcq.getMaxPickupTime()*1000)) { + //not valid itinerary - check new driver plan + valid = false; + break; + } + previousDestination = dest; + } else if (action instanceof PlanActionDropoff) { + SimulationNode dest = pcq.getTo(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (!(time <= pcq.getMaxDropoffTime()*1000)) { + //not valid itinerary - check new driver plan + valid = false; + break; + } + previousDestination = dest; + } else if (action instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) action; + time = time + wait.getWaitTime(); + previousDestination = wait.getPosition(); + } else if (action instanceof PlanActionPickupTransfer) { + PlanActionPickupTransfer p = (PlanActionPickupTransfer) action; + SimulationNode dest = p.getPosition(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (!(time <= p.getMaxTime()*1000)) { + valid = false; + break; + } + previousDestination = dest; + } else if(action instanceof PlanActionDropoffTransfer) { + PlanActionDropoffTransfer p = (PlanActionDropoffTransfer) action; + SimulationNode dest = p.getPosition(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (!(time <= p.getMaxTime()*1000)) { + valid = false; + break; + } + previousDestination = dest; + } + } + } + } + // pridam wait time do planu pro druhe auto pokud je wait time zaporny + // pozor, pokud bych chtela smazat casovou rezervu 5 s, tak je tam nekde problem s wait akci s casem 0 + // - tak na to by bylo potreba udelat zvlast podminku a nejaky minimalni wait time tam nastavit, aby bylo zajistene poradi pri pruchodu algoritmem + else if (waitTime <= 0) { + maxTransferTime = time1; + // pridat 1000 je malo, ale 2000 dostacuje + waitTime = waitTime - 2000; + setMaxTransferTimeForDropoffTransferAction(maxTransferTime, itnryp1, request); + //transfer time je -waitTime + // pickup by nemel byt null protoze se nastavi v predeslem loopu + assert pickup != null; + PlanActionWait waitAction = new PlanActionWait(request, pickup.getPosition(), pickup.getMaxTime(), -waitTime); + transferTime = -waitTime; + itnryp2.add(indexPickupSecondCar, waitAction); + + //check tolerable delay for passengers in vehicle2 + long time = 0; + previousDestination = veh2.getPosition(); + // podivam se na trip plan + if (veh2.getCurrentTripPlan() != null) { + if (veh2.getCurrentTripPlan().getSize() == 0) { + SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getLastLocation(); + // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu + // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu + time += travelTimeProvider.getTravelTime(veh2, stopLoc); + previousDestination = stopLoc; + } + else if (veh2.getCurrentTripPlan().getSize() > 0) { + SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getFirstLocation(); + SimulationNode currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[0]; + boolean currLocIsVehiclePosition = false; + int curridx = 0; + while (currLoc != stopLoc) { + if (currLocIsVehiclePosition) { + time += travelTimeProvider.getTravelTime(veh2, currLoc); + } + if (currLoc == veh2.getPosition()) { + currLocIsVehiclePosition = true; + } + previousDestination = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx]; + curridx++; + currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx]; + } + } + } + + for (PlanAction action : itnryp2) { + if (action instanceof PlanRequestAction) { + PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); + if (action instanceof PlanActionPickup) { + SimulationNode dest = pcq.getFrom(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (!(time <= pcq.getMaxPickupTime()*1000)) { + //not valid itinerary - check new driver plan + valid = false; + break; + } + previousDestination = dest; + } else if (action instanceof PlanActionDropoff) { + SimulationNode dest = pcq.getTo(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (!(time <= pcq.getMaxDropoffTime()*1000)) { + //not valid itinerary - check new driver plan + valid = false; + break; + } + previousDestination = dest; + } else if (action instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) action; + time = time + wait.getWaitTime(); + previousDestination = wait.getPosition(); + } else if (action instanceof PlanActionPickupTransfer) { + PlanActionPickupTransfer p = (PlanActionPickupTransfer) action; + SimulationNode dest = p.getPosition(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (!(time <= p.getMaxTime()*1000)) { + valid = false; + break; + } + previousDestination = dest; + } else if(action instanceof PlanActionDropoffTransfer) { + PlanActionDropoffTransfer p = (PlanActionDropoffTransfer) action; + SimulationNode dest = p.getPosition(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (!(time <= p.getMaxTime()*1000)) { + valid = false; + break; + } + previousDestination = dest; + } + } + } + } + else { + maxTransferTime = time2 - 2000; +// maxTransferTime = time1; + setMaxTransferTimeForDropoffTransferAction(maxTransferTime, itnryp1, request); + } + if(valid) { + List> itnrys = new ArrayList<>(); + itnrys.add(itnryp1); + itnrys.add(itnryp2); + Pair>, Long> ret = new Pair<>(itnrys, transferTime); + return ret; + } + else { + return null; + } + } + + public List getPickupActions(List plan) { + List pickups = new ArrayList<>(); + for(PlanAction action : plan) { + if(action instanceof PlanActionPickup || action instanceof PlanActionPickupTransfer) { + pickups.add(action); + } + } + return pickups; + } + + public void setMaxTransferTimeForDropoffTransferAction(long maxTime, List itinerary, PlanComputationRequest request) { + maxTime = maxTime + timeProvider.getCurrentSimTime(); + int maxTimeInt = (int) Math.floor(maxTime / 1000.0); + for (PlanAction action : itinerary) { + if (action instanceof PlanActionDropoffTransfer) { + if(((PlanActionDropoffTransfer) action).getRequest() == request) { + PlanActionDropoffTransfer ac = (PlanActionDropoffTransfer) action; + ac.setMaxTime(maxTimeInt-1); + } + } + } + } + + + public List getDropoffActions(List plan) { + List dropoffs = new ArrayList<>(); + for(PlanAction action : plan) { + if(action instanceof PlanActionDropoff || action instanceof PlanActionDropoffTransfer) { + dropoffs.add(action); + } + } + return dropoffs; + } + + private HashMap getEstimatedTimesOfDropoff(List itinerary, RideSharingOnDemandVehicle vehicle) { + long time = timeProvider.getCurrentSimTime(); + long timeToFinishEdge = 0; + SimulationNode previousDestination = vehicle.getPosition(); + if (vehicle.getCurrentTripPlan() != null) { + if (vehicle.getCurrentTripPlan().getSize() == 0) { + SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getLastLocation(); + // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu + // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu + timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, stopLoc); + previousDestination = stopLoc; + } + else if (vehicle.getCurrentTripPlan().getSize() > 0) { + SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getFirstLocation(); + SimulationNode currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[0]; + boolean currLocIsVehiclePosition = false; + int curridx = 0; + while (currLoc != stopLoc) { + if (currLocIsVehiclePosition) { + timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, currLoc); + } + if (currLoc == vehicle.getPosition()) { + currLocIsVehiclePosition = true; + } + previousDestination = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx]; + curridx++; + currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx]; + } + } + } + + time = time + timeToFinishEdge; + + HashMap times = new HashMap<>(); + for (PlanAction action : itinerary) { + if (action instanceof PlanActionPickup || action instanceof PlanActionPickupTransfer) { + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, action.getPosition()); + if (time > ((PlanRequestAction) action).request.getMaxPickupTime() * 1000) { + //not valid + return null; + } + previousDestination = action.getPosition(); + } else if (action instanceof PlanActionDropoff || action instanceof PlanActionDropoffTransfer) { + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, action.getPosition()); + if (time > ((PlanRequestAction) action).request.getMaxDropoffTime() * 1000) { + //not valid + return null; + } + times.put(((PlanRequestAction) action).getRequest(), time); + previousDestination = action.getPosition(); + } else if (action instanceof PlanActionWait) { + time = time + ((PlanActionWait) action).getWaitTime(); + } + + } + return times; + } + + private List findItineraryWithMinimumDelayNew(List> lst, List originalPlan, RideSharingOnDemandVehicle vehicle) { + HashMap timesOfDropOriginal = getEstimatedTimesOfDropoff(originalPlan, vehicle); + if (timesOfDropOriginal == null) { + //plan neni validni + // to je chyba, puvodni plan by mel byt validni vzdy + return null; + //TODO throw exception + } + List delays = new ArrayList<>(); + for (List itnry : lst) { + HashMap timesOfDropNew = getEstimatedTimesOfDropoff(itnry, vehicle); + if (timesOfDropNew == null) { + //plan neni validni + delays.add(Long.MAX_VALUE); + } else { + // plan je validni, spocitam zpozdeni + long delay = countDelayDifference(timesOfDropOriginal, timesOfDropNew); + delays.add(delay); + } + } + //find max in delays + int maxAt = 0; + for (int i = 0; i < delays.size(); i++) { + maxAt = delays.get(i) > delays.get(maxAt) ? i : maxAt; + } + if (delays.get(maxAt) == Long.MAX_VALUE) { + return null; + } + List bestPlan = lst.get(maxAt); + return bestPlan; + } + + private long countDelayDifference(HashMap originalMap, HashMap newMap) { + long time = 0; + for (Map.Entry entry : originalMap.entrySet()) { + long difference = Math.abs(entry.getValue() - newMap.get(entry.getKey())); + time = time + difference; + } + // todo maybe add delay for a new passenger? + return time; + } + + private List removeCurrentPositionActions(List listOfActionsWithPositions) { + List copyOfList = new ArrayList<>(); + copyOfList.addAll(listOfActionsWithPositions); + for (PlanAction action : listOfActionsWithPositions) { + if (action instanceof PlanActionCurrentPosition) { + copyOfList.remove(action); + } + } + return copyOfList; + } + + + private List findPlanWithNoTransferNew(PlanComputationRequest newRequest, RideSharingOnDemandVehicle vehicle) { + DriverPlan vehiclePlan; + if (planMap.containsKey(vehicle)) { + vehiclePlan = planMap.get(vehicle); + } else { + vehiclePlan = vehicle.getCurrentPlanNoUpdate(); + } + if (isWithTransfer(vehiclePlan)) { + // v aute nekdo prestupuje + // musim oddelit segment s prestupem + // ze zbytku vezmu pickups, pridam novy a potom hledam permutace dropoff akci + int indexLastTransfer = findLastTransferActionIndex(vehiclePlan); + List segmentWithTransfer = vehiclePlan.plan.subList(0, indexLastTransfer+1); + List segmentWithTransferWithoutPositionAction = removeCurrentPositionActions(segmentWithTransfer); + + List segmentAfterTransfer = vehiclePlan.plan.subList(indexLastTransfer+1, vehiclePlan.plan.size()); + List> lstTemp = new ArrayList<>(); + List> lst = new ArrayList<>(); + List newPlan = new ArrayList<>(); + for (PlanAction action : segmentAfterTransfer) { + newPlan.add(action); + } + //add pickup and dropoff for new request + newPlan.add(newRequest.getPickUpAction()); + newPlan.add(newRequest.getDropOffAction()); + //get pickup order based on heuristic from TASeT paper + List pickups = getPickupActions(newPlan); + List dropoffs = getDropoffActions(newPlan); + //permute dropoff orders + List> dropoffOrders = permute(dropoffs); + for (List dropoffPlan : dropoffOrders) { + lstTemp.add(createItineraryList(pickups, dropoffPlan)); + } + // ted spojit puvodni segment a kadzy itinerare z lst + for (List itnry : lstTemp) { + List newList = new ArrayList<>(segmentWithTransferWithoutPositionAction); + newList.addAll(itnry); + lst.add(newList); + } + return findItineraryWithMinimumDelayNew(lst, vehiclePlan.plan, vehicle); + + } else { + //neni prestup v aute + List> lst = new ArrayList<>(); + List newPlan = new ArrayList<>(); + newPlan.addAll(vehiclePlan.plan); + //add pickup and dropoff for new request + newPlan.add(newRequest.getPickUpAction()); + newPlan.add(newRequest.getDropOffAction()); + //get pickup order based on heuristic from TASeT paper + List pickups = getPickupActions(newPlan); + List dropoffs = getDropoffActions(newPlan); + //permute dropoff orders + List> dropoffOrders = permute(dropoffs); + for (List dropoffPlan : dropoffOrders) { + lst.add(createItineraryList(pickups, dropoffPlan)); + } + return findItineraryWithMinimumDelayNew(lst, vehiclePlan.plan, vehicle); + } + } + + private List findPlanWithNoTransferActionsNew(PlanAction pickup, PlanAction dropoff, RideSharingOnDemandVehicle vehicle) { + DriverPlan vehiclePlan; + if (planMap.containsKey(vehicle)) { + vehiclePlan = planMap.get(vehicle); + } else { + vehiclePlan = vehicle.getCurrentPlanNoUpdate(); + } + if (isWithTransfer(vehiclePlan)) { + // v aute nekdo prestupuje + // musim oddelit segment s prestupem + // ze zbytku vezmu pickups, pridam novy a potom hledam permutace dropoff akci + int indexLastTransfer = findLastTransferActionIndex(vehiclePlan); + List segmentWithTransfer = vehiclePlan.plan.subList(0, indexLastTransfer+1); + List segmentWithTransferWithoutPositionAction = removeCurrentPositionActions(segmentWithTransfer); + + List segmentAfterTransfer = vehiclePlan.plan.subList(indexLastTransfer+1, vehiclePlan.plan.size()); + List> lstTemp = new ArrayList<>(); + List> lst = new ArrayList<>(); + List newPlan = new ArrayList<>(); + newPlan.addAll(segmentAfterTransfer); + //add pickup and dropoff for new request + newPlan.add(pickup); + newPlan.add(dropoff); + //get pickup order based on heuristic from TASeT paper + List pickups = getPickupActions(newPlan); + List dropoffs = getDropoffActions(newPlan); + //permute dropoff orders + List> dropoffOrders = permute(dropoffs); + for (List dropoffPlan : dropoffOrders) { + lstTemp.add(createItineraryList(pickups, dropoffPlan)); + } + // ted spojit puvodni segment a kadzy itinerare z lst + for (List itnry : lstTemp) { + List newList = new ArrayList<>(segmentWithTransferWithoutPositionAction); + newList.addAll(itnry); + lst.add(newList); + } + return findItineraryWithMinimumDelayNew(lst, vehiclePlan.plan, vehicle); + + } else { + //neni prestup v aute + List> lst = new ArrayList<>(); + List newPlan = new ArrayList<>(); + newPlan.addAll(vehiclePlan.plan); + //add pickup and dropoff for new request + newPlan.add(pickup); + newPlan.add(dropoff); + //get pickup order based on heuristic from TASeT paper + List pickups = getPickupActions(newPlan); + List dropoffs = getDropoffActions(newPlan); + //permute dropoff orders + List> dropoffOrders = permute(dropoffs); + for (List dropoffPlan : dropoffOrders) { + lst.add(createItineraryList(pickups, dropoffPlan)); + } + return findItineraryWithMinimumDelayNew(lst, vehiclePlan.plan, vehicle); + } + } + + private List createItineraryList(List pickupOrder, List dropoffOrder) { + List listOfActionsOrdered = new ArrayList<>(pickupOrder); + listOfActionsOrdered.addAll(dropoffOrder); + return listOfActionsOrdered; + } + + /** + * @return new list with all permutations of PlanActrions from lst List. + */ + public List> permute(List lst) { + List> list = new ArrayList<>(); + permuteHelper(list, new ArrayList<>(), lst); + return list; + } + + /** + * Helper function for permute() + */ + private void permuteHelper(List> list, List resultList, List lst){ + // Base case + if(resultList.size() == lst.size()){ + list.add(new ArrayList<>(resultList)); + } + else{ + for(int i = 0; i < lst.size(); i++){ + if(resultList.contains(lst.get(i))) + { + // If element already exists in the list then skip + continue; + } + // Choose element + resultList.add(lst.get(i)); + // Explore + permuteHelper(list, resultList, lst); + // Unchoose element + resultList.remove(resultList.size() - 1); + } + } + } + + private boolean canServeRequestTASeT2(RideSharingOnDemandVehicle vehicle, PlanComputationRequest request) { + Set requestsOnBoardSet = new HashSet<>(); + DriverPlan actualPlan = vehicle.getCurrentPlanNoUpdate(); + for (PlanAction action : actualPlan) { + if (action instanceof PlanRequestAction) { + PlanRequestAction requestAction = (PlanRequestAction) action; + requestsOnBoardSet.add(requestAction.request); + } + } + List requestsOnBoard = new ArrayList<>(requestsOnBoardSet); + // kolik lidi je prave ted v aute + boolean taxiFree = true; + int taxiCapacity = vehicle.getCapacity(); + if (requestsOnBoardSet.size() >= taxiCapacity) { + taxiFree = false; + } + if (!taxiFree) { + return false; + } else { + if (requestsOnBoard.size() == 0) { + long timeToNewRequest = travelTimeProvider.getTravelTime(vehicle, request.getFrom()); + if (timeToNewRequest <= request.getMaxPickupTime() * 1000) { + return true; + } + return false; + } + if (isWithTransfer(vehicle.getCurrentPlanNoUpdate())) { + // nekdo prestupuje + int indexLastTransferAction = findLastTransferActionIndex(vehicle.getCurrentPlanNoUpdate()); + long timeToFinishCurrentEdge = 0; + SimulationNode previousPos = vehicle.getPosition(); + if (vehicle.getCurrentTask() != null) { + timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(vehicle, vehicle.getCurrentTask().getPosition()); + previousPos = vehicle.getCurrentTask().getPosition(); + } + long timeToLastTransferAction = 0; + for (int q = 0; q < indexLastTransferAction + 1; q++) { + if (vehicle.getCurrentPlanNoUpdate().plan.get(q) instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) vehicle.getCurrentPlanNoUpdate().plan.get(q); + timeToLastTransferAction = timeToLastTransferAction + wait.getWaitTime(); + } else { + timeToLastTransferAction = timeToLastTransferAction + travelTimeProvider.getExpectedTravelTime(previousPos, vehicle.getCurrentPlanNoUpdate().plan.get(q).getPosition()); + } + previousPos = vehicle.getCurrentPlanNoUpdate().plan.get(q).getPosition(); + } + // ted potrebuju najit posledni pickup ve zbyvajicim driver planu po prestupu + List segmentAfterTransfer = vehicle.getCurrentPlanNoUpdate().plan.subList(indexLastTransferAction + 1, vehicle.getCurrentPlanNoUpdate().plan.size()); + int indexLastPickupSegment = findLastPickupIndexList(segmentAfterTransfer); + long timeToLastPickup = 0; + SimulationNode previousPos2 = vehicle.getCurrentPlanNoUpdate().plan.get(vehicle.getCurrentPlanNoUpdate().plan.size() - 1).getPosition(); + if (segmentAfterTransfer.size() > 0) { + previousPos2 = segmentAfterTransfer.get(0).getPosition(); + for (int q = 0; q < indexLastPickupSegment + 1; q++) { + timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos2, segmentAfterTransfer.get(q).getPosition()); + previousPos2 = segmentAfterTransfer.get(q).getPosition(); + } + } + + //odtud jestli muze dojet k requestu - tj. cas od mista kde skoncil k vyzvednuti requestu + long timeToNewRequest = travelTimeProvider.getExpectedTravelTime(previousPos2, request.getFrom()); + long estimatedArrival = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastTransferAction + timeToLastPickup + timeToNewRequest; + if (estimatedArrival <= request.getMaxPickupTime() * 1000) { + return true; + } else { + return false; + } + } else { + //neprestupuje nikdo + int indexLastPickup = findLastPickupIndex(vehicle.getCurrentPlanNoUpdate()); + long timeToFinishCurrentEdge = 0; + SimulationNode previousPos = vehicle.getPosition(); + if (vehicle.getCurrentTask() != null) { + timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(vehicle, vehicle.getCurrentTask().getPosition()); + previousPos = vehicle.getCurrentTask().getPosition(); + } + long timeToLastPickup = 0; + for (int q = 0; q < indexLastPickup + 1; q++) { + timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos, vehicle.getCurrentPlanNoUpdate().plan.get(q).getPosition()); + previousPos = vehicle.getCurrentPlanNoUpdate().plan.get(q).getPosition(); + } + long timeToNewRequest = travelTimeProvider.getExpectedTravelTime(previousPos, request.getFrom()); + long estimatedArrival = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastPickup + timeToNewRequest; + if (estimatedArrival <= request.getMaxPickupTime() * 1000) { + return true; + } else { + return false; + } + } + + } + } +} + diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java index 9b09a1e0..b8de5261 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java @@ -44,12 +44,6 @@ public class GreedyTASeTSolver extends DARPSolver implements EventHandler { private final OnDemandvehicleStationStorage onDemandvehicleStationStorage; - private final double maxDistance = 100; - - private final double maxDistanceSquared = 10000; - - private final int maxDelayTime = 10; - private List transferPoints; protected final DefaultPlanComputationRequest.DefaultPlanComputationRequestFactory requestFactory; @@ -910,12 +904,12 @@ else if (veh1.getCurrentTripPlan().getSize() > 0) { // pokud je kladny, tak to znamena ze prvni auto prijede drive nez druhe - bude cekat cestujici boolean valid = true; - // todo edit + // pridat wait i pro druhe auto tam, kde je rozdil mensi nez 5 s // aby tam byla rezerva - if (waitTime > 0 && waitTime < 5000) { - // ceka aspon 5 sekund - long newWait = 5000 - waitTime; + if (waitTime > 0 && waitTime < 2000) { + // ceka aspon 2 s + long newWait = 2000 - waitTime; PlanActionWait waitAction = new PlanActionWait(request, pickup.getPosition(), pickup.getMaxTime(), newWait); transferTime = newWait; itnryp2.add(indexPickupSecondCar, waitAction); @@ -994,7 +988,8 @@ else if (veh2.getCurrentTripPlan().getSize() > 0) { // pozor, pokud bych chtela smazat casovou rezervu 5 s, tak je tam nekde problem s wait akci s casem 0 // - tak na to by bylo potreba udelat zvlast podminku a nejaky minimalni wait time tam nastavit, aby bylo zajistene poradi pri pruchodu algoritmem if (waitTime <= 0) { - waitTime = waitTime - 5000; + // pridat 1000 je malo, ale 2000 dostacuje + waitTime = waitTime - 2000; //transfer time je -waitTime // pickup by nemel byt null protoze se nastavi v predeslem loopu assert pickup != null; diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/TransferPlan.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/TransferPlan.java index be378d2d..62974c40 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/TransferPlan.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/TransferPlan.java @@ -12,7 +12,7 @@ public class TransferPlan { public final long delay; public final Pair>, List> pair; - TransferPlan(long trasferTime, long delay, Pair>, List> pair) { + public TransferPlan(long trasferTime, long delay, Pair>, List> pair) { this.trasferTime = trasferTime; this.delay = delay; this.pair = pair; diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionWait.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionWait.java index 112df16e..5eab7c49 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionWait.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionWait.java @@ -6,12 +6,50 @@ public class PlanActionWait extends PlanRequestAction { protected long waitTime; + protected boolean waitingStarted = false; + protected long waitingStartedAt; + + protected boolean waitingPaused = false; + + protected long waitingPausedAt; + + public long getWaitingStartedAt() { + return waitingStartedAt; + } + + public void setWaitingStartedAt(long waitingStartedAt) { + this.waitingStartedAt = waitingStartedAt; + } public long getWaitTime(){ return waitTime; } + public boolean isWaitingStarted() { + return waitingStarted; + } + + public boolean isWaitingPaused() { + return waitingPaused; + } + + public void setWaitingPaused(boolean waitingPaused) { + this.waitingPaused = waitingPaused; + } + + public long getWaitingPausedAt() { + return waitingPausedAt; + } + + public void setWaitingPausedAt(long waitingPausedAt) { + this.waitingPausedAt = waitingPausedAt; + } + + public void setWaitingStarted(boolean waitingStarted) { + this.waitingStarted = waitingStarted; + } + public void setWaitTime(long waitTime) { this.waitTime = waitTime; } @@ -21,6 +59,7 @@ public void setWaitTime(long waitTime) { public PlanActionWait(PlanComputationRequest request, SimulationNode node, int maxTime, long waitTime) { super(request, node, maxTime); this.waitTime = waitTime; + this.waitingStarted = false; } diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanRequestAction.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanRequestAction.java index e86f588e..4b6c202d 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanRequestAction.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanRequestAction.java @@ -29,7 +29,7 @@ public abstract class PlanRequestAction extends PlanAction{ /** * Time constraint in seconds */ - private final int maxTime; + private int maxTime; public PlanComputationRequest getRequest() { return request; @@ -42,6 +42,10 @@ public PlanComputationRequest getRequest() { public int getMaxTime() { return maxTime; } + + public void setMaxTime(int maxTime) { + this.maxTime = maxTime; + } diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java new file mode 100644 index 00000000..15af55fa --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java @@ -0,0 +1,728 @@ +package cz.cvut.fel.aic.simod.ridesharing.transferinsertion; + +import com.google.inject.Inject; +import com.google.inject.Singleton; +import cz.cvut.fel.aic.agentpolis.config.AgentpolisConfig; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.TimeProvider; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.AgentPolisEntity; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.agentpolis.utils.PositionUtil; +import cz.cvut.fel.aic.alite.common.event.Event; +import cz.cvut.fel.aic.alite.common.event.EventHandler; +import cz.cvut.fel.aic.alite.common.event.EventProcessor; +import cz.cvut.fel.aic.alite.common.event.typed.TypedSimulation; +import cz.cvut.fel.aic.simod.config.SimodConfig; +import cz.cvut.fel.aic.simod.event.OnDemandVehicleEvent; +import cz.cvut.fel.aic.simod.ridesharing.DARPSolver; +import cz.cvut.fel.aic.simod.ridesharing.DroppedDemandsAnalyzer; +import cz.cvut.fel.aic.simod.ridesharing.PlanCostProvider; +import cz.cvut.fel.aic.simod.ridesharing.RideSharingOnDemandVehicle; +import cz.cvut.fel.aic.simod.ridesharing.greedyTASeT.TransferPlan; +import cz.cvut.fel.aic.simod.ridesharing.insertionheuristic.DriverPlan; +import cz.cvut.fel.aic.simod.ridesharing.model.*; +import cz.cvut.fel.aic.simod.storage.OnDemandVehicleStorage; +import cz.cvut.fel.aic.simod.storage.OnDemandvehicleStationStorage; +import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider; +import org.jgrapht.alg.util.Pair; + +import java.awt.image.AreaAveragingScaleFilter; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +@Singleton +public class TransferInsertionSolver extends DARPSolver implements EventHandler { + + private final TypedSimulation eventProcessor; + + private final SimodConfig config; + + private final TimeProvider timeProvider; + + private final PositionUtil positionUtil; + + private final DroppedDemandsAnalyzer droppedDemandsAnalyzer; + + private final OnDemandvehicleStationStorage onDemandvehicleStationStorage; + + + private List transferPoints; + + protected final DefaultPlanComputationRequest.DefaultPlanComputationRequestFactory requestFactory; + + private Map planMap; + + + @Inject + public TransferInsertionSolver( + OnDemandVehicleStorage vehicleStorage, + TravelTimeProvider travelTimeProvider, + PlanCostProvider travelCostProvider, + DefaultPlanComputationRequest.DefaultPlanComputationRequestFactory requestFactory, + TypedSimulation eventProcessor, + SimodConfig config, + TimeProvider timeProvider, + PositionUtil positionUtil, + DroppedDemandsAnalyzer droppedDemandsAnalyzer, + OnDemandvehicleStationStorage onDemandvehicleStationStorage, + AgentpolisConfig agentpolisConfig) { + + super(vehicleStorage, travelTimeProvider, travelCostProvider, requestFactory); + this.eventProcessor = eventProcessor; + this.config = config; + this.timeProvider = timeProvider; + this.positionUtil = positionUtil; + this.droppedDemandsAnalyzer = droppedDemandsAnalyzer; + this.onDemandvehicleStationStorage = onDemandvehicleStationStorage; + this.requestFactory = requestFactory; + + setEventHandeling(); + } + + public void setTransferPoints(List transferPoints) { + this.transferPoints = transferPoints; + } + + @Override + public EventProcessor getEventProcessor() { + return eventProcessor; + } + + @Override + public void handleEvent(Event event) { + + } + + private void setEventHandeling() { + List typesToHandle = new LinkedList<>(); + + typesToHandle.add(OnDemandVehicleEvent.PICKUP); + eventProcessor.addEventHandler(this, typesToHandle); + } + + @Override + public Map solve(List newRequests, List waitingRequests) { + + // nacist taxiky + List taxis = new ArrayList<>(); + for(AgentPolisEntity tVvehicle: vehicleStorage.getEntitiesForIteration()) { + RideSharingOnDemandVehicle vehicle = (RideSharingOnDemandVehicle) tVvehicle; + taxis.add(vehicle); + } + // nacist requesty + List requests = new ArrayList<>(newRequests); + + // ke kazdemu requestu priradit auta, ktera k nemu mohou dojet vcas + int[] possiblePickupTaxisCounts = new int[requests.size()]; + int i = 0; + Map> possiblePickupTaxisMap = new HashMap<>(); + for(PlanComputationRequest request : requests) { + int counter = 0; + List possiblePickupTaxisOneRequest = new ArrayList<>(); + for(RideSharingOnDemandVehicle t : taxis) { + if (canPickupRequestInTime(t, request)) { + counter++; + possiblePickupTaxisOneRequest.add(t); + } + } + possiblePickupTaxisCounts[i] = counter; + possiblePickupTaxisMap.put(request, possiblePickupTaxisOneRequest); + i++; + } + + //sort R by the number of possible pickup taxis + List requestsCopy = new ArrayList<>(requests); + requests.sort(Comparator.comparing(x -> possiblePickupTaxisCounts[requestsCopy.indexOf(x)])); + //order to descending order + Collections.reverse(requests); + + planMap = new ConcurrentHashMap<>(); + + // zkusim najit plan bez prestupu + for (PlanComputationRequest request : requests) { + List>, List>> itinerariesPairs = new ArrayList<>(); + List canPickupRequestTaxis = possiblePickupTaxisMap.get(request); + List delays = new ArrayList<>(); + List waitTimes = new ArrayList<>(); + + long minimalTravelTime = travelTimeProvider.getExpectedTravelTime(request.getFrom(), request.getTo()); + for (RideSharingOnDemandVehicle taxi : canPickupRequestTaxis) { + List positnry = findItineraryBestInsertion(request.getPickUpAction(), request.getDropOffAction(), taxi); + if (positnry != null) { + // pridat plan do nejakeho seznamu vsech validnich planu + Long dropoffTime = getDropoffTimeForRequest(positnry, taxi, request); + if (dropoffTime == null) { + // chyba + continue; + } + delays.add(dropoffTime - timeProvider.getCurrentSimTime() - minimalTravelTime); + waitTimes.add((long) Long.MAX_VALUE); + List> listItinerary = new ArrayList<>(); + listItinerary.add(positnry); + List vehicles = new ArrayList<>(); + vehicles.add(taxi); + itinerariesPairs.add(new Pair<>(listItinerary, vehicles)); + } + + for (SimulationNode station : transferPoints) { + if (timeProvider.getCurrentSimTime() + travelTimeProvider.getTravelTime(taxi, request.getFrom()) + travelTimeProvider.getExpectedTravelTime(request.getFrom(), station) > + request.getMaxDropoffTime() * 1000 - travelTimeProvider.getExpectedTravelTime(station, request.getTo())) { + continue; + } + // najit auta, do kterych je mozne prestoupit + for (int k = 0; k < taxis.size(); k++) { + if (taxi.equals(taxis.get(k))) { + continue; + } else if (station == request.getTo()) { + continue; + } else if (station == request.getFrom()) { + continue; + } else if (timeProvider.getCurrentSimTime() + travelTimeProvider.getTravelTime(taxis.get(k), station) > + request.getMaxDropoffTime() * 1000 - travelTimeProvider.getExpectedTravelTime(station, request.getTo())) { + continue; + } else { + int maxDropOffTime = request.getMaxDropoffTime() - (int) Math.round(travelTimeProvider.getExpectedTravelTime(station, request.getTo()) / 1000.0); + + // todo: mozna u dropoff akce upravit max time o dve sekundy driv? + PlanActionDropoffTransfer dropoffActionTransfer = new PlanActionDropoffTransfer(request, station, maxDropOffTime); + PlanActionPickupTransfer pickupActionTransfer = new PlanActionPickupTransfer(request, station, maxDropOffTime); + + //vytvorim plan pro prvni usek cesty + List itnryp1 = findItineraryBestInsertion(request.getPickUpAction(), dropoffActionTransfer, taxi); + if (itnryp1 == null) { + continue; + } + Long dropTime = getDropoffTimeForRequest(itnryp1, taxi, request); + + //vytvorim plan pro druhy usek cesty + List itnryp2 = findTransferItineraryBestInsertion(pickupActionTransfer, request.getDropOffAction(), taxis.get(k), dropTime); + if (itnryp2 == null) { + continue; + } + int maxTransferTime = countMaxTimeTransfer(itnryp1, taxi, itnryp2, taxis.get(k), request); + + for (PlanAction action : itnryp1) { + if (action.equals(dropoffActionTransfer)) { + ((PlanActionDropoffTransfer)action).setMaxTime(maxTransferTime); + } + } + + Long dropoffTime = getDropoffTimeForRequest(itnryp2, taxis.get(k), request); + if (dropoffTime == null) { + // chyba + continue; + } + delays.add(dropoffTime - timeProvider.getCurrentSimTime() - minimalTravelTime); + + long waitTime = getWaitTimeForRequest(itnryp2, request); + waitTimes.add(waitTime); + + List> listItinerary = new ArrayList<>(); + listItinerary.add(itnryp1); + listItinerary.add(itnryp2); + List vehicles = new ArrayList<>(); + vehicles.add(taxi); + vehicles.add(taxis.get(k)); + itinerariesPairs.add(new Pair<>(listItinerary, vehicles)); + + } + } + } + } + + // vyberu nejlepsi a dam ho do mapy + // ted budu chtit plany seradit podle delay + // vyberu z nich treba 20 % + // ty dale seradim podle waitTime + // budu se snazit vybrat takove, co maji wait time 0 a vetsi (uplatnuji prestup), + // pokud zadne takove nebudou, vezmu i ty s wait Time -1 (to jsou ty bez prestupu) + + List transferPlans = new ArrayList<>(); + for (int j = 0; j < itinerariesPairs.size(); j++) { + TransferPlan t = new TransferPlan(waitTimes.get(j), delays.get(j), itinerariesPairs.get(j)); + transferPlans.add(t); + } + transferPlans.sort(TransferPlan::compareByDelay); + //vezmu hornich beta procent + double beta = 0.2; + int numOfTaken = (int) (delays.size() * beta); + if (numOfTaken == 0) { + numOfTaken = 1; + } + List sublistTransferPlans = new ArrayList<>(); + for (int q = 0; q < numOfTaken; q++) + { + if(!transferPlans.isEmpty()) { + sublistTransferPlans.add(transferPlans.get(q)); + } + } + sublistTransferPlans.sort(TransferPlan::compareByTransferTime); + + + if (!sublistTransferPlans.isEmpty()) { + Pair>, List> key = sublistTransferPlans.get(0).pair; + List> plansForVehicles = key.getFirst(); + List vehicles = key.getSecond(); + for (int q = 0; q < vehicles.size(); q++) { + List vehPlan = plansForVehicles.get(q); +// List planWithPos = new ArrayList<>(); +// planWithPos.add(vehicles.get(q).getCurrentPlanNoUpdate().plan.get(0)); +// planWithPos.addAll(vehPlan); + DriverPlan dp = new DriverPlan(vehPlan, 0, 0); + planMap.put(vehicles.get(q), dp); + } + +// DriverPlan newPlan = new DriverPlan(s.get(0).getFirst().get(0), 0, 0); +// planMap.put(itinerariesPairs.get(0).getSecond().get(0), newPlan); + } + } + + + // jak hledat plan bez prestupu? + // v planu nikdo neprestupuje - provedu insertion metodu + // v planu prestupuje, ale je to prvni cast - provedu insertion metodu, ale musim mit spravne nastaveny maxTime dropoffTransfer akce + // v planu prestupuje, ale je to druhy usek - muzu zkusit udelat to same, ale nesmim prekrocit maxTime u pickupTransfer akce + + // potom budu hledat stanice ve kterych je mozne prestoupit + // zkusim vytvorit prestupni plan + // prvni usek budu vytvaret uplne stejne jako je hledani planu bez prestupu + // zjistim cas prijezdu auta na stanici s prestupujicim cestujicim + // na druhy usek vyzkousim vsechny moznosti kam akce zaradit + // do planu pridam waitAkci - spocitam cas prijezdu druheho auta na stanici a cas dorovnam wait akci, aby to sedelo + // nastavim maxTransferTime + // zkontroluju jestli je plan validni, nevalidni plany zahodim + // z validnich planu vyberu ten, co bude mit nejmensi zpozdeni + // zkombinuji tyto dva plany ? + + // ze vsech planu vyberu nekolik s nejmensim delay + + // budu chtit uprednostnit plany s prestupem + + // zaroven ale budu vybirat takove plany, co maji kratky wait time, aby auta zbytecne nestala ve stanici + + return planMap; + } + + + + + + + + + public List findItineraryBestInsertion(PlanAction pickup, PlanAction dropoff, RideSharingOnDemandVehicle vehicle) { + DriverPlan currentVehiclePlan; + if (planMap.containsKey(vehicle)) { + currentVehiclePlan = planMap.get(vehicle); + } else { + currentVehiclePlan = vehicle.getCurrentPlanNoUpdate(); + } + List> allPosibleActionsOrder = new ArrayList<>(); + List planDurations = new ArrayList<>(); + + for (int i = 1; i < currentVehiclePlan.plan.size()+1; i++) { + for (int j = i+1; j < currentVehiclePlan.plan.size()+2; j++) { + List tempPlan = new ArrayList<>(currentVehiclePlan.plan); + tempPlan.add(i, pickup); + tempPlan.add(j, dropoff); + Pair p = checkValidItineraryAndCountPlanDuration(tempPlan, vehicle); + if (p.getFirst()) { + if (checkCapacityNotExceeded(tempPlan, vehicle)) { + allPosibleActionsOrder.add(tempPlan); + planDurations.add(p.getSecond()); + } + } + } + } + + if (allPosibleActionsOrder.isEmpty()) { + return null; + } + + int minIndex = planDurations.indexOf(Collections.min(planDurations)); + List selectedPlan = allPosibleActionsOrder.get(minIndex); + + return selectedPlan; + } + + public List findTransferItineraryBestInsertion(PlanAction pickup, PlanAction dropoff, RideSharingOnDemandVehicle vehicle, Long arrivalToStationForVeh1) { + DriverPlan currentVehiclePlan; + if (planMap.containsKey(vehicle)) { + currentVehiclePlan = planMap.get(vehicle); + } else { + currentVehiclePlan = vehicle.getCurrentPlanNoUpdate(); + } + List> allPosibleActionsOrder = new ArrayList<>(); + List planDurations = new ArrayList<>(); + + for (int i = 1; i < currentVehiclePlan.plan.size()+1; i++) { + for (int j = i+1; j < currentVehiclePlan.plan.size()+2; j++) { + List tempPlan = new ArrayList<>(currentVehiclePlan.plan); + tempPlan.add(i, pickup); + tempPlan.add(j, dropoff); + Long arrivalTime = getArrivalTimeToStation(tempPlan, vehicle, ((PlanRequestAction)pickup).request); + assert arrivalTime != null; + long waitTime = arrivalToStationForVeh1 - arrivalTime; +// int waitTime = (int) (Math.round(arrivalToStationForVeh1 / 1000.0) - Math.round(arrivalTime / 1000.0)); + if (waitTime >= 0) { + waitTime += 3000; + PlanActionWait waitAction = new PlanActionWait(((PlanRequestAction)pickup).request, pickup.getPosition(), ((PlanRequestAction) pickup).getMaxTime(), waitTime); + tempPlan.add(i, waitAction); + } + else if (waitTime < 0 && waitTime > -3000) { + waitTime -= 3000; + PlanActionWait waitAction = new PlanActionWait(((PlanRequestAction)pickup).request, pickup.getPosition(), ((PlanRequestAction) pickup).getMaxTime(), -waitTime); + tempPlan.add(i, waitAction); + } + Pair p = checkValidItineraryAndCountPlanDuration(tempPlan, vehicle); + if (p.getFirst()) { + if (checkCapacityNotExceeded(tempPlan, vehicle)) { + allPosibleActionsOrder.add(tempPlan); + planDurations.add(p.getSecond()); + } + } + } + } + + if (allPosibleActionsOrder.isEmpty()) { + return null; + } + + int minIndex = planDurations.indexOf(Collections.min(planDurations)); + List selectedPlan = allPosibleActionsOrder.get(minIndex); + + return selectedPlan; + } + + public long getWaitTimeForRequest(List itinerary, PlanComputationRequest request) { + for (PlanAction action : itinerary) { + if (action instanceof PlanActionWait) { + if (((PlanActionWait) action).request == request) { + return ((PlanActionWait) action).getWaitTime(); + } + } + } + return 0; + } + + public int countMaxTimeTransfer(List itnryp1, RideSharingOnDemandVehicle veh1, List itnryp2, RideSharingOnDemandVehicle veh2, PlanComputationRequest request) { + boolean isWaitInItnryp2 = false; + for (PlanAction action : itnryp2) { + if (action instanceof PlanActionWait) { + if (((PlanActionWait) action).request == request) { + isWaitInItnryp2 = true; + } + } + } + if (isWaitInItnryp2) { + Long dropTime = getDropoffTimeForRequest(itnryp1, veh1, request); + int time = (int) Math.round(dropTime / 1000.0); + return time; + } else { + Long dropTime = getArrivalTimeToStation(itnryp2, veh2, request); + int time = (int) Math.round(dropTime / 1000.0); + return time - 2; + } + } + + public boolean canPickupRequestInTime(RideSharingOnDemandVehicle vehicle, PlanComputationRequest request) { + // cas prijezdu auta k pickup pozici je mensi nez maxPickupTime requestu + long time = timeProvider.getCurrentSimTime(); + long timeToFinishEdge = 0; + SimulationNode previousDestination = vehicle.getPosition(); + + // podivam se na current trip plan a spocitam cas potrebny na dokonceni cesty po aktualni hrane + if (vehicle.getCurrentTripPlan() != null) { + if (vehicle.getCurrentTripPlan().getSize() == 0) { + SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getLastLocation(); + // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu + // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu + timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, stopLoc); + previousDestination = stopLoc; + } + else if (vehicle.getCurrentTripPlan().getSize() > 0) { + SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getFirstLocation(); + SimulationNode currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[0]; + boolean currLocIsVehiclePosition = false; + int curridx = 0; + while (currLoc != stopLoc) { + if (currLocIsVehiclePosition) { + timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, currLoc); + } + if (currLoc == vehicle.getPosition()) { + currLocIsVehiclePosition = true; + } + previousDestination = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx]; + curridx++; + currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx]; + } + } + } + time += timeToFinishEdge; + + long timeToNewPickup = travelTimeProvider.getExpectedTravelTime(previousDestination, request.getFrom()); + time += timeToNewPickup; + + if (!(time > request.getMaxPickupTime() * 1000)) { + return true; + } + return false; + + } + + private boolean checkCapacityNotExceeded(List itinerary, RideSharingOnDemandVehicle vehicle) { + int freeCapacity = vehicle.getFreeCapacity(); + for (PlanAction action : itinerary) { + if (action instanceof PlanActionPickup || action instanceof PlanActionPickupTransfer) { + freeCapacity -= 1; + if (freeCapacity < 0) { + return false; + } + } + else if (action instanceof PlanActionDropoff || action instanceof PlanActionDropoffTransfer) { + freeCapacity += 1; + } + } + return true; + } + + private Pair checkValidItineraryAndCountPlanDuration(List itinerary, RideSharingOnDemandVehicle vehicle) { + SimulationNode previousDestination; + boolean ret = true; + long time = timeProvider.getCurrentSimTime(); + long timeToFinishEdge = 0; + previousDestination = vehicle.getPosition(); + + // podivam se na current trip plan a spocitam cas potrebny na dokonceni cesty po aktualni hrane + if (vehicle.getCurrentTripPlan() != null) { + if (vehicle.getCurrentTripPlan().getSize() == 0) { + SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getLastLocation(); + // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu + // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu + timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, stopLoc); + previousDestination = stopLoc; + } + else if (vehicle.getCurrentTripPlan().getSize() > 0) { + SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getFirstLocation(); + SimulationNode currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[0]; + boolean currLocIsVehiclePosition = false; + int curridx = 0; + while (currLoc != stopLoc) { + if (currLocIsVehiclePosition) { + timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, currLoc); + } + if (currLoc == vehicle.getPosition()) { + currLocIsVehiclePosition = true; + } + previousDestination = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx]; + curridx++; + currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx]; + } + } + } + time += timeToFinishEdge; + + for (PlanAction action : itinerary) { + if (action instanceof PlanRequestAction) { + PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); + if (action instanceof PlanActionPickup) { + SimulationNode dest = pcq.getFrom(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (!(time < pcq.getMaxPickupTime() * 1000)) { + ret = false; + break; + } + previousDestination = dest; + } else if(action instanceof PlanActionPickupTransfer) { + PlanActionPickupTransfer pickupTransfer = (PlanActionPickupTransfer) action; + SimulationNode dest = pickupTransfer.getPosition(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (!(time < pickupTransfer.getMaxTime() * 1000)) { + ret = false; + break; + } + previousDestination = dest; + } else if(action instanceof PlanActionDropoffTransfer) { + PlanActionDropoffTransfer dropoffTransfer = (PlanActionDropoffTransfer) action; + SimulationNode dest = dropoffTransfer.getPosition(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (!(time < dropoffTransfer.getMaxTime() * 1000)) { + ret = false; + break; + } + previousDestination = dest; + } else if (action instanceof PlanActionDropoff) { + SimulationNode dest = pcq.getTo(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (!(time < pcq.getMaxDropoffTime() * 1000)) { + ret = false; + break; + } + previousDestination = dest; + } else if (action instanceof PlanActionWait) { + SimulationNode dest = action.getPosition(); + PlanActionWait wait = (PlanActionWait) action; + if (!(wait.isWaitingStarted())) { + time = time + wait.getWaitTime(); + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = action.getPosition(); + } else { + long substract; + long waitTime; + if (wait.isWaitingPaused()) { + substract = wait.getWaitingPausedAt() - wait.getWaitingStartedAt(); + waitTime = wait.getWaitTime() - substract; + } else { + waitTime = wait.getWaitTime() - (timeProvider.getCurrentSimTime() - wait.getWaitingStartedAt()); + + } + time = time + waitTime; + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = action.getPosition(); + } + } + } + } + Pair p = new Pair<>(ret, time); + return p; + } + + private Long getDropoffTimeForRequest(List itinerary, RideSharingOnDemandVehicle vehicle, PlanComputationRequest request) { + long time = timeProvider.getCurrentSimTime(); + long timeToFinishEdge = 0; + SimulationNode previousDestination = vehicle.getPosition(); + if (vehicle.getCurrentTripPlan() != null) { + if (vehicle.getCurrentTripPlan().getSize() == 0) { + SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getLastLocation(); + timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, stopLoc); + previousDestination = stopLoc; + } + else if (vehicle.getCurrentTripPlan().getSize() > 0) { + SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getFirstLocation(); + SimulationNode currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[0]; + boolean currLocIsVehiclePosition = false; + int curridx = 0; + while (currLoc != stopLoc) { + if (currLocIsVehiclePosition) { + timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, currLoc); + } + if (currLoc == vehicle.getPosition()) { + currLocIsVehiclePosition = true; + } + previousDestination = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx]; + curridx++; + currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx]; + } + } + } + time = time + timeToFinishEdge; + + for (PlanAction action : itinerary) { + if (action instanceof PlanActionPickup || action instanceof PlanActionPickupTransfer) { + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, action.getPosition()); + previousDestination = action.getPosition(); + } else if (action instanceof PlanActionDropoff || action instanceof PlanActionDropoffTransfer) { + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, action.getPosition()); + if (((PlanRequestAction) action).getRequest() == request) { + return time; + } + + previousDestination = action.getPosition(); + } else if (action instanceof PlanActionWait) { + SimulationNode dest = action.getPosition(); + PlanActionWait wait = (PlanActionWait) action; + if (!(wait.isWaitingStarted())) { + time = time + wait.getWaitTime(); + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = action.getPosition(); + } else { + long substract; + long waitTime; + if (wait.isWaitingPaused()) { + substract = wait.getWaitingPausedAt() - wait.getWaitingStartedAt(); + waitTime = wait.getWaitTime() - substract; + } else { + waitTime = wait.getWaitTime() - (timeProvider.getCurrentSimTime() - wait.getWaitingStartedAt()); + + } + time = time + waitTime; + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = action.getPosition(); + } + } + + } + return null; + } + + private Long getArrivalTimeToStation(List itinerary, RideSharingOnDemandVehicle vehicle, PlanComputationRequest request) { + long time = timeProvider.getCurrentSimTime(); + long timeToFinishEdge = 0; + SimulationNode previousDestination = vehicle.getPosition(); + if (vehicle.getCurrentTripPlan() != null) { + if (vehicle.getCurrentTripPlan().getSize() == 0) { + SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getLastLocation(); + timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, stopLoc); + previousDestination = stopLoc; + } + else if (vehicle.getCurrentTripPlan().getSize() > 0) { + SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getFirstLocation(); + SimulationNode currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[0]; + boolean currLocIsVehiclePosition = false; + int curridx = 0; + while (currLoc != stopLoc) { + if (currLocIsVehiclePosition) { + timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, currLoc); + } + if (currLoc == vehicle.getPosition()) { + currLocIsVehiclePosition = true; + } + previousDestination = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx]; + curridx++; + currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx]; + } + } + } + time = time + timeToFinishEdge; + + for (PlanAction action : itinerary) { + if (action instanceof PlanActionPickup || action instanceof PlanActionPickupTransfer) { + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, action.getPosition()); + if (((PlanRequestAction) action).getRequest() == request) { + return time; + } + previousDestination = action.getPosition(); + } else if (action instanceof PlanActionDropoff || action instanceof PlanActionDropoffTransfer) { + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, action.getPosition()); + previousDestination = action.getPosition(); + } else if (action instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) action; + SimulationNode dest = action.getPosition(); + if (!(wait.isWaitingStarted())) { + time = time + wait.getWaitTime(); + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = action.getPosition(); + } else { + // aktivita uz zacala + // podivam se jestli uz je i pauznuta + // odectu uz odcekany cas + long substract; + long waitTime; + if (wait.isWaitingPaused()) { + substract = wait.getWaitingPausedAt() - wait.getWaitingStartedAt(); + waitTime = wait.getWaitTime() - substract; + } else { + waitTime = wait.getWaitTime() - (timeProvider.getCurrentSimTime() - wait.getWaitingStartedAt()); + + } + time = time + waitTime; + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = action.getPosition(); + } + } + + } + return null; + } + + +} diff --git a/src/test/java/cz/cvut/fel/aic/simod/system/TestOnDemandVehicle.java b/src/test/java/cz/cvut/fel/aic/simod/system/TestOnDemandVehicle.java index ecec74f8..7789879c 100644 --- a/src/test/java/cz/cvut/fel/aic/simod/system/TestOnDemandVehicle.java +++ b/src/test/java/cz/cvut/fel/aic/simod/system/TestOnDemandVehicle.java @@ -32,6 +32,7 @@ import cz.cvut.fel.aic.alite.common.event.EventProcessor; import cz.cvut.fel.aic.simod.StationsDispatcher; import cz.cvut.fel.aic.simod.WaitTransferActivityFactory; +import cz.cvut.fel.aic.simod.WaitWithStopActivityFactory; import cz.cvut.fel.aic.simod.config.SimodConfig; import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicle; import cz.cvut.fel.aic.simod.storage.PhysicalTransportVehicleStorage; @@ -56,7 +57,7 @@ public TestOnDemandVehicle( SimodConfig config, IdGenerator idGenerator, AgentpolisConfig agentpolisConfig, - WaitTransferActivityFactory waitTransferActivityFactory, + WaitWithStopActivityFactory waitWithStopActivityFactory, WaitActivityFactory waitActivityFactory, @Assisted String vehicleId, @Assisted SimulationNode startPosition) { @@ -71,7 +72,7 @@ public TestOnDemandVehicle( config, idGenerator, agentpolisConfig, - waitTransferActivityFactory, + waitWithStopActivityFactory, waitActivityFactory, vehicleId, startPosition); diff --git a/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java b/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java index 19798b6a..b0b84bfb 100644 --- a/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java +++ b/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java @@ -24,6 +24,8 @@ import cz.cvut.fel.aic.geographtools.util.Transformer; import cz.cvut.fel.aic.simod.DriveToTransferStationActivityFactory; import cz.cvut.fel.aic.simod.WaitTransferActivityFactory; +import cz.cvut.fel.aic.simod.WaitWithStop; +import cz.cvut.fel.aic.simod.WaitWithStopActivityFactory; import cz.cvut.fel.aic.simod.config.SimodConfig; import cz.cvut.fel.aic.simod.entity.DemandAgent; import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicle; @@ -109,7 +111,7 @@ public long getCurrentSimTime() { // start position of 1st vehicle SimulationNode startPos = graph.getNode(6); // top left corner - WaitTransferActivityFactory waitTransferActivityFactory = new WaitTransferActivityFactory(); + WaitWithStopActivityFactory waitWithStopActivityFactory = new WaitWithStopActivityFactory(); WaitActivityFactory waitActivityFactory = new WaitActivityFactory(); DriveToTransferStationActivityFactory driveToTransferStationActivityFactory = null; @@ -126,7 +128,7 @@ public long getCurrentSimTime() { simodConfig, idGenerator3, agentpolisConfig, - waitTransferActivityFactory, + waitWithStopActivityFactory, waitActivityFactory, null, "1", @@ -145,7 +147,7 @@ public long getCurrentSimTime() { simodConfig, idGenerator3, agentpolisConfig, - waitTransferActivityFactory, + waitWithStopActivityFactory, waitActivityFactory, null, "2", From 10176a02c360461382774c8fe4ead1f802c92879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kub=C3=ADkov=C3=A1=2C=20Ad=C3=A9la?= Date: Wed, 4 May 2022 20:04:45 +0200 Subject: [PATCH 11/21] Add ceil/floor rounding for time computation in TransferInsertionSolver --- .../TransferInsertionSolver.java | 579 +++++++++++++++++- 1 file changed, 554 insertions(+), 25 deletions(-) diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java index 15af55fa..533c05b8 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java @@ -155,7 +155,7 @@ public Map solve(List> listItinerary = new ArrayList<>(); listItinerary.add(positnry); List vehicles = new ArrayList<>(); @@ -182,36 +182,61 @@ public Map solve(List itnryp1 = findItineraryBestInsertion(request.getPickUpAction(), dropoffActionTransfer, taxi); + // TODO prvni usek = ceil + List itnryp1 = findItineraryBestInsertionFirstSegment(request.getPickUpAction(), dropoffActionTransfer, taxi); if (itnryp1 == null) { continue; } - Long dropTime = getDropoffTimeForRequest(itnryp1, taxi, request); + Integer dropTime = getDropoffTimeForRequestFirstSegment(itnryp1, taxi, request); - //vytvorim plan pro druhy usek cesty - List itnryp2 = findTransferItineraryBestInsertion(pickupActionTransfer, request.getDropOffAction(), taxis.get(k), dropTime); + //vytvorim plan pro prvni usek cesty +// List itnryp1 = findItineraryBestInsertion(request.getPickUpAction(), dropoffActionTransfer, taxi); +// if (itnryp1 == null) { +// continue; +// } +// Long dropTime = getDropoffTimeForRequest(itnryp1, taxi, request); + + // TODO druhy usek = floor + List itnryp2 = findTransferItineraryBestInsertionSecondSegment(pickupActionTransfer, request.getDropOffAction(), taxis.get(k), dropTime); if (itnryp2 == null) { continue; } - int maxTransferTime = countMaxTimeTransfer(itnryp1, taxi, itnryp2, taxis.get(k), request); - + int maxTransferTime = countMaxTimeTransferRound(itnryp1, taxi, itnryp2, taxis.get(k), request); for (PlanAction action : itnryp1) { if (action.equals(dropoffActionTransfer)) { ((PlanActionDropoffTransfer)action).setMaxTime(maxTransferTime); } } - - Long dropoffTime = getDropoffTimeForRequest(itnryp2, taxis.get(k), request); + Integer dropoffTime = getDropoffTimeForRequestFirstSegment(itnryp2, taxis.get(k), request); if (dropoffTime == null) { // chyba continue; } - delays.add(dropoffTime - timeProvider.getCurrentSimTime() - minimalTravelTime); + delays.add(dropoffTime * 1000 - timeProvider.getCurrentSimTime() - minimalTravelTime); + + + //vytvorim plan pro druhy usek cesty +// List itnryp2 = findTransferItineraryBestInsertion(pickupActionTransfer, request.getDropOffAction(), taxis.get(k), dropTime); +// if (itnryp2 == null) { +// continue; +// } +// int maxTransferTime = countMaxTimeTransfer(itnryp1, taxi, itnryp2, taxis.get(k), request); +// +// for (PlanAction action : itnryp1) { +// if (action.equals(dropoffActionTransfer)) { +// ((PlanActionDropoffTransfer)action).setMaxTime(maxTransferTime); +// } +// } +// +// Long dropoffTime = getDropoffTimeForRequest(itnryp2, taxis.get(k), request); +// if (dropoffTime == null) { +// // chyba +// continue; +// } +// delays.add(dropoffTime - timeProvider.getCurrentSimTime() - minimalTravelTime); long waitTime = getWaitTimeForRequest(itnryp2, request); waitTimes.add(waitTime); @@ -236,15 +261,27 @@ public Map solve(List transferPlans = new ArrayList<>(); +// for (int j = 0; j < itinerariesPairs.size(); j++) { +// TransferPlan t = new TransferPlan(waitTimes.get(j), delays.get(j), itinerariesPairs.get(j)); +// transferPlans.add(t); +// } + List transferPlans = new ArrayList<>(); for (int j = 0; j < itinerariesPairs.size(); j++) { - TransferPlan t = new TransferPlan(waitTimes.get(j), delays.get(j), itinerariesPairs.get(j)); - transferPlans.add(t); + if (waitTimes.get(j) != Long.MAX_VALUE && waitTimes.get(j) > 10000) { + + } else { + TransferPlan t = new TransferPlan(waitTimes.get(j), delays.get(j), itinerariesPairs.get(j)); + transferPlans.add(t); + } } - transferPlans.sort(TransferPlan::compareByDelay); - //vezmu hornich beta procent + + +// verze1 + transferPlans.sort(TransferPlan::compareByTransferTime); double beta = 0.2; - int numOfTaken = (int) (delays.size() * beta); + int numOfTaken = (int) (transferPlans.size() * beta); if (numOfTaken == 0) { numOfTaken = 1; } @@ -255,7 +292,7 @@ public Map solve(List solve(List findItineraryBestInsertionFirstSegment(PlanAction pickup, PlanAction dropoff, RideSharingOnDemandVehicle vehicle) { + DriverPlan currentVehiclePlan; + if (planMap.containsKey(vehicle)) { + currentVehiclePlan = planMap.get(vehicle); + } else { + currentVehiclePlan = vehicle.getCurrentPlanNoUpdate(); + } + List> allPosibleActionsOrder = new ArrayList<>(); + List planDurations = new ArrayList<>(); + + for (int i = 1; i < currentVehiclePlan.plan.size()+1; i++) { + for (int j = i+1; j < currentVehiclePlan.plan.size()+2; j++) { + List tempPlan = new ArrayList<>(currentVehiclePlan.plan); + tempPlan.add(i, pickup); + tempPlan.add(j, dropoff); + Pair p = checkValidItineraryAndCountPlanDurationFirstPart(tempPlan, vehicle); + if (p.getFirst()) { + if (checkCapacityNotExceeded(tempPlan, vehicle)) { + allPosibleActionsOrder.add(tempPlan); + planDurations.add(p.getSecond()); + } + } + } + } + + if (allPosibleActionsOrder.isEmpty()) { + return null; + } + + int minIndex = planDurations.indexOf(Collections.min(planDurations)); + List selectedPlan = allPosibleActionsOrder.get(minIndex); + + return selectedPlan; + } + + public List findTransferItineraryBestInsertionSecondSegment(PlanAction pickup, PlanAction dropoff, RideSharingOnDemandVehicle vehicle, int arrivalToStationForVeh1) { + DriverPlan currentVehiclePlan; + if (planMap.containsKey(vehicle)) { + currentVehiclePlan = planMap.get(vehicle); + } else { + currentVehiclePlan = vehicle.getCurrentPlanNoUpdate(); + } + List> allPosibleActionsOrder = new ArrayList<>(); + List planDurations = new ArrayList<>(); + + for (int i = 1; i < currentVehiclePlan.plan.size()+1; i++) { + for (int j = i+1; j < currentVehiclePlan.plan.size()+2; j++) { + List tempPlan = new ArrayList<>(currentVehiclePlan.plan); + tempPlan.add(i, pickup); + tempPlan.add(j, dropoff); + Integer arrivalTime = getArrivalTimeToStationIntFloor(tempPlan, vehicle, ((PlanRequestAction)pickup).request); + assert arrivalTime != null; + int waitTime = arrivalToStationForVeh1 - arrivalTime; + // wait time budu mit v sekundach + if (waitTime > 0) { +// waitTime += 3000; + PlanActionWait waitAction = new PlanActionWait(((PlanRequestAction)pickup).request, pickup.getPosition(), ((PlanRequestAction) pickup).getMaxTime(), waitTime * 1000); + tempPlan.add(i, waitAction); + } +// else if (waitTime < 0 && waitTime > -3000) { +// waitTime -= 3000; +// PlanActionWait waitAction = new PlanActionWait(((PlanRequestAction)pickup).request, pickup.getPosition(), ((PlanRequestAction) pickup).getMaxTime(), -waitTime); +// tempPlan.add(i, waitAction); +// } + Pair p = checkValidItineraryAndCountPlanDurationSecondPart(tempPlan, vehicle); + if (p.getFirst()) { + if (checkCapacityNotExceeded(tempPlan, vehicle)) { + allPosibleActionsOrder.add(tempPlan); + planDurations.add(p.getSecond()); + } + } + } + } + + if (allPosibleActionsOrder.isEmpty()) { + return null; + } + + int minIndex = planDurations.indexOf(Collections.min(planDurations)); + List selectedPlan = allPosibleActionsOrder.get(minIndex); + + return selectedPlan; + } public List findItineraryBestInsertion(PlanAction pickup, PlanAction dropoff, RideSharingOnDemandVehicle vehicle) { DriverPlan currentVehiclePlan; @@ -362,7 +482,6 @@ public List findTransferItineraryBestInsertion(PlanAction pickup, Pl Long arrivalTime = getArrivalTimeToStation(tempPlan, vehicle, ((PlanRequestAction)pickup).request); assert arrivalTime != null; long waitTime = arrivalToStationForVeh1 - arrivalTime; -// int waitTime = (int) (Math.round(arrivalToStationForVeh1 / 1000.0) - Math.round(arrivalTime / 1000.0)); if (waitTime >= 0) { waitTime += 3000; PlanActionWait waitAction = new PlanActionWait(((PlanRequestAction)pickup).request, pickup.getPosition(), ((PlanRequestAction) pickup).getMaxTime(), waitTime); @@ -373,6 +492,12 @@ else if (waitTime < 0 && waitTime > -3000) { PlanActionWait waitAction = new PlanActionWait(((PlanRequestAction)pickup).request, pickup.getPosition(), ((PlanRequestAction) pickup).getMaxTime(), -waitTime); tempPlan.add(i, waitAction); } +// else if (waitTime < 0 && waitTime > -2000) { +// waitTime += 2000; +// PlanActionWait waitAction = new PlanActionWait(((PlanRequestAction)pickup).request, pickup.getPosition(), ((PlanRequestAction) pickup).getMaxTime(), waitTime); +// tempPlan.add(i, waitAction); +// +// } Pair p = checkValidItineraryAndCountPlanDuration(tempPlan, vehicle); if (p.getFirst()) { if (checkCapacityNotExceeded(tempPlan, vehicle)) { @@ -424,6 +549,26 @@ public int countMaxTimeTransfer(List itnryp1, RideSharingOnDemandVeh } } + public int countMaxTimeTransferRound(List itnryp1, RideSharingOnDemandVehicle veh1, List itnryp2, RideSharingOnDemandVehicle veh2, PlanComputationRequest request) { + boolean isWaitInItnryp2 = false; + for (PlanAction action : itnryp2) { + if (action instanceof PlanActionWait) { + if (((PlanActionWait) action).request == request) { + isWaitInItnryp2 = true; + } + } + } + if (isWaitInItnryp2) { + Integer dropTime = getDropoffTimeForRequestFirstSegment(itnryp1, veh1, request); +// int time = (int) Math.round(dropTime / 1000.0); + return dropTime; + } else { + Integer dropTime = getArrivalTimeToStationIntFloor(itnryp2, veh2, request); +// int time = (int) Math.round(dropTime / 1000.0); + return dropTime - 1; + } + } + public boolean canPickupRequestInTime(RideSharingOnDemandVehicle vehicle, PlanComputationRequest request) { // cas prijezdu auta k pickup pozici je mensi nez maxPickupTime requestu long time = timeProvider.getCurrentSimTime(); @@ -520,13 +665,15 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { } } time += timeToFinishEdge; +// int timeRounded = (int) Math.round(time / 1000.0); for (PlanAction action : itinerary) { if (action instanceof PlanRequestAction) { PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); if (action instanceof PlanActionPickup) { SimulationNode dest = pcq.getFrom(); - time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); +// timeRounded += (int) Math.round(time / 1000.0); if (!(time < pcq.getMaxPickupTime() * 1000)) { ret = false; break; @@ -535,7 +682,8 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { } else if(action instanceof PlanActionPickupTransfer) { PlanActionPickupTransfer pickupTransfer = (PlanActionPickupTransfer) action; SimulationNode dest = pickupTransfer.getPosition(); - time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); +// timeRounded += (int) Math.round(time / 1000.0); if (!(time < pickupTransfer.getMaxTime() * 1000)) { ret = false; break; @@ -544,7 +692,8 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { } else if(action instanceof PlanActionDropoffTransfer) { PlanActionDropoffTransfer dropoffTransfer = (PlanActionDropoffTransfer) action; SimulationNode dest = dropoffTransfer.getPosition(); - time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); +// timeRounded += (int) Math.round(time / 1000.0); if (!(time < dropoffTransfer.getMaxTime() * 1000)) { ret = false; break; @@ -552,7 +701,8 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { previousDestination = dest; } else if (action instanceof PlanActionDropoff) { SimulationNode dest = pcq.getTo(); - time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); +// timeRounded += (int) Math.round(time / 1000.0); if (!(time < pcq.getMaxDropoffTime() * 1000)) { ret = false; break; @@ -562,8 +712,10 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { SimulationNode dest = action.getPosition(); PlanActionWait wait = (PlanActionWait) action; if (!(wait.isWaitingStarted())) { - time = time + wait.getWaitTime(); + time += wait.getWaitTime(); +// time = time + wait.getWaitTime(); time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); +// timeRounded += (int) Math.round(time / 1000.0); previousDestination = action.getPosition(); } else { long substract; @@ -575,8 +727,10 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { waitTime = wait.getWaitTime() - (timeProvider.getCurrentSimTime() - wait.getWaitingStartedAt()); } +// timeRounded += (int) Math.round(waitTime / 1000.0); time = time + waitTime; time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); +// timeRounded += (int) Math.round(time / 1000.0); previousDestination = action.getPosition(); } } @@ -586,6 +740,304 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { return p; } + private Pair checkValidItineraryAndCountPlanDurationFirstPart(List itinerary, RideSharingOnDemandVehicle vehicle) { + SimulationNode previousDestination; + boolean ret = true; + long time = timeProvider.getCurrentSimTime(); + long timeToFinishEdge = 0; + previousDestination = vehicle.getPosition(); + int timeRounded = (int) Math.ceil(timeProvider.getCurrentSimTime() / 1000.0); + + // podivam se na current trip plan a spocitam cas potrebny na dokonceni cesty po aktualni hrane + if (vehicle.getCurrentTripPlan() != null) { + if (vehicle.getCurrentTripPlan().getSize() == 0) { + SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getLastLocation(); + // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu + // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu + timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, stopLoc); + previousDestination = stopLoc; + } + else if (vehicle.getCurrentTripPlan().getSize() > 0) { + SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getFirstLocation(); + SimulationNode currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[0]; + boolean currLocIsVehiclePosition = false; + int curridx = 0; + while (currLoc != stopLoc) { + if (currLocIsVehiclePosition) { + timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, currLoc); + } + if (currLoc == vehicle.getPosition()) { + currLocIsVehiclePosition = true; + } + previousDestination = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx]; + curridx++; + currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx]; + } + } + } + time += timeToFinishEdge; + timeRounded += (int) Math.ceil(timeToFinishEdge / 1000.0); + + for (PlanAction action : itinerary) { + if (action instanceof PlanRequestAction) { + PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); + if (action instanceof PlanActionPickup) { + SimulationNode dest = pcq.getFrom(); + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + timeRounded += (int) Math.ceil(travelTimeProvider.getExpectedTravelTime(previousDestination, dest) / 1000.0); + if (!(timeRounded < pcq.getMaxPickupTime())) { + ret = false; + break; + } + previousDestination = dest; + } else if(action instanceof PlanActionPickupTransfer) { + PlanActionPickupTransfer pickupTransfer = (PlanActionPickupTransfer) action; + SimulationNode dest = pickupTransfer.getPosition(); + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + timeRounded += (int) Math.ceil(travelTimeProvider.getExpectedTravelTime(previousDestination, dest) / 1000.0); + if (!(timeRounded < pickupTransfer.getMaxTime())) { + ret = false; + break; + } + previousDestination = dest; + } else if(action instanceof PlanActionDropoffTransfer) { + PlanActionDropoffTransfer dropoffTransfer = (PlanActionDropoffTransfer) action; + SimulationNode dest = dropoffTransfer.getPosition(); + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + timeRounded += (int) Math.ceil(travelTimeProvider.getExpectedTravelTime(previousDestination, dest) / 1000.0); + if (!(timeRounded < dropoffTransfer.getMaxTime())) { + ret = false; + break; + } + previousDestination = dest; + } else if (action instanceof PlanActionDropoff) { + SimulationNode dest = pcq.getTo(); + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + timeRounded += (int) Math.ceil(travelTimeProvider.getExpectedTravelTime(previousDestination, dest) / 1000.0); + if (!(timeRounded < pcq.getMaxDropoffTime())) { + ret = false; + break; + } + previousDestination = dest; + } else if (action instanceof PlanActionWait) { + SimulationNode dest = action.getPosition(); + PlanActionWait wait = (PlanActionWait) action; + if (!(wait.isWaitingStarted())) { + time += wait.getWaitTime(); + timeRounded += (int) Math.ceil(wait.getWaitTime() / 1000.0); + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + timeRounded += (int) Math.ceil(travelTimeProvider.getExpectedTravelTime(previousDestination, dest) / 1000.0); + previousDestination = action.getPosition(); + } else { + long substract; + long waitTime; + if (wait.isWaitingPaused()) { + substract = wait.getWaitingPausedAt() - wait.getWaitingStartedAt(); + waitTime = wait.getWaitTime() - substract; + } else { + waitTime = wait.getWaitTime() - (timeProvider.getCurrentSimTime() - wait.getWaitingStartedAt()); + + } + time = time + waitTime; + timeRounded += (int) Math.ceil(wait.getWaitTime() / 1000.0); + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + timeRounded += (int) Math.ceil(travelTimeProvider.getExpectedTravelTime(previousDestination, dest) / 1000.0); + previousDestination = action.getPosition(); + } + } + } + } + Pair p = new Pair<>(ret, timeRounded); + return p; + } + + private Pair checkValidItineraryAndCountPlanDurationSecondPart(List itinerary, RideSharingOnDemandVehicle vehicle) { + SimulationNode previousDestination; + boolean ret = true; + long time = timeProvider.getCurrentSimTime(); + long timeToFinishEdge = 0; + previousDestination = vehicle.getPosition(); + int timeRounded = (int) Math.floor(timeProvider.getCurrentSimTime() / 1000.0); + + // podivam se na current trip plan a spocitam cas potrebny na dokonceni cesty po aktualni hrane + if (vehicle.getCurrentTripPlan() != null) { + if (vehicle.getCurrentTripPlan().getSize() == 0) { + SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getLastLocation(); + // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu + // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu + timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, stopLoc); + previousDestination = stopLoc; + } + else if (vehicle.getCurrentTripPlan().getSize() > 0) { + SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getFirstLocation(); + SimulationNode currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[0]; + boolean currLocIsVehiclePosition = false; + int curridx = 0; + while (currLoc != stopLoc) { + if (currLocIsVehiclePosition) { + timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, currLoc); + } + if (currLoc == vehicle.getPosition()) { + currLocIsVehiclePosition = true; + } + previousDestination = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx]; + curridx++; + currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx]; + } + } + } + time += timeToFinishEdge; + timeRounded += (int) Math.floor(timeToFinishEdge / 1000.0); + + for (PlanAction action : itinerary) { + if (action instanceof PlanRequestAction) { + PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); + if (action instanceof PlanActionPickup) { + SimulationNode dest = pcq.getFrom(); + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + timeRounded += (int) Math.floor(travelTimeProvider.getExpectedTravelTime(previousDestination, dest) / 1000.0); + if (!(timeRounded < pcq.getMaxPickupTime())) { + ret = false; + break; + } + previousDestination = dest; + } else if(action instanceof PlanActionPickupTransfer) { + PlanActionPickupTransfer pickupTransfer = (PlanActionPickupTransfer) action; + SimulationNode dest = pickupTransfer.getPosition(); + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + timeRounded += (int) Math.floor(travelTimeProvider.getExpectedTravelTime(previousDestination, dest) / 1000.0); + if (!(timeRounded < pickupTransfer.getMaxTime())) { + ret = false; + break; + } + previousDestination = dest; + } else if(action instanceof PlanActionDropoffTransfer) { + PlanActionDropoffTransfer dropoffTransfer = (PlanActionDropoffTransfer) action; + SimulationNode dest = dropoffTransfer.getPosition(); + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + timeRounded += (int) Math.floor(travelTimeProvider.getExpectedTravelTime(previousDestination, dest) / 1000.0); + if (!(timeRounded < dropoffTransfer.getMaxTime())) { + ret = false; + break; + } + previousDestination = dest; + } else if (action instanceof PlanActionDropoff) { + SimulationNode dest = pcq.getTo(); + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + timeRounded += (int) Math.floor(travelTimeProvider.getExpectedTravelTime(previousDestination, dest) / 1000.0); + if (!(timeRounded < pcq.getMaxDropoffTime())) { + ret = false; + break; + } + previousDestination = dest; + } else if (action instanceof PlanActionWait) { + SimulationNode dest = action.getPosition(); + PlanActionWait wait = (PlanActionWait) action; + if (!(wait.isWaitingStarted())) { + time += wait.getWaitTime(); + timeRounded += (int) Math.floor(wait.getWaitTime() / 1000.0); + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + timeRounded += (int) Math.floor(travelTimeProvider.getExpectedTravelTime(previousDestination, dest) / 1000.0); + previousDestination = action.getPosition(); + } else { + long substract; + long waitTime; + if (wait.isWaitingPaused()) { + substract = wait.getWaitingPausedAt() - wait.getWaitingStartedAt(); + waitTime = wait.getWaitTime() - substract; + } else { + waitTime = wait.getWaitTime() - (timeProvider.getCurrentSimTime() - wait.getWaitingStartedAt()); + + } + time = time + waitTime; + timeRounded += (int) Math.floor(wait.getWaitTime() / 1000.0); + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + timeRounded += (int) Math.floor(travelTimeProvider.getExpectedTravelTime(previousDestination, dest) / 1000.0); + previousDestination = action.getPosition(); + } + } + } + } + Pair p = new Pair<>(ret, timeRounded); + return p; + } + + private Integer getDropoffTimeForRequestFirstSegment(List itinerary, RideSharingOnDemandVehicle vehicle, PlanComputationRequest request) { + long time = timeProvider.getCurrentSimTime(); + long timeToFinishEdge = 0; + int timeInt = (int) Math.ceil(timeProvider.getCurrentSimTime() / 1000.0); + SimulationNode previousDestination = vehicle.getPosition(); + if (vehicle.getCurrentTripPlan() != null) { + if (vehicle.getCurrentTripPlan().getSize() == 0) { + SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getLastLocation(); + timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, stopLoc); + previousDestination = stopLoc; + } + else if (vehicle.getCurrentTripPlan().getSize() > 0) { + SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getFirstLocation(); + SimulationNode currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[0]; + boolean currLocIsVehiclePosition = false; + int curridx = 0; + while (currLoc != stopLoc) { + if (currLocIsVehiclePosition) { + timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, currLoc); + } + if (currLoc == vehicle.getPosition()) { + currLocIsVehiclePosition = true; + } + previousDestination = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx]; + curridx++; + currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx]; + } + } + } + time = time + timeToFinishEdge; + timeInt += (int) Math.ceil(timeToFinishEdge / 1000.0); + + for (PlanAction action : itinerary) { + if (action instanceof PlanActionPickup || action instanceof PlanActionPickupTransfer) { + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, action.getPosition()); + timeInt += (int) Math.ceil(travelTimeProvider.getExpectedTravelTime(previousDestination, action.getPosition()) / 1000.0); + previousDestination = action.getPosition(); + } else if (action instanceof PlanActionDropoff || action instanceof PlanActionDropoffTransfer) { + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, action.getPosition()); + timeInt += (int) Math.ceil(travelTimeProvider.getExpectedTravelTime(previousDestination, action.getPosition()) / 1000.0); + if (((PlanRequestAction) action).getRequest() == request) { + return timeInt; + } + + previousDestination = action.getPosition(); + } else if (action instanceof PlanActionWait) { + SimulationNode dest = action.getPosition(); + PlanActionWait wait = (PlanActionWait) action; + if (!(wait.isWaitingStarted())) { + time = time + wait.getWaitTime(); + timeInt += (int) Math.ceil(wait.getWaitTime()); + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + timeInt += (int) Math.ceil(travelTimeProvider.getExpectedTravelTime(previousDestination, action.getPosition()) / 1000.0); + previousDestination = action.getPosition(); + } else { + long substract; + long waitTime; + if (wait.isWaitingPaused()) { + substract = wait.getWaitingPausedAt() - wait.getWaitingStartedAt(); + waitTime = wait.getWaitTime() - substract; + } else { + waitTime = wait.getWaitTime() - (timeProvider.getCurrentSimTime() - wait.getWaitingStartedAt()); + } + time = time + waitTime; + timeInt += (int) Math.ceil(wait.getWaitTime()); + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + timeInt += (int) Math.ceil(travelTimeProvider.getExpectedTravelTime(previousDestination, action.getPosition()) / 1000.0); + previousDestination = action.getPosition(); + } + } + + } + return null; + } + + private Long getDropoffTimeForRequest(List itinerary, RideSharingOnDemandVehicle vehicle, PlanComputationRequest request) { long time = timeProvider.getCurrentSimTime(); long timeToFinishEdge = 0; @@ -642,7 +1094,6 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { waitTime = wait.getWaitTime() - substract; } else { waitTime = wait.getWaitTime() - (timeProvider.getCurrentSimTime() - wait.getWaitingStartedAt()); - } time = time + waitTime; time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); @@ -724,5 +1175,83 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { return null; } + private Integer getArrivalTimeToStationIntFloor(List itinerary, RideSharingOnDemandVehicle vehicle, PlanComputationRequest request) { + long time = timeProvider.getCurrentSimTime(); + int timeInt = (int) Math.floor(timeProvider.getCurrentSimTime() / 1000.0); + long timeToFinishEdge = 0; + SimulationNode previousDestination = vehicle.getPosition(); + if (vehicle.getCurrentTripPlan() != null) { + if (vehicle.getCurrentTripPlan().getSize() == 0) { + SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getLastLocation(); + timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, stopLoc); + previousDestination = stopLoc; + } + else if (vehicle.getCurrentTripPlan().getSize() > 0) { + SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getFirstLocation(); + SimulationNode currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[0]; + boolean currLocIsVehiclePosition = false; + int curridx = 0; + while (currLoc != stopLoc) { + if (currLocIsVehiclePosition) { + timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, currLoc); + } + if (currLoc == vehicle.getPosition()) { + currLocIsVehiclePosition = true; + } + previousDestination = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx]; + curridx++; + currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx]; + } + } + } + time = time + timeToFinishEdge; + timeInt += (int) Math.floor(timeToFinishEdge / 1000.0); + + for (PlanAction action : itinerary) { + if (action instanceof PlanActionPickup || action instanceof PlanActionPickupTransfer) { + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, action.getPosition()); + timeInt += (int) Math.floor(travelTimeProvider.getExpectedTravelTime(previousDestination, action.getPosition())/1000.0); + if (((PlanRequestAction) action).getRequest() == request) { + return timeInt; + } + previousDestination = action.getPosition(); + } else if (action instanceof PlanActionDropoff || action instanceof PlanActionDropoffTransfer) { + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, action.getPosition()); + timeInt += (int) Math.floor(travelTimeProvider.getExpectedTravelTime(previousDestination, action.getPosition())/1000.0); + previousDestination = action.getPosition(); + } else if (action instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) action; + SimulationNode dest = action.getPosition(); + if (!(wait.isWaitingStarted())) { + time = time + wait.getWaitTime(); + timeInt += (int) Math.floor(wait.getWaitTime() / 1000.0); + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + timeInt += (int) Math.floor(travelTimeProvider.getExpectedTravelTime(previousDestination, action.getPosition())/1000.0); + previousDestination = action.getPosition(); + } else { + // aktivita uz zacala + // podivam se jestli uz je i pauznuta + // odectu uz odcekany cas + long substract; + long waitTime; + if (wait.isWaitingPaused()) { + substract = wait.getWaitingPausedAt() - wait.getWaitingStartedAt(); + waitTime = wait.getWaitTime() - substract; + } else { + waitTime = wait.getWaitTime() - (timeProvider.getCurrentSimTime() - wait.getWaitingStartedAt()); + + } + time = time + waitTime; + timeInt += (int) Math.floor(waitTime / 1000.0); + time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + timeInt += (int) Math.floor(travelTimeProvider.getExpectedTravelTime(previousDestination, action.getPosition())/1000.0); + previousDestination = action.getPosition(); + } + } + + } + return null; + } + } From 9227bb6fee795cd48b8b249978a16c9d0c9f28b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kub=C3=ADkov=C3=A1=2C=20Ad=C3=A9la?= Date: Wed, 4 May 2022 20:40:14 +0200 Subject: [PATCH 12/21] Delete comments --- .../TransferInsertionSolver.java | 145 +----------------- 1 file changed, 5 insertions(+), 140 deletions(-) diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java index 533c05b8..68642491 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java @@ -25,7 +25,6 @@ import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider; import org.jgrapht.alg.util.Pair; -import java.awt.image.AreaAveragingScaleFilter; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -137,7 +136,6 @@ public Map solve(List(); - // zkusim najit plan bez prestupu for (PlanComputationRequest request : requests) { List>, List>> itinerariesPairs = new ArrayList<>(); List canPickupRequestTaxis = possiblePickupTaxisMap.get(request); @@ -148,14 +146,13 @@ public Map solve(List positnry = findItineraryBestInsertion(request.getPickUpAction(), request.getDropOffAction(), taxi); if (positnry != null) { - // pridat plan do nejakeho seznamu vsech validnich planu Long dropoffTime = getDropoffTimeForRequest(positnry, taxi, request); if (dropoffTime == null) { // chyba continue; } delays.add(dropoffTime - timeProvider.getCurrentSimTime() - minimalTravelTime); - waitTimes.add(Long.MAX_VALUE); + waitTimes.add((long)0); List> listItinerary = new ArrayList<>(); listItinerary.add(positnry); List vehicles = new ArrayList<>(); @@ -185,21 +182,14 @@ public Map solve(List itnryp1 = findItineraryBestInsertionFirstSegment(request.getPickUpAction(), dropoffActionTransfer, taxi); if (itnryp1 == null) { continue; } Integer dropTime = getDropoffTimeForRequestFirstSegment(itnryp1, taxi, request); - //vytvorim plan pro prvni usek cesty -// List itnryp1 = findItineraryBestInsertion(request.getPickUpAction(), dropoffActionTransfer, taxi); -// if (itnryp1 == null) { -// continue; -// } -// Long dropTime = getDropoffTimeForRequest(itnryp1, taxi, request); - - // TODO druhy usek = floor + // druhy usek = floor List itnryp2 = findTransferItineraryBestInsertionSecondSegment(pickupActionTransfer, request.getDropOffAction(), taxis.get(k), dropTime); if (itnryp2 == null) { continue; @@ -217,27 +207,6 @@ public Map solve(List itnryp2 = findTransferItineraryBestInsertion(pickupActionTransfer, request.getDropOffAction(), taxis.get(k), dropTime); -// if (itnryp2 == null) { -// continue; -// } -// int maxTransferTime = countMaxTimeTransfer(itnryp1, taxi, itnryp2, taxis.get(k), request); -// -// for (PlanAction action : itnryp1) { -// if (action.equals(dropoffActionTransfer)) { -// ((PlanActionDropoffTransfer)action).setMaxTime(maxTransferTime); -// } -// } -// -// Long dropoffTime = getDropoffTimeForRequest(itnryp2, taxis.get(k), request); -// if (dropoffTime == null) { -// // chyba -// continue; -// } -// delays.add(dropoffTime - timeProvider.getCurrentSimTime() - minimalTravelTime); - long waitTime = getWaitTimeForRequest(itnryp2, request); waitTimes.add(waitTime); @@ -254,31 +223,13 @@ public Map solve(List transferPlans = new ArrayList<>(); -// for (int j = 0; j < itinerariesPairs.size(); j++) { -// TransferPlan t = new TransferPlan(waitTimes.get(j), delays.get(j), itinerariesPairs.get(j)); -// transferPlans.add(t); -// } - List transferPlans = new ArrayList<>(); for (int j = 0; j < itinerariesPairs.size(); j++) { - if (waitTimes.get(j) != Long.MAX_VALUE && waitTimes.get(j) > 10000) { - - } else { + if (waitTimes.get(j) < 10000) { TransferPlan t = new TransferPlan(waitTimes.get(j), delays.get(j), itinerariesPairs.get(j)); transferPlans.add(t); } } - - -// verze1 transferPlans.sort(TransferPlan::compareByTransferTime); double beta = 0.2; int numOfTaken = (int) (transferPlans.size() * beta); @@ -294,57 +245,23 @@ public Map solve(List>, List> key = sublistTransferPlans.get(0).pair; List> plansForVehicles = key.getFirst(); List vehicles = key.getSecond(); for (int q = 0; q < vehicles.size(); q++) { List vehPlan = plansForVehicles.get(q); -// List planWithPos = new ArrayList<>(); -// planWithPos.add(vehicles.get(q).getCurrentPlanNoUpdate().plan.get(0)); -// planWithPos.addAll(vehPlan); DriverPlan dp = new DriverPlan(vehPlan, 0, 0); planMap.put(vehicles.get(q), dp); } -// DriverPlan newPlan = new DriverPlan(s.get(0).getFirst().get(0), 0, 0); -// planMap.put(itinerariesPairs.get(0).getSecond().get(0), newPlan); } } - - - // jak hledat plan bez prestupu? - // v planu nikdo neprestupuje - provedu insertion metodu - // v planu prestupuje, ale je to prvni cast - provedu insertion metodu, ale musim mit spravne nastaveny maxTime dropoffTransfer akce - // v planu prestupuje, ale je to druhy usek - muzu zkusit udelat to same, ale nesmim prekrocit maxTime u pickupTransfer akce - - // potom budu hledat stanice ve kterych je mozne prestoupit - // zkusim vytvorit prestupni plan - // prvni usek budu vytvaret uplne stejne jako je hledani planu bez prestupu - // zjistim cas prijezdu auta na stanici s prestupujicim cestujicim - // na druhy usek vyzkousim vsechny moznosti kam akce zaradit - // do planu pridam waitAkci - spocitam cas prijezdu druheho auta na stanici a cas dorovnam wait akci, aby to sedelo - // nastavim maxTransferTime - // zkontroluju jestli je plan validni, nevalidni plany zahodim - // z validnich planu vyberu ten, co bude mit nejmensi zpozdeni - // zkombinuji tyto dva plany ? - - // ze vsech planu vyberu nekolik s nejmensim delay - - // budu chtit uprednostnit plany s prestupem - - // zaroven ale budu vybirat takove plany, co maji kratky wait time, aby auta zbytecne nestala ve stanici - return planMap; } - - - - public List findItineraryBestInsertionFirstSegment(PlanAction pickup, PlanAction dropoff, RideSharingOnDemandVehicle vehicle) { DriverPlan currentVehiclePlan; if (planMap.containsKey(vehicle)) { @@ -398,17 +315,10 @@ public List findTransferItineraryBestInsertionSecondSegment(PlanActi Integer arrivalTime = getArrivalTimeToStationIntFloor(tempPlan, vehicle, ((PlanRequestAction)pickup).request); assert arrivalTime != null; int waitTime = arrivalToStationForVeh1 - arrivalTime; - // wait time budu mit v sekundach if (waitTime > 0) { -// waitTime += 3000; PlanActionWait waitAction = new PlanActionWait(((PlanRequestAction)pickup).request, pickup.getPosition(), ((PlanRequestAction) pickup).getMaxTime(), waitTime * 1000); tempPlan.add(i, waitAction); } -// else if (waitTime < 0 && waitTime > -3000) { -// waitTime -= 3000; -// PlanActionWait waitAction = new PlanActionWait(((PlanRequestAction)pickup).request, pickup.getPosition(), ((PlanRequestAction) pickup).getMaxTime(), -waitTime); -// tempPlan.add(i, waitAction); -// } Pair p = checkValidItineraryAndCountPlanDurationSecondPart(tempPlan, vehicle); if (p.getFirst()) { if (checkCapacityNotExceeded(tempPlan, vehicle)) { @@ -492,12 +402,6 @@ else if (waitTime < 0 && waitTime > -3000) { PlanActionWait waitAction = new PlanActionWait(((PlanRequestAction)pickup).request, pickup.getPosition(), ((PlanRequestAction) pickup).getMaxTime(), -waitTime); tempPlan.add(i, waitAction); } -// else if (waitTime < 0 && waitTime > -2000) { -// waitTime += 2000; -// PlanActionWait waitAction = new PlanActionWait(((PlanRequestAction)pickup).request, pickup.getPosition(), ((PlanRequestAction) pickup).getMaxTime(), waitTime); -// tempPlan.add(i, waitAction); -// -// } Pair p = checkValidItineraryAndCountPlanDuration(tempPlan, vehicle); if (p.getFirst()) { if (checkCapacityNotExceeded(tempPlan, vehicle)) { @@ -526,7 +430,7 @@ public long getWaitTimeForRequest(List itinerary, PlanComputationReq } } } - return 0; + return -1; } public int countMaxTimeTransfer(List itnryp1, RideSharingOnDemandVehicle veh1, List itnryp2, RideSharingOnDemandVehicle veh2, PlanComputationRequest request) { @@ -560,27 +464,21 @@ public int countMaxTimeTransferRound(List itnryp1, RideSharingOnDema } if (isWaitInItnryp2) { Integer dropTime = getDropoffTimeForRequestFirstSegment(itnryp1, veh1, request); -// int time = (int) Math.round(dropTime / 1000.0); return dropTime; } else { Integer dropTime = getArrivalTimeToStationIntFloor(itnryp2, veh2, request); -// int time = (int) Math.round(dropTime / 1000.0); return dropTime - 1; } } public boolean canPickupRequestInTime(RideSharingOnDemandVehicle vehicle, PlanComputationRequest request) { - // cas prijezdu auta k pickup pozici je mensi nez maxPickupTime requestu long time = timeProvider.getCurrentSimTime(); long timeToFinishEdge = 0; SimulationNode previousDestination = vehicle.getPosition(); - // podivam se na current trip plan a spocitam cas potrebny na dokonceni cesty po aktualni hrane if (vehicle.getCurrentTripPlan() != null) { if (vehicle.getCurrentTripPlan().getSize() == 0) { SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getLastLocation(); - // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu - // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, stopLoc); previousDestination = stopLoc; } @@ -637,12 +535,9 @@ private Pair checkValidItineraryAndCountPlanDuration(List 0) { } } time += timeToFinishEdge; -// int timeRounded = (int) Math.round(time / 1000.0); for (PlanAction action : itinerary) { if (action instanceof PlanRequestAction) { @@ -673,7 +567,6 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { if (action instanceof PlanActionPickup) { SimulationNode dest = pcq.getFrom(); time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); -// timeRounded += (int) Math.round(time / 1000.0); if (!(time < pcq.getMaxPickupTime() * 1000)) { ret = false; break; @@ -683,7 +576,6 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { PlanActionPickupTransfer pickupTransfer = (PlanActionPickupTransfer) action; SimulationNode dest = pickupTransfer.getPosition(); time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); -// timeRounded += (int) Math.round(time / 1000.0); if (!(time < pickupTransfer.getMaxTime() * 1000)) { ret = false; break; @@ -693,7 +585,6 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { PlanActionDropoffTransfer dropoffTransfer = (PlanActionDropoffTransfer) action; SimulationNode dest = dropoffTransfer.getPosition(); time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); -// timeRounded += (int) Math.round(time / 1000.0); if (!(time < dropoffTransfer.getMaxTime() * 1000)) { ret = false; break; @@ -702,7 +593,6 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { } else if (action instanceof PlanActionDropoff) { SimulationNode dest = pcq.getTo(); time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); -// timeRounded += (int) Math.round(time / 1000.0); if (!(time < pcq.getMaxDropoffTime() * 1000)) { ret = false; break; @@ -713,9 +603,7 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { PlanActionWait wait = (PlanActionWait) action; if (!(wait.isWaitingStarted())) { time += wait.getWaitTime(); -// time = time + wait.getWaitTime(); time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); -// timeRounded += (int) Math.round(time / 1000.0); previousDestination = action.getPosition(); } else { long substract; @@ -725,12 +613,9 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { waitTime = wait.getWaitTime() - substract; } else { waitTime = wait.getWaitTime() - (timeProvider.getCurrentSimTime() - wait.getWaitingStartedAt()); - } -// timeRounded += (int) Math.round(waitTime / 1000.0); time = time + waitTime; time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); -// timeRounded += (int) Math.round(time / 1000.0); previousDestination = action.getPosition(); } } @@ -748,12 +633,9 @@ private Pair checkValidItineraryAndCountPlanDurationFirstPart( previousDestination = vehicle.getPosition(); int timeRounded = (int) Math.ceil(timeProvider.getCurrentSimTime() / 1000.0); - // podivam se na current trip plan a spocitam cas potrebny na dokonceni cesty po aktualni hrane if (vehicle.getCurrentTripPlan() != null) { if (vehicle.getCurrentTripPlan().getSize() == 0) { SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getLastLocation(); - // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu - // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, stopLoc); previousDestination = stopLoc; } @@ -836,7 +718,6 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { waitTime = wait.getWaitTime() - substract; } else { waitTime = wait.getWaitTime() - (timeProvider.getCurrentSimTime() - wait.getWaitingStartedAt()); - } time = time + waitTime; timeRounded += (int) Math.ceil(wait.getWaitTime() / 1000.0); @@ -859,12 +740,9 @@ private Pair checkValidItineraryAndCountPlanDurationSecondPart previousDestination = vehicle.getPosition(); int timeRounded = (int) Math.floor(timeProvider.getCurrentSimTime() / 1000.0); - // podivam se na current trip plan a spocitam cas potrebny na dokonceni cesty po aktualni hrane if (vehicle.getCurrentTripPlan() != null) { if (vehicle.getCurrentTripPlan().getSize() == 0) { SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getLastLocation(); - // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu - // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, stopLoc); previousDestination = stopLoc; } @@ -947,7 +825,6 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { waitTime = wait.getWaitTime() - substract; } else { waitTime = wait.getWaitTime() - (timeProvider.getCurrentSimTime() - wait.getWaitingStartedAt()); - } time = time + waitTime; timeRounded += (int) Math.floor(wait.getWaitTime() / 1000.0); @@ -1005,7 +882,6 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { if (((PlanRequestAction) action).getRequest() == request) { return timeInt; } - previousDestination = action.getPosition(); } else if (action instanceof PlanActionWait) { SimulationNode dest = action.getPosition(); @@ -1032,7 +908,6 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { previousDestination = action.getPosition(); } } - } return null; } @@ -1077,7 +952,6 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { if (((PlanRequestAction) action).getRequest() == request) { return time; } - previousDestination = action.getPosition(); } else if (action instanceof PlanActionWait) { SimulationNode dest = action.getPosition(); @@ -1100,7 +974,6 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { previousDestination = action.getPosition(); } } - } return null; } @@ -1153,9 +1026,6 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); previousDestination = action.getPosition(); } else { - // aktivita uz zacala - // podivam se jestli uz je i pauznuta - // odectu uz odcekany cas long substract; long waitTime; if (wait.isWaitingPaused()) { @@ -1229,9 +1099,6 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { timeInt += (int) Math.floor(travelTimeProvider.getExpectedTravelTime(previousDestination, action.getPosition())/1000.0); previousDestination = action.getPosition(); } else { - // aktivita uz zacala - // podivam se jestli uz je i pauznuta - // odectu uz odcekany cas long substract; long waitTime; if (wait.isWaitingPaused()) { @@ -1252,6 +1119,4 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { } return null; } - - } From 04426c76004afdab95b854da6f9e7369299f3373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kub=C3=ADkov=C3=A1=2C=20Ad=C3=A9la?= Date: Wed, 4 May 2022 22:07:12 +0200 Subject: [PATCH 13/21] Add rounding in greedy TASeT solver --- .../greedyTASeT/GreedyTASeTSolver.java | 484 ++++++++++++++---- 1 file changed, 372 insertions(+), 112 deletions(-) diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java index b8de5261..a5414aca 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java @@ -3,7 +3,6 @@ import com.google.inject.Inject; import com.google.inject.Singleton; import cz.cvut.fel.aic.agentpolis.config.AgentpolisConfig; -import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.trip.VehicleTrip; import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.TimeProvider; import cz.cvut.fel.aic.agentpolis.simmodel.entity.AgentPolisEntity; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; @@ -76,15 +75,6 @@ public GreedyTASeTSolver( this.onDemandvehicleStationStorage = onDemandvehicleStationStorage; this.requestFactory = requestFactory; -// // max distance in meters between vehicle and request for the vehicle to be considered to serve the request -// maxDistance = (double) config.ridesharing.maxProlongationInSeconds -// * agentpolisConfig.maxVehicleSpeedInMeters; -// maxDistanceSquared = maxDistance * maxDistance; -// -// // the traveltime from vehicle to request cannot be greater than max prolongation in milliseconds for the -// // vehicle to be considered to serve the request -// maxDelayTime = config.ridesharing.maxProlongationInSeconds * 1000; - setEventHandeling(); } @@ -194,7 +184,6 @@ private long countTimeToNewPickup(RideSharingOnDemandVehicle taxi, PlanComputati taxiPlan = taxi.getCurrentPlanNoUpdate(); } if (isWithTransfer(taxiPlan)) { - // nekdo prestupuje int indexLastTransferAction = findLastTransferActionIndex(taxiPlan); long timeToFinishCurrentEdge = 0; SimulationNode previousPos = taxi.getPosition(); @@ -212,7 +201,6 @@ private long countTimeToNewPickup(RideSharingOnDemandVehicle taxi, PlanComputati } previousPos = taxiPlan.plan.get(q).getPosition(); } - // ted potrebuju najit posledni pickup ve zbyvajicim driver planu po prestupu List segmentAfterTransfer = taxiPlan.plan.subList(indexLastTransferAction+1, taxiPlan.plan.size()); int indexLastPickupSegment = findLastPickupIndexList(segmentAfterTransfer); long timeToLastPickup = 0; @@ -234,7 +222,6 @@ private long countTimeToNewPickup(RideSharingOnDemandVehicle taxi, PlanComputati return estimatedArrivalToPickup; } else { - //neprestupuje nikdo int indexLastPickup = findLastPickupIndex(taxiPlan); long timeToFinishCurrentEdge = 0; SimulationNode previousPos = taxi.getPosition(); @@ -273,7 +260,6 @@ private Map heuristics(List requestsOnBoardSet = new HashSet<>(); DriverPlan actualPlan = taxi.getCurrentPlanNoUpdate(); for(PlanAction action : actualPlan) { @@ -330,7 +316,6 @@ private Map heuristics(List requestsInSegmentSet = new HashSet<>(); for(PlanAction action : segmentAfterTransfer) { if(action instanceof PlanRequestAction) { @@ -348,7 +333,6 @@ private Map heuristics(List heuristics(List maxTime) { @@ -409,14 +392,11 @@ private Map heuristics(List>, List>> templistP = new ArrayList<>(); - // list ve kterem je list dvojic - list dvojic, protoze dvojice muze byt jen jedna (neni prestup) nebo dve (je prestup) List delays = new ArrayList<>(); List transferTimes = new ArrayList<>(); List canPickupRequestTaxis = possiblePickupTaxisMap.get(request); for (RideSharingOnDemandVehicle taxi : canPickupRequestTaxis) { List posbitnry = findPlanWithNoTransferNew(request, taxi); - // pokud neexistuje ani jeden validni itinerar, tak je posbitnry null - // tehdy ho nebudu pridavat do templistu if (posbitnry != null) { if (checkValidItinerary(posbitnry, taxi)) { List> tmp = new ArrayList<>(); @@ -451,7 +431,6 @@ private Map heuristics(List request.getMaxDropoffTime() * 1000 - travelTimeProvider.getExpectedTravelTime(station, request.getTo())) { continue; @@ -459,7 +438,6 @@ private Map heuristics(List heuristics(List itnryp1 = findPlanWithNoTransferActionsNew(request.getPickUpAction(), dropoffActionTransfer, taxi); // pro auto List itnryp2 = findPlanWithNoTransferActionsNew(pickupActionTransfer, request.getDropOffAction(), taxis.get(k)); if (itnryp1 == null || itnryp2 == null) { - // neexistuje plan continue; } Pair>, Long> p = createChargePlanNoNewRequests(itnryp1, itnryp2, taxi, taxis.get(k), request); if (p == null) { - // neni zadny validni plan a tedy neni mozne prestoupit, takze neudelam nic continue; } else { List> itnrys = p.getFirst(); @@ -500,14 +476,8 @@ private Map heuristics(List>, List> pair2 = new Pair<>(tmp2, tmpVehs2); templistP.add(pair2); - // travel time daneho requestu s prestupem spocitam jako: - // cas nez prvni auto dojede pro request a vyzvedne ho - // + cas jizdy v prvnim vozidle - // + pokud druhe auto prijede pozdeji nez to prvni tak k tomu prictu rozdil - // + doba jizdy v druhem aute HashMap drops = getEstimatedTimesOfDropoff(itnryp2, taxis.get(k)); if (drops == null) { - // not valid delays.add(Long.MAX_VALUE); transferTimes.add((long) -1); continue; @@ -531,7 +501,6 @@ private Map heuristics(List heuristics(List heuristics(List requestsOnBoardSet = new HashSet<>(); DriverPlan actualPlan; if (planMap.containsKey(taxis.get(z))) { @@ -589,19 +554,16 @@ private Map heuristics(List requestsOnBoard = new ArrayList<>(requestsOnBoardSet); - // kolik lidi je prave ted v aute boolean taxiFree = true; int taxiCapacity = taxi.getCapacity(); if (requestsOnBoardSet.size() >= taxiCapacity) { taxiFree = false; } for(int j = 0; j < stationsCount; j++) { - //check if taxi has free seat if (!taxiFree) { LT[j][z] = Long.MAX_VALUE; } else { if (isWithTransfer(actualPlan)) { - // nekdo prestupuje int indexLastTransferAction = findLastTransferActionIndex(actualPlan); long timeToFinishCurrentEdge = 0; SimulationNode previousPos = taxi.getPosition(); @@ -619,7 +581,6 @@ private Map heuristics(List segmentAfterTransfer = actualPlan.plan.subList(indexLastTransferAction + 1, actualPlan.plan.size()); int indexLastPickupSegment = findLastPickupIndexList(segmentAfterTransfer); long timeToLastPickup = 0; @@ -635,7 +596,6 @@ private Map heuristics(List requestsInSegmentSet = new HashSet<>(); for (PlanAction action : segmentAfterTransfer) { if (action instanceof PlanRequestAction) { @@ -652,7 +612,6 @@ private Map heuristics(List heuristics(List maxTime) { @@ -692,12 +650,9 @@ private boolean checkValidItinerary(List itinerary, RideSharingOnDem long timeToFinishEdge = 0; previousDestination = vehicle.getPosition(); - // podivam se na trip plan if (vehicle.getCurrentTripPlan() != null) { if (vehicle.getCurrentTripPlan().getSize() == 0) { SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getLastLocation(); - // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu - // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, stopLoc); previousDestination = stopLoc; } @@ -728,7 +683,6 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { SimulationNode dest = pcq.getFrom(); time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); if (!(time < pcq.getMaxPickupTime()*1000)) { - //not valid itinerary ret = false; break; } @@ -747,7 +701,6 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { SimulationNode dest = pcq.getTo(); time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); if (!(time < pcq.getMaxDropoffTime()*1000)) { - //not valid itinerary ret = false; break; } @@ -766,15 +719,9 @@ private Pair>, Long> createChargePlanNoNewRequests(List 0) { } time1 = timeToFinishEdge1; - // nemusim pricitat current sim time, protoze budu od sebe oba casy odecitat, jde mi jen o jejich rozdil long transferTime = 0; //expected arrival time of first car for (PlanAction action : itnryp1) { @@ -838,12 +784,9 @@ else if (veh1.getCurrentTripPlan().getSize() > 0) { PlanActionPickupTransfer pickup = null; previousDestination = veh2.getPosition(); - // podivam se na trip plan if (veh2.getCurrentTripPlan() != null) { if (veh2.getCurrentTripPlan().getSize() == 0) { SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getLastLocation(); - // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu - // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu timeToFinishEdge2 += travelTimeProvider.getTravelTime(veh2, stopLoc); previousDestination = stopLoc; } else if (veh2.getCurrentTripPlan().getSize() > 0) { @@ -898,17 +841,11 @@ else if (veh1.getCurrentTripPlan().getSize() > 0) { } indexPickupSecondCar++; } - long waitTime = time2 - time1; // k wait time prictu navic rezervu - - // pokud je zaporny, tak druhe auto bude muset cekat waitTime dlouho - // pokud je kladny, tak to znamena ze prvni auto prijede drive nez druhe - bude cekat cestujici + long waitTime = time2 - time1; boolean valid = true; -// pridat wait i pro druhe auto tam, kde je rozdil mensi nez 5 s -// aby tam byla rezerva if (waitTime > 0 && waitTime < 2000) { - // ceka aspon 2 s long newWait = 2000 - waitTime; PlanActionWait waitAction = new PlanActionWait(request, pickup.getPosition(), pickup.getMaxTime(), newWait); transferTime = newWait; @@ -917,12 +854,9 @@ else if (veh1.getCurrentTripPlan().getSize() > 0) { //check tolerable delay for passengers in vehicle2 long time = 0; previousDestination = veh2.getPosition(); - // podivam se na trip plan if (veh2.getCurrentTripPlan() != null) { if (veh2.getCurrentTripPlan().getSize() == 0) { SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getLastLocation(); - // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu - // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu time += travelTimeProvider.getTravelTime(veh2, stopLoc); previousDestination = stopLoc; } @@ -952,7 +886,6 @@ else if (veh2.getCurrentTripPlan().getSize() > 0) { SimulationNode dest = pcq.getFrom(); time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); if (!(time < pcq.getMaxPickupTime()*1000)) { - //not valid itinerary - check new driver plan valid = false; break; } @@ -961,7 +894,6 @@ else if (veh2.getCurrentTripPlan().getSize() > 0) { SimulationNode dest = pcq.getTo(); time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); if (!(time < pcq.getMaxDropoffTime()*1000)) { - //not valid itinerary - check new driver plan valid = false; break; } @@ -984,28 +916,18 @@ else if (veh2.getCurrentTripPlan().getSize() > 0) { } } } - // pridam wait time do planu pro druhe auto pokud je wait time zaporny - // pozor, pokud bych chtela smazat casovou rezervu 5 s, tak je tam nekde problem s wait akci s casem 0 - // - tak na to by bylo potreba udelat zvlast podminku a nejaky minimalni wait time tam nastavit, aby bylo zajistene poradi pri pruchodu algoritmem if (waitTime <= 0) { - // pridat 1000 je malo, ale 2000 dostacuje waitTime = waitTime - 2000; - //transfer time je -waitTime - // pickup by nemel byt null protoze se nastavi v predeslem loopu assert pickup != null; PlanActionWait waitAction = new PlanActionWait(request, pickup.getPosition(), pickup.getMaxTime(), -waitTime); transferTime = -waitTime; itnryp2.add(indexPickupSecondCar, waitAction); - //check tolerable delay for passengers in vehicle2 long time = 0; previousDestination = veh2.getPosition(); - // podivam se na trip plan if (veh2.getCurrentTripPlan() != null) { if (veh2.getCurrentTripPlan().getSize() == 0) { SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getLastLocation(); - // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu - // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu time += travelTimeProvider.getTravelTime(veh2, stopLoc); previousDestination = stopLoc; } @@ -1035,7 +957,6 @@ else if (veh2.getCurrentTripPlan().getSize() > 0) { SimulationNode dest = pcq.getFrom(); time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); if (!(time < pcq.getMaxPickupTime()*1000)) { - //not valid itinerary - check new driver plan valid = false; break; } @@ -1044,7 +965,6 @@ else if (veh2.getCurrentTripPlan().getSize() > 0) { SimulationNode dest = pcq.getTo(); time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); if (!(time < pcq.getMaxDropoffTime()*1000)) { - //not valid itinerary - check new driver plan valid = false; break; } @@ -1079,6 +999,377 @@ else if (veh2.getCurrentTripPlan().getSize() > 0) { } } + private Pair>, Long> createChargePlanNoNewRequestsWithRounding(List itnryp1, List itnryp2, RideSharingOnDemandVehicle veh1, RideSharingOnDemandVehicle veh2, PlanComputationRequest request) { + long time1 = 0; + int time1Int = 0; + long timeToFinishEdge1 = 0; + SimulationNode previousDestination = veh1.getPosition(); + + if (veh1.getCurrentTripPlan() != null) { + if (veh1.getCurrentTripPlan().getSize() == 0) { + SimulationNode stopLoc = (SimulationNode) veh1.getCurrentTripPlan().getLastLocation(); + timeToFinishEdge1 += travelTimeProvider.getTravelTime(veh1, stopLoc); + previousDestination = stopLoc; + } + else if (veh1.getCurrentTripPlan().getSize() > 0) { + SimulationNode stopLoc = (SimulationNode) veh1.getCurrentTripPlan().getFirstLocation(); + SimulationNode currLoc = (SimulationNode) veh1.getCurrentTripPlan().getAllLocations()[0]; + boolean currLocIsVehiclePosition = false; + int curridx = 0; + while (currLoc != stopLoc) { + if (currLocIsVehiclePosition) { + timeToFinishEdge1 += travelTimeProvider.getTravelTime(veh1, currLoc); + } + if (currLoc == veh1.getPosition()) { + currLocIsVehiclePosition = true; + } + previousDestination = (SimulationNode) veh1.getCurrentTripPlan().getAllLocations()[curridx]; + curridx++; + currLoc = (SimulationNode) veh1.getCurrentTripPlan().getAllLocations()[curridx]; + } + } + } + time1 = timeToFinishEdge1; + time1Int += (int) Math.ceil(timeToFinishEdge1 / 1000.0); + + long transferTime = 0; + + //expected arrival time of first car + for (PlanAction action : itnryp1) { + if (action instanceof PlanRequestAction) { + PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); + if (action instanceof PlanActionPickup) { + SimulationNode dest = pcq.getFrom(); + time1 = time1 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + time1Int += (int) Math.ceil(travelTimeProvider.getExpectedTravelTime(previousDestination, dest)/1000.0); + previousDestination = dest; + } else if(action instanceof PlanActionPickupTransfer) { + PlanActionPickupTransfer pickupTransfer = (PlanActionPickupTransfer) action; + SimulationNode dest = pickupTransfer.getPosition(); + time1 = time1 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + time1Int += (int) Math.ceil(travelTimeProvider.getExpectedTravelTime(previousDestination, dest)/1000.0); + previousDestination = dest; + } else if(action instanceof PlanActionDropoffTransfer) { + PlanActionDropoffTransfer dropoffTransfer = (PlanActionDropoffTransfer) action; + SimulationNode dest = dropoffTransfer.getPosition(); + time1 = time1 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + time1Int += (int) Math.ceil(travelTimeProvider.getExpectedTravelTime(previousDestination, dest)/1000.0); + if (dropoffTransfer.request == request) { + break; + } + previousDestination = dest; + } else if (action instanceof PlanActionDropoff) { + SimulationNode dest = pcq.getTo(); + time1 = time1 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + time1Int += (int) Math.ceil(travelTimeProvider.getExpectedTravelTime(previousDestination, dest)/1000.0); + previousDestination = dest; + } else if (action instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) action; + time1 = time1 + wait.getWaitTime(); + time1Int += (int) Math.ceil(wait.getWaitTime())/1000.0; + } + } + } + // expected arrival of second car + int indexPickupSecondCar = 0; + long time2 = 0; + int time2Int = 0; + long timeToFinishEdge2 = 0; + PlanActionPickupTransfer pickup = null; + previousDestination = veh2.getPosition(); + + if (veh2.getCurrentTripPlan() != null) { + if (veh2.getCurrentTripPlan().getSize() == 0) { + SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getLastLocation(); + timeToFinishEdge2 += travelTimeProvider.getTravelTime(veh2, stopLoc); + previousDestination = stopLoc; + } else if (veh2.getCurrentTripPlan().getSize() > 0) { + SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getFirstLocation(); + SimulationNode currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[0]; + boolean currLocIsVehiclePosition = false; + int curridx = 0; + while (currLoc != stopLoc) { + if (currLocIsVehiclePosition) { + timeToFinishEdge2 += travelTimeProvider.getTravelTime(veh2, currLoc); + } + if (currLoc == veh2.getPosition()) { + currLocIsVehiclePosition = true; + } + previousDestination = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx]; + curridx++; + currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx]; + } + } + } + time2 = timeToFinishEdge2; + time2Int += (int) Math.floor(timeToFinishEdge2/1000.0); + + for (PlanAction action : itnryp2) { + if (action instanceof PlanRequestAction) { + PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); + if (action instanceof PlanActionPickup) { + SimulationNode dest = pcq.getFrom(); + time2 = time2 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + time2Int += (int) Math.floor(travelTimeProvider.getExpectedTravelTime(previousDestination, dest) / 1000.0); + previousDestination = dest; + } else if(action instanceof PlanActionPickupTransfer) { + PlanActionPickupTransfer pickupTransfer = (PlanActionPickupTransfer) action; + SimulationNode dest = pickupTransfer.getPosition(); + time2 = time2 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + time2Int += (int) Math.floor(travelTimeProvider.getExpectedTravelTime(previousDestination, dest) / 1000.0); + if (pickupTransfer.request == request) { + pickup = pickupTransfer; + break; + } + previousDestination = dest; + } else if(action instanceof PlanActionDropoffTransfer) { + PlanActionDropoffTransfer dropoffTransfer = (PlanActionDropoffTransfer) action; + SimulationNode dest = dropoffTransfer.getPosition(); + time2 = time2 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + time2Int += (int) Math.floor(travelTimeProvider.getExpectedTravelTime(previousDestination, dest) / 1000.0); + previousDestination = dest; + } else if (action instanceof PlanActionDropoff) { + SimulationNode dest = pcq.getTo(); + time2 = time2 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + time2Int += (int) Math.floor(travelTimeProvider.getExpectedTravelTime(previousDestination, dest) / 1000.0); + previousDestination = dest; + } else if (action instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) action; + time2 = time2 + wait.getWaitTime(); + time2Int += (int) Math.floor(wait.getWaitTime() / 1000.0); + } + } + indexPickupSecondCar++; + } + long waitTime = time2 - time1; + int waitTimeInt = time2Int - time1Int; + + boolean valid = true; + + if (waitTime > 0) { + PlanActionWait waitAction = new PlanActionWait(request, pickup.getPosition(), pickup.getMaxTime(), waitTimeInt * 1000); + transferTime = waitTimeInt * 1000; + itnryp2.add(indexPickupSecondCar, waitAction); + + long time = 0; + previousDestination = veh2.getPosition(); + if (veh2.getCurrentTripPlan() != null) { + if (veh2.getCurrentTripPlan().getSize() == 0) { + SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getLastLocation(); + time += travelTimeProvider.getTravelTime(veh2, stopLoc); + previousDestination = stopLoc; + } + else if (veh2.getCurrentTripPlan().getSize() > 0) { + SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getFirstLocation(); + SimulationNode currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[0]; + boolean currLocIsVehiclePosition = false; + int curridx = 0; + while (currLoc != stopLoc) { + if (currLocIsVehiclePosition) { + time += travelTimeProvider.getTravelTime(veh2, currLoc); + } + if (currLoc == veh2.getPosition()) { + currLocIsVehiclePosition = true; + } + previousDestination = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx]; + curridx++; + currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx]; + } + } + } + + for (PlanAction action : itnryp2) { + if (action instanceof PlanRequestAction) { + PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); + if (action instanceof PlanActionPickup) { + SimulationNode dest = pcq.getFrom(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (!(time < pcq.getMaxPickupTime()*1000)) { + valid = false; + break; + } + previousDestination = dest; + } else if (action instanceof PlanActionDropoff) { + SimulationNode dest = pcq.getTo(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + if (!(time < pcq.getMaxDropoffTime()*1000)) { + valid = false; + break; + } + previousDestination = dest; + } else if (action instanceof PlanActionWait) { + PlanActionWait wait = (PlanActionWait) action; + time = time + wait.getWaitTime(); + previousDestination = wait.getPosition(); + } else if (action instanceof PlanActionPickupTransfer) { + PlanActionPickupTransfer p = (PlanActionPickupTransfer) action; + SimulationNode dest = p.getPosition(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = dest; + } else if(action instanceof PlanActionDropoffTransfer) { + PlanActionDropoffTransfer p = (PlanActionDropoffTransfer) action; + SimulationNode dest = p.getPosition(); + time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); + previousDestination = dest; + } + } + } + } + +// if (waitTime > 0 && waitTime < 2000) { +// long newWait = 2000 - waitTime; +// PlanActionWait waitAction = new PlanActionWait(request, pickup.getPosition(), pickup.getMaxTime(), newWait); +// transferTime = newWait; +// itnryp2.add(indexPickupSecondCar, waitAction); +// +// //check tolerable delay for passengers in vehicle2 +// long time = 0; +// previousDestination = veh2.getPosition(); +// if (veh2.getCurrentTripPlan() != null) { +// if (veh2.getCurrentTripPlan().getSize() == 0) { +// SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getLastLocation(); +// time += travelTimeProvider.getTravelTime(veh2, stopLoc); +// previousDestination = stopLoc; +// } +// else if (veh2.getCurrentTripPlan().getSize() > 0) { +// SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getFirstLocation(); +// SimulationNode currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[0]; +// boolean currLocIsVehiclePosition = false; +// int curridx = 0; +// while (currLoc != stopLoc) { +// if (currLocIsVehiclePosition) { +// time += travelTimeProvider.getTravelTime(veh2, currLoc); +// } +// if (currLoc == veh2.getPosition()) { +// currLocIsVehiclePosition = true; +// } +// previousDestination = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx]; +// curridx++; +// currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx]; +// } +// } +// } +// +// for (PlanAction action : itnryp2) { +// if (action instanceof PlanRequestAction) { +// PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); +// if (action instanceof PlanActionPickup) { +// SimulationNode dest = pcq.getFrom(); +// time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); +// if (!(time < pcq.getMaxPickupTime()*1000)) { +// valid = false; +// break; +// } +// previousDestination = dest; +// } else if (action instanceof PlanActionDropoff) { +// SimulationNode dest = pcq.getTo(); +// time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); +// if (!(time < pcq.getMaxDropoffTime()*1000)) { +// valid = false; +// break; +// } +// previousDestination = dest; +// } else if (action instanceof PlanActionWait) { +// PlanActionWait wait = (PlanActionWait) action; +// time = time + wait.getWaitTime(); +// previousDestination = wait.getPosition(); +// } else if (action instanceof PlanActionPickupTransfer) { +// PlanActionPickupTransfer p = (PlanActionPickupTransfer) action; +// SimulationNode dest = p.getPosition(); +// time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); +// previousDestination = dest; +// } else if(action instanceof PlanActionDropoffTransfer) { +// PlanActionDropoffTransfer p = (PlanActionDropoffTransfer) action; +// SimulationNode dest = p.getPosition(); +// time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); +// previousDestination = dest; +// } +// } +// } +// } +// if (waitTime <= 0) { +// waitTime = waitTime - 2000; +// assert pickup != null; +// PlanActionWait waitAction = new PlanActionWait(request, pickup.getPosition(), pickup.getMaxTime(), -waitTime); +// transferTime = -waitTime; +// itnryp2.add(indexPickupSecondCar, waitAction); +// +// long time = 0; +// previousDestination = veh2.getPosition(); +// if (veh2.getCurrentTripPlan() != null) { +// if (veh2.getCurrentTripPlan().getSize() == 0) { +// SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getLastLocation(); +// time += travelTimeProvider.getTravelTime(veh2, stopLoc); +// previousDestination = stopLoc; +// } +// else if (veh2.getCurrentTripPlan().getSize() > 0) { +// SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getFirstLocation(); +// SimulationNode currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[0]; +// boolean currLocIsVehiclePosition = false; +// int curridx = 0; +// while (currLoc != stopLoc) { +// if (currLocIsVehiclePosition) { +// time += travelTimeProvider.getTravelTime(veh2, currLoc); +// } +// if (currLoc == veh2.getPosition()) { +// currLocIsVehiclePosition = true; +// } +// previousDestination = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx]; +// curridx++; +// currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx]; +// } +// } +// } +// +// for (PlanAction action : itnryp2) { +// if (action instanceof PlanRequestAction) { +// PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); +// if (action instanceof PlanActionPickup) { +// SimulationNode dest = pcq.getFrom(); +// time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); +// if (!(time < pcq.getMaxPickupTime()*1000)) { +// valid = false; +// break; +// } +// previousDestination = dest; +// } else if (action instanceof PlanActionDropoff) { +// SimulationNode dest = pcq.getTo(); +// time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); +// if (!(time < pcq.getMaxDropoffTime()*1000)) { +// valid = false; +// break; +// } +// previousDestination = dest; +// } else if (action instanceof PlanActionWait) { +// PlanActionWait wait = (PlanActionWait) action; +// time = time + wait.getWaitTime(); +// previousDestination = wait.getPosition(); +// } else if (action instanceof PlanActionPickupTransfer) { +// PlanActionPickupTransfer p = (PlanActionPickupTransfer) action; +// SimulationNode dest = p.getPosition(); +// time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); +// previousDestination = dest; +// } else if(action instanceof PlanActionDropoffTransfer) { +// PlanActionDropoffTransfer p = (PlanActionDropoffTransfer) action; +// SimulationNode dest = p.getPosition(); +// time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); +// previousDestination = dest; +// } +// } +// } +// } + if(valid) { + List> itnrys = new ArrayList<>(); + itnrys.add(itnryp1); + itnrys.add(itnryp2); + Pair>, Long> ret = new Pair<>(itnrys, transferTime); + return ret; + } + else { + return null; + } + } + public List getPickupActions(List plan) { List pickups = new ArrayList<>(); for(PlanAction action : plan) { @@ -1106,8 +1397,6 @@ private HashMap getEstimatedTimesOfDropoff(List 0) { if (action instanceof PlanActionPickup || action instanceof PlanActionPickupTransfer) { time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, action.getPosition()); if (time > ((PlanRequestAction) action).request.getMaxPickupTime() * 1000) { - //not valid return null; } previousDestination = action.getPosition(); } else if (action instanceof PlanActionDropoff || action instanceof PlanActionDropoffTransfer) { time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, action.getPosition()); if (time > ((PlanRequestAction) action).request.getMaxDropoffTime() * 1000) { - //not valid return null; } times.put(((PlanRequestAction) action).getRequest(), time); @@ -1152,7 +1439,6 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { } else if (action instanceof PlanActionWait) { time = time + ((PlanActionWait) action).getWaitTime(); } - } return times; } @@ -1160,8 +1446,6 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { private List findItineraryWithMinimumDelayNew(List> lst, List originalPlan, RideSharingOnDemandVehicle vehicle) { HashMap timesOfDropOriginal = getEstimatedTimesOfDropoff(originalPlan, vehicle); if (timesOfDropOriginal == null) { - //plan neni validni - // to je chyba, puvodni plan by mel byt validni vzdy return null; //TODO throw exception } @@ -1169,15 +1453,12 @@ private List findItineraryWithMinimumDelayNew(List> for (List itnry : lst) { HashMap timesOfDropNew = getEstimatedTimesOfDropoff(itnry, vehicle); if (timesOfDropNew == null) { - //plan neni validni delays.add(Long.MAX_VALUE); } else { - // plan je validni, spocitam zpozdeni long delay = countDelayDifference(timesOfDropOriginal, timesOfDropNew); delays.add(delay); } } - //find max in delays int maxAt = 0; for (int i = 0; i < delays.size(); i++) { maxAt = delays.get(i) > delays.get(maxAt) ? i : maxAt; @@ -1219,9 +1500,6 @@ private List findPlanWithNoTransferNew(PlanComputationRequest newReq vehiclePlan = vehicle.getCurrentPlanNoUpdate(); } if (isWithTransfer(vehiclePlan)) { - // v aute nekdo prestupuje - // musim oddelit segment s prestupem - // ze zbytku vezmu pickups, pridam novy a potom hledam permutace dropoff akci int indexLastTransfer = findLastTransferActionIndex(vehiclePlan); List segmentWithTransfer = vehiclePlan.plan.subList(0, indexLastTransfer+1); List segmentWithTransferWithoutPositionAction = removeCurrentPositionActions(segmentWithTransfer); @@ -1233,10 +1511,8 @@ private List findPlanWithNoTransferNew(PlanComputationRequest newReq for (PlanAction action : segmentAfterTransfer) { newPlan.add(action); } - //add pickup and dropoff for new request newPlan.add(newRequest.getPickUpAction()); newPlan.add(newRequest.getDropOffAction()); - //get pickup order based on heuristic from TASeT paper List pickups = getPickupActions(newPlan); List dropoffs = getDropoffActions(newPlan); //permute dropoff orders @@ -1244,7 +1520,6 @@ private List findPlanWithNoTransferNew(PlanComputationRequest newReq for (List dropoffPlan : dropoffOrders) { lstTemp.add(createItineraryList(pickups, dropoffPlan)); } - // ted spojit puvodni segment a kadzy itinerare z lst for (List itnry : lstTemp) { List newList = new ArrayList<>(segmentWithTransferWithoutPositionAction); newList.addAll(itnry); @@ -1253,14 +1528,11 @@ private List findPlanWithNoTransferNew(PlanComputationRequest newReq return findItineraryWithMinimumDelayNew(lst, vehiclePlan.plan, vehicle); } else { - //neni prestup v aute List> lst = new ArrayList<>(); List newPlan = new ArrayList<>(); newPlan.addAll(vehiclePlan.plan); - //add pickup and dropoff for new request newPlan.add(newRequest.getPickUpAction()); newPlan.add(newRequest.getDropOffAction()); - //get pickup order based on heuristic from TASeT paper List pickups = getPickupActions(newPlan); List dropoffs = getDropoffActions(newPlan); //permute dropoff orders @@ -1280,9 +1552,6 @@ private List findPlanWithNoTransferActionsNew(PlanAction pickup, Pla vehiclePlan = vehicle.getCurrentPlanNoUpdate(); } if (isWithTransfer(vehiclePlan)) { - // v aute nekdo prestupuje - // musim oddelit segment s prestupem - // ze zbytku vezmu pickups, pridam novy a potom hledam permutace dropoff akci int indexLastTransfer = findLastTransferActionIndex(vehiclePlan); List segmentWithTransfer = vehiclePlan.plan.subList(0, indexLastTransfer+1); List segmentWithTransferWithoutPositionAction = removeCurrentPositionActions(segmentWithTransfer); @@ -1303,7 +1572,6 @@ private List findPlanWithNoTransferActionsNew(PlanAction pickup, Pla for (List dropoffPlan : dropoffOrders) { lstTemp.add(createItineraryList(pickups, dropoffPlan)); } - // ted spojit puvodni segment a kadzy itinerare z lst for (List itnry : lstTemp) { List newList = new ArrayList<>(segmentWithTransferWithoutPositionAction); newList.addAll(itnry); @@ -1312,7 +1580,6 @@ private List findPlanWithNoTransferActionsNew(PlanAction pickup, Pla return findItineraryWithMinimumDelayNew(lst, vehiclePlan.plan, vehicle); } else { - //neni prestup v aute List> lst = new ArrayList<>(); List newPlan = new ArrayList<>(); newPlan.addAll(vehiclePlan.plan); @@ -1381,7 +1648,6 @@ private boolean canServeRequestTASeT2(RideSharingOnDemandVehicle vehicle, PlanCo } } List requestsOnBoard = new ArrayList<>(requestsOnBoardSet); - // kolik lidi je prave ted v aute boolean taxiFree = true; int taxiCapacity = vehicle.getCapacity(); if (requestsOnBoardSet.size() >= taxiCapacity) { @@ -1399,7 +1665,6 @@ private boolean canServeRequestTASeT2(RideSharingOnDemandVehicle vehicle, PlanCo return false; } if (isWithTransfer(vehicle.getCurrentPlanNoUpdate())) { - // nekdo prestupuje int indexLastTransferAction = findLastTransferActionIndex(vehicle.getCurrentPlanNoUpdate()); long timeToFinishCurrentEdge = 0; SimulationNode previousPos = vehicle.getPosition(); @@ -1417,7 +1682,6 @@ private boolean canServeRequestTASeT2(RideSharingOnDemandVehicle vehicle, PlanCo } previousPos = vehicle.getCurrentPlanNoUpdate().plan.get(q).getPosition(); } - // ted potrebuju najit posledni pickup ve zbyvajicim driver planu po prestupu List segmentAfterTransfer = vehicle.getCurrentPlanNoUpdate().plan.subList(indexLastTransferAction+1, vehicle.getCurrentPlanNoUpdate().plan.size()); int indexLastPickupSegment = findLastPickupIndexList(segmentAfterTransfer); long timeToLastPickup = 0; @@ -1429,8 +1693,6 @@ private boolean canServeRequestTASeT2(RideSharingOnDemandVehicle vehicle, PlanCo previousPos2 = segmentAfterTransfer.get(q).getPosition(); } } - - //odtud jestli muze dojet k requestu - tj. cas od mista kde skoncil k vyzvednuti requestu long timeToNewRequest = travelTimeProvider.getExpectedTravelTime(previousPos2, request.getFrom()); long estimatedArrival = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastTransferAction + timeToLastPickup + timeToNewRequest; if (estimatedArrival <= request.getMaxPickupTime() * 1000) { @@ -1440,7 +1702,6 @@ private boolean canServeRequestTASeT2(RideSharingOnDemandVehicle vehicle, PlanCo } } else { - //neprestupuje nikdo int indexLastPickup = findLastPickupIndex(vehicle.getCurrentPlanNoUpdate()); long timeToFinishCurrentEdge = 0; SimulationNode previousPos = vehicle.getPosition(); @@ -1461,7 +1722,6 @@ private boolean canServeRequestTASeT2(RideSharingOnDemandVehicle vehicle, PlanCo return false; } } - } } } From b8e44f7a98efd36a86e91579b8540a75473b1b8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kub=C3=ADkov=C3=A1=2C=20Ad=C3=A9la?= Date: Wed, 4 May 2022 22:36:23 +0200 Subject: [PATCH 14/21] Fix rounding in TASeT --- .../greedyTASeT/GreedyTASeTSolver.java | 150 +----------------- 1 file changed, 3 insertions(+), 147 deletions(-) diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java index a5414aca..b95a48fd 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java @@ -461,7 +461,7 @@ private Map heuristics(List>, Long> p = createChargePlanNoNewRequests(itnryp1, itnryp2, taxi, taxis.get(k), request); + Pair>, Long> p = createChargePlanNoNewRequestsWithRounding(itnryp1, itnryp2, taxi, taxis.get(k), request); if (p == null) { continue; } else { @@ -1141,13 +1141,12 @@ else if (veh1.getCurrentTripPlan().getSize() > 0) { } indexPickupSecondCar++; } - long waitTime = time2 - time1; int waitTimeInt = time2Int - time1Int; boolean valid = true; - if (waitTime > 0) { - PlanActionWait waitAction = new PlanActionWait(request, pickup.getPosition(), pickup.getMaxTime(), waitTimeInt * 1000); + if (waitTimeInt < 0) { + PlanActionWait waitAction = new PlanActionWait(request, pickup.getPosition(), pickup.getMaxTime(), -waitTimeInt * 1000); transferTime = waitTimeInt * 1000; itnryp2.add(indexPickupSecondCar, waitAction); @@ -1215,149 +1214,6 @@ else if (veh2.getCurrentTripPlan().getSize() > 0) { } } } - -// if (waitTime > 0 && waitTime < 2000) { -// long newWait = 2000 - waitTime; -// PlanActionWait waitAction = new PlanActionWait(request, pickup.getPosition(), pickup.getMaxTime(), newWait); -// transferTime = newWait; -// itnryp2.add(indexPickupSecondCar, waitAction); -// -// //check tolerable delay for passengers in vehicle2 -// long time = 0; -// previousDestination = veh2.getPosition(); -// if (veh2.getCurrentTripPlan() != null) { -// if (veh2.getCurrentTripPlan().getSize() == 0) { -// SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getLastLocation(); -// time += travelTimeProvider.getTravelTime(veh2, stopLoc); -// previousDestination = stopLoc; -// } -// else if (veh2.getCurrentTripPlan().getSize() > 0) { -// SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getFirstLocation(); -// SimulationNode currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[0]; -// boolean currLocIsVehiclePosition = false; -// int curridx = 0; -// while (currLoc != stopLoc) { -// if (currLocIsVehiclePosition) { -// time += travelTimeProvider.getTravelTime(veh2, currLoc); -// } -// if (currLoc == veh2.getPosition()) { -// currLocIsVehiclePosition = true; -// } -// previousDestination = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx]; -// curridx++; -// currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx]; -// } -// } -// } -// -// for (PlanAction action : itnryp2) { -// if (action instanceof PlanRequestAction) { -// PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); -// if (action instanceof PlanActionPickup) { -// SimulationNode dest = pcq.getFrom(); -// time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); -// if (!(time < pcq.getMaxPickupTime()*1000)) { -// valid = false; -// break; -// } -// previousDestination = dest; -// } else if (action instanceof PlanActionDropoff) { -// SimulationNode dest = pcq.getTo(); -// time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); -// if (!(time < pcq.getMaxDropoffTime()*1000)) { -// valid = false; -// break; -// } -// previousDestination = dest; -// } else if (action instanceof PlanActionWait) { -// PlanActionWait wait = (PlanActionWait) action; -// time = time + wait.getWaitTime(); -// previousDestination = wait.getPosition(); -// } else if (action instanceof PlanActionPickupTransfer) { -// PlanActionPickupTransfer p = (PlanActionPickupTransfer) action; -// SimulationNode dest = p.getPosition(); -// time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); -// previousDestination = dest; -// } else if(action instanceof PlanActionDropoffTransfer) { -// PlanActionDropoffTransfer p = (PlanActionDropoffTransfer) action; -// SimulationNode dest = p.getPosition(); -// time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); -// previousDestination = dest; -// } -// } -// } -// } -// if (waitTime <= 0) { -// waitTime = waitTime - 2000; -// assert pickup != null; -// PlanActionWait waitAction = new PlanActionWait(request, pickup.getPosition(), pickup.getMaxTime(), -waitTime); -// transferTime = -waitTime; -// itnryp2.add(indexPickupSecondCar, waitAction); -// -// long time = 0; -// previousDestination = veh2.getPosition(); -// if (veh2.getCurrentTripPlan() != null) { -// if (veh2.getCurrentTripPlan().getSize() == 0) { -// SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getLastLocation(); -// time += travelTimeProvider.getTravelTime(veh2, stopLoc); -// previousDestination = stopLoc; -// } -// else if (veh2.getCurrentTripPlan().getSize() > 0) { -// SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getFirstLocation(); -// SimulationNode currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[0]; -// boolean currLocIsVehiclePosition = false; -// int curridx = 0; -// while (currLoc != stopLoc) { -// if (currLocIsVehiclePosition) { -// time += travelTimeProvider.getTravelTime(veh2, currLoc); -// } -// if (currLoc == veh2.getPosition()) { -// currLocIsVehiclePosition = true; -// } -// previousDestination = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx]; -// curridx++; -// currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx]; -// } -// } -// } -// -// for (PlanAction action : itnryp2) { -// if (action instanceof PlanRequestAction) { -// PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest(); -// if (action instanceof PlanActionPickup) { -// SimulationNode dest = pcq.getFrom(); -// time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); -// if (!(time < pcq.getMaxPickupTime()*1000)) { -// valid = false; -// break; -// } -// previousDestination = dest; -// } else if (action instanceof PlanActionDropoff) { -// SimulationNode dest = pcq.getTo(); -// time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); -// if (!(time < pcq.getMaxDropoffTime()*1000)) { -// valid = false; -// break; -// } -// previousDestination = dest; -// } else if (action instanceof PlanActionWait) { -// PlanActionWait wait = (PlanActionWait) action; -// time = time + wait.getWaitTime(); -// previousDestination = wait.getPosition(); -// } else if (action instanceof PlanActionPickupTransfer) { -// PlanActionPickupTransfer p = (PlanActionPickupTransfer) action; -// SimulationNode dest = p.getPosition(); -// time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); -// previousDestination = dest; -// } else if(action instanceof PlanActionDropoffTransfer) { -// PlanActionDropoffTransfer p = (PlanActionDropoffTransfer) action; -// SimulationNode dest = p.getPosition(); -// time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest); -// previousDestination = dest; -// } -// } -// } -// } if(valid) { List> itnrys = new ArrayList<>(); itnrys.add(itnryp1); From 0bb7b198c4718b16702704cb7b28d482ac796d6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kub=C3=ADkov=C3=A1=2C=20Ad=C3=A9la?= Date: Sun, 8 May 2022 15:35:29 +0200 Subject: [PATCH 15/21] Descending to ascending order of requests, wrong from TASeT paper. --- .../aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java | 4 ++-- .../transferinsertion/TransferInsertionSolver.java | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java index b95a48fd..4ece9861 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java @@ -384,8 +384,8 @@ private Map heuristics(List requestsCopy = new ArrayList<>(requests); requests.sort(Comparator.comparing(x -> possiblePickupTaxisCounts[requestsCopy.indexOf(x)])); - //order to descending order - Collections.reverse(requests); + //order to descending order - ve skutecnosti to ma byt ascending, i kdyz pisou descending :]]] +// Collections.reverse(requests); planMap = new ConcurrentHashMap<>(); diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java index 68642491..61159ea4 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java @@ -131,8 +131,7 @@ public Map solve(List requestsCopy = new ArrayList<>(requests); requests.sort(Comparator.comparing(x -> possiblePickupTaxisCounts[requestsCopy.indexOf(x)])); - //order to descending order - Collections.reverse(requests); + planMap = new ConcurrentHashMap<>(); From b771df7038577ff9971d7d46c988903d4680b266 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kub=C3=ADkov=C3=A1=2C=20Ad=C3=A9la?= Date: Sun, 8 May 2022 18:22:45 +0200 Subject: [PATCH 16/21] Delete condition for discarding possible plans with longer waiting --- .../ridesharing/transferinsertion/TransferInsertionSolver.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java index 61159ea4..0efcdeff 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java @@ -224,10 +224,8 @@ public Map solve(List transferPlans = new ArrayList<>(); for (int j = 0; j < itinerariesPairs.size(); j++) { - if (waitTimes.get(j) < 10000) { TransferPlan t = new TransferPlan(waitTimes.get(j), delays.get(j), itinerariesPairs.get(j)); transferPlans.add(t); - } } transferPlans.sort(TransferPlan::compareByTransferTime); double beta = 0.2; From 48c36eba4042728d564f199fbbd3d8cded9fa610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kub=C3=ADkov=C3=A1=2C=20Ad=C3=A9la?= Date: Sun, 8 May 2022 22:41:30 +0200 Subject: [PATCH 17/21] Fix selecting of action order in possible plans --- .../transferinsertion/TransferInsertionSolver.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java index 0efcdeff..9ed7df67 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java @@ -268,6 +268,8 @@ public List findItineraryBestInsertionFirstSegment(PlanAction pickup } List> allPosibleActionsOrder = new ArrayList<>(); List planDurations = new ArrayList<>(); + Pair originalPlanPair = checkValidItineraryAndCountPlanDurationFirstPart(currentVehiclePlan.plan, vehicle); + Integer durationOriginalPlan = originalPlanPair.getSecond(); for (int i = 1; i < currentVehiclePlan.plan.size()+1; i++) { for (int j = i+1; j < currentVehiclePlan.plan.size()+2; j++) { @@ -278,7 +280,7 @@ public List findItineraryBestInsertionFirstSegment(PlanAction pickup if (p.getFirst()) { if (checkCapacityNotExceeded(tempPlan, vehicle)) { allPosibleActionsOrder.add(tempPlan); - planDurations.add(p.getSecond()); + planDurations.add(p.getSecond() - durationOriginalPlan); } } } @@ -303,6 +305,9 @@ public List findTransferItineraryBestInsertionSecondSegment(PlanActi } List> allPosibleActionsOrder = new ArrayList<>(); List planDurations = new ArrayList<>(); + Pair originalPlanPair = checkValidItineraryAndCountPlanDurationSecondPart(currentVehiclePlan.plan, vehicle); + Integer durationOriginalPlan = originalPlanPair.getSecond(); + for (int i = 1; i < currentVehiclePlan.plan.size()+1; i++) { for (int j = i+1; j < currentVehiclePlan.plan.size()+2; j++) { @@ -320,7 +325,7 @@ public List findTransferItineraryBestInsertionSecondSegment(PlanActi if (p.getFirst()) { if (checkCapacityNotExceeded(tempPlan, vehicle)) { allPosibleActionsOrder.add(tempPlan); - planDurations.add(p.getSecond()); + planDurations.add(p.getSecond() - durationOriginalPlan); } } } @@ -345,6 +350,9 @@ public List findItineraryBestInsertion(PlanAction pickup, PlanAction } List> allPosibleActionsOrder = new ArrayList<>(); List planDurations = new ArrayList<>(); + Pair originalPlanPair = checkValidItineraryAndCountPlanDuration(currentVehiclePlan.plan, vehicle); + Long durationOriginalPlan = originalPlanPair.getSecond(); + for (int i = 1; i < currentVehiclePlan.plan.size()+1; i++) { for (int j = i+1; j < currentVehiclePlan.plan.size()+2; j++) { @@ -355,7 +363,7 @@ public List findItineraryBestInsertion(PlanAction pickup, PlanAction if (p.getFirst()) { if (checkCapacityNotExceeded(tempPlan, vehicle)) { allPosibleActionsOrder.add(tempPlan); - planDurations.add(p.getSecond()); + planDurations.add(p.getSecond() - durationOriginalPlan); } } } From a8ebb224b519b82a3fb9ab8e99faa105933232c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kub=C3=ADkov=C3=A1=2C=20Ad=C3=A9la?= Date: Mon, 9 May 2022 02:26:50 +0200 Subject: [PATCH 18/21] Fix less to less or equal in valid itinerary check --- .../transferinsertion/TransferInsertionSolver.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java index 9ed7df67..0c45e965 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java @@ -472,7 +472,7 @@ public int countMaxTimeTransferRound(List itnryp1, RideSharingOnDema return dropTime; } else { Integer dropTime = getArrivalTimeToStationIntFloor(itnryp2, veh2, request); - return dropTime - 1; + return dropTime; } } @@ -581,7 +581,7 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { PlanActionPickupTransfer pickupTransfer = (PlanActionPickupTransfer) action; SimulationNode dest = pickupTransfer.getPosition(); time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); - if (!(time < pickupTransfer.getMaxTime() * 1000)) { + if (!(time <= pickupTransfer.getMaxTime() * 1000)) { ret = false; break; } @@ -590,7 +590,7 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { PlanActionDropoffTransfer dropoffTransfer = (PlanActionDropoffTransfer) action; SimulationNode dest = dropoffTransfer.getPosition(); time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); - if (!(time < dropoffTransfer.getMaxTime() * 1000)) { + if (!(time <= dropoffTransfer.getMaxTime() * 1000)) { ret = false; break; } @@ -682,7 +682,7 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { SimulationNode dest = pickupTransfer.getPosition(); time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); timeRounded += (int) Math.ceil(travelTimeProvider.getExpectedTravelTime(previousDestination, dest) / 1000.0); - if (!(timeRounded < pickupTransfer.getMaxTime())) { + if (!(timeRounded <= pickupTransfer.getMaxTime())) { ret = false; break; } @@ -692,7 +692,7 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { SimulationNode dest = dropoffTransfer.getPosition(); time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); timeRounded += (int) Math.ceil(travelTimeProvider.getExpectedTravelTime(previousDestination, dest) / 1000.0); - if (!(timeRounded < dropoffTransfer.getMaxTime())) { + if (!(timeRounded <= dropoffTransfer.getMaxTime())) { ret = false; break; } @@ -789,7 +789,7 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { SimulationNode dest = pickupTransfer.getPosition(); time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); timeRounded += (int) Math.floor(travelTimeProvider.getExpectedTravelTime(previousDestination, dest) / 1000.0); - if (!(timeRounded < pickupTransfer.getMaxTime())) { + if (!(timeRounded <= pickupTransfer.getMaxTime())) { ret = false; break; } @@ -799,7 +799,7 @@ else if (vehicle.getCurrentTripPlan().getSize() > 0) { SimulationNode dest = dropoffTransfer.getPosition(); time += travelTimeProvider.getExpectedTravelTime(previousDestination, dest); timeRounded += (int) Math.floor(travelTimeProvider.getExpectedTravelTime(previousDestination, dest) / 1000.0); - if (!(timeRounded < dropoffTransfer.getMaxTime())) { + if (!(timeRounded <= dropoffTransfer.getMaxTime())) { ret = false; break; } From bd875ea84235251af1f4288fcfb59da7edb0b793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kub=C3=ADkov=C3=A1=2C=20Ad=C3=A9la?= Date: Thu, 19 May 2022 18:15:30 +0200 Subject: [PATCH 19/21] Add statistics --- .../aic/simod/OnDemandVehiclesSimulation.java | 32 ++++++ .../cvut/fel/aic/simod/config/Statistics.java | 12 ++ .../fel/aic/simod/entity/DemandAgent.java | 4 +- .../greedyTASeT/GreedyTASeTSolver.java | 62 +++++++++- .../InsertionHeuristicSolver.java | 26 +++++ .../TransferInsertionSolver.java | 54 +++++++++ .../cvut/fel/aic/simod/statistics/Result.java | 7 +- .../aic/simod/statistics/StatisticEvent.java | 3 +- .../fel/aic/simod/statistics/Statistics.java | 106 +++++++++++++++++- .../AstarTravelTimeProvider.java | 16 +-- .../cz/cvut/fel/aic/simod/config/config.cfg | 6 + .../greedyTASeT/GreedyTASeTSolverTest.java | 2 +- 12 files changed, 305 insertions(+), 25 deletions(-) diff --git a/src/main/java/cz/cvut/fel/aic/simod/OnDemandVehiclesSimulation.java b/src/main/java/cz/cvut/fel/aic/simod/OnDemandVehiclesSimulation.java index 1e2bd4ca..b32a90ef 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/OnDemandVehiclesSimulation.java +++ b/src/main/java/cz/cvut/fel/aic/simod/OnDemandVehiclesSimulation.java @@ -20,8 +20,12 @@ import com.google.inject.Injector; import cz.cvut.fel.aic.agentpolis.config.AgentpolisConfig; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.TripsUtil; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.trip.Trip; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.init.MapInitializer; import cz.cvut.fel.aic.agentpolis.simulator.creator.SimulationCreator; +import cz.cvut.fel.aic.agentpolis.simulator.visualization.visio.VisioPositionUtil; import cz.cvut.fel.aic.agentpolis.system.AgentPolisInitializer; import cz.cvut.fel.aic.simod.config.SimodConfig; import cz.cvut.fel.aic.simod.config.TransferInsertion; @@ -29,6 +33,7 @@ import cz.cvut.fel.aic.simod.init.StationsInitializer; import cz.cvut.fel.aic.simod.init.StatisticInitializer; import cz.cvut.fel.aic.simod.init.TransferPointsInitializer; +import cz.cvut.fel.aic.simod.io.TimeTrip; import cz.cvut.fel.aic.simod.io.TripTransform; import cz.cvut.fel.aic.simod.rebalancing.ReactiveRebalancing; import cz.cvut.fel.aic.simod.ridesharing.greedyTASeT.GreedyTASeTSolver; @@ -39,6 +44,10 @@ import cz.cvut.fel.aic.simod.tripUtil.TripsUtilCached; import java.io.File; import java.net.MalformedURLException; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + import org.slf4j.LoggerFactory; /** @@ -135,6 +144,29 @@ public void run(String[] args) { injector.getInstance(EventInitializer.class).initialize( tripTransform.loadTripsFromTxt(new File(config.tripsPath)), null); +// USED TO COMPUTE STATISTICS OF DEMAND +// List lengths = new ArrayList<>(); +// List> trips = tripTransform.loadTripsFromTxt(new File(config.tripsPath)); +// for (TimeTrip trip : trips) { +// SimulationNode origin = trip.getAllLocations()[0]; +// SimulationNode destination = trip.getAllLocations()[1]; +// Trip t = injector.getInstance(TripsUtil.class).createTrip(origin, destination); +// long l = injector.getInstance(VisioPositionUtil.class).getTripLengthInMeters(t); +// lengths.add(l); +// } +// +//// get max, min and avg +// lengths.stream() // +// .max(Comparator.comparing(i -> i)) // +// .ifPresent(max -> System.out.println("Maximum found is " + max)); +// lengths.stream() // +// .min(Comparator.comparing(i -> i)) // +// .ifPresent(min -> System.out.println("Minimum found is " + min)); +// lengths.stream() // +// .mapToLong(i -> i) // +// .average() // +// .ifPresent(avg -> System.out.println("Average found is " + avg)); + injector.getInstance(StatisticInitializer.class).initialize(); // start it up diff --git a/src/main/java/cz/cvut/fel/aic/simod/config/Statistics.java b/src/main/java/cz/cvut/fel/aic/simod/config/Statistics.java index 7b6ecbc2..54a6b1f0 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/config/Statistics.java +++ b/src/main/java/cz/cvut/fel/aic/simod/config/Statistics.java @@ -9,6 +9,10 @@ public class Statistics { public String occupanciesFilePath; + public String inactiveVehiclesFilePath; + + public String inactiveVehiclesFileName; + public String ridesharingFileName; public Integer statisticIntervalMilis; @@ -41,6 +45,10 @@ public class Statistics { public String ridesharingFilePath; + public String waitingTimesFilePath; + + public String waitingTimesFileName; + public Statistics(Map statistics) { this.resultFilePath = (String) statistics.get("result_file_path"); this.occupanciesFilePath = (String) statistics.get("occupancies_file_path"); @@ -60,5 +68,9 @@ public Statistics(Map statistics) { this.serviceFileName = (String) statistics.get("service_file_name"); this.serviceFilePath = (String) statistics.get("service_file_path"); this.ridesharingFilePath = (String) statistics.get("ridesharing_file_path"); + this.inactiveVehiclesFileName = (String) statistics.get("inactive_vehicles_file_name"); + this.inactiveVehiclesFilePath = (String) statistics.get("inactive_vehicles_file_path"); + this.waitingTimesFileName = (String) statistics.get("waiting_times_file_name"); + this.waitingTimesFilePath = (String) statistics.get("waiting_times_file_path"); } } diff --git a/src/main/java/cz/cvut/fel/aic/simod/entity/DemandAgent.java b/src/main/java/cz/cvut/fel/aic/simod/entity/DemandAgent.java index bd78d319..cb3f9592 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/entity/DemandAgent.java +++ b/src/main/java/cz/cvut/fel/aic/simod/entity/DemandAgent.java @@ -216,6 +216,9 @@ public void tripPaused() { else{ state = DemandAgentState.TRANSFERING; // this.onDemandVehicle = null; + eventProcessor.addEvent(StatisticEvent.DEMAND_DROPPED_AT_TRANSFER, null, null, + null); + } } @@ -230,7 +233,6 @@ public void tripRePaused(OnDemandVehicle vehicle) { // } // else{ state = DemandAgentState.DRIVING; - realPickupTime = timeProvider.getCurrentSimTime(); this.onDemandVehicle = vehicle; // } } diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java index 4ece9861..a26c41d1 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java @@ -49,7 +49,9 @@ public class GreedyTASeTSolver extends DARPSolver implements EventHandler { private Map planMap; + protected List> inactiveVehicles; + protected List> waitingTimes; @Inject @@ -74,6 +76,8 @@ public GreedyTASeTSolver( this.droppedDemandsAnalyzer = droppedDemandsAnalyzer; this.onDemandvehicleStationStorage = onDemandvehicleStationStorage; this.requestFactory = requestFactory; + inactiveVehicles = new ArrayList<>(); + waitingTimes = new ArrayList<>(); setEventHandeling(); } @@ -146,6 +150,22 @@ private boolean isWithTransfer(DriverPlan plan) { return false; } + + private void logInactiveVehicles(List vehicles) { + for (RideSharingOnDemandVehicle vehicle : vehicles) { + if (vehicle.getCurrentPlanNoUpdate().plan.size() == 1) { + if (!planMap.containsKey(vehicle)) { + // toto vozidlo ma prazdny plan + inactiveVehicles.add(new Pair(vehicle.getId(), (int) Math.round(timeProvider.getCurrentSimTime() / 1000.0))); + } + } + } + } + + private void logWaitingTime(RideSharingOnDemandVehicle vehicle, Integer waitTimeInSeconds) { + waitingTimes.add(new Pair(vehicle.getId(), waitTimeInSeconds)); + } + private int findLastPickupIndex(DriverPlan plan) { int index = -1; for (int i = 0; i < plan.getLength(); i++) { @@ -532,6 +552,10 @@ private Map heuristics(List planWithPos = new ArrayList<>(); planWithPos.add(vehicles.get(q).getCurrentPlanNoUpdate().plan.get(0)); planWithPos.addAll(vehPlan); + int waitTime = findWaitingAction(vehPlan, vehicles.get(q), request); + if (waitTime > 0) { + logWaitingTime(vehicles.get(q), waitTime); + } DriverPlan dp = new DriverPlan(planWithPos, 0, 0); planMap.put(vehicles.get(q), dp); } @@ -640,9 +664,32 @@ private Map heuristics(List plan, RideSharingOnDemandVehicle vehicle, PlanComputationRequest request) { + for (PlanAction action : plan) { + if (action instanceof PlanActionWait) { + if (((PlanActionWait) action).getRequest() == request) { + PlanActionWait wait = (PlanActionWait) action; + return (int) Math.round(wait.getWaitTime() / 1000.0); + } + } + } + return 0; + } + + public List> getInactiveVehicles() { + return inactiveVehicles; + } + + public List> getWaitingTimes() { + return waitingTimes; + } + private boolean checkValidItinerary(List itinerary, RideSharingOnDemandVehicle vehicle) { SimulationNode previousDestination = vehicle.getPosition(); boolean ret = true; @@ -1001,7 +1048,7 @@ else if (veh2.getCurrentTripPlan().getSize() > 0) { private Pair>, Long> createChargePlanNoNewRequestsWithRounding(List itnryp1, List itnryp2, RideSharingOnDemandVehicle veh1, RideSharingOnDemandVehicle veh2, PlanComputationRequest request) { long time1 = 0; - int time1Int = 0; + int time1Int = (int) Math.ceil(timeProvider.getCurrentSimTime() / 1000.0); long timeToFinishEdge1 = 0; SimulationNode previousDestination = veh1.getPosition(); @@ -1070,10 +1117,11 @@ else if (veh1.getCurrentTripPlan().getSize() > 0) { } } } + time1Int += 1; // expected arrival of second car int indexPickupSecondCar = 0; long time2 = 0; - int time2Int = 0; + int time2Int = (int) Math.floor(timeProvider.getCurrentSimTime() / 1000.0); long timeToFinishEdge2 = 0; PlanActionPickupTransfer pickup = null; previousDestination = veh2.getPosition(); @@ -1141,16 +1189,18 @@ else if (veh1.getCurrentTripPlan().getSize() > 0) { } indexPickupSecondCar++; } - int waitTimeInt = time2Int - time1Int; + time2Int -= 1; + int waitTimeInt = time1Int - time2Int; boolean valid = true; - if (waitTimeInt < 0) { - PlanActionWait waitAction = new PlanActionWait(request, pickup.getPosition(), pickup.getMaxTime(), -waitTimeInt * 1000); + if (waitTimeInt > 0) { + PlanActionWait waitAction = new PlanActionWait(request, pickup.getPosition(), pickup.getMaxTime(), waitTimeInt * 1000); transferTime = waitTimeInt * 1000; itnryp2.add(indexPickupSecondCar, waitAction); - long time = 0; + long time = timeProvider.getCurrentSimTime(); +// int timeInt = (int) Math.round(timeProvider.getCurrentSimTime() / 1000.0); previousDestination = veh2.getPosition(); if (veh2.getCurrentTripPlan() != null) { if (veh2.getCurrentTripPlan().getSize() == 0) { diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/insertionheuristic/InsertionHeuristicSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/insertionheuristic/InsertionHeuristicSolver.java index c7561a6d..65623806 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/insertionheuristic/InsertionHeuristicSolver.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/insertionheuristic/InsertionHeuristicSolver.java @@ -56,6 +56,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import me.tongfei.progressbar.ProgressBar; +import org.jgrapht.alg.util.Pair; import org.slf4j.LoggerFactory; /** @@ -116,6 +117,8 @@ public class InsertionHeuristicSolver extends DARPSolver implements EventHandler private int[] usedVehiclesPerStation; private List vehiclesForPlanning; + + protected List> inactiveVehicles; @@ -140,6 +143,7 @@ public InsertionHeuristicSolver( this.eventProcessor = eventProcessor; this.droppedDemandsAnalyzer = droppedDemandsAnalyzer; this.onDemandvehicleStationStorage = onDemandvehicleStationStorage; + inactiveVehicles = new ArrayList<>(); // max distance in meters between vehicle and request for the vehicle to be considered to serve the request @@ -159,6 +163,12 @@ public Map solve(List waitingRequests) { callCount++; long startTime = System.nanoTime(); + + List taxis = new ArrayList<>(); + for(AgentPolisEntity tVvehicle: vehicleStorage.getEntitiesForIteration()) { + RideSharingOnDemandVehicle vehicle = (RideSharingOnDemandVehicle) tVvehicle; + taxis.add(vehicle); + } planMap = new ConcurrentHashMap<>(); @@ -219,6 +229,7 @@ public Map solve(List requests) { requests.size())); } + private void logInactiveVehicles(List vehicles) { + for (RideSharingOnDemandVehicle vehicle : vehicles) { + if (vehicle.getCurrentPlanNoUpdate().plan.size() == 1) { + if (!planMap.containsKey(vehicle)) { + // toto vozidlo ma prazdny plan + inactiveVehicles.add(new Pair(vehicle.getId(), (int) Math.round(timeProvider.getCurrentSimTime() / 1000.0))); + } + } + } + } + private void computeBestPlanForRequest(PlanComputationRequest request) { resetBestPlan(); @@ -545,6 +567,10 @@ private void processRequest(PlanComputationRequest request) { // } // return listForPlanning; // } + + public List> getInactiveVehicles() { + return inactiveVehicles; + } private List getVehiclesForPlanning() { vehiclesForPlanning = new ArrayList<>(); diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java index 0c45e965..8226bf7d 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/transferinsertion/TransferInsertionSolver.java @@ -3,14 +3,19 @@ import com.google.inject.Inject; import com.google.inject.Singleton; import cz.cvut.fel.aic.agentpolis.config.AgentpolisConfig; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.TripsUtil; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.trip.Trip; import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.TimeProvider; import cz.cvut.fel.aic.agentpolis.simmodel.entity.AgentPolisEntity; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.EGraphType; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationEdge; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; import cz.cvut.fel.aic.agentpolis.utils.PositionUtil; import cz.cvut.fel.aic.alite.common.event.Event; import cz.cvut.fel.aic.alite.common.event.EventHandler; import cz.cvut.fel.aic.alite.common.event.EventProcessor; import cz.cvut.fel.aic.alite.common.event.typed.TypedSimulation; +import cz.cvut.fel.aic.geographtools.Node; import cz.cvut.fel.aic.simod.config.SimodConfig; import cz.cvut.fel.aic.simod.event.OnDemandVehicleEvent; import cz.cvut.fel.aic.simod.ridesharing.DARPSolver; @@ -50,6 +55,12 @@ public class TransferInsertionSolver extends DARPSolver implements EventHandler private Map planMap; + protected List> inactiveVehicles; + + protected List> waitingTimes; + + protected List> demandTripMinimalLength; + @Inject public TransferInsertionSolver( @@ -73,6 +84,9 @@ public TransferInsertionSolver( this.droppedDemandsAnalyzer = droppedDemandsAnalyzer; this.onDemandvehicleStationStorage = onDemandvehicleStationStorage; this.requestFactory = requestFactory; + inactiveVehicles = new ArrayList<>(); + waitingTimes = new ArrayList<>(); + demandTripMinimalLength = new ArrayList<>(); setEventHandeling(); } @@ -98,6 +112,21 @@ private void setEventHandeling() { eventProcessor.addEventHandler(this, typesToHandle); } + private void logWaitingTime(RideSharingOnDemandVehicle vehicle, Integer waitTimeInSeconds) { + waitingTimes.add(new Pair(vehicle.getId(), waitTimeInSeconds)); + } + + private void logInactiveVehicles(List vehicles) { + for (RideSharingOnDemandVehicle vehicle : vehicles) { + if (vehicle.getCurrentPlanNoUpdate().plan.size() == 1) { + if (!planMap.containsKey(vehicle)) { + // toto vozidlo ma prazdny plan + inactiveVehicles.add(new Pair(vehicle.getId(), (int) Math.round(timeProvider.getCurrentSimTime() / 1000.0))); + } + } + } + } + @Override public Map solve(List newRequests, List waitingRequests) { @@ -248,16 +277,41 @@ public Map solve(List vehicles = key.getSecond(); for (int q = 0; q < vehicles.size(); q++) { List vehPlan = plansForVehicles.get(q); + int waitTime = findWaitingAction(vehPlan, vehicles.get(q), request); + if (waitTime > 0) { + logWaitingTime(vehicles.get(q), waitTime); + } DriverPlan dp = new DriverPlan(vehPlan, 0, 0); planMap.put(vehicles.get(q), dp); } } } + + logInactiveVehicles(taxis); + return planMap; } + public Integer findWaitingAction(List plan, RideSharingOnDemandVehicle vehicle, PlanComputationRequest request) { + for (PlanAction action : plan) { + if (action instanceof PlanActionWait) { + if (((PlanActionWait) action).getRequest() == request) { + PlanActionWait wait = (PlanActionWait) action; + return (int) Math.round(wait.getWaitTime() / 1000.0); + } + } + } + return 0; + } + public List> getInactiveVehicles() { + return inactiveVehicles; + } + + public List> getWaitingTimes() { + return waitingTimes; + } public List findItineraryBestInsertionFirstSegment(PlanAction pickup, PlanAction dropoff, RideSharingOnDemandVehicle vehicle) { DriverPlan currentVehiclePlan; diff --git a/src/main/java/cz/cvut/fel/aic/simod/statistics/Result.java b/src/main/java/cz/cvut/fel/aic/simod/statistics/Result.java index 37765757..7ce4e571 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/statistics/Result.java +++ b/src/main/java/cz/cvut/fel/aic/simod/statistics/Result.java @@ -55,6 +55,8 @@ public class Result { private final long totalDistanceRebalancing; + private final int transfersDone; + @@ -122,6 +124,8 @@ public long getTotalDistanceToStation() { public long getTotalDistanceRebalancing() { return totalDistanceRebalancing; } + + public int getTransfersDone() { return transfersDone; } @@ -134,7 +138,7 @@ public Result(long tickCount, double averageLoadTotal, int maxLoad, double avera double averageKmToStartLocation, double averageKmToStation, double averageKmRebalancing, int numberOfDemandsNotServedFromNearestStation, int numberOfDemandsDropped, int demandsCount, int numberOfVehicles, int numberOfRebalancingDropped, long totalDistanceWithPassenger, - long totalDistanceToStartLocation, long totalDistanceToStation, long totalDistanceRebalancing) { + long totalDistanceToStartLocation, long totalDistanceToStation, long totalDistanceRebalancing, int transfersDone) { this.tickCount = tickCount; this.averageLoadTotal = averageLoadTotal; this.maxLoad = maxLoad; @@ -151,6 +155,7 @@ public Result(long tickCount, double averageLoadTotal, int maxLoad, double avera this.totalDistanceToStartLocation = totalDistanceToStartLocation; this.totalDistanceToStation = totalDistanceToStation; this.totalDistanceRebalancing = totalDistanceRebalancing; + this.transfersDone = transfersDone; } diff --git a/src/main/java/cz/cvut/fel/aic/simod/statistics/StatisticEvent.java b/src/main/java/cz/cvut/fel/aic/simod/statistics/StatisticEvent.java index b6c98667..c3a32370 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/statistics/StatisticEvent.java +++ b/src/main/java/cz/cvut/fel/aic/simod/statistics/StatisticEvent.java @@ -25,5 +25,6 @@ public enum StatisticEvent { TICK, VEHICLE_LEFT_STATION_TO_SERVE_DEMAND, - DEMAND_DROPPED_OFF + DEMAND_DROPPED_OFF, + DEMAND_DROPPED_AT_TRANSFER } diff --git a/src/main/java/cz/cvut/fel/aic/simod/statistics/Statistics.java b/src/main/java/cz/cvut/fel/aic/simod/statistics/Statistics.java index 653c78e7..0d343cb0 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/statistics/Statistics.java +++ b/src/main/java/cz/cvut/fel/aic/simod/statistics/Statistics.java @@ -31,6 +31,7 @@ import cz.cvut.fel.aic.alite.common.event.typed.TypedSimulation; import cz.cvut.fel.aic.simod.CsvWriter; import cz.cvut.fel.aic.simod.StationsDispatcher; +import cz.cvut.fel.aic.simod.config.InsertionHeuristic; import cz.cvut.fel.aic.simod.config.SimodConfig; import cz.cvut.fel.aic.simod.entity.OnDemandVehicleState; import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicle; @@ -38,7 +39,12 @@ import cz.cvut.fel.aic.simod.event.OnDemandVehicleEventContent; import cz.cvut.fel.aic.simod.io.Common; import cz.cvut.fel.aic.simod.ridesharing.DARPSolver; +import cz.cvut.fel.aic.simod.ridesharing.RideSharingOnDemandVehicle; +import cz.cvut.fel.aic.simod.ridesharing.insertionheuristic.InsertionHeuristicSolver; +import org.jgrapht.alg.util.Pair; import cz.cvut.fel.aic.simod.ridesharing.RidesharingDispatcher; +import cz.cvut.fel.aic.simod.ridesharing.greedyTASeT.GreedyTASeTSolver; +import cz.cvut.fel.aic.simod.ridesharing.transferinsertion.TransferInsertionSolver; import cz.cvut.fel.aic.simod.statistics.content.RidesharingBatchStats; import cz.cvut.fel.aic.simod.statistics.content.RidesharingBatchStatsIH; import cz.cvut.fel.aic.simod.statistics.content.RidesharingBatchStatsVGA; @@ -123,6 +129,8 @@ public class Statistics extends AliteEntity implements EventHandler{ private long totalDistanceToStation; private long totalDistanceRebalancing; + + private int transfersDone; @@ -158,6 +166,7 @@ public Statistics(TypedSimulation eventProcessor, Provider all tickCount = 0; averageEdgeLoad = new LinkedList<>(); maxLoad = 0; + transfersDone = 0; eventProcessor.addEventHandler(this); init(eventProcessor); @@ -179,6 +188,9 @@ public void handleEvent(Event event) { case DEMAND_DROPPED_OFF: handleDemandDropoff((DemandServiceStatistic) event.getContent()); break; + case DEMAND_DROPPED_AT_TRANSFER: + handleTransfer(); + break; } } else if(event.getType() instanceof OnDemandVehicleEvent){ @@ -215,6 +227,10 @@ private void measure() { countEdgeLoadForInterval(); countVehicleOccupancyForInterval(); } + + private void handleTransfer() { + transfersDone++; + } private void saveResult(){ @@ -226,7 +242,7 @@ private void saveResult(){ onDemandVehicleStationsCentral.getNumberOfDemandsDropped(), onDemandVehicleStationsCentral.getDemandsCount(), numberOfVehicles, onDemandVehicleStationsCentral.getNumberOfRebalancingDropped(), totalDistanceWithPassenger, - totalDistanceToStartLocation, totalDistanceToStation, totalDistanceRebalancing); + totalDistanceToStartLocation, totalDistanceToStation, totalDistanceRebalancing, transfersDone); ObjectMapper mapper = new ObjectMapper(); @@ -246,6 +262,8 @@ public void simulationFinished() { saveOnDemandVehicleEvents(); saveDistances(); saveOccupancies(); + saveInactiveVehicles(); + saveWaitingTimes(); saveServiceStatistics(); if(onDemandVehicleStationsCentral instanceof RidesharingDispatcher){ saveDarpSolverComputationalTimes(); @@ -271,6 +289,7 @@ protected List getEventTypesToHandle() { typesToHandle.add(OnDemandVehicleEvent.REACH_NEAREST_STATION); typesToHandle.add(DriveEvent.VEHICLE_ENTERED_EDGE); typesToHandle.add(StatisticEvent.DEMAND_DROPPED_OFF); + typesToHandle.add(StatisticEvent.DEMAND_DROPPED_AT_TRANSFER); return typesToHandle; } @@ -426,6 +445,91 @@ private void saveServiceStatistics() { LOGGER.error(null, ex); } } + + private void saveWaitingTimes() { + if (dARPSolver instanceof TransferInsertionSolver) { + TransferInsertionSolver transferInsertionSolver = (TransferInsertionSolver) dARPSolver; + if (transferInsertionSolver.getWaitingTimes().size() < 1) { + return; + } + try { + CsvWriter writer = new CsvWriter(Common.getFileWriter(config.statistics.waitingTimesFilePath)); + writer.writeLine("id", "waiting_time"); + for (Pair waitingTimesPair : transferInsertionSolver.getWaitingTimes()) { + writer.writeLine(waitingTimesPair.getFirst(), Integer.toString(waitingTimesPair.getSecond())); + } + writer.close(); + } catch (IOException ex) { + LOGGER.error(null, ex); + } + } else if (dARPSolver instanceof GreedyTASeTSolver) { + GreedyTASeTSolver greedyTASeTSolver = (GreedyTASeTSolver) dARPSolver; + if (greedyTASeTSolver.getInactiveVehicles().size() < 1) { + return; + } + try { + CsvWriter writer = new CsvWriter(Common.getFileWriter(config.statistics.waitingTimesFilePath)); + writer.writeLine("id", "waiting_time"); + for (Pair waitingTimesPair : greedyTASeTSolver.getWaitingTimes()) { + writer.writeLine(waitingTimesPair.getFirst(), Integer.toString(waitingTimesPair.getSecond())); + } + writer.close(); + } catch (IOException ex) { + LOGGER.error(null, ex); + } + } + } + private void saveInactiveVehicles() { + if (dARPSolver instanceof TransferInsertionSolver) { + TransferInsertionSolver transferInsertionSolver = (TransferInsertionSolver) dARPSolver; + if (transferInsertionSolver.getInactiveVehicles().size() < 1) { + return; + } + try { + CsvWriter writer = new CsvWriter(Common.getFileWriter(config.statistics.inactiveVehiclesFilePath)); + writer.writeLine("id", "time"); + for (Pair inactiveVehiclePair: transferInsertionSolver.getInactiveVehicles()) { + writer.writeLine(inactiveVehiclePair.getFirst(), Integer.toString(inactiveVehiclePair.getSecond())); + } + writer.close(); + } catch (IOException ex) { + LOGGER.error(null, ex); + } + + } else if (dARPSolver instanceof GreedyTASeTSolver) { + GreedyTASeTSolver greedyTASeTSolver = (GreedyTASeTSolver) dARPSolver; + if (greedyTASeTSolver.getInactiveVehicles().size() < 1) { + return; + } + try { + CsvWriter writer = new CsvWriter(Common.getFileWriter(config.statistics.inactiveVehiclesFilePath)); + writer.writeLine("id", "time"); + for (Pair inactiveVehiclePair: greedyTASeTSolver.getInactiveVehicles()) { + writer.writeLine(inactiveVehiclePair.getFirst(), Integer.toString(inactiveVehiclePair.getSecond())); + } + writer.close(); + } catch (IOException ex) { + LOGGER.error(null, ex); + } + } else if (dARPSolver instanceof InsertionHeuristicSolver) { + InsertionHeuristicSolver insertionHeuristicSolver = (InsertionHeuristicSolver) dARPSolver; + if (insertionHeuristicSolver.getInactiveVehicles().size() < 1) { + return; + } + try { + CsvWriter writer = new CsvWriter(Common.getFileWriter(config.statistics.inactiveVehiclesFilePath)); + writer.writeLine("id", "time"); + for (Pair inactiveVehiclePair: insertionHeuristicSolver.getInactiveVehicles()) { + writer.writeLine(inactiveVehiclePair.getFirst(), Integer.toString(inactiveVehiclePair.getSecond())); + } + writer.close(); + } catch (IOException ex) { + LOGGER.error(null, ex); + } + + } + + } private void saveRidesharingStatistics() { int highestGroup = 0; diff --git a/src/main/java/cz/cvut/fel/aic/simod/traveltimecomputation/AstarTravelTimeProvider.java b/src/main/java/cz/cvut/fel/aic/simod/traveltimecomputation/AstarTravelTimeProvider.java index 1990314e..0d29a727 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/traveltimecomputation/AstarTravelTimeProvider.java +++ b/src/main/java/cz/cvut/fel/aic/simod/traveltimecomputation/AstarTravelTimeProvider.java @@ -49,28 +49,16 @@ public class AstarTravelTimeProvider extends TravelTimeProvider{ private final MoveUtil moveUtil; -// @Inject -// public AstarTravelTimeProvider( -// TimeProvider timeProvider, -// TripsUtil tripsUtil, -// TransportNetworks transportNetworks, -// MoveUtil moveUtil) { -// super(timeProvider); -// this.tripsUtil = tripsUtil; -// this.moveUtil = moveUtil; -// this.graph = transportNetworks.getGraph(EGraphType.HIGHWAY); -// } - @Inject public AstarTravelTimeProvider( TimeProvider timeProvider, TripsUtil tripsUtil, - Graph graph, + TransportNetworks transportNetworks, MoveUtil moveUtil) { super(timeProvider); this.tripsUtil = tripsUtil; this.moveUtil = moveUtil; - this.graph = graph; + this.graph = transportNetworks.getGraph(EGraphType.HIGHWAY); } diff --git a/src/main/resources/cz/cvut/fel/aic/simod/config/config.cfg b/src/main/resources/cz/cvut/fel/aic/simod/config/config.cfg index c57e7d70..1b62cadd 100644 --- a/src/main/resources/cz/cvut/fel/aic/simod/config/config.cfg +++ b/src/main/resources/cz/cvut/fel/aic/simod/config/config.cfg @@ -171,6 +171,12 @@ statistics: group_data_filename: 'group_data.csv' group_data_file_path: $simod_experiment_dir + $statistics.group_data_filename + + inactive_vehicles_file_name: 'inactive_vehicles.csv' + inactive_vehicles_file_path: $simod_experiment_dir + $statistics.inactive_vehicles_file_name + + waiting_times_file_name: 'waiting_times.csv' + waiting_times_file_path: $simod_experiment_dir + $statistics.waiting_times_file_name } !parent diff --git a/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java b/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java index b0b84bfb..4119e4f1 100644 --- a/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java +++ b/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/greedyTASeT/GreedyTASeTSolverTest.java @@ -96,7 +96,7 @@ public long getCurrentSimTime() { ); // Time providers - AstarTravelTimeProvider astarTravelTimeProvider = new AstarTravelTimeProvider(timeProvider1, tripsUtil, graph, moveUtil); + AstarTravelTimeProvider astarTravelTimeProvider = new AstarTravelTimeProvider(timeProvider1, tripsUtil, null, moveUtil); StandardTimeProvider standardTimeProvider = new StandardTimeProvider(eventProcessor); StandardPlanCostProvider travelCostProvider = new StandardPlanCostProvider(simodConfig); From 583acc96a1b725b5dd8c644b5146b2d8018b6fab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kub=C3=ADkov=C3=A1=2C=20Ad=C3=A9la?= Date: Thu, 19 May 2022 18:20:04 +0200 Subject: [PATCH 20/21] Edit imports, add new scripts for plots. --- python/simod/demand_sample.py | 2 +- python/simod/resources/config.cfg | 4 +- python/simod/station_positions_map.py | 6 +- .../comparisons/comparison_table.py | 4 +- .../density_histogram_scenario_comparion.py | 4 +- .../occupancy_histogram_comparison.py | 6 +- .../comparisons/performance_comparison.py | 4 +- .../comparisons/sensitivity_analysis.py | 10 +- .../transfer_ridesharing_comparison_table.py | 100 ++++++++++++++++++ python/simod/statistics/delay_percentage.py | 65 ++++++++++++ python/simod/statistics/demand_service.py | 3 +- .../demand_trip_duration_histogram.py | 4 +- python/simod/statistics/fleet_utilization.py | 85 +++++++++++++++ python/simod/statistics/model/edges.py | 2 +- python/simod/statistics/model/occupancy.py | 2 +- python/simod/statistics/model/ridesharing.py | 2 +- python/simod/statistics/model/service.py | 2 +- python/simod/statistics/model/traffic_load.py | 4 +- python/simod/statistics/model/transit.py | 4 +- python/simod/statistics/model/trips.py | 2 +- python/simod/statistics/occupancy.py | 40 +++++-- .../statistics/traffic_density_histogram.py | 10 +- python/simod/statistics/trip_statistics.py | 11 +- .../statistics/waiting_time_histogram.py | 66 ++++++++++++ 24 files changed, 392 insertions(+), 50 deletions(-) create mode 100644 python/simod/statistics/comparisons/transfer_ridesharing_comparison_table.py create mode 100644 python/simod/statistics/delay_percentage.py create mode 100644 python/simod/statistics/fleet_utilization.py create mode 100644 python/simod/statistics/waiting_time_histogram.py diff --git a/python/simod/demand_sample.py b/python/simod/demand_sample.py index a4c30b06..e34bdfd8 100644 --- a/python/simod/demand_sample.py +++ b/python/simod/demand_sample.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # -from amodsim.init import config +from simod.init import config import math import pandas as pd import numpy as np diff --git a/python/simod/resources/config.cfg b/python/simod/resources/config.cfg index 98fa811e..6de3bca0 100644 --- a/python/simod/resources/config.cfg +++ b/python/simod/resources/config.cfg @@ -1,9 +1,9 @@ # common data for all experiments -data_dir: 'C:/AIC Experiment data/VGA/' +data_dir: '/Users/adela/Documents/bakalarka/randomdemand/' map_dir: $data_dir + 'maps/' -experiments_dir: 'HERE FILL THE PROJECT EXPERIMENT DIR PATH/' +experiments_dir: '/Users/adela/Documents/bakalarka/randomdemand/experiments/test/' rci_experiments_dir: 'HERE FILL THE PROJECT RCI EXPERIMENT DIR PATH/' # change this for each experiment! diff --git a/python/simod/station_positions_map.py b/python/simod/station_positions_map.py index 2f79556a..634b3216 100644 --- a/python/simod/station_positions_map.py +++ b/python/simod/station_positions_map.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # -from amodsim.init import config +from simod.init import config import numpy as np import matplotlib @@ -26,7 +26,7 @@ import roadmaptools.utm import matplotlib import matplotlib.font_manager as fm -import amodsim.demand +import simod.demand from mpl_toolkits.axes_grid1.anchored_artists import AnchoredSizeBar from matplotlib.colors import LogNorm @@ -69,7 +69,7 @@ # map = np.random.rand(len(lon_range), len(lat_range)) # - fill heatmap -demand_data = amodsim.demand.load(config.trips_path) +demand_data = simod.demand.load(config.trips_path) xlist, ylist = roadmaptools.plotting.export_nodes_for_matplotlib(demand_data[["from_lat", "from_lon"]].to_numpy()) for i, x in enumerate(xlist): y = ylist[i] diff --git a/python/simod/statistics/comparisons/comparison_table.py b/python/simod/statistics/comparisons/comparison_table.py index 4568693a..6a43c153 100644 --- a/python/simod/statistics/comparisons/comparison_table.py +++ b/python/simod/statistics/comparisons/comparison_table.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # -from amodsim.init import config +from simod.init import config import numpy as np import roadmaptools.inout @@ -25,7 +25,7 @@ from typing import List # from scripts.printer import print_table # from statistics.model.traffic_load import VehiclePhase -from amodsim.statistics.traffic_density_histogram import TrafficDensityHistogram +from simod.statistics.traffic_density_histogram import TrafficDensityHistogram def compute_stats(result: List, histogram: TrafficDensityHistogram, load) -> List: diff --git a/python/simod/statistics/comparisons/density_histogram_scenario_comparion.py b/python/simod/statistics/comparisons/density_histogram_scenario_comparion.py index 811c7199..3e7d8668 100644 --- a/python/simod/statistics/comparisons/density_histogram_scenario_comparion.py +++ b/python/simod/statistics/comparisons/density_histogram_scenario_comparion.py @@ -17,14 +17,14 @@ # along with this program. If not, see . # -from amodsim.init import config +from simod.init import config import matplotlib.pyplot as plt import numpy as np import statistics.model.traffic_load as traffic_load from matplotlib.axes import Axes -from amodsim.statistics.traffic_density_histogram import TrafficDensityHistogram, HIGH_THRESHOLD, HISTOGRAM_SAMPLES +from simod.statistics.traffic_density_histogram import TrafficDensityHistogram, HIGH_THRESHOLD, HISTOGRAM_SAMPLES from statistics.model.traffic_load import VehiclePhase diff --git a/python/simod/statistics/comparisons/occupancy_histogram_comparison.py b/python/simod/statistics/comparisons/occupancy_histogram_comparison.py index 453a98d7..a219fbde 100644 --- a/python/simod/statistics/comparisons/occupancy_histogram_comparison.py +++ b/python/simod/statistics/comparisons/occupancy_histogram_comparison.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # -from amodsim.init import config +from simod.init import config import numpy as np import pandas as pd @@ -24,8 +24,8 @@ import matplotlib.pyplot as plt import datetime import roadmaptools.inout -import amodsim.statistics.model.occupancy as occupancy -import amodsim.statistics.comparisons.common as common +import simod.statistics.model.occupancy as occupancy +import simod.statistics.comparisons.common as common from matplotlib.ticker import FuncFormatter diff --git a/python/simod/statistics/comparisons/performance_comparison.py b/python/simod/statistics/comparisons/performance_comparison.py index 9907a504..7e31a657 100644 --- a/python/simod/statistics/comparisons/performance_comparison.py +++ b/python/simod/statistics/comparisons/performance_comparison.py @@ -16,10 +16,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # -from init import config +from simod.init import config import matplotlib.pyplot as plt -import amodsim.statistics.model.ridesharing as ridesharing +import simod.statistics.model.ridesharing as ridesharing ih_capacity1_stats = ridesharing.load(config.comparison.experiment_1_dir) diff --git a/python/simod/statistics/comparisons/sensitivity_analysis.py b/python/simod/statistics/comparisons/sensitivity_analysis.py index 1bca887f..d407957c 100644 --- a/python/simod/statistics/comparisons/sensitivity_analysis.py +++ b/python/simod/statistics/comparisons/sensitivity_analysis.py @@ -16,14 +16,14 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # -from amodsim.init import config +from simod.init import config from typing import List, Tuple import roadmaptools.inout -import amodsim.statistics.model.edges as edges -import amodsim.statistics.model.transit as transit -import amodsim.statistics.model.ridesharing as ridesharing -import amodsim.statistics.model.service as service +import simod.statistics.model.edges as edges +import simod.statistics.model.transit as transit +import simod.statistics.model.ridesharing as ridesharing +import simod.statistics.model.service as service import matplotlib.pyplot as plt delay_experiments = ["sw-vga-max_delay_3_min", "sw-vga", "sw-vga-max_delay_5_min", "sw-vga-max_delay_6_min"] diff --git a/python/simod/statistics/comparisons/transfer_ridesharing_comparison_table.py b/python/simod/statistics/comparisons/transfer_ridesharing_comparison_table.py new file mode 100644 index 00000000..69c6c71e --- /dev/null +++ b/python/simod/statistics/comparisons/transfer_ridesharing_comparison_table.py @@ -0,0 +1,100 @@ +from simod.init import config + +import numpy as np +import pandas.errors +import roadmaptools.inout +import simod.statistics.model.traffic_load as traffic_load +import simod.statistics.model.transit as transit +import simod.statistics.model.edges as edges +import simod.statistics.model.ridesharing as ridesharing +import simod.statistics.model.service as service +import simod.statistics.model.occupancy as occupancy + +from typing import List, Dict, Iterable +from pandas import DataFrame +from roadmaptools.printer import print_table, print_info +from simod.statistics.traffic_density_histogram import TrafficDensityHistogram +from simod.statistics.model.vehicle_state import VehicleState + + +def compute_stats(result: Dict, histogram: TrafficDensityHistogram, load, experiment_dir: str, + edge_data: DataFrame) -> List: + # km total + transit_data = transit.load(experiment_dir) + km_total_window = int(round(transit.get_total_distance(transit_data, edge_data, True) / 1000 / 100)) + km_per_served_demand = round(km_total_window / (result["demandsCount"] - result["numberOfDemandsDropped"]), 3) + + dropped_demand_count = result["numberOfDemandsDropped"] + demand_count_served = result["demandsCount"] - result["numberOfDemandsDropped"] + + occupancies = occupancy.load(experiment_dir) + occupancies_in_window = occupancy.filter_window(occupancies) + used_cars_count = len(occupancies_in_window.vehicle_id.unique()) + + # delay + service_stat = service.load_dataframe(experiment_dir) + delays_window = service.get_delays(service_stat, True, False) + mean_delay = int(round(delays_window.mean() / 1000)) + + transfers_count = result['transfersDone'] + + return [km_total_window, dropped_demand_count, used_cars_count, mean_delay, demand_count_served, + km_per_served_demand, transfers_count] + +exp_dir_1 = '/Users/adela/Documents/bakalarka/vysledky2/InsertionHeuristic/Archiv/experiments/test/' +# exp_dir_2 = '/Users/adela/Documents/bakalarka/vysledky2/transferInsertionHeuristic/Archiv/experiments/test/' +exp_dir_2 = '/Users/adela/Documents/bakalarka/randomdemand/experiments/test/' + +exp_dir_3 = '/Users/adela/Documents/bakalarka/vysledky2/taset/Archiv/experiments/test/' + +edges_path = '/Users/adela/Documents/bakalarka/randomdemand/maps/edges.geojson' +loaded_edges = roadmaptools.inout.load_geojson(edges_path) +edge_data = edges.make_data_frame(loaded_edges) +edge_object_data = edges.load_edges_mapped_by_id(loaded_edges) + +results_insertion_heuristic \ + = roadmaptools.inout.load_json(exp_dir_1 + config.statistics.result_file_name) +results_insertion_heuristic_transfer \ + = roadmaptools.inout.load_json(exp_dir_2 + config.statistics.result_file_name) +results_taset \ + = roadmaptools.inout.load_json(exp_dir_3 + config.statistics.result_file_name) + +loads_insertion_heuristic = traffic_load.load_all_edges_load_history( + exp_dir_1 + config.statistics.all_edges_load_history_file_name) +loads_insertion_heuristic_transfer = traffic_load.load_all_edges_load_history( + exp_dir_2 + config.statistics.all_edges_load_history_file_name) +loads_taset = traffic_load.load_all_edges_load_history( + exp_dir_3 + config.statistics.all_edges_load_history_file_name) + +histogram = TrafficDensityHistogram(edge_object_data) + +insertion_heuristic_data = compute_stats(results_insertion_heuristic, histogram, loads_insertion_heuristic["ALL"], + exp_dir_1, edge_data) +insertion_heuristic_transfer_data = compute_stats(results_insertion_heuristic_transfer, histogram, + loads_insertion_heuristic_transfer["ALL"], exp_dir_2, + edge_data) +taset_data = compute_stats(results_taset, histogram, loads_taset["ALL"], + exp_dir_3, edge_data) + +output_table = np.array([[" ", "INSERTION HEURISTIC", "INSERTION HEURISTIC TRANSFER", "GREEDY HEURISTIC TRANSFER"], + ["Dropped demands", insertion_heuristic_data[1], insertion_heuristic_transfer_data[1], + taset_data[1]], + ["Demands served", insertion_heuristic_data[4], insertion_heuristic_transfer_data[4], + taset_data[4]], + ["Total transfers", insertion_heuristic_data[6], insertion_heuristic_transfer_data[6], + taset_data[6]], + ["Total veh. dist. traveled (km)", insertion_heuristic_data[0], + insertion_heuristic_transfer_data[0], taset_data[0]], + ["Total veh. dist. traveled per demand served (km)", insertion_heuristic_data[5], + insertion_heuristic_transfer_data[5], taset_data[5]], + ["Used car count", insertion_heuristic_data[2], insertion_heuristic_transfer_data[2], + taset_data[2]], + ["Average delay (s)", insertion_heuristic_data[3], insertion_heuristic_transfer_data[3], + taset_data[3]], + + ]) + +# console results +print("COMPARISON:") +print() +print_table(output_table) \ No newline at end of file diff --git a/python/simod/statistics/delay_percentage.py b/python/simod/statistics/delay_percentage.py new file mode 100644 index 00000000..d6df6365 --- /dev/null +++ b/python/simod/statistics/delay_percentage.py @@ -0,0 +1,65 @@ +import numpy as np +import pandas as pd +import matplotlib.pyplot as plt +import pandas.errors +import roadmaptools.inout +import simod.statistics.model.traffic_load as traffic_load +import simod.statistics.model.transit as transit +import simod.statistics.model.edges as edges +import simod.statistics.model.ridesharing as ridesharing +import simod.statistics.model.service as service +import simod.statistics.model.occupancy as occupancy + + +exp_dir_1 = '/Users/adela/Documents/bakalarka/vysledky2/InsertionHeuristic/Archiv/experiments/test/' +exp_dir_2 = '/Users/adela/Documents/bakalarka/vysledky2/transferInsertionHeuristic/Archiv/experiments/test/' +exp_dir_3 = '/Users/adela/Documents/bakalarka/vysledky2/taset/Archiv/experiments/test/' + +save_dir_1 = '/Users/adela/Documents/bakalarka/vysledky2/InsertionHeuristic/Archiv/img/' +save_dir_2 = '/Users/adela/Documents/bakalarka/vysledky2/transferInsertionHeuristic/Archiv/img/' +save_dir_3 = '/Users/adela/Documents/bakalarka/vysledky2/taset/Archiv/img/' + + +# delays dataframe +# TODO change dir +service_stat = service.load_dataframe(exp_dir_3) +# TODO change dir +save_results_to = save_dir_3 + +delays = service.get_delays(service_stat, True, False).to_frame() +service_stat['percentage_delay'] = (service_stat['dropoff_time'] - service_stat['demand_time']) / service_stat['min_possible_delay'] - 1 +maximum = service_stat['percentage_delay'].max() +service_stat['percentage_delay_norm'] = service_stat['percentage_delay'] / maximum + +new_df = service_stat.where(service_stat['percentage_delay'] > 0.0) +new_df = new_df.dropna() + +bins = [0.0, 0.1, 0.2, 0.3, 0.4, 0.6, 0.8, 1 * maximum] + + +bins_df = pd.cut(new_df['percentage_delay'], bins) +print(bins_df.value_counts()) + +t = bins_df.value_counts(sort=False) +labels = ['< 10 %', '< 20 %', '< 30 %', '< 40 %', '< 60 %', '< 80 %', '81 % +'] + + +counts = t +plt.axis('equal') +explode = bins +colors = ['#191970','#0038E2','#0071C6','#329A82', '#46C3A6', '#93DCCB', '#E0F5F0'] +colors2 = ['#E6F7FF', '#BAE7FF', '#91D5FF', '#69C0FF', '#1890FF', '#096DD9', '#0050B3', '#002766'] +cc = list(reversed(colors)) +counts.plot(kind='pie', fontsize=15, colors=cc, labels=t, + wedgeprops={"edgecolor": "black", + 'linewidth': 0.2, + 'antialiased': True} + ) +plt.legend(labels=labels, loc="best") +plt.ylabel('') + + +plt.savefig(save_results_to + 'delay_percentages', bbox_inches='tight', transparent=True) + + +plt.show() \ No newline at end of file diff --git a/python/simod/statistics/demand_service.py b/python/simod/statistics/demand_service.py index 838ce18f..482496eb 100644 --- a/python/simod/statistics/demand_service.py +++ b/python/simod/statistics/demand_service.py @@ -17,7 +17,8 @@ # along with this program. If not, see . # -from simod.init import config, roadmaptools_config +from simod.init import config +from roadmaptools.config import roadmaptools_config from tqdm import tqdm import numpy as np diff --git a/python/simod/statistics/demand_trip_duration_histogram.py b/python/simod/statistics/demand_trip_duration_histogram.py index 32f42f2e..eac110c7 100644 --- a/python/simod/statistics/demand_trip_duration_histogram.py +++ b/python/simod/statistics/demand_trip_duration_histogram.py @@ -16,12 +16,12 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # -from amodsim.init import config +from simod.init import config import numpy as np import matplotlib.pyplot as plt from matplotlib.ticker import FuncFormatter -from amodsim.statistics.model import demand_trips +from simod.statistics.model import demand_trips trips_data = demand_trips.load() diff --git a/python/simod/statistics/fleet_utilization.py b/python/simod/statistics/fleet_utilization.py new file mode 100644 index 00000000..ddb1c4d5 --- /dev/null +++ b/python/simod/statistics/fleet_utilization.py @@ -0,0 +1,85 @@ + +from simod.init import config + +from tqdm import tqdm +import numpy as np +import pandas as pd +import matplotlib.pyplot as plt +import matplotlib +import roadmaptools.inout +import simod.utils + +from matplotlib.ticker import FuncFormatter +from pandas import DataFrame + + +def to_percent_x(x, position): + # Ignore the passed in position. This has the effect of scaling the default + # tick locations. + s = str(int(round(100 * x))) + + # The percent symbol needs escaping in latex + if matplotlib.rcParams['text.usetex'] is True: + return s + r'$\%$' + else: + return s + '%' + +def to_percent_y(y, position): + # Ignore the passed in position. This has the effect of scaling the default + # tick locations. + s = str(int(round(10 * y))) + + # The percent symbol needs escaping in latex + if matplotlib.rcParams['text.usetex'] is True: + return s + r'$\%$' + else: + return s + '%' + + +data_dir_1 = '/Users/adela/Documents/bakalarka/vysledky2/InsertionHeuristic/Archiv/experiments/test/inactive_vehicles.csv' +data_dir_2 = '/Users/adela/Documents/bakalarka/vysledky2/transferInsertionHeuristic/Archiv/experiments/test/inactive_vehicles.csv' +data_dir_3 = '/Users/adela/Documents/bakalarka/vysledky2/taset/Archiv/experiments/test/inactive_vehicles.csv' + +save_dir_1 = '/Users/adela/Documents/bakalarka/vysledky2/InsertionHeuristic/Archiv/img/' +save_dir_2 = '/Users/adela/Documents/bakalarka/vysledky2/transferInsertionHeuristic/Archiv/img/' +save_dir_3 = '/Users/adela/Documents/bakalarka/vysledky2/taset/Archiv/img/' + +# TODO change dir +df = pd.read_csv(data_dir_3) + +# vehicles = df['id'].values + +occur = df.groupby(['id']).size() + +occur_df = occur.to_frame() +occur_df = occur_df.reset_index() +occur_df.columns=['id','occurance_inactive'] +occur_df['time_inactive'] = occur_df['occurance_inactive'] * 30 + +simulation_duration = 5 * 60 * 60 + 600 # in seconds + +occur_df['percentage_active'] = (simulation_duration - occur_df['time_inactive']) / simulation_duration + +df_short = occur_df[['id', 'percentage_active']] + +fig, axis = plt.subplots(1, 1, subplot_kw={"adjustable": 'box'}, figsize=(4, 3)) + +plt.gca().xaxis.set_major_formatter(FuncFormatter(to_percent_x)) + +bins = np.arange(0, 1, 0.1) +axis.set_xticks(bins) +plt.xticks(fontsize=9, rotation=0) + +axis.hist(occur_df['percentage_active'], bins, density=False, stacked=False, edgecolor='black', linewidth=0.4) + +# plt.title("Vehicle utilization") + +# TODO change dir +save_results_to = save_dir_3 +plt.savefig(save_results_to + 'vehicle-utilization', bbox_inches='tight', transparent=True) + +plt.show() + + + +print('done') \ No newline at end of file diff --git a/python/simod/statistics/model/edges.py b/python/simod/statistics/model/edges.py index d51304e1..a276d2ba 100644 --- a/python/simod/statistics/model/edges.py +++ b/python/simod/statistics/model/edges.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # -from amodsim.init import config +from simod.init import config import pandas import roadmaptools.inout diff --git a/python/simod/statistics/model/occupancy.py b/python/simod/statistics/model/occupancy.py index 46648a5d..9f585f78 100644 --- a/python/simod/statistics/model/occupancy.py +++ b/python/simod/statistics/model/occupancy.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # -from amodsim.init import config +from simod.init import config import pandas diff --git a/python/simod/statistics/model/ridesharing.py b/python/simod/statistics/model/ridesharing.py index 26e9ad97..c0460b78 100644 --- a/python/simod/statistics/model/ridesharing.py +++ b/python/simod/statistics/model/ridesharing.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # -from amodsim.init import config +from simod.init import config import pandas import roadmaptools.inout diff --git a/python/simod/statistics/model/service.py b/python/simod/statistics/model/service.py index aeb2e509..c45f62c3 100644 --- a/python/simod/statistics/model/service.py +++ b/python/simod/statistics/model/service.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # -from amodsim.init import config +from simod.init import config import pandas diff --git a/python/simod/statistics/model/traffic_load.py b/python/simod/statistics/model/traffic_load.py index c5d4a2bf..3561e808 100644 --- a/python/simod/statistics/model/traffic_load.py +++ b/python/simod/statistics/model/traffic_load.py @@ -18,7 +18,7 @@ # from pandas.io.formats.format import return_docstring -from amodsim.init import config +from simod.init import config import json import matplotlib @@ -28,7 +28,7 @@ from matplotlib import cm from roadmaptools.printer import print_info -from amodsim.json_cache import load_json_file +from simod.json_cache import load_json_file CRITICAL_DENSITY = config.critical_density diff --git a/python/simod/statistics/model/transit.py b/python/simod/statistics/model/transit.py index c90f3e87..0adb661e 100644 --- a/python/simod/statistics/model/transit.py +++ b/python/simod/statistics/model/transit.py @@ -16,13 +16,13 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # -from amodsim.init import config +from simod.init import config import pandas from typing import Union from pandas import DataFrame -from amodsim.statistics.model.vehicle_state import VehicleState +from simod.statistics.model.vehicle_state import VehicleState cols = ["time", "edge_id", "vehicle_state"] diff --git a/python/simod/statistics/model/trips.py b/python/simod/statistics/model/trips.py index 1d8d1d30..4c21aad1 100644 --- a/python/simod/statistics/model/trips.py +++ b/python/simod/statistics/model/trips.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # -from amodsim.init import config +from simod.init import config import pandas import roadmaptools.inout diff --git a/python/simod/statistics/occupancy.py b/python/simod/statistics/occupancy.py index d0802939..a3248f47 100644 --- a/python/simod/statistics/occupancy.py +++ b/python/simod/statistics/occupancy.py @@ -17,14 +17,14 @@ # along with this program. If not, see . # -from amodsim.init import config +from simod.init import config from tqdm import tqdm import numpy as np import matplotlib.pyplot as plt import matplotlib import roadmaptools.inout -import amodsim.utils +import simod.utils from matplotlib.ticker import FuncFormatter from pandas import DataFrame @@ -42,8 +42,25 @@ def to_percent(y, position): return s + '%' -results = roadmaptools.inout.load_json(config.statistics.result_file_path) -data = np.genfromtxt(config.statistics.occupancies_file_path, delimiter=',') +exp_dir_1 = '/Users/adela/Documents/bakalarka/vysledky2/InsertionHeuristic/Archiv/experiments/test/result.json' +exp_dir_2 = '/Users/adela/Documents/bakalarka/vysledky2/transferInsertionHeuristic/Archiv/experiments/test/result.json' +exp_dir_3 = '/Users/adela/Documents/bakalarka/vysledky2/taset/Archiv/experiments/test/result.json' + +# results = roadmaptools.inout.load_json(config.statistics.result_file_path) +# TODO change dir +results = roadmaptools.inout.load_json(exp_dir_3) + +occ_dir_1 = '/Users/adela/Documents/bakalarka/vysledky2/InsertionHeuristic/Archiv/experiments/test/vehicle_occupancy.csv' +occ_dir_2 = '/Users/adela/Documents/bakalarka/vysledky2/transferInsertionHeuristic/Archiv/experiments/test/vehicle_occupancy.csv' +occ_dir_3 = '/Users/adela/Documents/bakalarka/vysledky2/taset/Archiv/experiments/test/vehicle_occupancy.csv' +# TODO change dir +data = np.genfromtxt(occ_dir_3, delimiter=',') + +save_dir_1 = '/Users/adela/Documents/bakalarka/vysledky2/InsertionHeuristic/Archiv/img/' +save_dir_2 = '/Users/adela/Documents/bakalarka/vysledky2/transferInsertionHeuristic/Archiv/img/' +save_dir_3 = '/Users/adela/Documents/bakalarka/vysledky2/taset/Archiv/img/' +# TODO change dir +save_results_to = save_dir_3 occupancy_col = data[:,2] @@ -60,9 +77,11 @@ def to_percent(y, position): bins = np.arange(-0.5, 6.5, 1) -axis.hist(occupancy_col, bins, normed=True) +# axis.hist(occupancy_col, bins, normed=True) +axis.hist(occupancy_col, bins, density=True, stacked=True) +# plt.title('Vehicle occupancy') -# plt.savefig(config.images.occupancy_histogram, bbox_inches='tight', transparent=True) +plt.savefig(save_results_to + 'occupancy', bbox_inches='tight', transparent=True) # in window @@ -82,9 +101,12 @@ def to_percent(y, position): # axis.set_xlabel("Vehicle occupancy [persons]") # axis.set_ylabel("Share of vehicles") -axis.hist(occupancy_in_window, bins, normed=True) +# axis.hist(occupancy_in_window, bins, normed=True) +axis.hist(occupancy_in_window, bins, density=True, stacked=True) + +# plt.savefig(config.images.occupancy_histogram_window, bbox_inches='tight', transparent=True) +plt.savefig(save_results_to + 'occupancy-window', bbox_inches='tight', transparent=True) -plt.savefig(config.images.occupancy_histogram_window, bbox_inches='tight', transparent=True) # occupancy in time df = DataFrame(data, columns=["period", "id", "occupancy"]) @@ -95,5 +117,7 @@ def to_percent(y, position): fig, axis = plt.subplots(1, 1, subplot_kw={"adjustable": 'box'}, figsize=(4, 3)) axis.plot(avg_occupancies_per_period) +# plt.title("Average vehicle occupancy over time") +plt.savefig(save_results_to + 'occupancy-in-time', bbox_inches='tight', transparent=True) plt.show() diff --git a/python/simod/statistics/traffic_density_histogram.py b/python/simod/statistics/traffic_density_histogram.py index 0296e02c..81a22c68 100644 --- a/python/simod/statistics/traffic_density_histogram.py +++ b/python/simod/statistics/traffic_density_histogram.py @@ -16,17 +16,17 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # -from amodsim.init import config +from simod.init import config import matplotlib.pyplot as plt import numpy as np from matplotlib import rcParams from roadmaptools.printer import print_info, print_table -from amodsim.statistics.model.traffic_load import WINDOW_START, WINDOW_END, WINDOW_LENGTH -from amodsim.statistics.model.vehicle_state import VehicleState -from amodsim.utils import to_percetnt, col_to_percent -import amodsim.statistics.model.traffic_load as traffic_load +from simod.statistics.model.traffic_load import WINDOW_START, WINDOW_END, WINDOW_LENGTH +from simod.statistics.model.vehicle_state import VehicleState +from simod.utils import to_percetnt, col_to_percent +import simod.statistics.model.traffic_load as traffic_load HISTOGRAM_SAMPLES = 16 diff --git a/python/simod/statistics/trip_statistics.py b/python/simod/statistics/trip_statistics.py index 2f578d01..1f0d73ca 100644 --- a/python/simod/statistics/trip_statistics.py +++ b/python/simod/statistics/trip_statistics.py @@ -23,11 +23,11 @@ from matplotlib.ticker import FuncFormatter from simod.statistics.model import trips -HOURS_IN_DAY = 24 +HOURS_IN_DAY = 5 MINUTES_IN_HOUR = 60 -HISTOGRAM_SAMPLES = 96 +HISTOGRAM_SAMPLES = 5 def format_timestamps(tick, tick_index): @@ -43,7 +43,8 @@ def format_timestamps(tick, tick_index): counts, bins, patches = axis.hist(trips_data["start_time"], HISTOGRAM_SAMPLES) -tick_interval = int(HISTOGRAM_SAMPLES / 16) +tick_interval = 5 +tick_interval = int(HISTOGRAM_SAMPLES / 20) axis.set_xticks(bins[0::tick_interval]) axis.xaxis.set_major_formatter(FuncFormatter(format_timestamps)) @@ -52,8 +53,8 @@ def format_timestamps(tick, tick_index): plt.subplots_adjust(bottom=0.2) axis.get_xaxis().set_tick_params(direction='out') - -# plt.savefig(config.images.trip_start_histogram, bbox_inches='tight', transparent=True, pad_inches=0) +save_dir_1 = '/Users/adela/Documents/bakalarka/vysledky/' +plt.savefig(save_dir_1 + 'demands_in_time', bbox_inches='tight', transparent=True, pad_inches=0) # fig, axis = plt.subplots(figsize=(6, 4)) # diff --git a/python/simod/statistics/waiting_time_histogram.py b/python/simod/statistics/waiting_time_histogram.py new file mode 100644 index 00000000..cba8bfd0 --- /dev/null +++ b/python/simod/statistics/waiting_time_histogram.py @@ -0,0 +1,66 @@ +import matplotlib.pyplot as plt +import pandas.errors +import pandas as pd +import numpy as np +import matplotlib +import roadmaptools.inout +from matplotlib.ticker import FuncFormatter + +import simod.statistics.model.traffic_load as traffic_load +import simod.statistics.model.transit as transit +import simod.statistics.model.edges as edges +import simod.statistics.model.ridesharing as ridesharing +import simod.statistics.model.service as service +import simod.statistics.model.occupancy as occupancy + +def to_percent_x(x, position): + # Ignore the passed in position. This has the effect of scaling the default + # tick locations. + s = str(int(round(100 * x))) + + # The percent symbol needs escaping in latex + if matplotlib.rcParams['text.usetex'] is True: + return s + r'$\%$' + else: + return s + '%' + +def to_percent_y(y, position): + # Ignore the passed in position. This has the effect of scaling the default + # tick locations. + s = str(int(round(10 * y))) + + # The percent symbol needs escaping in latex + if matplotlib.rcParams['text.usetex'] is True: + return s + r'$\%$' + else: + return s + '%' + + +exp_dir_2 = '/Users/adela/Documents/bakalarka/vysledky2/transferInsertionHeuristic/Archiv/experiments/test/waiting_times.csv' +save_dir_2 = '/Users/adela/Documents/bakalarka/vysledky2/transferInsertionHeuristic/Archiv/img/' +exp_dir_3 = '/Users/adela/Documents/bakalarka/vysledky2/taset/Archiv/experiments/test/waiting_times.csv' +save_dir_3 = '/Users/adela/Documents/bakalarka/vysledky2/taset/Archiv/img/' + + +# delays dataframe +# TODO change dir +df = pd.read_csv(exp_dir_2) +# TODO change dir +save_results_to = save_dir_2 + +fig, axis = plt.subplots(1, 1, subplot_kw={"adjustable": 'box'}, figsize=(4, 3)) + +maximum = df['waiting_time'].max() + +bins = np.arange(0, maximum+20, 10) +labels = bins[0::2] +axis.set_xticks(labels) +plt.xticks(fontsize=8, rotation=0) + +axis.hist(df['waiting_time'], bins, density=False, stacked=False, edgecolor='black', linewidth=0.4) + +# plt.title("Waiting times") + +plt.savefig(save_results_to + 'waiting_times', bbox_inches='tight', transparent=True) + +plt.show() \ No newline at end of file From 2eef324f061dd7809f5a527b5700364e46a4cfb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kub=C3=ADkov=C3=A1=2C=20Ad=C3=A9la?= Date: Thu, 19 May 2022 18:23:58 +0200 Subject: [PATCH 21/21] Add map plots playground --- python/simod/statistics/map_from_edges.py | 90 +++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 python/simod/statistics/map_from_edges.py diff --git a/python/simod/statistics/map_from_edges.py b/python/simod/statistics/map_from_edges.py new file mode 100644 index 00000000..c8a2ad23 --- /dev/null +++ b/python/simod/statistics/map_from_edges.py @@ -0,0 +1,90 @@ +import geopandas as gpd +import contextily as ctx +import matplotlib.pyplot as plt +import pandas as pd +import seaborn as sns +import shapely +from mpl_toolkits.basemap import Basemap +import rasterio.crs +from ctypes.util import find_library + + + +def add_basemap(ax, zoom, url='http://tile.stamen.com/terrain/tileZ/tileX/tileY.png'): + xmin, xmax, ymin, ymax = ax.axis() + basemap, extent = ctx.bounds2img(xmin, ymin, xmax, ymax, zoom=zoom, source=url) + ax.imshow(basemap, extent=extent, interpolation='bilinear') + # restore original x/y limits + ax.axis((xmin, xmax, ymin, ymax)) + + + +# find_library('geos_c') + +# data = gpd.read_file('/Users/adela/Documents/bakalarka/randomdemand/maps/edges.geojson') +save_dir = '/Users/adela/Documents/bakalarka/vysledky2/' + +data = pd.read_csv('/Users/adela/Documents/bakalarka/randomdemand/trips.txt', sep=" ", header=None) +data.columns = ["time", "y", "x", "y2", "x2"] +data_part1 = data[['y', 'x']] +data_part2 = data[['y2', 'x2']] +# +new_data = pd.concat([data_part1, data_part2.rename(columns={'y2': 'y', 'x2': 'x'})], ignore_index=True) +new_data = new_data.reset_index() +# +gdf = gpd.GeoDataFrame(new_data, geometry=gpd.points_from_xy(new_data.y, new_data.x), crs='EPSG:4326') + + +gdf.geometry.map(lambda polygon: shapely.ops.transform(lambda x, y: (y, x), polygon)) + +gdf = gdf.set_crs(epsg='4326', allow_override=True) +gdf = gdf['geometry'] + +df_wm = gdf.to_crs(epsg=3857) +# ax = gdf.plot(figsize=(10, 10), alpha=0.7, c='grey') + +ax = gdf.plot(figsize=(10, 10), alpha=0, c='grey') +# ctx.add_basemap(ax, crs='EPSG:3857', source=ctx.providers.Stamen.TonerLite) + +sns.kdeplot(data=new_data, + x='y', + y='x', + fill=True, + cmap='coolwarm', + alpha=0.6, + gridsize=300, + levels=10, + ax=ax, + legend=False) + +# ax = gdf.plot(figsize=(10, 10), alpha=0.1, c='grey') + +# ctx.add_basemap(ax, zoom=18) +# ctx.add_basemap(ax, crs=df_wm.crs.to_string(), zoom=10) +# m.shadedrelief() + +# minx, miny, maxx, maxy = data.total_bounds + +# print(minx, maxx, miny, maxy) + +# ax = gdf.plot(figsize=(10, 10), alpha=0.5, edgecolor='b') + +# add_basemap(ax, zoom=10) +# ctx.add_basemap(ax, crs=gdf.crs, zoom=10) + +# ctx.add_basemap(ax, zoom=12, source=ctx.providers.OpenStreetMap.Mapnik) +# ctx.add_basemap(ax, crs=gdf.crs, source=ctx.providers.OpenStreetMap.Mapnik) +# ctx.add_basemap(ax, source=ctx.providers.Stamen.TonerLite) +# ctx.add_basemap(ax, source=ctx.providers.Stamen.TonerLite, crs=gdf.crs.to_string()) + +# ax.get_xaxis().set_ticks([]) +# ax.get_yaxis().set_ticks([]) +ax.set_ylabel('') +ax.set_xlabel('') + +# plt.savefig(save_dir + 'road_graph', bbox_inches='tight', transparent=True) +# plt.savefig(save_dir + 'demand_locations', bbox_inches='tight', transparent=True) +plt.savefig(save_dir + 'demand_heatmap', bbox_inches='tight', transparent=True) + +plt.show() +