From 789ea36dbff48e2f9e3248dfecbce3f4eab67e3c Mon Sep 17 00:00:00 2001 From: tschlenther Date: Thu, 28 Sep 2023 16:45:12 +0200 Subject: [PATCH] analyse number of rejection by time bin --- .../DrtAnalysisControlerListener.java | 129 ++++++++++++++---- 1 file changed, 102 insertions(+), 27 deletions(-) diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/DrtAnalysisControlerListener.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/DrtAnalysisControlerListener.java index 7fd5197abe8..17f55751141 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/DrtAnalysisControlerListener.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/DrtAnalysisControlerListener.java @@ -19,31 +19,7 @@ package org.matsim.contrib.drt.analysis; -import static java.util.stream.Collectors.toList; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.io.BufferedWriter; -import java.io.FileOutputStream; -import java.io.IOException; -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Comparator; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Optional; -import java.util.TreeMap; -import java.util.function.Function; -import java.util.stream.Collectors; - +import com.google.common.base.Preconditions; import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; import org.apache.logging.log4j.LogManager; @@ -70,12 +46,13 @@ import org.matsim.contrib.drt.passenger.events.DrtRequestSubmittedEvent; import org.matsim.contrib.drt.run.DrtConfigGroup; import org.matsim.contrib.drt.schedule.DrtStayTask; +import org.matsim.contrib.dvrp.analysis.VehicleOccupancyProfileCalculator; import org.matsim.contrib.dvrp.fleet.DvrpVehicle; import org.matsim.contrib.dvrp.fleet.DvrpVehicleSpecification; import org.matsim.contrib.dvrp.fleet.FleetSpecification; import org.matsim.contrib.dvrp.optimizer.Request; import org.matsim.contrib.dvrp.passenger.PassengerPickedUpEvent; -import org.matsim.contrib.dvrp.analysis.VehicleOccupancyProfileCalculator; +import org.matsim.contrib.dvrp.passenger.PassengerRequestRejectedEvent; import org.matsim.core.config.Config; import org.matsim.core.config.groups.QSimConfigGroup; import org.matsim.core.controler.MatsimServices; @@ -87,7 +64,20 @@ import org.matsim.core.utils.misc.Time; import org.matsim.vehicles.Vehicle; -import com.google.common.base.Preconditions; +import java.awt.*; +import java.io.BufferedWriter; +import java.io.FileOutputStream; +import java.io.IOException; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.List; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static java.util.stream.Collectors.toList; /** * @author jbischoff @@ -176,6 +166,13 @@ public void notifyIterationEnds(IterationEndsEvent event) { .sorted(Comparator.comparing(leg -> leg.departureTime)) .collect(toList()); + List rejectionEvents = drtEventSequenceCollector.getRejectedRequestSequences() + .values() + .stream() + .map(eventSequence -> eventSequence.getRejected().get()) + .sorted(Comparator.comparing(rejectionEvent -> rejectionEvent.getTime())) + .collect(toList()); + collection2Text(drtEventSequenceCollector.getRejectedRequestSequences().values(), filename(event, "drt_rejections", ".csv"), String.join(delimiter, "time", "personId", "fromLinkId", "toLinkId", "fromX", "fromY", "toX", "toY"), seq -> { DrtRequestSubmittedEvent submission = seq.getSubmitted(); @@ -252,6 +249,7 @@ public void notifyIterationEnds(IterationEndsEvent event) { writeVehicleDistances(drtVehicleStats.getVehicleStates(), filename(event, "vehicleDistanceStats", ".csv"), delimiter); analyseDetours(network, legs, drtVehicleStats.getTravelDistances(), drtCfg, filename(event, "drt_detours"), createGraphs, delimiter); analyseWaitTimes(filename(event, "waitStats"), legs, 1800, createGraphs, delimiter); + analyseRejections(filename(event,"drt_rejections_perTimeBin"), rejectionEvents,1800, createGraphs, delimiter); analyseConstraints(filename(event, "constraints"), legs, createGraphs); double endTime = qSimCfg.getEndTime() @@ -399,6 +397,7 @@ public void notifyShutdown(ShutdownEvent event) { dumpOutput(event.getIteration(), "waitTimeComparison", ".png"); dumpOutput(event.getIteration(), "waitTimeComparison", ".csv"); dumpOutput(event.getIteration(), "drt_rejections", ".csv"); + dumpOutput(event.getIteration(), "drt_rejections_perTimeBin", ".csv"); dumpOutput(event.getIteration(), "drt_legs", ".csv"); dumpOutput(event.getIteration(), "vehicleDistanceStats", ".csv"); dumpOutput(event.getIteration(), "drt_detours", ".csv"); @@ -453,6 +452,33 @@ private static Map> splitLegsIntoBins(Collection le return splitLegs; } + private static Map> splitEventsIntoBins(List rejectionEvents, int binSize_s) { + Map> rejections = new TreeMap<>(); + + int startTime = ((int)(rejectionEvents.get(0).getTime() / binSize_s)) * binSize_s; + int endTime = ((int)(rejectionEvents.get(rejectionEvents.size() - 1).getTime() / binSize_s) + 1) * binSize_s; + + for (int time = startTime; time < endTime; time = time + binSize_s) { + + // rejection list in this timebin + List rejectionList = new ArrayList<>(); + + //Iterate through each rejection + for (PassengerRequestRejectedEvent rejectedEvent : rejectionEvents){ + double rejectionTime = rejectedEvent.getTime(); + if (rejectionTime > endTime || rejectionTime < startTime) { + LogManager.getLogger(DrtAnalysisControlerListener.class).error("wrong end / start Times for analysis"); + } + + if (rejectionTime > time && rejectionTime < time + binSize_s) { + rejectionList.add(rejectedEvent); + } + } + rejections.put((double)time, rejectionList); + } + return rejections; + } + private static void analyzeBoardingsAndDeboardings(List legs, String delimiter, double startTime, double endTime, double timeBinSize, String boardingsFile, String deboardingsFile, Network network) { if (endTime < startTime) { @@ -708,6 +734,55 @@ private static void analyseWaitTimes(String fileName, List legs, int bin } + private static void analyseRejections(String fileName, List rejectionEvents, int binsize_s, boolean createGraphs, String delimiter) { + if (rejectionEvents.size() == 0) + return; + + Map> splitEvents = splitEventsIntoBins(rejectionEvents, binsize_s); + + DecimalFormat format = new DecimalFormat(); + format.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US)); + format.setMinimumIntegerDigits(1); + format.setMaximumFractionDigits(2); + format.setGroupingUsed(false); + + SimpleDateFormat sdf2 = new SimpleDateFormat("HH:mm:ss"); + + BufferedWriter bw = IOUtils.getBufferedWriter(fileName + ".csv"); + TimeSeriesCollection dataset = new TimeSeriesCollection(); + TimeSeries rejections = new TimeSeries("number of rejections"); + + try { + bw.write(String.join(delimiter, "timebin", "rejections")); + + for(Map.Entry> e : splitEvents.entrySet()){ + int drt_numOfRejection = 0; + if (!e.getValue().isEmpty()) { + drt_numOfRejection = e.getValue().size(); + } + + Minute h = new Minute(sdf2.parse(Time.writeTime(e.getKey()))); + + rejections.addOrUpdate(h, Double.valueOf(drt_numOfRejection)); + bw.newLine(); + bw.write(String.join(delimiter, Time.writeTime(e.getKey()) + "",// + format.format(drt_numOfRejection) +"")); + } + + bw.flush(); + bw.close(); + if (createGraphs) { + dataset.addSeries(rejections); + JFreeChart chart = chartProfile(splitEvents.size(), dataset, "Number of rejections", "Number"); + ChartSaveUtils.saveAsPNG(chart, fileName, 1500, 1000); + } + + } catch (IOException | ParseException e) { + + e.printStackTrace(); + } + } + private static JFreeChart chartProfile(int length, TimeSeriesCollection dataset, String descriptor, String yax) { JFreeChart chart = ChartFactory.createTimeSeriesChart(descriptor, "Time", yax, dataset);