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) {
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         MsgHandler::getMessageInstance()->progressMsg("Parsing time " + toString(t));
00150         // recheck whether a new cell got valid
00151         bool changed = false;
00152         while (next != myContainer.end() && (*next)->begin <= t && (*next)->end > t) {
00153             std::pair<std::string, std::string> odID = std::make_pair((*next)->origin, (*next)->destination);
00154             // check whether the current cell must be extended by the last fraction
00155             if (fractionLeft.find(odID) != fractionLeft.end()) {
00156                 (*next)->vehicleNumber += fractionLeft[odID];
00157                 fractionLeft[odID] = 0;
00158             }
00159             // get the new departures (into tmp)
00160             std::vector<ODVehicle> tmp;
00161             SUMOReal fraction = computeDeparts(*next, vehName, tmp, uniform, prefix);
00162             // copy new departures if any
00163             if (tmp.size() != 0) {
00164                 copy(tmp.begin(), tmp.end(), back_inserter(vehicles));
00165                 changed = true;
00166             }
00167             // save the fraction
00168             if (fraction != 0) {
00169                 if (fractionLeft.find(odID) == fractionLeft.end()) {
00170                     fractionLeft[odID] = fraction;
00171                 } else {
00172                     fractionLeft[odID] += fraction;
00173                 }
00174             }
00175             //
00176             ++next;
00177         }
00178         if (changed) {
00179             sort(vehicles.begin(), vehicles.end(), descending_departure_comperator());
00180         }
00181         std::vector<ODVehicle>::reverse_iterator i = vehicles.rbegin();
00182         for (; i != vehicles.rend() && (*i).depart == t; ++i) {
00183             myNoWritten++;
00184             dev.openTag("trip") << " id=\"" << (*i).id << "\" depart=\"" << t << ".00\" "
00185                                 << "from=\"" << (*i).from << "\" "
00186                                 << "to=\"" << (*i).to << "\"";
00187             if (!noVtype && (*i).cell->vehicleType.length() != 0) {
00188                 dev << " type=\"" << (*i).cell->vehicleType << "\"";
00189             }
00190             dev << " fromTaz=\"" << (*i).cell->origin << "\"";
00191             dev << " toTaz=\"" << (*i).cell->destination << "\"";
00192             if (oc.isSet("departlane") && oc.getString("departlane") != "default") {
00193                 dev << " departLane=\"" << oc.getString("departlane") << "\"";
00194             }
00195             if (oc.isSet("departpos")) {
00196                 dev << " departPos=\"" << oc.getString("departpos") << "\"";
00197             }
00198             if (oc.isSet("departspeed") && oc.getString("departspeed") != "default") {
00199                 dev << " departSpeed=\"" << oc.getString("departspeed") << "\"";
00200             }
00201             if (oc.isSet("arrivallane")) {
00202                 dev << " arrivalLane=\"" << oc.getString("arrivallane") << "\"";
00203             }
00204             if (oc.isSet("arrivalpos")) {
00205                 dev << " arrivalPos=\"" << oc.getString("arrivalpos") << "\"";
00206             }
00207             if (oc.isSet("arrivalspeed")) {
00208                 dev << " arrivalSpeed=\"" << oc.getString("arrivalspeed") << "\"";
00209             }
00210             dev.closeTag(true);
00211         }
00212         while (vehicles.size() != 0 && (*vehicles.rbegin()).depart == t) {
00213             vehicles.pop_back();
00214         }
00215     }
00216 }
00217 
00218 
00219 SUMOReal
00220 ODMatrix::getNoLoaded() const {
00221     return myNoLoaded;
00222 }
00223 
00224 
00225 SUMOReal
00226 ODMatrix::getNoWritten() const {
00227     return myNoWritten;
00228 }
00229 
00230 
00231 SUMOReal
00232 ODMatrix::getNoDiscarded() const {
00233     return myNoDiscarded;
00234 }
00235 
00236 
00237 void
00238 ODMatrix::applyCurve(const Distribution_Points& ps, ODCell* cell, CellVector& newCells) {
00239     for (size_t i = 0; i < ps.getAreaNo(); ++i) {
00240         ODCell* ncell = new ODCell();
00241         ncell->begin = (SUMOTime) ps.getAreaBegin(i);
00242         ncell->end = (SUMOTime) ps.getAreaEnd(i);
00243         ncell->origin = cell->origin;
00244         ncell->destination = cell->destination;
00245         ncell->vehicleType = cell->vehicleType;
00246         ncell->vehicleNumber = cell->vehicleNumber * ps.getAreaPerc(i);
00247         newCells.push_back(ncell);
00248     }
00249 }
00250 
00251 
00252 void
00253 ODMatrix::applyCurve(const Distribution_Points& ps) {
00254     CellVector oldCells = myContainer;
00255     myContainer.clear();
00256     for (CellVector::iterator i = oldCells.begin(); i != oldCells.end(); ++i) {
00257         CellVector newCells;
00258         applyCurve(ps, *i, newCells);
00259         copy(newCells.begin(), newCells.end(), back_inserter(myContainer));
00260         delete *i;
00261     }
00262 }
00263 
00264 
00265 
00266 /****************************************************************************/
00267 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines