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 2001-2010 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 <utils/common/RandHelper.h>
00039 #include <utils/iodevices/OutputDevice.h>
00040 
00041 #ifdef CHECK_MEMORY_LEAKS
00042 #include <foreign/nvwa/debug_new.h>
00043 #endif // CHECK_MEMORY_LEAKS
00044 
00045 
00046 // ===========================================================================
00047 // method definitions
00048 // ===========================================================================
00049 ODMatrix::ODMatrix(const ODDistrictCont &dc) throw()
00050         : myDistricts(dc), myNoLoaded(0), myNoWritten(0), myNoDiscarded(0) {}
00051 
00052 
00053 ODMatrix::~ODMatrix() throw() {
00054     for (CellVector::iterator i=myContainer.begin(); i!=myContainer.end(); ++i) {
00055         delete *i;
00056     }
00057     myContainer.clear();
00058 }
00059 
00060 
00061 void
00062 ODMatrix::add(SUMOReal vehicleNumber, SUMOTime begin,
00063               SUMOTime end, const std::string &origin, const std::string &destination,
00064               const std::string &vehicleType) throw() {
00065     myNoLoaded += vehicleNumber;
00066     if (myDistricts.get(origin)==0&&myDistricts.get(destination)==0) {
00067         MsgHandler::getWarningInstance()->inform("Missing origin '" + origin + "' and destination '" + destination + "' (" + toString(vehicleNumber) + " vehicles).");
00068     } else if (myDistricts.get(origin)==0&&vehicleNumber>0) {
00069         MsgHandler::getErrorInstance()->inform("Missing origin '" + origin + "' (" + toString(vehicleNumber) + " vehicles).");
00070         myNoDiscarded += vehicleNumber;
00071     } else if (myDistricts.get(destination)==0&&vehicleNumber>0) {
00072         MsgHandler::getErrorInstance()->inform("Missing destination '" + destination + "' (" + toString(vehicleNumber) + " vehicles).");
00073         myNoDiscarded += vehicleNumber;
00074     } else {
00075         if (myDistricts.get(origin)->sourceNumber()==0) {
00076             MsgHandler::getErrorInstance()->inform("District '" + origin + "' has no source.");
00077             myNoDiscarded += vehicleNumber;
00078         } else if (myDistricts.get(destination)->sinkNumber()==0) {
00079             MsgHandler::getErrorInstance()->inform("District '" + destination + "' has no sink.");
00080             myNoDiscarded += vehicleNumber;
00081         } else {
00082             ODCell *cell = new ODCell();
00083             cell->begin = begin;
00084             cell->end = end;
00085             cell->origin = origin;
00086             cell->destination = destination;
00087             cell->vehicleType = vehicleType;
00088             cell->vehicleNumber = vehicleNumber;
00089             myContainer.push_back(cell);
00090         }
00091     }
00092 }
00093 
00094 
00095 SUMOReal
00096 ODMatrix::computeEmissions(ODCell *cell,
00097                            size_t &vehName, std::vector<ODVehicle> &into,
00098                            bool uniform, const std::string &prefix) throw() {
00099     int vehicles2emit = (int) cell->vehicleNumber;
00100     // compute whether the fraction forces an additional vehicle emission
00101     SUMOReal mrand = RandHelper::rand();
00102     SUMOReal mprob = (SUMOReal) cell->vehicleNumber - (SUMOReal) vehicles2emit;
00103     if (mrand<mprob) {
00104         vehicles2emit++;
00105     }
00106 
00107     SUMOReal offset = (SUMOReal)(cell->end - cell->begin) / (SUMOReal) vehicles2emit / (SUMOReal) 2.;
00108     for (int i=0; i<vehicles2emit; ++i) {
00109         ODVehicle veh;
00110         veh.id = prefix + toString(vehName++);
00111 
00112         if (uniform) {
00113             veh.depart = (unsigned int)(offset + cell->begin + ((SUMOReal)(cell->end - cell->begin) * (SUMOReal) i / (SUMOReal) vehicles2emit));
00114         } else {
00115             veh.depart = (unsigned int) RandHelper::rand((int) cell->begin, (int) cell->end);
00116         }
00117 
00118         veh.from = myDistricts.getRandomSourceFromDistrict(cell->origin);
00119         veh.to = myDistricts.getRandomSinkFromDistrict(cell->destination);
00120         veh.cell = cell;
00121         into.push_back(veh);
00122     }
00123     return cell->vehicleNumber - vehicles2emit;
00124 }
00125 
00126 
00127 void
00128 ODMatrix::write(SUMOTime begin, SUMOTime end,
00129                 OutputDevice &dev, bool uniform, bool noVtype,
00130                 const std::string &prefix) throw() {
00131     if (myContainer.size()==0) {
00132         return;
00133     }
00134     OptionsCont &oc = OptionsCont::getOptions();
00135     std::map<std::pair<std::string, std::string>, SUMOReal> fractionLeft;
00136     size_t vehName = 0;
00137     sort(myContainer.begin(), myContainer.end(), cell_by_begin_sorter());
00138     // recheck begin time
00139     ODCell *first = *myContainer.begin();
00140     begin = MAX2(begin, first->begin);
00141     CellVector::iterator next = myContainer.begin();
00142     std::vector<ODVehicle> vehicles;
00143     // go through the time steps
00144     for (SUMOTime t=begin; t!=end; t++) {
00145         MsgHandler::getMessageInstance()->progressMsg("Parsing time " + toString(t));
00146         // recheck whether a new cell got valid
00147         bool changed = false;
00148         while (next!=myContainer.end()&&(*next)->begin<=t&&(*next)->end>t) {
00149             std::pair<std::string, std::string> odID = std::make_pair((*next)->origin, (*next)->destination);
00150             // check whether the current cell must be extended by the last fraction
00151             if (fractionLeft.find(odID)!=fractionLeft.end()) {
00152                 (*next)->vehicleNumber += fractionLeft[odID];
00153                 fractionLeft[odID] = 0;
00154             }
00155             // get the new emissions (into tmp)
00156             std::vector<ODVehicle> tmp;
00157             SUMOReal fraction = computeEmissions(*next, vehName, tmp, uniform, prefix);
00158             // copy new emissions if any
00159             if (tmp.size()!=0) {
00160                 copy(tmp.begin(), tmp.end(), back_inserter(vehicles));
00161                 changed = true;
00162             }
00163             // save the fraction
00164             if (fraction!=0) {
00165                 if (fractionLeft.find(odID)==fractionLeft.end()) {
00166                     fractionLeft[odID] = fraction;
00167                 } else {
00168                     fractionLeft[odID] += fraction;
00169                 }
00170             }
00171             //
00172             ++next;
00173         }
00174         if (changed) {
00175             sort(vehicles.begin(), vehicles.end(), descending_departure_comperator());
00176         }
00177         std::vector<ODVehicle>::reverse_iterator i = vehicles.rbegin();
00178         for (; i!=vehicles.rend()&&(*i).depart==t; ++i) {
00179             myNoWritten++;
00180             dev.openTag("tripdef") << " id=\"" << (*i).id << "\" depart=\"" << t << ".00\" "
00181             << "from=\"" << (*i).from << "\" "
00182             << "to=\"" << (*i).to << "\"";
00183             if (!noVtype&&(*i).cell->vehicleType.length()!=0) {
00184                 dev << " type=\"" << (*i).cell->vehicleType << "\"";
00185             }
00186             if (oc.getBool("with-taz")) {
00187                 dev << " fromtaz=\"" << (*i).cell->origin << "\"";
00188                 dev << " totaz=\"" << (*i).cell->destination << "\"";
00189             }
00190             if (oc.isSet("departlane") && oc.getString("departlane")!="default") {
00191                 dev << " departlane=\"" << oc.getString("departlane") << "\"";
00192             }
00193             if (oc.isSet("departpos")) {
00194                 dev << " departpos=\"" << oc.getString("departpos") << "\"";
00195             }
00196             if (oc.isSet("departspeed") && oc.getString("departspeed")!="default") {
00197                 dev << " departspeed=\"" << oc.getString("departspeed") << "\"";
00198             }
00199             if (oc.isSet("arrivallane")) {
00200                 dev << " arrivallane=\"" << oc.getString("arrivallane") << "\"";
00201             }
00202             if (oc.isSet("arrivalpos")) {
00203                 dev << " arrivalpos=\"" << oc.getString("arrivalpos") << "\"";
00204             }
00205             if (oc.isSet("arrivalspeed")) {
00206                 dev << " arrivalspeed=\"" << oc.getString("arrivalspeed") << "\"";
00207             }
00208             dev.closeTag(true);
00209         }
00210         while (vehicles.size()!=0&&(*vehicles.rbegin()).depart==t) {
00211             vehicles.pop_back();
00212         }
00213     }
00214 }
00215 
00216 
00217 SUMOReal
00218 ODMatrix::getNoLoaded() const throw() {
00219     return myNoLoaded;
00220 }
00221 
00222 
00223 SUMOReal
00224 ODMatrix::getNoWritten() const throw() {
00225     return myNoWritten;
00226 }
00227 
00228 
00229 SUMOReal
00230 ODMatrix::getNoDiscarded() const throw() {
00231     return myNoDiscarded;
00232 }
00233 
00234 
00235 void
00236 ODMatrix::applyCurve(const Distribution_Points &ps, ODCell *cell, CellVector &newCells) throw() {
00237     for (size_t i=0; i<ps.getAreaNo(); ++i) {
00238         ODCell *ncell = new ODCell();
00239         ncell->begin = (SUMOTime) ps.getAreaBegin(i);
00240         ncell->end = (SUMOTime) ps.getAreaEnd(i);
00241         ncell->origin = cell->origin;
00242         ncell->destination = cell->destination;
00243         ncell->vehicleType = cell->vehicleType;
00244         ncell->vehicleNumber = cell->vehicleNumber * ps.getAreaPerc(i);
00245         newCells.push_back(ncell);
00246     }
00247 }
00248 
00249 
00250 void
00251 ODMatrix::applyCurve(const Distribution_Points &ps) throw() {
00252     CellVector oldCells = myContainer;
00253     myContainer.clear();
00254     for (CellVector::iterator i=oldCells.begin(); i!=oldCells.end(); ++i) {
00255         CellVector newCells;
00256         applyCurve(ps, *i, newCells);
00257         copy(newCells.begin(), newCells.end(), back_inserter(myContainer));
00258         delete *i;
00259     }
00260 }
00261 
00262 
00263 
00264 /****************************************************************************/
00265 

Generated on Wed May 5 00:06:35 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6