Java tutorial
/* *********************************************************************** * * project: org.matsim.* * * * *********************************************************************** * * * * copyright : (C) 2012 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.sergioo.workplaceCapacities2012; import java.io.BufferedReader; import java.io.EOFException; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.PrintWriter; import java.sql.ResultSet; import java.sql.SQLException; import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; import org.apache.commons.math3.linear.Array2DRowRealMatrix; import org.apache.commons.math3.linear.ArrayRealVector; import org.apache.commons.math3.linear.EigenDecomposition; import org.apache.commons.math3.linear.RealMatrix; import org.apache.commons.math3.linear.RealVector; import org.apache.commons.math3.ml.clustering.CentroidCluster; import org.apache.commons.math3.ml.clustering.Cluster; import org.apache.commons.math3.ml.clustering.KMeansPlusPlusClusterer; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.network.Network; import org.matsim.api.core.v01.population.Person; import org.matsim.core.config.ConfigUtils; import org.matsim.core.network.MatsimNetworkReader; import org.matsim.core.network.NetworkImpl; import org.matsim.core.router.AStarLandmarks; import org.matsim.core.router.util.PreProcessLandmarks; import org.matsim.core.router.util.TravelDisutility; import org.matsim.core.router.util.TravelTime; import org.matsim.core.scenario.ScenarioImpl; import org.matsim.core.scenario.ScenarioUtils; import org.matsim.core.utils.collections.Tuple; import org.matsim.core.utils.geometry.CoordImpl; import org.matsim.core.utils.geometry.CoordUtils; import org.matsim.core.utils.geometry.CoordinateTransformation; import org.matsim.core.utils.geometry.transformations.TransformationFactory; import org.matsim.core.utils.gis.ShapeFileReader; import org.matsim.facilities.ActivityFacilities; import org.matsim.facilities.ActivityFacilitiesImpl; import org.matsim.facilities.ActivityFacility; import org.matsim.facilities.ActivityFacilityImpl; import org.matsim.facilities.ActivityOption; import org.matsim.facilities.ActivityOptionImpl; import org.matsim.facilities.FacilitiesUtils; import org.matsim.facilities.FacilitiesWriter; import org.matsim.facilities.OpeningTime; import org.matsim.facilities.OpeningTimeImpl; import org.matsim.pt.transitSchedule.api.TransitStopFacility; import org.matsim.vehicles.Vehicle; import org.opengis.feature.simple.SimpleFeature; import others.sergioo.util.algebra.Matrix1DImpl; import others.sergioo.util.algebra.Matrix2DImpl; import others.sergioo.util.algebra.Matrix3DImpl; import others.sergioo.util.algebra.MatrixND; import others.sergioo.util.algebra.PointND; import others.sergioo.util.dataBase.DataBaseAdmin; import others.sergioo.util.dataBase.NoConnectionException; import playground.sergioo.visualizer2D2012.networkVisualizer.SimpleNetworkWindow; import playground.sergioo.visualizer2D2012.networkVisualizer.networkPainters.NetworkPainter; import playground.sergioo.workplaceCapacities2012.gui.BSSimpleNetworkWindow; import playground.sergioo.workplaceCapacities2012.gui.ClustersWindow; import playground.sergioo.workplaceCapacities2012.gui.WeigthsNetworkWindow; import playground.sergioo.workplaceCapacities2012.gui.WorkersAreaPainter; import playground.sergioo.workplaceCapacities2012.gui.WorkersBSPainter; import playground.sergioo.workplaceCapacities2012.hits.PersonSchedule; import playground.sergioo.workplaceCapacities2012.hits.PointPerson; import playground.sergioo.workplaceCapacities2012.hits.Trip; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.MultiPolygon; import com.vividsolutions.jts.geom.Polygon; public class MainWorkplaceCapacities { //Classes private static class ModeShareZone { private final double modeShare; private double difference = 0; private final List<Double> capacities = new ArrayList<Double>(); public ModeShareZone(double modeShare) { this.modeShare = modeShare; } } //Constants private static final String NETWORK_FILE = "./data/currentSimulation/singapore2.xml"; private static final String LINKS_MAP_FILE = "./data/facilities/auxiliar/links.map"; private static final String QUANTITIES_MAP_FILE = "./data/facilities/auxiliar/quantities.map"; private static final String WEIGHTS_MAP_FILE = "./data/facilities/auxiliar/weightsMap.map"; private static final String TRAVEL_TIMES_FILE = "./data/facilities/auxiliar/travelTimes.dat"; private static final String WEIGHTS2_MAP_FILE = "./data/facilities/auxiliar/weights.map"; private static final String CLUSTERS_FILE = "./data/facilities/auxiliar/clusters.map"; private static final String AREAS_MAP_FILE = "./data/facilities/auxiliar/areasMPL.map"; private static final String POLYGONS_FILE = "./data/facilities/Masterplan_Areas.shp"; private static final String CAPACITIES_FILE = "./data/facilities/auxiliar/capacities.map"; private static final String BUILDINGS_FILE = "./data/facilities/auxiliar/buildings.xml"; private static final String INPUT_FILE = "./data/facilities/parametersAu.txt"; private static final String OUTPUT_FILE = "./data/facilities/matrixAu.dat"; private static final String SOLUTION_FILE = "./data/facilities/solutionAu.txt"; private static final String WORK_FACILITIES_FILEO = "./data/facilities/workFacilitiesO.xml"; private static final String WORK_FACILITIES_FILE = "./data/facilities/workFacilities.xml"; private static final double WALKING_SPEED = 4 / 3.6; private static final double PRIVATE_BUS_SPEED = 16 / 3.6; private static final double MIN_TRAVEL_TIME = 3 * 60; private static final double MAX_TRAVEL_TIME = 15 * 60; private static final String SEPARATOR = ";;;"; private static final int NUM_NEAR = 3; //Static attributes private static int SIZE = 10; private static int NUM_ITERATIONS = 100; private static List<CentroidCluster<PointPerson>> clusters; private static SortedMap<Id<ActivityFacility>, MPAreaData> dataMPAreas = new TreeMap<Id<ActivityFacility>, MPAreaData>(); private static SortedMap<String, Coord> stopsBase = new TreeMap<String, Coord>(); private static Network network; private static List<List<Double>> travelTimes; private static SortedMap<Id<ActivityFacility>, Double> maximumAreaCapacities; private static List<List<Double>> stopScheduleCapacities; private static ActivityFacilities buildings; //private static Coord downLeft = new CoordImpl(103.83355, 1.2814); //private static Coord upRight = new CoordImpl(103.8513, 1.2985); private static Coord downLeft = new CoordImpl(-Double.MAX_VALUE, -Double.MAX_VALUE); private static Coord upRight = new CoordImpl(Double.MAX_VALUE, Double.MAX_VALUE); private static HashMap<String, Double> workerAreas = new HashMap<String, Double>(); //Main /** * @param args * @throws NoConnectionException * @throws SQLException * @throws ClassNotFoundException * @throws IllegalAccessException * @throws InstantiationException * @throws IOException * @throws BadStopException */ public static void main(String[] args) throws BadStopException, IOException, InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException, NoConnectionException { if (args.length == 2) { SIZE = Integer.parseInt(args[0]); NUM_ITERATIONS = Integer.parseInt(args[1]); } loadData(); //calculateOptimizationParameters(); boolean exception = true; while (exception) { System.out.println("Run the solver and press Enter when the file is copied in the folder"); new BufferedReader(new InputStreamReader(System.in)).readLine(); try { readMasterAreaResults(); } catch (Exception e) { continue; } exception = false; } ActivityFacilitiesImpl facilities = capacitiesToBuildings(); new FacilitiesWriter(facilities).write(WORK_FACILITIES_FILEO); } //Static Methods private static void loadData() throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException, NoConnectionException { DataBaseAdmin dataBaseAux = new DataBaseAdmin(new File("./data/facilities/DataBaseAuxiliar.properties")); ResultSet stopsResult = dataBaseAux.executeQuery("SELECT * FROM stops"); while (stopsResult.next()) stopsBase.put(stopsResult.getString(1), new CoordImpl(stopsResult.getDouble(3), stopsResult.getDouble(2))); stopsResult.close(); dataBaseAux.close(); System.out.println("Stops done!"); try { ObjectInputStream ois = new ObjectInputStream(new FileInputStream(CLUSTERS_FILE)); clusters = (List<CentroidCluster<PointPerson>>) ois.readObject(); ois.close(); } catch (EOFException e) { clusters = clusterWorkActivities(getWorkActivityTimes()); } new ClustersWindow("Work times cluster PCA back: " + getClustersDeviations(clusters) + " " + getWeightedClustersDeviations(clusters), clusters).setVisible(true); System.out.println("Clustering done!"); ScenarioImpl scenario = (ScenarioImpl) ScenarioUtils.createScenario(ConfigUtils.createConfig()); new MatsimNetworkReader(scenario).readFile(NETWORK_FILE); network = scenario.getNetwork(); setMPAreas(); setWorkerAreas(); System.out.println("Types done!"); /*new MatsimFacilitiesReader(scenario).readFile(BUILDINGS_FILE); buildings = scenario.getActivityFacilities();*/ } private static void calculateOptimizationParameters() throws BadStopException, IOException, InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException, NoConnectionException { System.out.println("Process starts with " + SIZE + " clusters and " + NUM_ITERATIONS + " iterations."); /*CoordinateTransformation coordinateTransformation = TransformationFactory.getCoordinateTransformation(TransformationFactory.WGS84, TransformationFactory.WGS84_UTM48N); downLeft=coordinateTransformation.transform(downLeft); upRight=coordinateTransformation.transform(upRight);*/ Map<Id<TransitStopFacility>, Double> stopCapacities = new HashMap<Id<TransitStopFacility>, Double>(); Map<String, Double> quantitiesMap; try { ObjectInputStream ois = new ObjectInputStream(new FileInputStream(QUANTITIES_MAP_FILE)); quantitiesMap = (Map<String, Double>) ois.readObject(); stopCapacities = (Map<Id<TransitStopFacility>, Double>) ois.readObject(); ois.close(); } catch (EOFException e) { quantitiesMap = calculateStopClustersQuantities(stopCapacities); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(QUANTITIES_MAP_FILE)); oos.writeObject(quantitiesMap); oos.writeObject(stopCapacities); oos.close(); } MatrixND<Double> quantities = new Matrix2DImpl(new int[] { clusters.size(), stopsBase.size() }); stopScheduleCapacities = new ArrayList<List<Double>>(); Iterator<String> stopIdsI = stopsBase.keySet().iterator(); //Iterator<Coord> stopsI = stopsBase.values().iterator(); for (int s = 0; s < quantities.getDimension(1); s++) { String stopId = stopIdsI.next(); /*Coord stopCoord = stopsI.next(); boolean inStop = stopCoord.getX()>downLeft.getX() && stopCoord.getX()<upRight.getX() && stopCoord.getY()>downLeft.getY() && stopCoord.getY()<upRight.getY(); if(inStop)*/ stopScheduleCapacities.add(new ArrayList<Double>()); for (int c = 0; c < quantities.getDimension(0); c++) { Double quantity = quantitiesMap.get(stopId + SEPARATOR + c); if (quantity == null) quantity = 0.0; quantities.setElement(new int[] { c, s }, quantity); //if(inStop) stopScheduleCapacities.get(stopScheduleCapacities.size() - 1).add(quantity); } } System.out.println("Quantities done!"); MatrixND<Double> maxs = new Matrix1DImpl(new int[] { dataMPAreas.size() }, 60.0); Iterator<Id<ActivityFacility>> mPAreaI = dataMPAreas.keySet().iterator(); maximumAreaCapacities = new TreeMap<Id<ActivityFacility>, Double>(); for (int f = 0; f < maxs.getDimension(0); f++) { Id<ActivityFacility> mPId = mPAreaI.next(); MPAreaData dataMPArea = dataMPAreas.get(mPId); double max = getMaxCapacity(dataMPArea) * dataMPArea.getModeShare() / (1 + dataMPArea.getModeShare()); maxs.setElement(new int[] { f }, max); Coord areaCoord = dataMPArea.getCoord(); if (areaCoord.getX() > downLeft.getX() && areaCoord.getX() < upRight.getX() && areaCoord.getY() > downLeft.getY() && areaCoord.getY() < upRight.getY()) maximumAreaCapacities.put(mPId, max); } System.out.println("Max areas done!"); Map<Tuple<Id<TransitStopFacility>, Id<ActivityFacility>>, Tuple<Boolean, Double>> weightsMap; try { ObjectInputStream ois = new ObjectInputStream(new FileInputStream(WEIGHTS_MAP_FILE)); weightsMap = (Map<Tuple<Id<TransitStopFacility>, Id<ActivityFacility>>, Tuple<Boolean, Double>>) ois .readObject(); ois.close(); try { ois = new ObjectInputStream(new FileInputStream(TRAVEL_TIMES_FILE)); travelTimes = (List<List<Double>>) ois.readObject(); ois.close(); } catch (EOFException e) { e.printStackTrace(); } } catch (EOFException e) { weightsMap = calculateAreaStopTravelTimes(stopsBase, stopCapacities, network); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(WEIGHTS_MAP_FILE)); oos.writeObject(weightsMap); oos.close(); oos = new ObjectOutputStream(new FileOutputStream(TRAVEL_TIMES_FILE)); oos.writeObject(travelTimes); oos.close(); } /*Map<Integer, Double> tts = new HashMap<Integer, Double>(); for(int i=0; i<travelTimes.size(); i++) if(travelTimes.get(i).get(8134)<36000) tts.put(i, travelTimes.get(i).get(8134));*/ new WeigthsNetworkWindow("Weights", new NetworkPainter(network), weightsMap, dataMPAreas, stopsBase) .setVisible(true); System.out.println("Travel times done!"); /*Matrix2DImpl weights = new Matrix2DImpl(new int[]{dataMPAreas.size(),stopsBase.size()}); mPAreaI = dataMPAreas.keySet().iterator(); for(int f=0; f<weights.getDimension(0); f++) { Id<ActivityFacility> mPAreaId = mPAreaI.next(); stopIdsI = stopsBase.keySet().iterator(); for(int s=0; s<weights.getDimension(1); s++) { Id<TransitStopFacility> sId = Id.create(stopIdsI.next(), TransitStopFacility.class); Tuple<Boolean, Double> weight = weightsMap.get(new Tuple<Id<TransitStopFacility>, Id<ActivityFacility>>(sId, mPAreaId)); if(weight==null) weights.setElement(f, s, 0.0); else weights.setElement(f, s, weight.getSecond()); } }*/ System.out.println("Weights done!"); Matrix2DImpl proportions = new Matrix2DImpl(new int[] { dataMPAreas.size(), clusters.size() }); Map<String, List<Double>> proportionsMap = calculateTypeBuildingOptionWeights(clusters); mPAreaI = dataMPAreas.keySet().iterator(); for (int f = 0; f < proportions.getDimension(0); f++) { Id<ActivityFacility> mPAreaId = mPAreaI.next(); for (int c = 0; c < proportions.getDimension(1); c++) proportions.setElement(f, c, proportionsMap.get(dataMPAreas.get(mPAreaId).getType()).get(c)); } System.out.println("Proportions done!"); writeOptimizationParameters(); } private static double getMaxCapacity(MPAreaData dataMPArea) { boolean withBuildings = false; GeometryFactory factory = new GeometryFactory(); if (withBuildings) { double max = 0; for (ActivityFacility building : buildings.getFacilities().values()) if (factory.createPoint(new Coordinate(building.getCoord().getX(), building.getCoord().getY())) .within(dataMPArea.getPolygon())) max += building.getActivityOptions().get("work").getCapacity(); return max; } else return (dataMPArea.getMaxArea() / workerAreas.get(dataMPArea.getType())); } private static Map<String, PointPerson> getWorkActivityTimes() throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException, NoConnectionException { DataBaseAdmin dataBaseHits = new DataBaseAdmin(new File("./data/hits/DataBase.properties")); Map<String, PersonSchedule> times; ResultSet timesResult = dataBaseHits.executeQuery( "SELECT pax_idx,trip_id,t6_purpose,t3_starttime,t4_endtime,p6_occup,t5_placetype FROM hits.hitsshort"); times = new HashMap<String, PersonSchedule>(); while (timesResult.next()) { PersonSchedule timesPerson = times.get(timesResult.getString(1)); if (timesPerson == null) { timesPerson = new PersonSchedule(timesResult.getString(1), timesResult.getString(6)); times.put(timesResult.getString(1), timesPerson); } if (timesResult.getInt(2) != 0) { Iterator<Entry<Integer, Trip>> timesPersonI = timesPerson.getTrips().entrySet().iterator(); Entry<Integer, Trip> last = null; while (timesPersonI.hasNext()) last = timesPersonI.next(); if (last == null || last.getKey() != timesResult.getInt(2)) { int startTime = (timesResult.getInt(4) % 100) * 60 + (timesResult.getInt(4) / 100) * 3600; int endTime = (timesResult.getInt(5) % 100) * 60 + (timesResult.getInt(5) / 100) * 3600; if (last != null && last.getKey() < timesResult.getInt(2) && last.getValue().getEndTime() > startTime) { startTime += 12 * 3600; endTime += 12 * 3600; } if (last != null && last.getKey() < timesResult.getInt(2) && last.getValue().getEndTime() > startTime) { startTime += 12 * 3600; endTime += 12 * 3600; } timesPerson.getTrips().put(timesResult.getInt(2), new Trip(timesResult.getString(3), startTime, endTime, timesResult.getString(7))); } } } timesResult.close(); Map<String, PointPerson> points = new HashMap<String, PointPerson>(); for (PersonSchedule timesPerson : times.values()) { SortedMap<Integer, Trip> tripsPerson = timesPerson.getTrips(); boolean startTimeSaved = false; double startTime = -1, endTime = -1; String placeType = null; if (tripsPerson.size() > 0) { for (int i = tripsPerson.keySet().iterator().next(); i <= tripsPerson.size(); i++) { if (!startTimeSaved && tripsPerson.get(i).getPurpose() != null && tripsPerson.get(i).getPurpose().equals("work")) { startTime = tripsPerson.get(i).getEndTime(); startTimeSaved = true; } if (i > tripsPerson.keySet().iterator().next() && tripsPerson.get(i - 1).getPurpose().equals("work")) { endTime = tripsPerson.get(i).getStartTime(); placeType = tripsPerson.get(i - 1).getPlaceType(); } } } if (startTime != -1 && endTime != -1 && endTime - startTime >= 7 * 3600 && endTime - startTime <= 16 * 3600) if (startTime > 24 * 3600) points.put(timesPerson.getId(), new PointPerson( timesPerson.getId(), timesPerson.getOccupation(), new Double[] { startTime - 24 * 3600, endTime - 24 * 3600 - (startTime - 24 * 3600) }, placeType)); else points.put(timesPerson.getId(), new PointPerson(timesPerson.getId(), timesPerson.getOccupation(), new Double[] { startTime, endTime - startTime }, placeType)); } Map<String, Double> weights; try { ObjectInputStream ois = new ObjectInputStream(new FileInputStream(WEIGHTS2_MAP_FILE)); weights = (Map<String, Double>) ois.readObject(); ois.close(); } catch (EOFException e) { weights = new HashMap<String, Double>(); ResultSet weightsR = dataBaseHits.executeQuery("SELECT pax_idx,hipf10 FROM hits.hitsshort_geo_hipf"); while (weightsR.next()) weights.put(weightsR.getString(1), weightsR.getDouble(2)); for (PointPerson pointPerson : points.values()) { if (weights.get(pointPerson.getId()) != null) pointPerson.setWeight(weights.get(pointPerson.getId())); else pointPerson.setWeight(100); } ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(WEIGHTS2_MAP_FILE)); oos.writeObject(weights); oos.close(); } dataBaseHits.close(); return points; } private static List<CentroidCluster<PointPerson>> clusterWorkActivities(Map<String, PointPerson> points) throws FileNotFoundException, IOException, ClassNotFoundException { List<CentroidCluster<PointPerson>> clusters = null; Set<PointPerson> pointsC = getPCATransformation(points.values()); clusters = new KMeansPlusPlusClusterer<PointPerson>(SIZE, 1000).cluster(pointsC); new ClustersWindow("Work times cluster PCA: " + getClustersDeviations(clusters) + " " + getWeightedClustersDeviations(clusters), clusters).setVisible(true); for (Cluster<PointPerson> cluster : clusters) for (PointPerson pointPersonT : cluster.getPoints()) { PointPerson pointPerson = points.get(pointPersonT.getId()); for (int d = 0; d < pointPersonT.getDimension(); d++) pointPersonT.setElement(d, pointPerson.getElement(d)); } ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(CLUSTERS_FILE)); oos.writeObject(clusters); oos.close(); return clusters; } private static double getClustersDeviations(List<CentroidCluster<PointPerson>> clusters) { double deviation = 0; for (CentroidCluster<PointPerson> cluster : clusters) for (PointPerson pointPerson : cluster.getPoints()) deviation += ((PointPerson) cluster.getCenter()).distanceFrom(pointPerson); return deviation; } private static double getWeightedClustersDeviations(List<CentroidCluster<PointPerson>> clusters) { double deviation = 0, totalWeight = 0; for (CentroidCluster<PointPerson> cluster : clusters) { for (PointPerson pointPerson : cluster.getPoints()) { deviation += ((PointPerson) cluster.getCenter()).distanceFrom(pointPerson) * pointPerson.getWeight(); totalWeight = pointPerson.getWeight(); } } return deviation / totalWeight; } private static Set<PointPerson> getPCATransformation(Collection<PointPerson> points) { RealMatrix pointsM = new Array2DRowRealMatrix(points.iterator().next().getDimension(), points.size()); int k = 0; for (PointND<Double> point : points) { for (int f = 0; f < point.getDimension(); f++) pointsM.setEntry(f, k, point.getElement(f)); k++; } RealMatrix means = new Array2DRowRealMatrix(pointsM.getRowDimension(), 1); for (int r = 0; r < means.getRowDimension(); r++) { double mean = 0; for (int c = 0; c < pointsM.getColumnDimension(); c++) mean += pointsM.getEntry(r, c) / pointsM.getColumnDimension(); means.setEntry(r, 0, mean); } RealMatrix deviations = new Array2DRowRealMatrix(pointsM.getRowDimension(), pointsM.getColumnDimension()); for (int r = 0; r < deviations.getRowDimension(); r++) for (int c = 0; c < deviations.getColumnDimension(); c++) deviations.setEntry(r, c, pointsM.getEntry(r, c) - means.getEntry(r, 0)); RealMatrix covariance = deviations.multiply(deviations.transpose()) .scalarMultiply(1 / (double) pointsM.getColumnDimension()); EigenDecomposition eigenDecomposition = new EigenDecomposition(covariance, 0); RealMatrix eigenVectorsT = eigenDecomposition.getVT(); RealVector eigenValues = new ArrayRealVector(eigenDecomposition.getD().getRowDimension()); for (int r = 0; r < eigenDecomposition.getD().getRowDimension(); r++) eigenValues.setEntry(r, eigenDecomposition.getD().getEntry(r, r)); for (int i = 0; i < eigenValues.getDimension(); i++) { for (int j = i + 1; j < eigenValues.getDimension(); j++) if (eigenValues.getEntry(i) < eigenValues.getEntry(j)) { double tempValue = eigenValues.getEntry(i); eigenValues.setEntry(i, eigenValues.getEntry(j)); eigenValues.setEntry(j, tempValue); RealVector tempVector = eigenVectorsT.getRowVector(i); eigenVectorsT.setRowVector(i, eigenVectorsT.getRowVector(j)); eigenVectorsT.setRowVector(j, tempVector); } eigenVectorsT.setRowVector(i, eigenVectorsT.getRowVector(i).mapMultiply(Math.sqrt(1 / eigenValues.getEntry(i)))); } RealVector standardDeviations = new ArrayRealVector(pointsM.getRowDimension()); for (int r = 0; r < covariance.getRowDimension(); r++) standardDeviations.setEntry(r, Math.sqrt(covariance.getEntry(r, r))); double zValue = standardDeviations.dotProduct(new ArrayRealVector(pointsM.getRowDimension(), 1)); RealMatrix zScore = deviations.scalarMultiply(1 / zValue); pointsM = eigenVectorsT.multiply(zScore); Set<PointPerson> pointsC = new HashSet<PointPerson>(); k = 0; for (PointPerson point : points) { PointPerson pointC = new PointPerson(point.getId(), point.getOccupation(), new Double[] { pointsM.getEntry(0, k), pointsM.getEntry(1, k) }, point.getPlaceType()); pointC.setWeight(point.getWeight()); pointsC.add(pointC); k++; } return pointsC; } private static Map<String, Double> calculateStopClustersQuantities( Map<Id<TransitStopFacility>, Double> stopCapacities) throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException, NoConnectionException { List<PointPerson> centers = new ArrayList<PointPerson>(); for (int c = 0; c < clusters.size(); c++) centers.add(clusters.get(c).getPoints().get(0).centroidOf(clusters.get(c).getPoints())); DataBaseAdmin dataBaseAux = new DataBaseAdmin(new File("./data/facilities/DataBaseAuxiliar.properties")); Map<String, Double> quantities = new HashMap<String, Double>(); Map<String, Integer> users = new HashMap<String, Integer>(); ResultSet tripsResult = dataBaseAux.executeQuery("SELECT * FROM DCM_work_activities"); int ts = 0; while (tripsResult.next()) { Id<TransitStopFacility> stopId = Id.create(tripsResult.getString(5), TransitStopFacility.class); Double quantity = stopCapacities.get(stopId); if (quantity == null) quantity = 0.0; stopCapacities.put(stopId, quantity + 1); Integer num = users.get(tripsResult.getString(2)); if (num == null) num = 0; users.put(tripsResult.getString(2), ++num); int nearestCluster = 0; PointPerson time = new PointPerson(tripsResult.getString(2) + "_" + num, "", new Double[] { (double) tripsResult.getInt(8), (double) (tripsResult.getInt(12) - tripsResult.getInt(8)) }, ""); for (int c = 0; c < clusters.size(); c++) if (centers.get(c).distanceFrom(time) < centers.get(nearestCluster).distanceFrom(time)) nearestCluster = c; String key = tripsResult.getString(5) + SEPARATOR + nearestCluster; quantity = quantities.get(key); if (quantity == null) quantity = 0.0; quantities.put(key, quantity + 1); ts++; } System.out.println(ts); tripsResult.close(); dataBaseAux.close(); return quantities; } private static void setMPAreas() throws FileNotFoundException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException, NoConnectionException { try { ObjectInputStream ois = new ObjectInputStream(new FileInputStream(AREAS_MAP_FILE)); dataMPAreas = (SortedMap<Id<ActivityFacility>, MPAreaData>) ois.readObject(); ois.close(); } catch (EOFException e) { DataBaseAdmin dataBaseAuxiliar = new DataBaseAdmin( new File("./data/facilities/DataBaseAuxiliar.properties")); CoordinateTransformation coordinateTransformation = TransformationFactory.getCoordinateTransformation( TransformationFactory.WGS84_SVY21, TransformationFactory.WGS84_UTM48N); ResultSet mPAreasR = dataBaseAuxiliar .executeQuery("SELECT * FROM masterplan_areas WHERE use_for_generation = 1"); while (mPAreasR.next()) { ResultSet mPAreasR2 = dataBaseAuxiliar .executeQuery("SELECT ZoneID,`Pu/Pr` FROM DCM_mplan_zones_modeshares WHERE objectID=" + mPAreasR.getInt(1)); mPAreasR2.next(); dataMPAreas.put(Id.create(mPAreasR.getString(1), ActivityFacility.class), new MPAreaData(Id.create(mPAreasR.getString(1), ActivityFacility.class), coordinateTransformation .transform(new CoordImpl(mPAreasR.getDouble(6), mPAreasR.getDouble(7))), mPAreasR.getString(2), mPAreasR.getDouble(5), Id.create(mPAreasR2.getInt(1), ActivityFacility.class), mPAreasR2.getDouble(2))); } mPAreasR.close(); dataBaseAuxiliar.close(); //Load polygons Collection<SimpleFeature> features = ShapeFileReader.getAllFeatures(POLYGONS_FILE); for (SimpleFeature feature : features) { MPAreaData area = dataMPAreas .get(Id.create((Integer) feature.getAttribute(1), ActivityFacility.class)); if (area != null) area.setPolygon((Polygon) ((MultiPolygon) feature.getDefaultGeometry()).getGeometryN(0)); } //Find nearest good links GeometryFactory factory = new GeometryFactory(); int i = 0; for (MPAreaData mPArea : dataMPAreas.values()) { if (i % 100 == 0) System.out.println(i++ + " of " + dataMPAreas.size()); Link nearestLink = null; double nearestDistance = Double.MAX_VALUE; for (Link link : network.getLinks().values()) if (link.getAllowedModes().contains("car")) { Coord fromNodeCoord = link.getFromNode().getCoord(); Coord toNodeCoord = link.getToNode().getCoord(); double distance = CoordUtils.distancePointLinesegment(fromNodeCoord, toNodeCoord, mPArea.getCoord()); if (distance < MAX_TRAVEL_TIME * WALKING_SPEED) if (distance < nearestDistance) { nearestDistance = distance; nearestLink = link; } else if (factory .createPoint(new Coordinate(fromNodeCoord.getX(), fromNodeCoord.getY())) .within(mPArea.getPolygon())) mPArea.addLinkId(link.getId()); else if (factory.createPoint(new Coordinate(toNodeCoord.getX(), toNodeCoord.getY())) .within(mPArea.getPolygon())) mPArea.addLinkId(link.getId()); } if (nearestLink == null && mPArea.getLinkIds().size() == 0) { for (Link link : network.getLinks().values()) if (link.getAllowedModes().contains("car")) { Coord fromNodeCoord = link.getFromNode().getCoord(); Coord toNodeCoord = link.getToNode().getCoord(); double distance = CoordUtils.distancePointLinesegment(fromNodeCoord, toNodeCoord, mPArea.getCoord()); if (distance < nearestDistance) { nearestDistance = distance; nearestLink = link; } } } if (nearestLink != null) mPArea.addLinkId(nearestLink.getId()); if (mPArea.getLinkIds().size() == 0) throw new RuntimeException("Error!"); } ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(AREAS_MAP_FILE)); oos.writeObject(dataMPAreas); oos.close(); } System.out.println("Areas done!"); } private static void setWorkerAreas() throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException, NoConnectionException { boolean commonSense = true; if (commonSense) { DataBaseAdmin dataBaseAux = new DataBaseAdmin( new File("./data/facilities/DataBaseAuxiliar.properties")); ResultSet typesResult = dataBaseAux.executeQuery("SELECT * FROM masterplan_areas_types"); while (typesResult.next()) workerAreas.put(typesResult.getString(1), typesResult.getDouble(2)); typesResult.close(); dataBaseAux.close(); } } private static Map<Tuple<Id<TransitStopFacility>, Id<ActivityFacility>>, Tuple<Boolean, Double>> calculateAreaStopTravelTimes( SortedMap<String, Coord> stopsBase, Map<Id<TransitStopFacility>, Double> stopsCapacities, Network network) throws BadStopException, IOException, InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException, NoConnectionException { List<Map<String, Id<Link>>> linksStops; try { ObjectInputStream ois = new ObjectInputStream(new FileInputStream(LINKS_MAP_FILE)); linksStops = (List<Map<String, Id<Link>>>) ois.readObject(); ois.close(); } catch (EOFException e) { linksStops = new ArrayList<Map<String, Id<Link>>>(); for (int n = 0; n < NUM_NEAR; n++) { linksStops.add(new HashMap<String, Id<Link>>()); for (Entry<String, Coord> stopBase : stopsBase.entrySet()) { Id<Link> nearest = network.getLinks().values().iterator().next().getId(); double nearestDistance = CoordUtils.calcDistance(network.getLinks().get(nearest).getCoord(), stopBase.getValue()); for (Link link : network.getLinks().values()) if (link.getAllowedModes().contains("car")) { boolean selected = false; for (int p = 0; p < n; p++) if (linksStops.get(p).get(stopBase.getKey()).equals(link.getId())) selected = true; if (!selected && CoordUtils.calcDistance(link.getToNode().getCoord(), stopBase.getValue()) < nearestDistance) { nearest = link.getId(); nearestDistance = CoordUtils.calcDistance( network.getLinks().get(nearest).getCoord(), stopBase.getValue()); } } linksStops.get(n).put(stopBase.getKey(), nearest); } } ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(LINKS_MAP_FILE)); oos.writeObject(linksStops); oos.close(); } //Compute stops facilities weights TravelDisutility travelMinCost = new TravelDisutility() { @Override public double getLinkTravelDisutility(final Link link, final double time, final Person person, final Vehicle vehicle) { return getLinkMinimumTravelDisutility(link); } @Override public double getLinkMinimumTravelDisutility(Link link) { return link.getLength() / WALKING_SPEED; } }; TravelTime timeFunction = new TravelTime() { @Override public double getLinkTravelTime(Link link, double time, Person person, Vehicle vehicle) { return link.getLength() / WALKING_SPEED; } }; PreProcessLandmarks preProcessData = new PreProcessLandmarks(travelMinCost); preProcessData.run(network); AStarLandmarks aStarLandmarks = new AStarLandmarks(network, preProcessData, timeFunction); Map<Tuple<Id<TransitStopFacility>, Id<ActivityFacility>>, Tuple<Boolean, Double>> weights = new HashMap<Tuple<Id<TransitStopFacility>, Id<ActivityFacility>>, Tuple<Boolean, Double>>(); Collection<Tuple<Id<TransitStopFacility>, Integer>> removeStops = new ArrayList<Tuple<Id<TransitStopFacility>, Integer>>(); travelTimes = new ArrayList<List<Double>>(); int s = 0; for (Entry<String, Coord> stop : stopsBase.entrySet()) { String stopKey = stop.getKey(); boolean mrtStop = stopKey.startsWith("STN"); /*Coord stopCoord = stop.getValue(); boolean inStop = stopCoord.getX()>downLeft.getX() && stopCoord.getX()<upRight.getX() && stopCoord.getY()>downLeft.getY() && stopCoord.getY()<upRight.getY(); if(inStop)*/ travelTimes.add(new ArrayList<Double>()); double maxTimeFromStop = 0; Collection<Id<Link>> linkIds = new ArrayList<Id<Link>>(); for (int n = 0; n < NUM_NEAR; n++) if (CoordUtils.calcDistance( network.getLinks().get(linksStops.get(n).get(stopKey)).getToNode().getCoord(), stop.getValue()) < MAX_TRAVEL_TIME * WALKING_SPEED / 5) linkIds.add(linksStops.get(n).get(stopKey)); Id<TransitStopFacility> stopId = Id.create(stopKey, TransitStopFacility.class); double maxCapacityNearFacilities = 0; int w = 0; for (MPAreaData mPArea : dataMPAreas.values()) { double distance = CoordUtils.calcDistance(stopsBase.get(stopKey), mPArea.getCoord()); /*Coord areaCoord = mPArea.getCoord(); boolean inArea = areaCoord.getX()>downLeft.getX() && areaCoord.getX()<upRight.getX() && areaCoord.getY()>downLeft.getY() && areaCoord.getY()<upRight.getY(); if(inStop && inArea) {*/ travelTimes.get(travelTimes.size() - 1).add(getCost(mrtStop, Math.floor(36000.0 + distance + 0.5))); w++; //} if (distance < MIN_TRAVEL_TIME * WALKING_SPEED) { weights.put(new Tuple<Id<TransitStopFacility>, Id<ActivityFacility>>(stopId, mPArea.getId()), new Tuple<Boolean, Double>(true, getCost(mrtStop, distance / WALKING_SPEED))); //if(inStop && inArea) { travelTimes.get(travelTimes.size() - 1).set(w - 1, getCost(mrtStop, distance / WALKING_SPEED)); mPArea.addTravelTime(stopId, distance / WALKING_SPEED); //} if (distance / WALKING_SPEED > maxTimeFromStop) maxTimeFromStop = distance / WALKING_SPEED; maxCapacityNearFacilities += maximumAreaCapacities.get(mPArea.getId()); } else if (distance < MAX_TRAVEL_TIME * WALKING_SPEED) { double walkingTime = Double.MAX_VALUE; for (Id<Link> linkId : linkIds) for (Id<Link> linkId2 : mPArea.getLinkIds()) { double walkingTimeA = aStarLandmarks.calcLeastCostPath( network.getLinks().get(linkId).getToNode(), network.getLinks().get(linkId2).getFromNode(), 0, null, null).travelCost + CoordUtils.calcDistance( network.getLinks().get(linkId2).getFromNode().getCoord(), mPArea.getCoord()) / WALKING_SPEED; if (walkingTimeA < walkingTime) walkingTime = walkingTimeA; } if (walkingTime <= MAX_TRAVEL_TIME) { weights.put( new Tuple<Id<TransitStopFacility>, Id<ActivityFacility>>(stopId, mPArea.getId()), new Tuple<Boolean, Double>(true, getCost(mrtStop, walkingTime))); //if(inStop && inArea) { travelTimes.get(travelTimes.size() - 1).set(w - 1, getCost(mrtStop, walkingTime)); mPArea.addTravelTime(stopId, walkingTime); //} if (walkingTime > maxTimeFromStop) maxTimeFromStop = walkingTime; maxCapacityNearFacilities += maximumAreaCapacities.get(mPArea.getId()); } } } if (stopsCapacities.get(stopId) > maxCapacityNearFacilities) { double maxCapacityNear2Facilities = maxCapacityNearFacilities; w = 0; for (MPAreaData mPArea : dataMPAreas.values()) { /*Coord areaCoord = mPArea.getCoord(); boolean inArea = areaCoord.getX()>downLeft.getX() && areaCoord.getX()<upRight.getX() && areaCoord.getY()>downLeft.getY() && areaCoord.getY()<upRight.getY(); if(inStop && inArea)*/ w++; if (CoordUtils.calcDistance(stopsBase.get(stopKey), mPArea.getCoord()) < (MAX_TRAVEL_TIME * 2 / 3) * PRIVATE_BUS_SPEED) { double walkingTime = Double.MAX_VALUE; for (Id<Link> linkId : linkIds) for (Id<Link> linkId2 : mPArea.getLinkIds()) { double walkingTimeA = aStarLandmarks.calcLeastCostPath( network.getLinks().get(linkId).getToNode(), network.getLinks().get(linkId2).getFromNode(), 0, null, null).travelCost + CoordUtils.calcDistance( network.getLinks().get(linkId2).getFromNode().getCoord(), mPArea.getCoord()) / WALKING_SPEED; if (walkingTimeA < walkingTime) walkingTime = walkingTimeA; } double privateBusTime = Double.MAX_VALUE; for (Id<Link> linkId : linkIds) for (Id<Link> linkId2 : mPArea.getLinkIds()) { double privateBusTimeA = aStarLandmarks.calcLeastCostPath( network.getLinks().get(linkId).getToNode(), network.getLinks().get(linkId2).getFromNode(), 0, null, null).travelCost * WALKING_SPEED / PRIVATE_BUS_SPEED + CoordUtils.calcDistance( network.getLinks().get(linkId2).getFromNode().getCoord(), mPArea.getCoord()) / WALKING_SPEED; if (privateBusTimeA < privateBusTime) privateBusTime = privateBusTimeA; } if (walkingTime > MAX_TRAVEL_TIME && privateBusTime <= (MAX_TRAVEL_TIME * 2 / 3)) { weights.put( new Tuple<Id<TransitStopFacility>, Id<ActivityFacility>>(stopId, mPArea.getId()), new Tuple<Boolean, Double>(false, getCost(mrtStop, privateBusTime))); //if(inStop && inArea) { travelTimes.get(travelTimes.size() - 1).set(w - 1, getCost(mrtStop, privateBusTime)); mPArea.addTravelTime(stopId, privateBusTime); //} if (privateBusTime > maxTimeFromStop) maxTimeFromStop = privateBusTime; maxCapacityNear2Facilities += maximumAreaCapacities.get(mPArea.getId()); } } } if (stopsCapacities.get(stopId) > maxCapacityNear2Facilities) { System.out.println("Far" + stopId); double maxCapacityNear3Facilities = maxCapacityNear2Facilities; w = 0; for (MPAreaData mPArea : dataMPAreas.values()) { /*Coord areaCoord = mPArea.getCoord(); boolean inArea = areaCoord.getX()>downLeft.getX() && areaCoord.getX()<upRight.getX() && areaCoord.getY()>downLeft.getY() && areaCoord.getY()<upRight.getY(); if(inStop && inArea)*/ w++; if (CoordUtils.calcDistance(stopsBase.get(stopKey), mPArea.getCoord()) < MAX_TRAVEL_TIME * PRIVATE_BUS_SPEED) { double privateBusTime = Double.MAX_VALUE; for (Id<Link> linkId : linkIds) for (Id<Link> linkId2 : mPArea.getLinkIds()) { double privateBusTimeA = aStarLandmarks.calcLeastCostPath( network.getLinks().get(linkId).getToNode(), network.getLinks().get(linkId2).getFromNode(), 0, null, null).travelCost * WALKING_SPEED / PRIVATE_BUS_SPEED + CoordUtils.calcDistance( network.getLinks().get(linkId2).getFromNode().getCoord(), mPArea.getCoord()) / WALKING_SPEED; if (privateBusTimeA < privateBusTime) privateBusTime = privateBusTimeA; } if (privateBusTime > (MAX_TRAVEL_TIME * 2 / 3) && privateBusTime <= MAX_TRAVEL_TIME) { weights.put( new Tuple<Id<TransitStopFacility>, Id<ActivityFacility>>(stopId, mPArea.getId()), new Tuple<Boolean, Double>(false, getCost(mrtStop, privateBusTime))); //if(inStop && inArea) { travelTimes.get(travelTimes.size() - 1).set(w - 1, getCost(mrtStop, privateBusTime)); mPArea.addTravelTime(stopId, privateBusTime); //} if (privateBusTime > maxTimeFromStop) maxTimeFromStop = privateBusTime; maxCapacityNear3Facilities += maximumAreaCapacities.get(mPArea.getId()); } } } if (stopsCapacities.get(stopId) > maxCapacityNear3Facilities) { System.out.println("Very far" + stopId); removeStops.add(new Tuple<Id<TransitStopFacility>, Integer>(stopId, s)); } } } double totalTimeFromStop = 0; maxTimeFromStop++; for (Entry<Tuple<Id<TransitStopFacility>, Id<ActivityFacility>>, Tuple<Boolean, Double>> weight : weights .entrySet()) if (weight.getKey().getFirst().equals(stopId)) { double correctWeight = maxTimeFromStop - weight.getValue().getSecond(); weights.put(weight.getKey(), new Tuple<Boolean, Double>(weight.getValue().getFirst(), correctWeight)); totalTimeFromStop += correctWeight; } if (totalTimeFromStop != 0) for (Entry<Tuple<Id<TransitStopFacility>, Id<ActivityFacility>>, Tuple<Boolean, Double>> weight : weights .entrySet()) if (weight.getKey().getFirst().equals(stopId)) weights.put(weight.getKey(), new Tuple<Boolean, Double>(weight.getValue().getFirst(), weight.getValue().getSecond() / totalTimeFromStop)); if (s++ % 100 == 0) System.out.println(s + " of " + stopsBase.size()); } int num = 0; for (Tuple<Id<TransitStopFacility>, Integer> stopId : removeStops) { num += stopsCapacities.get(stopId.getFirst()); /*stopsCapacities.remove(stopId.getFirst()); stopsBase.remove(stopId.getFirst().toString()); stopScheduleCapacities.remove(stopId.getSecond().intValue()); travelTimes.remove(stopId.getSecond().intValue());*/ } System.out.println(num + " workers lost."); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(AREAS_MAP_FILE)); oos.writeObject(dataMPAreas); oos.close(); return weights; } private static Double getCost(boolean mrtStop, double travelTime) { double tt1; if (mrtStop) tt1 = 540; else tt1 = 270; if (travelTime < tt1) return 90 * travelTime / tt1; else return travelTime - tt1 + 90; } private static Map<String, List<Double>> calculateTypeBuildingOptionWeights( List<CentroidCluster<PointPerson>> clusters) throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException, NoConnectionException { DataBaseAdmin dataBaseAux = new DataBaseAdmin(new File("./data/facilities/DataBaseAuxiliar.properties")); Map<String, List<String>> mPTypesAll = new HashMap<String, List<String>>(); Map<String, List<Double>> proportions = new HashMap<String, List<Double>>(); Map<String, Double> proportionsT = new HashMap<String, Double>(); ResultSet mPTypesResult = dataBaseAux.executeQuery("SELECT DISTINCT mp_type FROM mp_types_X_hits_types"); while (mPTypesResult.next()) { List<Double> list = new ArrayList<Double>(); for (int i = 0; i < clusters.size(); i++) list.add(0.0); proportions.put(mPTypesResult.getString(1), list); proportionsT.put(mPTypesResult.getString(1), 0.0); } for (int c = 0; c < clusters.size(); c++) for (PointPerson person : clusters.get(c).getPoints()) { String type = person.getPlaceType(); List<String> mPTypes = mPTypesAll.get(type); if (mPTypes == null) { mPTypes = getMPTypes(type, dataBaseAux); mPTypesAll.put(type, mPTypes); } for (String mPType : mPTypes) { List<Double> list = proportions.get(mPType); list.set(c, list.get(c) + 1); proportionsT.put(mPType, proportionsT.get(mPType) + 1); } } for (String key : proportions.keySet()) for (int c = 0; c < clusters.size(); c++) { Double proportion = proportions.get(key).get(c) / proportionsT.get(key); if (proportion.isNaN()) proportion = 0.0; proportions.get(key).set(c, proportion); } dataBaseAux.close(); return proportions; } private static List<String> getMPTypes(String placeType, DataBaseAdmin dataBaseAux) throws SQLException, NoConnectionException { ResultSet mPTypesResult = dataBaseAux .executeQuery("SELECT mp_type FROM mp_types_X_hits_types WHERE hits_type='" + placeType + "'"); List<String> mpTypes = new ArrayList<String>(); while (mPTypesResult.next()) mpTypes.add(mPTypesResult.getString(1)); mPTypesResult.close(); return mpTypes; } private static void writeOptimizationParameters() throws FileNotFoundException, IOException { double[][] travelTimesM = new double[travelTimes.size()][travelTimes.get(0).size()]; for (int s = 0; s < travelTimesM.length; s++) for (int w = 0; w < travelTimesM[s].length; w++) travelTimesM[s][w] = travelTimes.get(s).get(w); double[] maximumAreaCapacitiesM = new double[maximumAreaCapacities.size()]; Iterator<Double> it = maximumAreaCapacities.values().iterator(); for (int w = 0; w < maximumAreaCapacitiesM.length; w++) maximumAreaCapacitiesM[w] = it.next(); double[][] stopScheduleCapacitiesM = new double[stopScheduleCapacities.size()][stopScheduleCapacities.get(0) .size()]; for (int s = 0; s < stopScheduleCapacitiesM.length; s++) for (int c = 0; c < stopScheduleCapacitiesM[s].length; c++) stopScheduleCapacitiesM[s][c] = stopScheduleCapacities.get(s).get(c); int numStops = travelTimesM.length, numWorkAreas = travelTimesM[0].length, numWorkSchedules = stopScheduleCapacitiesM[0].length; List<Integer> workSchedules = new ArrayList<Integer>(); for (int i = 0; i < numWorkSchedules; i++) { int sum = 0; for (int j = 0; j < stopScheduleCapacitiesM.length; j++) sum += stopScheduleCapacitiesM[j][i]; if (sum > 0) workSchedules.add(i); } System.out.println("Size: " + numStops * numWorkAreas * workSchedules.size()); System.out.println("- Stops: " + numStops); System.out.println("- Work areas: " + numWorkAreas); System.out.println("- Work schedules: " + workSchedules.size()); PrintWriter writer = new PrintWriter(INPUT_FILE); writer.println("numStops = " + numStops + ";"); writer.println("numWorkAreas = " + numWorkAreas + ";"); writer.println("numWorkSchedules = " + workSchedules.size() + ";"); writer.println("travelTimes ="); writer.println("["); for (double[] tts : travelTimesM) { writer.print("[" + tts[0]); for (int i = 1; i < tts.length; i++) writer.print("," + tts[i]); writer.println("]"); } writer.println("];"); writer.println("maximumAreaCapacities ="); writer.print("[" + maximumAreaCapacitiesM[0]); for (int i = 1; i < maximumAreaCapacitiesM.length; i++) writer.print("," + maximumAreaCapacitiesM[i]); writer.println("];"); writer.println("stopScheduleCapacities ="); writer.println("["); for (double[] sss : stopScheduleCapacitiesM) { writer.print("[" + sss[workSchedules.get(0)]); for (int i = 1; i < workSchedules.size(); i++) writer.print("," + sss[workSchedules.get(i)]); writer.println("]"); } writer.println("];"); writer.close(); } private static void writeOptimizationParameters2(int numRegions) throws FileNotFoundException, IOException { List<double[][]> travelTimes = new ArrayList<double[][]>(); List<double[]> maximumAreaCapacities = new ArrayList<double[]>(); List<double[][]> stopScheduleCapacities = new ArrayList<double[][]>(); Set<StopCoord> pointsC = new HashSet<StopCoord>(); for (Entry<String, Coord> stop : stopsBase.entrySet()) pointsC.add(new StopCoord(stop.getValue().getX(), stop.getValue().getY(), Id.create(stop.getKey(), TransitStopFacility.class))); List<CentroidCluster<StopCoord>> clusters = new KMeansPlusPlusClusterer<StopCoord>(numRegions, 1000) .cluster(pointsC); for (int n = 0; n < numRegions; n++) { double[][] tts = new double[clusters.get(n).getPoints().size()][1]; for (StopCoord stop : clusters.get(n).getPoints()) { for (MPAreaData mPArea : dataMPAreas.values()) { Double tt = mPArea.getTravelTime(stop.getId()); int s = 0; int w = 0; if (tt != null) tts[s][w] = tt; } } travelTimes.add(tts); maximumAreaCapacities.add(new double[1]); stopScheduleCapacities.add(new double[clusters.get(n).getPoints().size()][SIZE]); } ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(INPUT_FILE)); oos.writeObject(travelTimes); oos.writeObject(maximumAreaCapacities); oos.writeObject(stopScheduleCapacities); oos.close(); } private static void fitCapacities(FittingCapacities fittingCapacities) throws FileNotFoundException, IOException, ClassNotFoundException { MatrixND<Double> capacities = null; try { ObjectInputStream ois = new ObjectInputStream(new FileInputStream(CAPACITIES_FILE)); capacities = (MatrixND<Double>) ois.readObject(); ois.close(); } catch (Exception e2) { Runtime.getRuntime().gc(); capacities = fittingCapacities.run(NUM_ITERATIONS); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(CAPACITIES_FILE)); oos.writeObject(capacities); oos.close(); System.out.println("Matrix written!"); } Matrix3DImpl matrix = (Matrix3DImpl) capacities; ActivityFacilityImpl fac = ((ActivityFacilitiesImpl) FacilitiesUtils.createActivityFacilities()) .createAndAddFacility(Id.create("dummy", ActivityFacility.class), new CoordImpl(0, 0)); for (int o = 0; o < matrix.getDimension(1); o++) { double[] center = new double[] { 0, 0 }; for (PointPerson pointPerson : clusters.get(o).getPoints()) for (int i = 0; i < 2; i++) center[i] += pointPerson.getElement(i); for (int i = 0; i < 2; i++) center[i] /= clusters.get(o).getPoints().size(); int minStart = ((int) Math.round(((center[0] % 3600.0) / 60) / 15)) * 15; int minDuration = ((int) Math.round(((center[1] % 3600.0) / 60) / 15)) * 15; NumberFormat numberFormat = new DecimalFormat("00"); String optionText = "w_" + numberFormat.format(Math.floor(center[0] / 3600)) + numberFormat.format(minStart) + "_" + numberFormat.format(Math.floor(center[1] / 3600)) + numberFormat.format(minDuration); OpeningTime openingTime = new OpeningTimeImpl(Math.round(center[0] / 900) * 900, Math.round((center[0] + center[1]) / 900) * 900); Iterator<MPAreaData> mPAreaI = dataMPAreas.values().iterator(); for (int f = 0; f < matrix.getDimension(0); f++) { MPAreaData mPArea = mPAreaI.next(); double pTCapacityFO = 0; for (int s = 0; s < matrix.getDimension(2); s++) pTCapacityFO += matrix.getElement(f, o, s); if (pTCapacityFO > 0) { ActivityOptionImpl activityOption = new ActivityOptionImpl(optionText); activityOption.setFacility(fac); activityOption.setCapacity(pTCapacityFO / mPArea.getModeShare()); activityOption.addOpeningTime(openingTime); mPArea.putActivityOption(activityOption); } } } } private static void readMasterAreaResults() throws IOException, ClassNotFoundException { double[][] matrixCapacities; try { ObjectInputStream ois = new ObjectInputStream(new FileInputStream(OUTPUT_FILE)); matrixCapacities = (double[][]) ois.readObject(); ois.close(); } catch (EOFException e) { BufferedReader reader = new BufferedReader(new FileReader(SOLUTION_FILE)); int numStops = new Integer(reader.readLine()); int numWorkAreas = new Integer(reader.readLine()); int numWorkSchedules = new Integer(reader.readLine()); matrixCapacities = new double[numWorkAreas][numWorkSchedules]; for (int w = 0; w < numWorkAreas; w++) for (int c = 0; c < numWorkSchedules; c++) matrixCapacities[w][c] = 0; for (int s = 0; s < numStops; s++) for (int w = 0; w < numWorkAreas; w++) { String line = reader.readLine(); String[] values = line.replaceAll("\\[", "").replaceAll("\\]", "").trim().split(" "); for (int c = 0; c < numWorkSchedules; c++) matrixCapacities[w][c] += new Double(values[c]); } reader.readLine(); reader.close(); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(OUTPUT_FILE)); oos.writeObject(matrixCapacities); oos.close(); } WorkersAreaPainter workersPainter = new WorkersAreaPainter(network); workersPainter.setData(matrixCapacities, dataMPAreas, stopsBase.values()); new SimpleNetworkWindow("Capacities", workersPainter).setVisible(true); Map<Id<ActivityFacility>, ModeShareZone> modeShareZones = new HashMap<Id<ActivityFacility>, ModeShareZone>(); Iterator<MPAreaData> mPAreaI = dataMPAreas.values().iterator(); for (int w = 0; w < matrixCapacities.length; w++) { MPAreaData mPArea = mPAreaI.next(); ModeShareZone modeShareZone = modeShareZones.get(mPArea.getZoneId()); if (modeShareZone == null) { modeShareZone = new ModeShareZone(mPArea.getModeShare()); modeShareZones.put(mPArea.getZoneId(), modeShareZone); } double capacity = 0; for (int c = 0; c < matrixCapacities[0].length; c++) { if (c == modeShareZone.capacities.size()) modeShareZone.capacities.add(0.0); modeShareZone.capacities.set(c, modeShareZone.capacities.get(c) + matrixCapacities[w][c]); capacity += matrixCapacities[w][c]; } modeShareZone.difference += getMaxCapacity(mPArea) - capacity; } System.out.println("Zones done!"); ActivityFacilityImpl fac = ((ActivityFacilitiesImpl) FacilitiesUtils.createActivityFacilities()) .createAndAddFacility(Id.create("dummy", ActivityFacility.class), new CoordImpl(0, 0)); for (int c = 0; c < matrixCapacities[0].length; c++) { double[] center = new double[] { 0, 0 }; for (PointPerson pointPerson : clusters.get(c).getPoints()) for (int i = 0; i < 2; i++) center[i] += pointPerson.getElement(i); for (int i = 0; i < 2; i++) center[i] /= clusters.get(c).getPoints().size(); int minStart = ((int) Math.round(((center[0] % 3600.0) / 60) / 15)) * 15; boolean oneHourMoreStart = false; if (minStart == 60) { oneHourMoreStart = true; minStart = 0; } int minDuration = ((int) Math.round(((center[1] % 3600.0) / 60) / 15)) * 15; boolean oneHourMoreDuration = false; if (minDuration == 60) { oneHourMoreDuration = true; minDuration = 0; } NumberFormat numberFormat = new DecimalFormat("00"); String optionText = "w_" + numberFormat.format(Math.floor(center[0] / 3600) + (oneHourMoreStart ? 1 : 0)) + numberFormat.format(minStart) + "_" + numberFormat.format(Math.floor(center[1] / 3600) + (oneHourMoreDuration ? 1 : 0)) + numberFormat.format(minDuration); OpeningTime openingTime = new OpeningTimeImpl(Math.round(center[0] / 900) * 900, Math.round((center[0] + center[1]) / 900) * 900); mPAreaI = dataMPAreas.values().iterator(); for (int w = 0; w < matrixCapacities.length; w++) { MPAreaData mPArea = mPAreaI.next(); double pTCapacityFO = matrixCapacities[w][c]; ActivityOptionImpl activityOption = new ActivityOptionImpl(optionText); activityOption.setFacility(fac); double capacity = 0; for (int sc = 0; sc < matrixCapacities[0].length; sc++) capacity += matrixCapacities[w][sc]; ModeShareZone zone = modeShareZones.get(mPArea.getZoneId()); double allCap = (getMaxCapacity(mPArea) - capacity) * zone.capacities.get(c) / zone.difference; activityOption.setCapacity(pTCapacityFO + (allCap / mPArea.getModeShare())); activityOption.addOpeningTime(openingTime); mPArea.putActivityOption(activityOption); } } } private static ActivityFacilitiesImpl capacitiesToBuildings() throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException, NoConnectionException { ActivityFacilitiesImpl facilities = (ActivityFacilitiesImpl) FacilitiesUtils.createActivityFacilities(); DataBaseAdmin dataBaseAux = new DataBaseAdmin(new File("./data/facilities/DataBaseAuxiliar.properties")); ResultSet buildingsR = dataBaseAux.executeQuery( "SELECT objectid, mpb.x as xcoord, mpb.y as ycoord, perc_surf as area_perc, fea_id AS id_building, postal_code as postal_code FROM work_facilities_aux.masterplan_areas mpa LEFT JOIN work_facilities_aux.masterplan_building_perc mpb ON mpa.objectid = mpb.object_id WHERE use_for_generation = 1"); int b = 0; Collection<Link> noCarLinks = new ArrayList<Link>(); for (Link link : network.getLinks().values()) if (!link.getAllowedModes().contains("car")) noCarLinks.add(link); for (Link link : noCarLinks) network.removeLink(link.getId()); Map<String, Double> scheduleCapacities = new HashMap<String, Double>(); while (buildingsR.next()) { Id<ActivityFacility> areaId = Id.create(buildingsR.getString(1), ActivityFacility.class); MPAreaData mPArea = dataMPAreas.get(areaId); Id<ActivityFacility> id = Id.create((int) (buildingsR.getFloat(5)), ActivityFacility.class); if (facilities.getFacilities().get(id) != null) continue; ActivityFacilityImpl building = facilities.createAndAddFacility(id, new CoordImpl(buildingsR.getDouble(2), buildingsR.getDouble(3))); building.setLinkId(((NetworkImpl) network).getNearestLinkExactly(building.getCoord()).getId()); building.setDesc(buildingsR.getString(6) + ":" + mPArea.getType().replaceAll("&", "AND")); double proportion = buildingsR.getDouble(4); for (ActivityOption activityOptionArea : mPArea.getActivityOptions().values()) { double capacity = activityOptionArea.getCapacity() * proportion; if (capacity > 0) { Double scheduleCapacity = scheduleCapacities.get(activityOptionArea.getType()); if (scheduleCapacity == null) scheduleCapacity = 0.0; scheduleCapacities.put(activityOptionArea.getType(), scheduleCapacity + capacity); ActivityOptionImpl activityOption = new ActivityOptionImpl(activityOptionArea.getType()); activityOption.setFacility(building); activityOption.setCapacity(capacity); activityOption.addOpeningTime(activityOptionArea.getOpeningTimes().first()); building.getActivityOptions().put(activityOption.getType(), activityOption); } } b++; } System.out.println(b + " buildings"); int numDesiredSchedules = 10; String[] schedules = new String[numDesiredSchedules]; for (int n = 0; n < schedules.length; n++) { double maxCap = 0; String maxSchedule = ""; for (Entry<String, Double> cap : scheduleCapacities.entrySet()) { boolean in = false; for (int c = 0; c < n; c++) if (schedules[c].equals(cap.getKey())) in = true; if (!in && cap.getValue() > maxCap) { maxCap = cap.getValue(); maxSchedule = cap.getKey(); } } schedules[n] = maxSchedule; } //capacitiesToIntegers(facilities); for (Link link : noCarLinks) network.addLink(link); WorkersBSPainter painter = new WorkersBSPainter(network); painter.setData(facilities, schedules); new BSSimpleNetworkWindow("Building capacities", painter).setVisible(true); return facilities; } private static void capacitiesToIntegers(ActivityFacilities facilities) { for (ActivityFacility building : facilities.getFacilities().values()) { String minOption = "", maxOption = ""; double minCapacity = Double.MAX_VALUE, maxCapacity = 0; double rawRest = 0; Set<String> zeroOptions = new HashSet<String>(); for (ActivityOption activityOption : building.getActivityOptions().values()) { double rawCapacity = activityOption.getCapacity(); double capacity = Math.round(rawCapacity); if (capacity == 0) zeroOptions.add(activityOption.getType()); activityOption.setCapacity(capacity); if (rawCapacity < minCapacity) { minCapacity = rawCapacity; minOption = activityOption.getType(); } if (rawCapacity > maxCapacity) { maxCapacity = rawCapacity; maxOption = activityOption.getType(); } rawRest += rawCapacity - capacity; } double rest = Math.round(rawRest); if (rest > 0) building.getActivityOptions().get(maxOption).setCapacity(Math.round(maxCapacity) + rest); else while (rest < 0) { rest = Math.round(minCapacity) + rest; if (rest > 0) building.getActivityOptions().get(minOption).setCapacity(rest); else { building.getActivityOptions().remove(minOption); if (rest < 0) { minCapacity = Double.MAX_VALUE; for (ActivityOption activityOption : building.getActivityOptions().values()) if (activityOption.getCapacity() < minCapacity) { minCapacity = activityOption.getCapacity(); minOption = activityOption.getType(); } } } } for (String zeroOption : zeroOptions) building.getActivityOptions().remove(zeroOption); } } }