|
SUMO - Simulation of Urban MObility
|
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