SUMO - Simulation of Urban MObility

ODMatrix.cpp

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