LCOV - code coverage report
Current view: top level - src/od - ODMatrix.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 11 11 100.0 %
Date: 2024-05-04 15:27:10 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /****************************************************************************/
       2             : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3             : // Copyright (C) 2006-2024 German Aerospace Center (DLR) and others.
       4             : // This program and the accompanying materials are made available under the
       5             : // terms of the Eclipse Public License 2.0 which is available at
       6             : // https://www.eclipse.org/legal/epl-2.0/
       7             : // This Source Code may also be made available under the following Secondary
       8             : // Licenses when the conditions for such availability set forth in the Eclipse
       9             : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10             : // or later which is available at
      11             : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12             : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13             : /****************************************************************************/
      14             : /// @file    ODMatrix.h
      15             : /// @author  Daniel Krajzewicz
      16             : /// @author  Michael Behrisch
      17             : /// @author  Yun-Pang Floetteroed
      18             : /// @date    05. Apr. 2006
      19             : ///
      20             : // An O/D (origin/destination) matrix
      21             : /****************************************************************************/
      22             : #pragma once
      23             : #include <config.h>
      24             : 
      25             : #include <iostream>
      26             : #include <sstream>
      27             : #include <fstream>
      28             : #include <vector>
      29             : #include <cstdlib>
      30             : #include <ctime>
      31             : #include <algorithm>
      32             : #include <set>
      33             : #include <string>
      34             : #include <utils/common/SUMOTime.h>
      35             : #include "ODCell.h"
      36             : #include "ODDistrictCont.h"
      37             : #include <utils/distribution/Distribution_Points.h>
      38             : #include <utils/importio/LineReader.h>
      39             : #include <utils/common/SUMOTime.h>
      40             : #include <utils/xml/SAXWeightsHandler.h>
      41             : 
      42             : // ===========================================================================
      43             : // class declarations
      44             : // ===========================================================================
      45             : class OptionsCont;
      46             : class OutputDevice;
      47             : class SUMOSAXHandler;
      48             : 
      49             : 
      50             : // ===========================================================================
      51             : // class definitions
      52             : // ===========================================================================
      53             : /**
      54             :  * @class ODMatrix
      55             :  * @brief An O/D (origin/destination) matrix
      56             :  *
      57             :  * This class is the internal representation of a loaded O/D-matrix. Beside
      58             :  *  being the storage for ODCells, the matrix also contains information about
      59             :  *  the numbers of loaded, discarded, and written vehicles.
      60             :  *
      61             :  * The matrix has a reference to the container of districts stored. This allows
      62             :  *  to validate added cell descriptions in means that using existing origins/
      63             :  *  destinations only is assured.
      64             :  *
      65             :  * In addition of being a storage, the matrix is also responsible for writing
      66             :  *  the results and contains methods for splitting the entries over time.
      67             :  */
      68             : class ODMatrix : public SAXWeightsHandler::EdgeFloatTimeLineRetriever {
      69             : 
      70             : public:
      71             :     /** @brief Constructor
      72             :      *
      73             :      * @param[in] dc The district container to obtain referenced districts from
      74             :      */
      75             :     ODMatrix(const ODDistrictCont& dc, double scale);
      76             : 
      77             : 
      78             :     /// Destructor
      79             :     ~ODMatrix();
      80             : 
      81             : 
      82             :     /** @brief Builds a single cell from the given values, verifying them
      83             :      *
      84             :      * At first, the number of loaded vehicles (myNoLoaded) is incremented
      85             :      *  by vehicleNumber.
      86             :      *
      87             :      * It is checked whether both the origin and the destination exist within
      88             :      *  the assigned district container (myDistricts). If one of them is missing,
      89             :      *  an error is generated, if both, a warning, because in the later case
      90             :      *  the described flow may lay completely beside the processed area. In both
      91             :      *  cases the given number of vehicles (vehicleNumber) is added to myNoDiscarded.
      92             :      *
      93             :      * If the origin/destination districts are known, a cell is built using the
      94             :      *  given values. This cell is added to the list of known cells (myContainer).
      95             :      *
      96             :      * @param[in] vehicleNumber The number of vehicles to store within the cell
      97             :      * @param[in] beginEnd The begin and the end of the interval the cell is valid for
      98             :      * @param[in] origin The origin district to use for the cell's flows
      99             :      * @param[in] destination The destination district to use for the cell's flows
     100             :      * @param[in] vehicleType The vehicle type to use for the cell's flows
     101             :      * @return whether the cell could be added
     102             :      */
     103             :     bool add(double vehicleNumber, const std::pair<SUMOTime, SUMOTime>& beginEnd,
     104             :              const std::string& origin, const std::string& destination,
     105             :              const std::string& vehicleType,
     106             :              const bool originIsEdge = false, const bool destinationIsEdge = false,
     107             :              bool noScaling = false);
     108             : 
     109             :     /** @brief Adds a single vehicle with departure time
     110             :      *
     111             :      * If there is no existing ODCell for the given parameters one is generated
     112             :      * using add(...)
     113             :      *
     114             :      * @param[in] id The id of the vehicle
     115             :      * @param[in] depart The departure time of the vehicle
     116             :      * @param[in] od The origin and destination district to use for the cell's flows
     117             :      * @param[in] vehicleType The vehicle type to use for the cell's flows
     118             :      * @return whether the vehicle could be added
     119             :      */
     120             :     bool add(const std::string& id, const SUMOTime depart,
     121             :              const std::string& fromTaz, const std::string& toTaz,
     122             :              const std::string& vehicleType,
     123             :              const bool originIsEdge = false, const bool destinationIsEdge = false);
     124             : 
     125             :     /** @brief Helper function for flow and trip output writing the depart
     126             :      *   and arrival attributes
     127             :      *
     128             :      * @param[in] dev The stream to write the generated vehicle trips to
     129             :      * @param[in] noVtype Whether vtype information shall not be written
     130             :      * @param[in] cell The OD cell containing the vtype
     131             :      */
     132             :     void writeDefaultAttrs(OutputDevice& dev, const bool noVtype,
     133             :                            const ODCell* const cell);
     134             : 
     135             :     /** @brief Writes the vehicles stored in the matrix assigning the sources and sinks
     136             :      *
     137             :      * The cells stored in myContainer are sorted, first. Then, for each time
     138             :      *  step to generate vehicles for, it is checked whether the topmost cell
     139             :      *  is valid for this time step. If so, vehicles are generated from this
     140             :      *  cell's description using "computeDeparts" and stored in an internal vector.
     141             :      *  The pointer is moved and the check is repeated until the current cell
     142             :      *  is not valid for the current time or no further cells exist.
     143             :      *
     144             :      * Then, for the current time step, the internal list of vehicles is sorted and
     145             :      *  all vehicles that start within this time step are written.
     146             :      *
     147             :      * The left fraction of vehicles to insert is saved for each O/D-dependency
     148             :      *  over time and the number of vehicles to generate is increased as soon
     149             :      *  as this value is larger than 1, decrementing it.
     150             :      *
     151             :      * @param[in] begin The begin time to generate vehicles for
     152             :      * @param[in] end The end time to generate vehicles for
     153             :      * @param[in] dev The stream to write the generated vehicle trips to
     154             :      * @param[in] uniform Information whether departure times shallbe uniformly spread or random
     155             :      * @param[in] differSourceSink whether source and sink shall be different edges
     156             :      * @param[in] noVtype Whether vtype information shall not be written
     157             :      * @param[in] prefix A prefix for the vehicle names
     158             :      * @param[in] stepLog Whether processed time shall be written
     159             :      * @param[in] pedestrians Writes trips for pedestrians
     160             :      * @param[in] persontrips Writes trips for persontrips
     161             :      */
     162             :     void write(SUMOTime begin, const SUMOTime end,
     163             :                OutputDevice& dev, const bool uniform,
     164             :                const bool differSourceSink, const bool noVtype,
     165             :                const std::string& prefix, const bool stepLog,
     166             :                bool pedestrians, bool persontrips,
     167             :                const std::string& modes);
     168             : 
     169             : 
     170             :     /** @brief Writes the flows stored in the matrix
     171             :      *
     172             :      * @param[in] begin The begin time to generate vehicles for
     173             :      * @param[in] end The end time to generate vehicles for
     174             :      * @param[in] dev The stream to write the generated vehicle trips to
     175             :      * @param[in] noVtype Whether vtype information shall not be written
     176             :      * @param[in] prefix A prefix for the flow names
     177             :      * @param[in] asProbability Write probability to spawn per second instead of number of vehicles
     178             :      * @param[in] pedestrians Writes flows for pedestrians
     179             :      * @param[in] persontrips Writes flows for persontrips
     180             :      */
     181             :     void writeFlows(const SUMOTime begin, const SUMOTime end,
     182             :                     OutputDevice& dev, const bool noVtype,
     183             :                     const std::string& prefix,
     184             :                     bool asProbability = false, bool pedestrians = false, bool persontrips = false,
     185             :                     const std::string& modes = "");
     186             : 
     187             : 
     188             :     /** @brief Returns the number of loaded vehicles
     189             :      *
     190             :      * Returns the value of myNoLoaded
     191             :      *
     192             :      * @return The number of loaded vehicles
     193             :      */
     194             :     double getNumLoaded() const;
     195             : 
     196             : 
     197             :     /** @brief Returns the number of written vehicles
     198             :      *
     199             :      * Returns the value of myNoWritten
     200             :      *
     201             :      * @return The number of written vehicles
     202             :      */
     203             :     double getNumWritten() const;
     204             : 
     205             : 
     206             :     /** @brief Returns the number of discarded vehicles
     207             :      *
     208             :      * Returns the value of myNoDiscarded
     209             :      *
     210             :      * @return The number of discarded vehicles
     211             :      */
     212             :     double getNumDiscarded() const;
     213             : 
     214             : 
     215             :     /** @brief Splits the stored cells dividing them on the given time line
     216             :      * @todo Describe
     217             :      */
     218             :     void applyCurve(const Distribution_Points& ps);
     219             : 
     220             : 
     221             :     /** @brief read a VISUM-matrix with the O Format
     222             :      *  @todo Describe
     223             :      */
     224             :     void readO(LineReader& lr, double scale,
     225             :                std::string vehType, bool matrixHasVehType);
     226             : 
     227             :     /** @brief read a VISUM-matrix with the V Format
     228             :      *  @todo Describe
     229             :      */
     230             :     void readV(LineReader& lr, double scale,
     231             :                std::string vehType, bool matrixHasVehType);
     232             : 
     233             :     /** @brief read a matrix in one of several formats
     234             :      *  @todo Describe
     235             :      */
     236             :     void loadMatrix(OptionsCont& oc);
     237             : 
     238             :     /** @brief read SUMO routes
     239             :      *  @todo Describe
     240             :      */
     241             :     void loadRoutes(OptionsCont& oc, SUMOSAXHandler& handler);
     242             : 
     243             :     /** @brief split the given timeline
     244             :      *  @todo Describe
     245             :      */
     246             :     Distribution_Points parseTimeLine(const std::vector<std::string>& def, bool timelineDayInHours);
     247             : 
     248             :     const std::vector<ODCell*>& getCells() {
     249             :         return myContainer;
     250             :     }
     251             : 
     252             :     void sortByBeginTime();
     253             : 
     254             :     SUMOTime getBegin() const {
     255         118 :         return myBegin;
     256             :     }
     257             : 
     258             :     SUMOTime getEnd() const {
     259          59 :         return myEnd;
     260             :     }
     261             : 
     262             :     void addTazRelWeight(const std::string intervalID, const std::string& from, const std::string& to,
     263             :                          double val, double beg, double end);
     264             : 
     265             : protected:
     266             :     /**
     267             :      * @struct ODVehicle
     268             :      * @brief An internal representation of a single vehicle
     269             :      */
     270             :     struct ODVehicle {
     271             :         /// @brief The id of the vehicle
     272             :         std::string id;
     273             :         /// @brief The departure time of the vehicle
     274             :         SUMOTime depart;
     275             :         /// @brief The cell of the ODMatrix which generated the vehicle
     276             :         ODCell* cell;
     277             :         /// @brief The edge the vehicles shall start at
     278             :         std::string from;
     279             :         /// @brief The edge the vehicles shall end at
     280             :         std::string to;
     281             : 
     282             :     };
     283             : 
     284             : 
     285             :     /** @brief Computes the vehicle departs stored in the given cell and saves them in "into"
     286             :      *
     287             :      * At first, the number of vehicles to insert is computed using the
     288             :      *  integer value of the vehicleNumber information from the given cell.
     289             :      *  In the case vehicleNumber has a fraction, an additional vehicle
     290             :      *  may be added in the case a chosen random number is lower than this fraction.
     291             :      *
     292             :      * If uniform is true, the departure times of the generated vehicles
     293             :      *  are spread uniformly, otherwise the departure time are chosen randomly from
     294             :      *  the interval.
     295             :      *
     296             :      * The vehicle names are generated by putting the value of vehName after the
     297             :      *  given prefix. The value of vehName is incremented with each generated vehicle.
     298             :      *
     299             :      * The number of left vehicles (the fraction if no additional vehicle was
     300             :      *  generated) is returned.
     301             :      *
     302             :      * @param[in] cell The cell to use
     303             :      * @param[in,out] vehName An incremented index of the generated vehicle
     304             :      * @param[out] into The storage to put generated vehicles into
     305             :      * @param[in] uniform Information whether departure times shallbe uniformly spread or random
     306             :      * @param[in] differSourceSink whether source and sink shall be different edges
     307             :      * @param[in] prefix A prefix for the vehicle names
     308             :      * @return The number of left vehicles to insert
     309             :      */
     310             :     double computeDeparts(ODCell* cell,
     311             :                           int& vehName, std::vector<ODVehicle>& into,
     312             :                           const bool uniform, const bool differSourceSink,
     313             :                           const std::string& prefix);
     314             : 
     315             : 
     316             :     /** @brief Splits the given cell dividing it on the given time line and
     317             :      *          storing the results in the given container
     318             :      *
     319             :      * For the given cell, a list of clones is generated. The number of these
     320             :      *  is equal to the number of "areas" within the given distribution
     321             :      *  description (time line in this case) and each clone's vehicleNumber
     322             :      *  is equal to the given cell's vehicle number multiplied with the area's
     323             :      *  probability. The clones are stored in the given cell vector.
     324             :      *
     325             :      * @see Distribution_Points
     326             :      * @param[in] ps The time line to apply
     327             :      * @param[in] cell The cell to split
     328             :      * @param[out] newCells The storage to put generated cells into
     329             :      * @todo describe better!!!
     330             :      */
     331             :     void applyCurve(const Distribution_Points& ps, ODCell* cell,
     332             :                     std::vector<ODCell*>& newCells);
     333             : 
     334             : 
     335             : private:
     336             :     /** @used in the functions readV and readO
     337             :      * @todo Describe
     338             :      */
     339             :     std::string getNextNonCommentLine(LineReader& lr);
     340             : 
     341             :     /** @used in the functions readV and readO
     342             :      * @todo Describe
     343             :      */
     344             :     SUMOTime parseSingleTime(const std::string& time);
     345             : 
     346             :     /** @used in the functions readV and readO
     347             :      * @todo Describe
     348             :      */
     349             :     std::pair<SUMOTime, SUMOTime> readTime(LineReader& lr);
     350             : 
     351             :     /** @used in the functions readV and readO
     352             :      * @todo Describe
     353             :      */
     354             :     double readFactor(LineReader& lr, double scale);
     355             : 
     356             : 
     357             : private:
     358             :     /// @brief The loaded cells
     359             :     std::vector<ODCell*> myContainer;
     360             : 
     361             :     /// @brief The loaded cells indexed by origin and destination
     362             :     std::map<const std::pair<const std::string, const std::string>, std::vector<ODCell*> > myShortCut;
     363             : 
     364             :     /// @brief The districts to retrieve sources/sinks from
     365             :     const ODDistrictCont& myDistricts;
     366             : 
     367             :     /// @brief The missing districts already warned about
     368             :     std::set<std::string> myMissingDistricts;
     369             : 
     370             :     /// @brief Number of loaded vehicles
     371             :     double myNumLoaded;
     372             : 
     373             :     /// @brief Number of written vehicles
     374             :     double myNumWritten;
     375             : 
     376             :     /// @brief Number of discarded vehicles
     377             :     double myNumDiscarded;
     378             : 
     379             :     /// @brief parsed time bounds
     380             :     SUMOTime myBegin, myEnd;
     381             : 
     382             :     /// @brief user-defined vType
     383             :     std::string myVType;
     384             : 
     385             :     /// @brief the scaling factor for traffic
     386             :     double myScale;
     387             : 
     388             :     /**
     389             :      * @class cell_by_begin_comparator
     390             :      * @brief Used for sorting the cells by the begin time they describe
     391             :      */
     392             :     class cell_by_begin_comparator {
     393             :     public:
     394             :         /// @brief constructor
     395             :         explicit cell_by_begin_comparator() { }
     396             : 
     397             : 
     398             :         /** @brief Comparing operator
     399             :          *
     400             :          * Compares two cells by the begin of the time they describe. The sort is stabilized
     401             :          * (with secondary sort keys being origin and destination) to get comparable results
     402             :          * with different platforms / compilers.
     403             :          *
     404             :          * @param[in] p1 First cell to compare
     405             :          * @param[in] p2 Second cell to compare
     406             :          * @return Whether the begin time of the first cell is lower than the one of the second
     407             :          */
     408      124840 :         int operator()(ODCell* p1, ODCell* p2) const {
     409      124840 :             if (p1->begin == p2->begin) {
     410       66420 :                 if (p1->origin == p2->origin) {
     411       25144 :                     return p1->destination < p2->destination;
     412             :                 }
     413       41276 :                 return p1->origin < p2->origin;
     414             :             }
     415       58420 :             return p1->begin < p2->begin;
     416             :         }
     417             : 
     418             :     };
     419             : 
     420             : 
     421             :     /**
     422             :      * @class descending_departure_comperator
     423             :      * @brief Used for sorting vehicles by their departure (latest first)
     424             :      *
     425             :      * A reverse operator to what may be expected is used in order to allow
     426             :      *  prunning the sorted vector from its tail.
     427             :      */
     428             :     class descending_departure_comperator {
     429             :     public:
     430             :         /// @brief constructor
     431             :         descending_departure_comperator() { }
     432             : 
     433             : 
     434             :         /** @brief Comparing operator
     435             :          *
     436             :          * Compares two vehicles by their departure time
     437             :          *
     438             :          * @param[in] p1 First vehicle to compare
     439             :          * @param[in] p2 Second vehicle to compare
     440             :          * @return Whether the departure time of the first vehicle is larger than the one of the second
     441             :          */
     442             :         bool operator()(const ODVehicle& p1, const ODVehicle& p2) const {
     443      170767 :             if (p1.depart == p2.depart) {
     444           7 :                 return p1.id > p2.id;
     445             :             }
     446      170760 :             return p1.depart > p2.depart;
     447             :         }
     448             : 
     449             :     };
     450             : 
     451             : private:
     452             :     /** @brief invalid copy constructor */
     453             :     ODMatrix(const ODMatrix& s);
     454             : 
     455             :     /** @brief invalid assignment operator */
     456             :     ODMatrix& operator=(const ODMatrix& s) = delete;
     457             : 
     458             : };

Generated by: LCOV version 1.14