Skip to content

Commit

Permalink
Merge branch 'refs/heads/master' into trip-by-group-analysis
Browse files Browse the repository at this point in the history
  • Loading branch information
rakow committed Jun 12, 2024
2 parents e6000b6 + 28b35a0 commit dde2022
Show file tree
Hide file tree
Showing 11 changed files with 72 additions and 61 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 @@ -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 @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ void saveLinkTravelTimes() throws IOException {
linkTTs[linkIdB.index()] = new double[] { 5.5, 6.6, 7.7, 8.8, 9.9 };

var stringWriter = new StringWriter();
DvrpOfflineTravelTimes.saveLinkTravelTimes(new TimeDiscretizer(3600, 900), linkTTs, stringWriter);
DvrpOfflineTravelTimes.saveLinkTravelTimes(new TimeDiscretizer(3600, 900),
linkTTs, stringWriter, ";");

var lines = stringWriter.toString().split("\n");
assertThat(lines).hasSize(3);
Expand All @@ -76,7 +77,8 @@ void loadLinkTravelTimes() throws IOException {
var lines = String.join("\n", line0, line1, line2);

var stringReader = new BufferedReader(new StringReader(lines));
var linkTTs = DvrpOfflineTravelTimes.loadLinkTravelTimes(new TimeDiscretizer(3600, 900), stringReader);
var linkTTs = DvrpOfflineTravelTimes.loadLinkTravelTimes(new TimeDiscretizer(3600, 900),
stringReader, ";");

//the matrix may have more than 2 rows (depends on how many link ids are cached)
//all rows are null (except for links A and B)
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@
<dependency>
<groupId>org.checkerframework</groupId>
<artifactId>checker-qual</artifactId>
<version>3.43.0</version>
<version>3.44.0</version>
</dependency>

<dependency>
Expand Down

0 comments on commit dde2022

Please sign in to comment.