Skip to content

Commit

Permalink
Merge pull request #9 from moia-oss/am-fix
Browse files Browse the repository at this point in the history
Update alonso-mora CW30
  • Loading branch information
nkuehnel authored Jul 24, 2024
2 parents 98c459f + d757c7e commit 9657c6e
Show file tree
Hide file tree
Showing 65 changed files with 2,239 additions and 2,252 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ jobs:

steps:
- uses: actions/checkout@v2
- name: Set up JDK 17
- name: Set up JDK 21
uses: actions/setup-java@v1
with:
java-version: 17
java-version: 21
- name: Install GLPK and CBC
run: sudo apt install glpk-utils coinor-cbc libglpk-java
- name: Run tests
Expand Down
863 changes: 168 additions & 695 deletions core/src/main/java/org/matsim/alonso_mora/AlonsoMoraConfigGroup.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ static private AlonsoMoraConfigGroup getAlonsoMoraConfig(Config config, String m
MultiModeAlonsoMoraConfigGroup multiModeConfig = MultiModeAlonsoMoraConfigGroup.get(config);

for (AlonsoMoraConfigGroup modeConfig : multiModeConfig.getModes().values()) {
if (modeConfig.getMode().equals(mode)) {
if (modeConfig.mode.equals(mode)) {
return modeConfig;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,10 @@ public void install() {
return new InformationCollector();
})).asEagerSingleton();

bindModal(RequestAggregationHandler.class).to(RequestAggregationHandler.class).asEagerSingleton();
addEventHandlerBinding().to(modalKey(RequestAggregationHandler.class));

bindModal(AnalysisListener.class).toProvider(modalProvider(getter -> {
return new AnalysisListener( //
getter.getModal(InformationCollector.class), //
getter.get(OutputDirectoryHierarchy.class), //
getter.getModal(RequestAggregationHandler.class) //
getter.get(OutputDirectoryHierarchy.class) //
);
})).asEagerSingleton();

Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.matsim.alonso_mora;

import java.util.Optional;

import org.matsim.contrib.drt.passenger.AcceptedDrtRequest;
import org.matsim.contrib.drt.passenger.DrtOfferAcceptor;
import org.matsim.contrib.drt.passenger.DrtRequest;

public class AlonsoMoraOfferAcceptor implements DrtOfferAcceptor {
@Override
public Optional<AcceptedDrtRequest> acceptDrtOffer(DrtRequest request, double departureTime, double arrivalTime) {
return Optional.of(AcceptedDrtRequest.newBuilder() //
.request(request) //
.earliestStartTime(request.getEarliestStartTime()) //
.latestArrivalTime(request.getLatestArrivalTime()) //
.latestStartTime(departureTime) //
.build());
}
}
98 changes: 21 additions & 77 deletions core/src/main/java/org/matsim/alonso_mora/AlonsoMoraOptimizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.concurrent.ForkJoinPool;
import java.util.stream.IntStream;

Expand Down Expand Up @@ -40,34 +37,24 @@ public class AlonsoMoraOptimizer implements DrtOptimizer {
private final List<DrtRequest> submittedRequests = new LinkedList<>();
private final double assignmentInterval;

private final int maximumGroupRequestSize;

private final ForkJoinPool forkJoinPool;
private final LeastCostPathCalculator router;
private final TravelTime travelTime;

private final InformationCollector collector;

private final Queue<AlonsoMoraRequest> prebookingQueue = new PriorityQueue<>((a, b) -> {
return Double.compare(a.getEarliestPickupTime(), b.getEarliestPickupTime());
});

private final double prebookingHorizon;

public AlonsoMoraOptimizer(AlonsoMoraAlgorithm algorithm, AlonsoMoraRequestFactory requestFactory,
ScheduleTimingUpdater scheduleTimingUpdater, Fleet fleet, double assignmentInterval,
int maximumGroupRequestSize, ForkJoinPool forkJoinPool, LeastCostPathCalculator router,
TravelTime travelTime, double prebookingHorizon, InformationCollector collector) {
ForkJoinPool forkJoinPool, LeastCostPathCalculator router, TravelTime travelTime,
InformationCollector collector) {
this.algorithm = algorithm;
this.requestFactory = requestFactory;
this.assignmentInterval = assignmentInterval;
this.scheduleTimingUpdater = scheduleTimingUpdater;
this.fleet = fleet;
this.maximumGroupRequestSize = maximumGroupRequestSize;
this.forkJoinPool = forkJoinPool;
this.router = router;
this.travelTime = travelTime;
this.prebookingHorizon = prebookingHorizon;
this.collector = collector;
}

Expand All @@ -76,89 +63,46 @@ public void requestSubmitted(Request request) {
submittedRequests.add((DrtRequest) request);
}

/**
* Goes through the submitted individual requests and tries to find those that
* should be aggregated to a collective request.
*/
private List<List<DrtRequest>> poolRequests(List<DrtRequest> submittedRequests) {
submittedRequests = new LinkedList<>(submittedRequests);
List<List<DrtRequest>> allPooledRequests = new LinkedList<>();

while (submittedRequests.size() > 0) {
List<DrtRequest> pooledRequests = new LinkedList<>();
pooledRequests.add(submittedRequests.remove(0));
DrtRequest mainRequest = pooledRequests.get(0);

Iterator<DrtRequest> iterator = submittedRequests.iterator();

while (iterator.hasNext() && pooledRequests.size() < maximumGroupRequestSize) {
DrtRequest nextRequest = iterator.next();

if (nextRequest.getFromLink() == mainRequest.getFromLink()) {
if (nextRequest.getToLink() == mainRequest.getToLink()) {
if (nextRequest.getEarliestStartTime() == mainRequest.getEarliestStartTime()) {
pooledRequests.add(nextRequest);
iterator.remove();
}
}
}
}

allPooledRequests.add(pooledRequests);
}

return allPooledRequests;
}

@Override
public void notifyMobsimBeforeSimStep(@SuppressWarnings("rawtypes") MobsimBeforeSimStepEvent e) {
double now = e.getSimulationTime();

if (now % assignmentInterval == 0) {
List<AlonsoMoraRequest> newRequests = new LinkedList<>();
List<AlonsoMoraRequest> processedRequests = new LinkedList<>();

List<List<DrtRequest>> pooledRequests = poolRequests(submittedRequests);
List<VrpPathWithTravelData> paths = new ArrayList<>(Collections.nCopies(pooledRequests.size(), null));
List<DrtRequest> submittedRequests = new ArrayList<>(this.submittedRequests);
this.submittedRequests.clear();

List<VrpPathWithTravelData> paths = new ArrayList<>(Collections.nCopies(submittedRequests.size(), null));

// Here this direct routing is performed
forkJoinPool.submit(() -> {
IntStream.range(0, pooledRequests.size()).parallel().forEach(i -> {
DrtRequest request = pooledRequests.get(i).get(0);
paths.set(i, VrpPaths.calcAndCreatePath(request.getFromLink(), request.getToLink(), request.getEarliestStartTime(), router,
travelTime));
IntStream.range(0, submittedRequests.size()).parallel().forEach(i -> {
DrtRequest request = submittedRequests.get(i);
paths.set(i, VrpPaths.calcAndCreatePath(request.getFromLink(), request.getToLink(),
request.getEarliestStartTime(), router, travelTime));
});
}).join();

// Grouped requests
for (int i = 0; i < pooledRequests.size(); i++) {
List<DrtRequest> pool = pooledRequests.get(i);

double earliestDepartureTime = pool.get(0).getEarliestStartTime();
for (int i = 0; i < submittedRequests.size(); i++) {
DrtRequest drtRequest = submittedRequests.get(i);

double earliestDepartureTime = drtRequest.getEarliestStartTime();
double directArrivalTime = paths.get(i).getTravelTime() + earliestDepartureTime;
double directRideDistance = VrpPaths.calcDistance(paths.get(i));

AlonsoMoraRequest request = requestFactory.createRequest(pool, directArrivalTime, earliestDepartureTime,
directRideDistance);
AlonsoMoraRequest request = requestFactory.createRequest(drtRequest, directArrivalTime,
earliestDepartureTime, directRideDistance);

if (now >= request.getEarliestPickupTime() - prebookingHorizon) {
newRequests.add(request);
} else {
prebookingQueue.add(request);
}
processedRequests.add(request);
}

while (prebookingQueue.size() > 0
&& now >= prebookingQueue.peek().getEarliestPickupTime() - prebookingHorizon) {
newRequests.add(prebookingQueue.poll());
}

submittedRequests.clear();

for (DvrpVehicle v : fleet.getVehicles().values()) {
scheduleTimingUpdater.updateTimings(v);
}

Optional<AlonsoMoraAlgorithm.Information> information = algorithm.run(newRequests, e.getSimulationTime());
Optional<AlonsoMoraAlgorithm.Information> information = algorithm.run(processedRequests,
e.getSimulationTime());

if (information.isPresent()) {
collector.addInformation(e.getSimulationTime(), information.get());
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.matsim.alonso_mora;

import org.matsim.api.core.v01.Id;
import org.matsim.contrib.drt.prebooking.unscheduler.RequestUnscheduler;
import org.matsim.contrib.dvrp.fleet.DvrpVehicle;
import org.matsim.contrib.dvrp.optimizer.Request;

public class AlonsoMoraUnscheduler implements RequestUnscheduler {
@Override
public void unscheduleRequest(double now, Id<DvrpVehicle> vehicleId, Id<Request> requestId) {
// in AM we do not unschedule any request as the schedules are rebuilt in every
// step
}
}
26 changes: 1 addition & 25 deletions core/src/main/java/org/matsim/alonso_mora/AnalysisListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

Expand All @@ -32,11 +31,9 @@
import org.matsim.alonso_mora.InformationCollector.RebalancingInformation;
import org.matsim.alonso_mora.InformationCollector.SolverInformation;
import org.matsim.alonso_mora.algorithm.assignment.AssignmentSolver.Solution.Status;
import org.matsim.api.core.v01.Id;
import org.matsim.contrib.common.timeprofile.TimeProfileCharts;
import org.matsim.contrib.common.timeprofile.TimeProfileCharts.ChartType;
import org.matsim.contrib.common.util.ChartSaveUtils;
import org.matsim.contrib.dvrp.optimizer.Request;
import org.matsim.core.controler.OutputDirectoryHierarchy;
import org.matsim.core.controler.events.IterationEndsEvent;
import org.matsim.core.controler.listener.IterationEndsListener;
Expand All @@ -50,19 +47,16 @@
*/
class AnalysisListener implements IterationEndsListener {
private final InformationCollector information;
private final RequestAggregationHandler requestHandler;
private final OutputDirectoryHierarchy outputHierarchy;

private final List<Long> numberOfInvalidSolutions = new LinkedList<>();
private final List<Long> numberOfNonOptimalSolutions = new LinkedList<>();
private final List<Long> numberOfOptimalSolutions = new LinkedList<>();
private final List<Long> numberOfReassignments = new LinkedList<>();

public AnalysisListener(InformationCollector information, OutputDirectoryHierarchy outputHierarchy,
RequestAggregationHandler requestHandler) {
public AnalysisListener(InformationCollector information, OutputDirectoryHierarchy outputHierarchy) {
this.information = information;
this.outputHierarchy = outputHierarchy;
this.requestHandler = requestHandler;
}

@Override
Expand Down Expand Up @@ -364,23 +358,5 @@ public void notifyIterationEnds(IterationEndsEvent event) {
ChartSaveUtils.saveAsPNG(stackedChart,
outputHierarchy.getIterationFilename(event.getIteration(), "am_occupancy_requests"), 1500, 1000);
}

{
List<Set<Id<Request>>> requests = requestHandler.consolidate();

try {
File path = new File(
outputHierarchy.getIterationFilename(event.getIteration(), "am_group_requests.txt"));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path)));

for (Set<Id<Request>> set : requests) {
writer.write(set.stream().map(String::valueOf).collect(Collectors.joining(",")) + "\n");
}

writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public Map<String, AlonsoMoraConfigGroup> getModes() {

for (ConfigGroup modeConfig : getParameterSets(AlonsoMoraConfigGroup.GROUP_NAME)) {
AlonsoMoraConfigGroup amConfig = (AlonsoMoraConfigGroup) modeConfig;
modes.put(amConfig.getMode(), amConfig);
modes.put(amConfig.mode, amConfig);
}

return modes;
Expand Down
Loading

0 comments on commit 9657c6e

Please sign in to comment.