Skip to content

Commit

Permalink
Merge branch 'master' into dependabot/maven/geotools.version-31.1
Browse files Browse the repository at this point in the history
  • Loading branch information
jfbischoff authored Jun 12, 2024
2 parents 2fd7d6b + 6faa3b1 commit 4a06655
Show file tree
Hide file tree
Showing 22 changed files with 317 additions and 168 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ public final class ShiftEfficiencyAnalysisControlerListener implements Iteration
private final DrtConfigGroup drtConfigGroup;
private final ShiftEfficiencyTracker shiftEfficiencyTracker;

private final String delimiter;

@Inject
public ShiftEfficiencyAnalysisControlerListener(DrtConfigGroup drtConfigGroup,
ShiftEfficiencyTracker shiftEfficiencyTracker,
Expand All @@ -52,6 +54,7 @@ public ShiftEfficiencyAnalysisControlerListener(DrtConfigGroup drtConfigGroup,
this.shiftEfficiencyTracker = shiftEfficiencyTracker;
this.drtShiftsSpecification = drtShiftsSpecification;
this.matsimServices = matsimServices;
this.delimiter = matsimServices.getConfig().global().getDefaultDelimiter();
}

@Override
Expand Down Expand Up @@ -131,7 +134,7 @@ private String filename(IterationEndsEvent event, String prefix, String extensio
.getIterationFilename(event.getIteration(), prefix + "_" + drtConfigGroup.getMode() + extension);
}

private static String line(Object... cells) {
return Arrays.stream(cells).map(Object::toString).collect(Collectors.joining(";", "", "\n"));
private String line(Object... cells) {
return Arrays.stream(cells).map(Object::toString).collect(Collectors.joining(delimiter, "", "\n"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,12 @@ public void install() {
public void install() {
bindModal(DrtZonalWaitTimesAnalyzer.class).toProvider(modalProvider(
getter -> new DrtZonalWaitTimesAnalyzer(drtConfig, getter.getModal(DrtEventSequenceCollector.class),
getter.getModal(ZoneSystem.class)))).asEagerSingleton();
getter.getModal(ZoneSystem.class), config.global().getDefaultDelimiter()))).asEagerSingleton();
addControlerListenerBinding().to(modalKey(DrtZonalWaitTimesAnalyzer.class));
}
});
}
});

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ private void writeIterationVehicleStats(String summarizeVehicles, String vehOcc,
try (var bw = getAppendingBufferedWriter("drt_detailed_distanceStats", ".csv")) {
if (!vheaderWritten) {
vheaderWritten = true;
bw.write("runId;iteration");
bw.write("runId" + delimiter + "iteration");
for (int i = 0; i <= maxcap; i++) {
bw.write(delimiter + i + " pax distance_m");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public void install() {

bindModal(DrtZonalWaitTimesAnalyzer.class).toProvider(modalProvider(
getter -> new DrtZonalWaitTimesAnalyzer(drtCfg, getter.getModal(DrtEventSequenceCollector.class),
getter.getModal(ZoneSystem.class)))).asEagerSingleton();
getter.getModal(ZoneSystem.class), getConfig().global().getDefaultDelimiter()))).asEagerSingleton();
addControlerListenerBinding().to(modalKey(DrtZonalWaitTimesAnalyzer.class));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,16 @@ public final class DrtZonalWaitTimesAnalyzer implements IterationEndsListener, S
private final ZoneSystem zones;
private static final Id<Zone> zoneIdForOutsideOfZonalSystem = Id.create("outsideOfDrtZonalSystem", Zone.class);
private static final String notAvailableString = "NaN";

private final String delimiter;
private static final Logger log = LogManager.getLogger(DrtZonalWaitTimesAnalyzer.class);

public DrtZonalWaitTimesAnalyzer(DrtConfigGroup configGroup, DrtEventSequenceCollector requestAnalyzer,
ZoneSystem zones) {
ZoneSystem zones, String delimiter) {
this.drtCfg = configGroup;
this.requestAnalyzer = requestAnalyzer;
this.zones = zones;
this.delimiter = delimiter;
}

@Override
Expand All @@ -76,7 +79,6 @@ public void notifyIterationEnds(IterationEndsEvent event) {
}

public void write(String fileName) {
String delimiter = ";";
Map<Id<Zone>, DescriptiveStatistics> zoneStats = createZonalStats();
BufferedWriter bw = IOUtils.getBufferedWriter(fileName);
try {
Expand All @@ -85,7 +87,11 @@ public void write(String fileName) {
format.setMinimumIntegerDigits(1);
format.setMaximumFractionDigits(2);
format.setGroupingUsed(false);
bw.append("zone;centerX;centerY;nRequests;sumWaitTime;meanWaitTime;min;max;p95;p90;p80;p75;p50");
String header = new StringJoiner(delimiter)
.add("zone").add("centerX").add("centerY").add("nRequests")
.add("sumWaitTime").add("meanWaitTime").add("min").add("max")
.add("p95").add("p90").add("p80").add("p75").add("p50").toString();
bw.append(header);
// sorted output
SortedSet<Id<Zone>> zoneIdsAndOutside = new TreeSet<>(zones.getZones().keySet());
zoneIdsAndOutside.add(zoneIdForOutsideOfZonalSystem);
Expand All @@ -96,31 +102,22 @@ public void write(String fileName) {
String centerY = drtZone != null ? String.valueOf(drtZone.getCentroid().getY()) : notAvailableString;
DescriptiveStatistics stats = zoneStats.get(zoneId);
bw.newLine();
bw.append(zoneId.toString())
.append(delimiter)
.append(centerX)
.append(delimiter)
.append(centerY)
.append(delimiter)
.append(format.format(stats.getN()))
.append(delimiter)
.append(format.format(stats.getSum()))
.append(delimiter)
.append(String.valueOf(stats.getMean()))
.append(delimiter)
.append(String.valueOf(stats.getMin()))
.append(delimiter)
.append(String.valueOf(stats.getMax()))
.append(delimiter)
.append(String.valueOf(stats.getPercentile(95)))
.append(delimiter)
.append(String.valueOf(stats.getPercentile(90)))
.append(delimiter)
.append(String.valueOf(stats.getPercentile(80)))
.append(delimiter)
.append(String.valueOf(stats.getPercentile(75)))
.append(delimiter)
.append(String.valueOf(stats.getPercentile(50)));
bw.append(
new StringJoiner(delimiter)
.add(zoneId.toString())
.add(centerX)
.add(centerY)
.add(format.format(stats.getN()))
.add(format.format(stats.getSum()))
.add(String.valueOf(stats.getMean()))
.add(String.valueOf(stats.getMin()))
.add(String.valueOf(stats.getMax()))
.add(String.valueOf(stats.getPercentile(95)))
.add(String.valueOf(stats.getPercentile(90)))
.add(String.valueOf(stats.getPercentile(80)))
.add(String.valueOf(stats.getPercentile(75)))
.add(String.valueOf(stats.getPercentile(50))).toString()
);
}
bw.flush();
bw.close();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;
import java.util.function.Supplier;

Expand Down Expand Up @@ -38,7 +40,7 @@ public class PrebookingStopActivity extends FirstLastSimStepDynActivity implemen
private final Map<Id<Request>, ? extends AcceptedDrtRequest> dropoffRequests;

private final IdMap<Request, Double> enterTimes = new IdMap<>(Request.class);
private final IdMap<Request, Double> leaveTimes = new IdMap<>(Request.class);
private final Queue<QueuedRequest> leaveTimes = new PriorityQueue<>();
private final Set<Id<Request>> enteredRequests = new HashSet<>();

private final PrebookingManager prebookingManager;
Expand Down Expand Up @@ -84,27 +86,30 @@ protected void beforeFirstStep(double now) {
private void initDropoffRequests(double now) {
for (var request : dropoffRequests.values()) {
double leaveTime = now + stopDurationProvider.calcDropoffDuration(vehicle, request.getRequest());
leaveTimes.put(request.getId(), leaveTime);
leaveTimes.add(new QueuedRequest(request.getId(), leaveTime));
}

updateDropoffRequests(now);
}

private boolean updateDropoffRequests(double now) {
var iterator = leaveTimes.entrySet().iterator();

while (iterator.hasNext()) {
var entry = iterator.next();

if (entry.getValue() <= now) { // Request should leave now
passengerHandler.dropOffPassengers(driver, entry.getKey(), now);
prebookingManager.notifyDropoff(entry.getKey());
onboard -= dropoffRequests.get(entry.getKey()).getPassengerCount();
iterator.remove();
}
while (!leaveTimes.isEmpty() && leaveTimes.peek().time <= now) {
Id<Request> requestId = leaveTimes.poll().id;
passengerHandler.dropOffPassengers(driver, requestId, now);
prebookingManager.notifyDropoff(requestId);
onboard -= dropoffRequests.get(requestId).getPassengerCount();
}

return leaveTimes.size() == 0;
return leaveTimes.isEmpty();
}

private record QueuedRequest(Id<Request> id, double time) implements Comparable<QueuedRequest> {

@Override
public int compareTo(QueuedRequest o) {
return Double.compare(this.time, o.time);
}
}

private boolean updatePickupRequests(double now) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ public void install() {
addTravelTimeBinding(DvrpTravelTimeModule.DVRP_ESTIMATED).toProvider(() -> {
URL url = ConfigGroup.getInputFileURL(getConfig().getContext(), dvrpCfg.initialTravelTimesFile);
var timeDiscretizer = new TimeDiscretizer(getConfig().travelTimeCalculator());
var linkTravelTimes = DvrpOfflineTravelTimes.loadLinkTravelTimes(timeDiscretizer, url);
var linkTravelTimes = DvrpOfflineTravelTimes.loadLinkTravelTimes(timeDiscretizer, url,
getConfig().global().getDefaultDelimiter());
return DvrpOfflineTravelTimes.asTravelTime(timeDiscretizer, linkTravelTimes);
}).asEagerSingleton();
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.matsim.contrib.dvrp.router.DvrpGlobalRoutingNetworkProvider;
import org.matsim.contrib.dvrp.run.DvrpConfigGroup;
import org.matsim.contrib.common.timeprofile.TimeDiscretizer;
import org.matsim.core.config.groups.GlobalConfigGroup;
import org.matsim.core.config.groups.TravelTimeCalculatorConfigGroup;
import org.matsim.core.controler.OutputDirectoryHierarchy;
import org.matsim.core.controler.events.AfterMobsimEvent;
Expand Down Expand Up @@ -63,18 +64,21 @@ public class DvrpOfflineTravelTimeEstimator
private final double[][] linkTravelTimes;
private final double alpha;

private final String delimiter;

@Inject
public DvrpOfflineTravelTimeEstimator(@Named(DvrpTravelTimeModule.DVRP_INITIAL) TravelTime initialTT,
@Named(DvrpTravelTimeModule.DVRP_OBSERVED) TravelTime observedTT,
@Named(DvrpGlobalRoutingNetworkProvider.DVRP_ROUTING) Network network,
TravelTimeCalculatorConfigGroup ttCalcConfig, DvrpConfigGroup dvrpConfig,
OutputDirectoryHierarchy outputDirectoryHierarchy) {
this(initialTT, observedTT, network, new TimeDiscretizer(ttCalcConfig), dvrpConfig.travelTimeEstimationAlpha, outputDirectoryHierarchy);
@Named(DvrpTravelTimeModule.DVRP_OBSERVED) TravelTime observedTT,
@Named(DvrpGlobalRoutingNetworkProvider.DVRP_ROUTING) Network network,
TravelTimeCalculatorConfigGroup ttCalcConfig, DvrpConfigGroup dvrpConfig,
OutputDirectoryHierarchy outputDirectoryHierarchy, GlobalConfigGroup globalConfig) {
this(initialTT, observedTT, network, new TimeDiscretizer(ttCalcConfig), dvrpConfig.travelTimeEstimationAlpha,
outputDirectoryHierarchy, globalConfig.getDefaultDelimiter());
}

public DvrpOfflineTravelTimeEstimator(TravelTime initialTT, TravelTime observedTT, Network network,
TimeDiscretizer timeDiscretizer, double travelTimeEstimationAlpha,
OutputDirectoryHierarchy outputDirectoryHierarchy) {
OutputDirectoryHierarchy outputDirectoryHierarchy, String delimiter) {
this.observedTT = observedTT;
this.network = network;

Expand All @@ -83,6 +87,7 @@ public DvrpOfflineTravelTimeEstimator(TravelTime initialTT, TravelTime observedT
this.timeInterval = timeDiscretizer.getTimeInterval();

this.outputDirectoryHierarchy = outputDirectoryHierarchy;
this.delimiter = delimiter;

alpha = travelTimeEstimationAlpha;
checkArgument(alpha > 0 && alpha <= 1, "travelTimeEstimationAlpha must be in (0,1]");
Expand Down Expand Up @@ -115,7 +120,8 @@ public void notifyMobsimBeforeCleanup(@SuppressWarnings("rawtypes") MobsimBefore
@Override
public void notifyAfterMobsim(AfterMobsimEvent event) {
DvrpOfflineTravelTimes.saveLinkTravelTimes(timeDiscretizer, linkTravelTimes,
outputDirectoryHierarchy.getIterationFilename(event.getIteration(), "dvrp_travel_times.csv.gz"));
outputDirectoryHierarchy.getIterationFilename(event.getIteration(),
"dvrp_travel_times.csv.gz"), delimiter);
}

private void updateTTs(TravelTime travelTime, double alpha) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,25 +41,25 @@
* @author Michal Maciejewski (michalm)
*/
public class DvrpOfflineTravelTimes {
private static final String DELIMITER = ";";

public static void saveLinkTravelTimes(TimeDiscretizer timeDiscretizer, double[][] linkTravelTimes,
String filename) {
String filename, String delimiter) {
try (Writer writer = IOUtils.getBufferedWriter(filename)) {
saveLinkTravelTimes(timeDiscretizer, linkTravelTimes, writer);
saveLinkTravelTimes(timeDiscretizer, linkTravelTimes, writer, delimiter);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

public static void saveLinkTravelTimes(TimeDiscretizer timeDiscretizer, double[][] linkTravelTimes, Writer writer)
public static void saveLinkTravelTimes(TimeDiscretizer timeDiscretizer, double[][] linkTravelTimes,
Writer writer, String delimiter)
throws IOException {
int intervalCount = timeDiscretizer.getIntervalCount();
//header row
writer.append("linkId" + DELIMITER);
writer.append("linkId").append(delimiter);
for (int i = 0; i < intervalCount; i++) {
double time = i * timeDiscretizer.getTimeInterval();
writer.append(time + DELIMITER);
writer.append(String.valueOf(time)).append(delimiter);
}
writer.append('\n');

Expand All @@ -71,12 +71,12 @@ public static void saveLinkTravelTimes(TimeDiscretizer timeDiscretizer, double[]
if (ttRow != null) {
checkArgument(ttRow.length == intervalCount);

writer.append(Id.get(idx, Link.class) + DELIMITER);
writer.append(String.valueOf(Id.get(idx, Link.class))).append(delimiter);
for (int t = 0; t < intervalCount; t++) {
// rounding up to full seconds, otherwise the output files are sometimes huge (even when gzipped)
// consider having a switch for enabling/disabling rounding
int tt = (int)Math.ceil(ttRow[t]);//rounding up to avoid zeros; also QSim rounds up
writer.append(tt + DELIMITER);
writer.append(String.valueOf(tt)).append(delimiter);
}
writer.append('\n');
}
Expand All @@ -101,27 +101,28 @@ public static TravelTime asTravelTime(TimeDiscretizer timeDiscretizer, double[][
};
}

public static double[][] loadLinkTravelTimes(TimeDiscretizer timeDiscretizer, URL url) {
public static double[][] loadLinkTravelTimes(TimeDiscretizer timeDiscretizer, URL url, String delimiter) {
try (BufferedReader reader = IOUtils.getBufferedReader(url)) {
return loadLinkTravelTimes(timeDiscretizer, reader);
return loadLinkTravelTimes(timeDiscretizer, reader, delimiter);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

public static double[][] loadLinkTravelTimes(TimeDiscretizer timeDiscretizer, BufferedReader reader)
public static double[][] loadLinkTravelTimes(TimeDiscretizer timeDiscretizer, BufferedReader reader,
String delimiter)
throws IOException {
//start with IdMap and then convert to array (to avoid index out of bounds)
IdMap<Link, double[]> linkTravelTimes = new IdMap<>(Link.class);

//header row
String[] headerLine = reader.readLine().split(";");
String[] headerLine = reader.readLine().split(delimiter);
verify(timeDiscretizer.getIntervalCount() == headerLine.length - 1);
verify(headerLine[0].equals("linkId"));
timeDiscretizer.forEach((bin, time) -> verify(Double.parseDouble(headerLine[bin + 1]) == time));

//regular rows
reader.lines().map(line -> line.split(DELIMITER)).forEach(cells -> {
reader.lines().map(line -> line.split(delimiter)).forEach(cells -> {
verify(timeDiscretizer.getIntervalCount() == cells.length - 1);

double[] row = new double[timeDiscretizer.getIntervalCount()];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ public void install() {
addTravelTimeBinding(DvrpTravelTimeModule.DVRP_INITIAL).toProvider(() -> {
URL url = ConfigGroup.getInputFileURL(getConfig().getContext(), dvrpCfg.initialTravelTimesFile);
var timeDiscretizer = new TimeDiscretizer(getConfig().travelTimeCalculator());
var linkTravelTimes = DvrpOfflineTravelTimes.loadLinkTravelTimes(timeDiscretizer, url);
var linkTravelTimes = DvrpOfflineTravelTimes.loadLinkTravelTimes(timeDiscretizer, url,
getConfig().global().getDefaultDelimiter());
return DvrpOfflineTravelTimes.asTravelTime(timeDiscretizer, linkTravelTimes);
}).asEagerSingleton();
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public class DvrpOfflineTravelTimeEstimatorTest {

@Test
void getLinkTravelTime_timeAreCorrectlyBinned() {
var estimator = new DvrpOfflineTravelTimeEstimator(initialTT, null, network, timeDiscretizer, 0.25, null);
var estimator = new DvrpOfflineTravelTimeEstimator(initialTT, null, network, timeDiscretizer, 0.25, null, ";");

//bin 0
assertThat(linkTravelTime(estimator, linkAB, -1)).isEqualTo(1);
Expand Down Expand Up @@ -98,7 +98,7 @@ void getLinkTravelTime_exponentialAveragingOverIterations() {
};

var estimator = new DvrpOfflineTravelTimeEstimator(initialTT, observedTT, network, timeDiscretizer, alpha,
null);
null,";");

//expected TTs for each time bin
double expectedTT_0 = 1;
Expand All @@ -125,7 +125,8 @@ void getLinkTravelTime_exponentialAveragingOverIterations() {
@Test
void getLinkTravelTime_linkOutsideNetwork_fail() {
var linkOutsideNetwork = new FakeLink(Id.createLinkId("some-link"));
var estimator = new DvrpOfflineTravelTimeEstimator(initialTT, null, network, timeDiscretizer, 0.25, null);
var estimator = new DvrpOfflineTravelTimeEstimator(initialTT, null, network, timeDiscretizer,
0.25, null, ";");

assertThatThrownBy(() -> linkTravelTime(estimator, linkOutsideNetwork, 0)).isExactlyInstanceOf(
NullPointerException.class)
Expand Down
Loading

0 comments on commit 4a06655

Please sign in to comment.