playground.michalm.chargerlocation.RunChargerLocationOptimization.java Source code

Java tutorial

Introduction

Here is the source code for playground.michalm.chargerlocation.RunChargerLocationOptimization.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;

import java.io.*;
import java.util.*;

import org.apache.commons.lang3.StringUtils;
import org.matsim.api.core.v01.*;
import org.matsim.contrib.dvrp.run.VrpConfigUtils;
import org.matsim.core.network.MatsimNetworkReader;
import org.matsim.core.scenario.ScenarioUtils;

import playground.michalm.berlin.BerlinZoneUtils;
import playground.michalm.chargerlocation.ChargerLocationProblem.ChargerLocationSolution;
import playground.michalm.util.distance.*;
import playground.michalm.zone.Zone;

public class RunChargerLocationOptimization {
    private ChargerLocationProblem problem;
    private ChargerLocationSolution initSolution;
    private ChargerLocationSolution finalSolution;

    private Map<Id<Zone>, Double> zonePotentials = new HashMap<>();
    private double totalPotential = 0;

    private enum EnergyConsumption {
        SUMMER_HEAT(69.75), NORMAL(41.75), WINTER_COLD(105.75), WINTER_COLD_FOSSIL_HEATING(41.75);

        private final double energyPerVehicle;//kWh

        private EnergyConsumption(double energyPerVehicle) {
            this.energyPerVehicle = energyPerVehicle;
        }
    }

    private enum TimeHorizon {
        //ANT'15 paper (Tue 4am - Wed 4am, 16-17 Apr 2014)
        _16H(16, 7, 32064), //
        _24H(24, 0, 40444);

        private final int hours;
        private final int fromHour;
        private final int toHour;
        private final int vehicleCount;

        private TimeHorizon(int hours, int fromHour, int vehicleHours) {
            this.hours = hours;
            this.fromHour = fromHour;

            toHour = fromHour + hours - 1;// 16h from 7am; 24h from 0am
            vehicleCount = vehicleHours / 16; //each vehicle operates 16 hours (2 shifts)
        }
    }

    private void createProblem() {
        //TST'15 paper
        double chargerPower = 50;//kW
        EnergyConsumption energyConsumption = EnergyConsumption.NORMAL;
        double deltaSOC = 16;//kWh

        //ANT'15 paper
        TimeHorizon horizon = TimeHorizon._16H;

        //LP constraints
        double maxDistance = 5_000;//m
        int maxChargersInZone = 30;
        //int maxChargers = 450;
        double supplyBuffer = 1.1;

        String dir = "d:/svn-vsp/sustainability-w-michal-and-dlr/data/";
        String networkFile = dir + "scenarios/2015_02_basic_scenario_v6/berlin_brb.xml";
        String zonesXmlFile = dir + "shp_merged/berlin_zones.xml";
        String zonesShpFile = dir + "shp_merged/berlin_zones.shp";
        String potentialFile = dir + "taxi_berlin/2014/status/idleVehiclesPerZoneAndHour.txt";
        //String taxiRanksFile = dir + "scenarios/2015_02_basic_scenario_v6/berlin_ranks.xml";

        Scenario scenario = ScenarioUtils.createScenario(VrpConfigUtils.createConfig());
        new MatsimNetworkReader(scenario).readFile(networkFile);

        //        DistanceCalculator calculator = DistanceCalculators
        //                .crateFreespeedDistanceCalculator(scenario.getNetwork());
        DistanceCalculator calculator = DistanceCalculators.BEELINE_DISTANCE_CALCULATOR;

        Map<Id<Zone>, Zone> zones = BerlinZoneUtils.readZones(scenario, zonesXmlFile, zonesShpFile);
        readPotentials(zones, potentialFile, horizon);

        double totalEnergyConsumed = Math.max(energyConsumption.energyPerVehicle - deltaSOC, 0)
                * horizon.vehicleCount;
        ZoneData zoneData = new ZoneData(zones, zonePotentials, totalEnergyConsumed / totalPotential);

        //read/create stations at either zone centroids or ranks 
        List<ChargingStation> stations = new ArrayList<>();
        for (Zone z : zones.values()) {
            Id<ChargingStation> id = Id.create(z.getId(), ChargingStation.class);
            ChargingStation station = new ChargingStation(id, z.getCoord(), chargerPower);
            stations.add(station);
        }
        ChargerData chargerData = new ChargerData(stations, horizon.hours);

        //        double maxEnergyProduced = Math.min(maxChargersInZone * stations.size(), maxChargers)
        //                * chargerPower * timeHorizon;
        //
        //        if (maxEnergyProduced < totalEnergyConsumed) {
        //            throw new RuntimeException("demand > supply: " + totalEnergyConsumed + " > "
        //                    + maxEnergyProduced);
        //        }

        int minMaxChargers = (int) Math.ceil(supplyBuffer * totalEnergyConsumed / (chargerPower * horizon.hours));
        System.out.println("minMaxChargers = " + minMaxChargers);

        problem = new ChargerLocationProblem(zoneData, chargerData, calculator, maxDistance, maxChargersInZone,
                minMaxChargers);
    }

    private void readPotentials(Map<Id<Zone>, Zone> zones, String potentialFile, TimeHorizon horizon) {
        if (horizon == TimeHorizon._24H) {
            //TODO does not work for 24h: should be Mon 4am till Fri 4am
            throw new IllegalArgumentException();
        }

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

        try (Scanner s = new Scanner(new File(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 && horizon.fromHour <= h && h <= horizon.toHour) {
                            potential += p;
                        }
                    }
                }

                zonePotentials.put(id, potential);
                totalPotential += potential;
            }
        } catch (FileNotFoundException e) {
            throw new RuntimeException();
        }
    }

    private void writeSolution(ChargerLocationSolution solution) {
        String dir = "d:/PP-rad/berlin/chargerLocation/";

        writeChargers(solution.x, dir + "chargers.csv");
        writeFlows(solution.f, dir + "flows.csv");
    }

    private void writeChargers(int[] x, String file) {
        List<ChargingStation> stations = problem.chargerData.stations;

        try (PrintWriter writer = new PrintWriter(file)) {
            for (int j = 0; j < problem.J; j++) {
                if (x[j] > 0) {
                    Id<ChargingStation> stationId = stations.get(j).getId();
                    writer.printf("%s,%d\n", stationId, x[j]);
                }
            }
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    private void writeFlows(double[][] f, String file) {
        List<ZoneData.Entry> zoneEntries = problem.zoneData.entries;
        List<ChargingStation> stations = problem.chargerData.stations;

        try (PrintWriter writer = new PrintWriter(file)) {
            for (int i = 0; i < problem.I; i++) {
                for (int j = 0; j < problem.J; j++) {
                    if (f[i][j] > 1e-2) {
                        Id<Zone> zoneId = zoneEntries.get(i).zone.getId();
                        Id<ChargingStation> stationId = stations.get(j).getId();
                        writer.printf("%s,%s,%.2f\n", zoneId, stationId, f[i][j]);
                    }
                }
            }
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    private void solveProblem() {
        //initSolution = new ChargerLocationFinder(problem).findInitialSolution();
        finalSolution = new ChargerLocationSolver(problem).solve(initSolution);

        writeSolution(finalSolution);
    }

    public static void main(String[] args) {
        RunChargerLocationOptimization runOptimizer = new RunChargerLocationOptimization();
        runOptimizer.createProblem();
        runOptimizer.solveProblem();

    }
}