SUMO - Simulation of Urban MObility
ODMatrix.cpp
Go to the documentation of this file.
00001 /****************************************************************************/
00009 // An O/D (origin/destination) matrix
00010 /****************************************************************************/
00011 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00012 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00013 /****************************************************************************/
00014 //
00015 //   This file is part of SUMO.
00016 //   SUMO is free software: you can redistribute it and/or modify
00017 //   it under the terms of the GNU General Public License as published by
00018 //   the Free Software Foundation, either version 3 of the License, or
00019 //   (at your option) any later version.
00020 //
00021 /****************************************************************************/
00022 
00023 
00024 // ===========================================================================
00025 // included modules
00026 // ===========================================================================
00027 #ifdef _MSC_VER
00028 #include <windows_config.h>
00029 #else
00030 #include <config.h>
00031 #endif
00032 
00033 #include "ODMatrix.h"
00034 #include <utils/options/OptionsCont.h>
00035 #include <utils/common/StdDefs.h>
00036 #include <utils/common/MsgHandler.h>
00037 #include <utils/common/ToString.h>
00038 #include <iostream>
00039 #include <algorithm>
00040 #include <list>
00041 #include <iterator>
00042 #include <utils/common/RandHelper.h>
00043 #include <utils/iodevices/OutputDevice.h>
00044 
00045 #ifdef CHECK_MEMORY_LEAKS
00046 #include <foreign/nvwa/debug_new.h>
00047 #endif // CHECK_MEMORY_LEAKS
00048 
00049 
00050 // ===========================================================================
00051 // method definitions
00052 // ===========================================================================
00053 ODMatrix::ODMatrix(const ODDistrictCont& dc)
00054     : myDistricts(dc), myNoLoaded(0), myNoWritten(0), myNoDiscarded(0) {}
00055 
00056 
00057 ODMatrix::~ODMatrix() {
00058     for (CellVector::iterator i = myContainer.begin(); i != myContainer.end(); ++i) {
00059         delete *i;
00060     }
00061     myContainer.clear();
00062 }
00063 
00064 
00065 void
00066 ODMatrix::add(SUMOReal vehicleNumber, SUMOTime begin,
00067               SUMOTime end, const std::string& origin, const std::string& destination,
00068               const std::string& vehicleType) {
00069     myNoLoaded += vehicleNumber;
00070     if (myDistricts.get(origin) == 0 && myDistricts.get(destination) == 0) {
00071         WRITE_WARNING("Missing origin '" + origin + "' and destination '" + destination + "' (" + toString(vehicleNumber) + " vehicles).");
00072     } else if (myDistricts.get(origin) == 0 && vehicleNumber > 0) {
00073         WRITE_ERROR("Missing origin '" + origin + "' (" + toString(vehicleNumber) + " vehicles).");
00074         myNoDiscarded += vehicleNumber;
00075     } else if (myDistricts.get(destination) == 0 && vehicleNumber > 0) {
00076         WRITE_ERROR("Missing destination '" + destination + "' (" + toString(vehicleNumber) + " vehicles).");
00077         myNoDiscarded += vehicleNumber;
00078     } else {
00079         if (myDistricts.get(origin)->sourceNumber() == 0) {
00080             WRITE_ERROR("District '" + origin + "' has no source.");
00081             myNoDiscarded += vehicleNumber;
00082         } else if (myDistricts.get(destination)->sinkNumber() == 0) {
00083             WRITE_ERROR("District '" + destination + "' has no sink.");
00084             myNoDiscarded += vehicleNumber;
00085         } else {
00086             ODCell* cell = new ODCell();
00087             cell->begin = begin;
00088             cell->end = end;
00089             cell->origin = origin;
00090             cell->destination = destination;
00091             cell->vehicleType = vehicleType;
00092             cell->vehicleNumber = vehicleNumber;
00093             myContainer.push_back(cell);
00094         }
00095     }
00096 }
00097 
00098 
00099 SUMOReal
00100 ODMatrix::computeDeparts(ODCell* cell,
00101                          size_t& vehName, std::vector<ODVehicle> &into,
00102                          bool uniform, const std::string& prefix) {
00103     int vehicles2insert = (int) cell->vehicleNumber;
00104     // compute whether the fraction forces an additional vehicle insertion
00105     SUMOReal mrand = RandHelper::rand();
00106     SUMOReal mprob = (SUMOReal) cell->vehicleNumber - (SUMOReal) vehicles2insert;
00107     if (mrand < mprob) {
00108         vehicles2insert++;
00109     }
00110 
00111     SUMOReal offset = (SUMOReal)(cell->end - cell->begin) / (SUMOReal) vehicles2insert / (SUMOReal) 2.;
00112     for (int i = 0; i < vehicles2insert; ++i) {
00113         ODVehicle veh;
00114         veh.id = prefix + toString(vehName++);
00115 
00116         if (uniform) {
00117             veh.depart = (unsigned int)(offset + cell->begin + ((SUMOReal)(cell->end - cell->begin) * (SUMOReal) i / (SUMOReal) vehicles2insert));
00118         } else {
00119             veh.depart = (unsigned int) RandHelper::rand((int) cell->begin, (int) cell->end);
00120         }
00121 
00122         veh.from = myDistricts.getRandomSourceFromDistrict(cell->origin);
00123         veh.to = myDistricts.getRandomSinkFromDistrict(cell->destination);
00124         veh.cell = cell;
00125         into.push_back(veh);
00126     }
00127     return cell->vehicleNumber - vehicles2insert;
00128 }
00129 
00130 
00131 void
00132 ODMatrix::write(SUMOTime begin, SUMOTime end,
00133                 OutputDevice& dev, bool uniform, bool noVtype,
00134                 const std::string& prefix, bool stepLog) {
00135     if (myContainer.size() == 0) {
00136         return;
00137     }
00138     OptionsCont& oc = OptionsCont::getOptions();
00139     std::map<std::pair<std::string, std::string>, SUMOReal> fractionLeft;
00140     size_t vehName = 0;
00141     sort(myContainer.begin(), myContainer.end(), cell_by_begin_sorter());
00142     // recheck begin time
00143     ODCell* first = *myContainer.begin();
00144     begin = MAX2(begin, first->begin);
00145     CellVector::iterator next = myContainer.begin();
00146     std::vector<ODVehicle> vehicles;
00147     // go through the time steps
00148     for (SUMOTime t = begin; t != end; t++) {
00149         if (stepLog) {
00150             std::cout << "Parsing time " + toString(t) << '\r';
00151         }
00152         // recheck whether a new cell got valid
00153         bool changed = false;
00154         while (next != myContainer.end() && (*next)->begin <= t && (*next)->end > t) {
00155             std::pair<std::string, std::string> odID = std::make_pair((*next)->origin, (*next)->destination);
00156             // check whether the current cell must be extended by the last fraction
00157             if (fractionLeft.find(odID) != fractionLeft.end()) {
00158                 (*next)->vehicleNumber += fractionLeft[odID];
00159                 fractionLeft[odID] = 0;
00160             }
00161             // get the new departures (into tmp)
00162             std::vector<ODVehicle> tmp;
00163             SUMOReal fraction = computeDeparts(*next, vehName, tmp, uniform, prefix);
00164             // copy new departures if any
00165             if (tmp.size() != 0) {
00166                 copy(tmp.begin(), tmp.end(), back_inserter(vehicles));
00167                 changed = true;
00168             }
00169             // save the fraction
00170             if (fraction != 0) {
00171                 if (fractionLeft.find(odID) == fractionLeft.end()) {
00172                     fractionLeft[odID] = fraction;
00173                 } else {
00174                     fractionLeft[odID] += fraction;
00175                 }
00176             }
00177             //
00178             ++next;
00179         }
00180         if (changed) {
00181             sort(vehicles.begin(), vehicles.end(), descending_departure_comperator());
00182         }
00183         std::vector<ODVehicle>::reverse_iterator i = vehicles.rbegin();
00184         for (; i != vehicles.rend() && (*i).depart == t; ++i) {
00185             myNoWritten++;
00186             dev.openTag("trip") << " id=\"" << (*i).id << "\" depart=\"" << t << ".00\" "
00187                                 << "from=\"" << (*i).from << "\" "
00188                                 << "to=\"" << (*i).to << "\"";
00189             if (!noVtype && (*i).cell->vehicleType.length() != 0) {
00190                 dev << " type=\"" << (*i).cell->vehicleType << "\"";
00191             }
00192             dev << " fromTaz=\"" << (*i).cell->origin << "\"";
00193             dev << " toTaz=\"" << (*i).cell->destination << "\"";
00194             if (oc.isSet("departlane") && oc.getString("departlane") != "default") {
00195                 dev << " departLane=\"" << oc.getString("departlane") << "\"";
00196             }
00197             if (oc.isSet("departpos")) {
00198                 dev << " departPos=\"" << oc.getString("departpos") << "\"";
00199             }
00200             if (oc.isSet("departspeed") && oc.getString("departspeed") != "default") {
00201                 dev << " departSpeed=\"" << oc.getString("departspeed") << "\"";
00202             }
00203             if (oc.isSet("arrivallane")) {
00204                 dev << " arrivalLane=\"" << oc.getString("arrivallane") << "\"";
00205             }
00206             if (oc.isSet("arrivalpos")) {
00207                 dev << " arrivalPos=\"" << oc.getString("arrivalpos") << "\"";
00208             }
00209             if (oc.isSet("arrivalspeed")) {
00210                 dev << " arrivalSpeed=\"" << oc.getString("arrivalspeed") << "\"";
00211             }
00212             dev.closeTag(true);
00213         }
00214         while (vehicles.size() != 0 && (*vehicles.rbegin()).depart == t) {
00215             vehicles.pop_back();
00216         }
00217     }
00218 }
00219 
00220 
00221 SUMOReal
00222 ODMatrix::getNoLoaded() const {
00223     return myNoLoaded;
00224 }
00225 
00226 
00227 SUMOReal
00228 ODMatrix::getNoWritten() const {
00229     return myNoWritten;
00230 }
00231 
00232 
00233 SUMOReal
00234 ODMatrix::getNoDiscarded() const {
00235     return myNoDiscarded;
00236 }
00237 
00238 
00239 void
00240 ODMatrix::applyCurve(const Distribution_Points& ps, ODCell* cell, CellVector& newCells) {
00241     for (size_t i = 0; i < ps.getAreaNo(); ++i) {
00242         ODCell* ncell = new ODCell();
00243         ncell->begin = (SUMOTime) ps.getAreaBegin(i);
00244         ncell->end = (SUMOTime) ps.getAreaEnd(i);
00245         ncell->origin = cell->origin;
00246         ncell->destination = cell->destination;
00247         ncell->vehicleType = cell->vehicleType;
00248         ncell->vehicleNumber = cell->vehicleNumber * ps.getAreaPerc(i);
00249         newCells.push_back(ncell);
00250     }
00251 }
00252 
00253 
00254 void
00255 ODMatrix::applyCurve(const Distribution_Points& ps) {
00256     CellVector oldCells = myContainer;
00257     myContainer.clear();
00258     for (CellVector::iterator i = oldCells.begin(); i != oldCells.end(); ++i) {
00259         CellVector newCells;
00260         applyCurve(ps, *i, newCells);
00261         copy(newCells.begin(), newCells.end(), back_inserter(myContainer));
00262         delete *i;
00263     }
00264 }
00265 
00266 
00267 
00268 /****************************************************************************/
00269 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines