org.matsim.contrib.drt.optimizer.rebalancing.mincostflow.AggregatedMinCostRelocationCalculator.java Source code

Java tutorial

Introduction

Here is the source code for org.matsim.contrib.drt.optimizer.rebalancing.mincostflow.AggregatedMinCostRelocationCalculator.java

Source

/* *********************************************************************** *
 * project: org.matsim.*
 * *********************************************************************** *
 *                                                                         *
 * copyright       : (C) 2018 by the members listed in the COPYING,        *
 *                   LICENSE and WARRANTY file.                            *
 * email           : info at matsim dot org                                *
 *                                                                         *
 * *********************************************************************** *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *   See also COPYING, LICENSE and WARRANTY file                           *
 *                                                                         *
 * *********************************************************************** */

package org.matsim.contrib.drt.optimizer.rebalancing.mincostflow;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;
import org.matsim.api.core.v01.Coord;
import org.matsim.api.core.v01.network.Link;
import org.matsim.api.core.v01.network.Network;
import org.matsim.contrib.drt.analysis.zonal.DrtZonalSystem;
import org.matsim.contrib.drt.optimizer.rebalancing.RebalancingStrategy.Relocation;
import org.matsim.contrib.dvrp.data.Vehicle;
import org.matsim.contrib.dvrp.router.DvrpRoutingNetworkProvider;
import org.matsim.contrib.dvrp.schedule.Schedules;
import org.matsim.contrib.util.distance.DistanceUtils;
import org.matsim.core.network.NetworkUtils;
import org.matsim.core.utils.geometry.geotools.MGC;

import com.google.inject.name.Named;
import com.vividsolutions.jts.geom.Geometry;

/**
 * @author michalm
 */
public class AggregatedMinCostRelocationCalculator implements MinCostRelocationCalculator {
    private final DrtZonalSystem zonalSystem;
    private final Network network;

    @Inject
    public AggregatedMinCostRelocationCalculator(DrtZonalSystem zonalSystem,
            @Named(DvrpRoutingNetworkProvider.DVRP_ROUTING) Network network) {
        this.zonalSystem = zonalSystem;
        this.network = network;
    }

    @Override
    public List<Relocation> calcRelocations(List<Pair<String, Integer>> supply, List<Pair<String, Integer>> demand,
            Map<String, List<Vehicle>> rebalancableVehiclesPerZone) {
        List<Triple<String, String, Integer>> interZonalRelocations = new TransportProblem<String, String>(
                this::calcStraightLineDistance).solve(supply, demand);
        return calcRelocations(rebalancableVehiclesPerZone, interZonalRelocations);
    }

    private int calcStraightLineDistance(String zone1, String zone2) {
        return (int) DistanceUtils.calculateDistance(zonalSystem.getZoneCentroid(zone1),
                zonalSystem.getZoneCentroid(zone2));
    }

    private List<Relocation> calcRelocations(Map<String, List<Vehicle>> rebalancableVehiclesPerZone,
            List<Triple<String, String, Integer>> interZonalRelocations) {
        List<Relocation> relocations = new ArrayList<>();
        for (Triple<String, String, Integer> r : interZonalRelocations) {
            List<Vehicle> rebalancableVehicles = rebalancableVehiclesPerZone.get(r.getLeft());

            String toZone = r.getMiddle();
            Geometry z = zonalSystem.getZone(toZone);
            Coord zoneCentroid = MGC.point2Coord(z.getCentroid());
            Link destinationLink = NetworkUtils.getNearestLink(network, zoneCentroid);

            int flow = r.getRight();
            for (int f = 0; f < flow; f++) {
                // TODO use BestDispatchFinder (needs to be moved from taxi to dvrp) instead
                Vehicle nearestVehicle = findNearestVehicle(rebalancableVehicles, destinationLink);
                relocations.add(new Relocation(nearestVehicle, destinationLink));
                rebalancableVehicles.remove(nearestVehicle);// TODO use map to have O(1) removal
            }
        }
        return relocations;
    }

    private Vehicle findNearestVehicle(List<Vehicle> rebalancableVehicles, Link destinationLink) {
        Coord toCoord = destinationLink.getFromNode().getCoord();
        return rebalancableVehicles.stream().min(Comparator.comparing(v -> DistanceUtils.calculateSquaredDistance(//
                Schedules.getLastLinkInSchedule(v).getToNode().getCoord(), toCoord))).get();
    }
}