playground.michalm.chargerlocation.TaxiBerlin.TaxiBerlinChargerLocationOptimization.java Source code

Java tutorial

Introduction

Here is the source code for playground.michalm.chargerlocation.TaxiBerlin.TaxiBerlinChargerLocationOptimization.java

Source

/* *********************************************************************** *
 * project: org.matsim.*
 *                                                                         *
 * *********************************************************************** *
 *                                                                         *
 * copyright       : (C) 2015 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 playground.michalm.chargerlocation.TaxiBerlin;

import java.util.*;

import org.apache.commons.lang3.StringUtils;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.network.Network;
import org.matsim.contrib.util.distance.DistanceCalculators;
import org.matsim.contrib.zone.Zone;
import org.matsim.core.network.NetworkUtils;
import org.matsim.core.network.io.MatsimNetworkReader;
import org.matsim.core.utils.io.IOUtils;

import playground.michalm.TaxiBerlin.TaxiBerlinZoneUtils;
import playground.michalm.chargerlocation.*;
import playground.michalm.chargerlocation.ChargerLocationProblem.ChargerLocationSolution;
import playground.michalm.ev.data.Charger;
import playground.michalm.ev.data.file.ChargerWriter;

public class TaxiBerlinChargerLocationOptimization {
    private static final int VEHICLE_HOURS = 32064;//ANT'15 paper (Tue 4am - Wed 4am, 16-17 Apr 2014)

    //influences mostly the outskirts
    private static final double MAX_DISTANCE = 3_000;//m

    //high value -> no influence (the current approach); low value -> lack of chargers at TXL
    private static final int MAX_CHARGERS_PER_ZONE = 30;

    //smaller demand -> larger oversupply (also sensitive to includeDeltaSOC)
    private static final double OVERSUPPLY = 1.1;

    //TST'15 paper
    private static final double DELTA_SOC = 16;//kWh
    private static final int HOURS = 16;//h, each vehicle operates 16 hours (2 shifts)

    //TST'15 paper (after fixing the error in XLS)
    private enum EScenario {
        STANDARD(41.75, 50), //
        HOT_SUMMER(55.75, 50), //
        COLD_WINTER(89.75, 25), //
        COLD_WINTER_FOSSIL_HEATING(41.75, 25);

        private final double energyPerVehicle_kWh;
        private final double chargePower_kW;

        private EScenario(double energyPerVehicle_kWh, double chargePower_kW) {
            this.energyPerVehicle_kWh = energyPerVehicle_kWh;
            this.chargePower_kW = chargePower_kW;
        }
    }

    private final boolean rechargeBeforeEnd;
    private final EScenario eScenario;

    private ChargerLocationProblem problem;
    private ChargerLocationSolution solution;

    private final String dir = "d:/eclipse/shared-svn/projects/sustainability-w-michal-and-dlr/data/";
    private final String zonesXmlFile = dir + "shp_merged/berlin_zones.xml";
    private final String zonesShpFile = dir + "shp_merged/berlin_zones.shp";
    private final String potentialFile = dir + "taxi_berlin/2014/status/idleVehiclesPerZoneAndHour.txt";
    private final String networkFile = dir + "network/berlin_brb.xml";

    public TaxiBerlinChargerLocationOptimization(EScenario eScenario, boolean includeDeltaSoc) {
        this.eScenario = eScenario;
        this.rechargeBeforeEnd = includeDeltaSoc;

    }

    private void createProblem() {
        Map<Id<Zone>, Zone> zones = TaxiBerlinZoneUtils.readZones(zonesXmlFile, zonesShpFile);
        DemandData<Zone> demandData = createDemandData(zones, potentialFile);
        ChargerLocationData<Zone> chargerData = new ChargerLocationData<>(zones.values());

        double totalEnergyRequired = VEHICLE_HOURS / HOURS
                * Math.max(eScenario.energyPerVehicle_kWh - (rechargeBeforeEnd ? 0 : DELTA_SOC), 0);

        problem = new ChargerLocationProblem(demandData, chargerData,
                DistanceCalculators.BEELINE_DISTANCE_CALCULATOR, HOURS, eScenario.chargePower_kW,
                totalEnergyRequired, OVERSUPPLY, MAX_DISTANCE, MAX_CHARGERS_PER_ZONE);
    }

    private DemandData<Zone> createDemandData(Map<Id<Zone>, Zone> zones, String potentialFile) {
        Map<Id<Zone>, Double> zonePotentials = new HashMap<>();

        //from: 20140407000000
        //to: 20140413230000 (incl.)
        final int FROM_DAY = 1;//monday
        final int TO_DAY = 4;//thursday (incl.)
        final int FROM_HOUR = 7;
        final int TO_HOUR = 19;//inclusive

        try (Scanner s = new Scanner(IOUtils.getBufferedReader(potentialFile))) {
            while (s.hasNext()) {
                String zoneId = StringUtils.leftPad(s.next(), 8, '0');
                Id<Zone> id = Id.create(zoneId, Zone.class);
                if (!zones.containsKey(id)) {
                    s.nextLine();
                    continue;
                }

                double potential = 0;
                for (int d = 1; d <= 7; d++) {
                    for (int h = 1; h <= 24; h++) {
                        double p = s.nextDouble();
                        if (FROM_DAY <= d && d <= TO_DAY && FROM_HOUR <= h && h <= TO_HOUR) {
                            potential += p;
                        }
                    }
                }

                zonePotentials.put(id, potential);
            }
        }

        return new DemandData<Zone>(zones.values(), zonePotentials);
    }

    private void solveProblem() {
        solution = new ChargerLocationSolver(problem).solve(null);
    }

    private void writeSolution() {
        String name = eScenario.name() + (rechargeBeforeEnd ? "_noDeltaSOC" : "_DeltaSOC");
        ChargerLocationSolutionWriter writer = new ChargerLocationSolutionWriter(problem, solution);
        writer.writeChargers(dir + "chargers_" + problem.maxChargers + "_" + name + ".csv");
        writer.writeFlows(dir + "flows_" + name + ".csv");

        Network network = NetworkUtils.createNetwork();
        new MatsimNetworkReader(network).readFile(networkFile);
        List<Charger> chargers = writer.generateChargers(network,
                TaxiBerlinZoneUtils.ZONE_TO_NETWORK_COORD_TRANSFORMATION, eScenario.chargePower_kW);
        new ChargerWriter(chargers).write(dir + "chargers_" + problem.maxChargers + "_" + name + ".xml");
    }

    public static void main(String[] args) {
        for (EScenario es : EScenario.values()) {
            System.err.println("==========================" + es.name());
            boolean rechargeBeforeEnd = !true;
            TaxiBerlinChargerLocationOptimization optimRunner = new TaxiBerlinChargerLocationOptimization(es,
                    rechargeBeforeEnd);
            optimRunner.createProblem();
            optimRunner.solveProblem();
            optimRunner.writeSolution();
        }
    }
}