LCOV - code coverage report
Current view: top level - src/utils/distribution - RandomDistributor.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 30 32 93.8 %
Date: 2024-05-05 15:31:14 Functions: 26 27 96.3 %

          Line data    Source code
       1             : /****************************************************************************/
       2             : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3             : // Copyright (C) 2005-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    RandomDistributor.h
      15             : /// @author  Daniel Krajzewicz
      16             : /// @author  Michael Behrisch
      17             : /// @author  Jakob Erdmann
      18             : /// @date    2005-09-15
      19             : ///
      20             : // Represents a generic random distribution
      21             : /****************************************************************************/
      22             : #pragma once
      23             : #include <config.h>
      24             : 
      25             : #include <cassert>
      26             : #include <limits>
      27             : #include <utils/common/RandHelper.h>
      28             : #include <utils/common/UtilExceptions.h>
      29             : 
      30             : 
      31             : // ===========================================================================
      32             : // class definitions
      33             : // ===========================================================================
      34             : /**
      35             :  * @class RandomDistributor
      36             :  * @brief Represents a generic random distribution
      37             :  *
      38             :  * This class allows to create random distributions by assigning
      39             :  *  arbitrary (non-negative) probabilities to its elements. The
      40             :  *  random number generator used is specified in RandHelper.
      41             :  *
      42             :  * @see RandHelper
      43             :  */
      44             : 
      45             : template<class T>
      46          74 : class RandomDistributor {
      47             : public:
      48             :     /** @brief Constructor for an empty distribution
      49             :      */
      50      118815 :     RandomDistributor() :
      51      766470 :         myProb(0) {
      52             :     }
      53             : 
      54             :     /// @brief Destructor
      55      803421 :     ~RandomDistributor() { }
      56             : 
      57             :     /** @brief Adds a value with an assigned probability to the distribution.
      58             :      *
      59             :      * If the value is already member of the distribution and checkDuplicates is
      60             :      * true (the default) the given probability is added to the current.
      61             :      * The probability has to be non-negative but values larger than one are
      62             :      * allowed (and scaled accordingly when an element is drawn).
      63             :      *
      64             :      * @param[in] val The value to add to the distribution
      65             :      * @param[in] prob The probability assigned to the value
      66             :      * @return true if a new value was added, false if just the probability of an existing one was updated
      67             :      */
      68     2175293 :     bool add(T val, double prob, bool checkDuplicates = true) {
      69     2175293 :         myProb += prob;
      70             :         assert(myProb >= 0);
      71     2175293 :         if (checkDuplicates) {
      72     4780301 :             for (int i = 0; i < (int)myVals.size(); i++) {
      73     2623633 :                 if (val == myVals[i]) {
      74       16765 :                     myProbs[i] += prob;
      75             :                     assert(myProbs[i] >= 0);
      76       16765 :                     return false;
      77             :                 }
      78             :             }
      79             :         } else {
      80             :             assert(prob >= 0);
      81             :         }
      82     2158528 :         myVals.push_back(val);
      83     2158528 :         myProbs.push_back(prob);
      84     2158528 :         return true;
      85             :     }
      86             : 
      87             :     /** @brief Removes a value with an assigned probability from the distribution.
      88             :      *
      89             :      * @param[in] val The value to remove from the distribution
      90             :      * @return true if a new value was added, false if just the probability of an existing one was updated
      91             :      */
      92         192 :     bool remove(T val) {
      93         536 :         for (int i = 0; i < (int)myVals.size(); i++) {
      94         454 :             if (myVals[i] == val) {
      95         110 :                 myProb -= myProbs[i];
      96         110 :                 myProbs.erase(myProbs.begin() + i);
      97         110 :                 myVals.erase(myVals.begin() + i);
      98         110 :                 return true;
      99             :             }
     100             :         }
     101             :         return false;
     102             :     }
     103             : 
     104             :     /** @brief Draw a sample of the distribution.
     105             :      *
     106             :      * A random sample is drawn according to the assigned probabilities.
     107             :      *
     108             :      * @param[in] which The random number generator to use; the static one will be used if 0 is passed
     109             :      * @return the drawn member
     110             :      */
     111     1322567 :     T get(SumoRNG* which = nullptr) const {
     112     1322567 :         if (myProb == 0) {
     113           0 :             throw OutOfBoundsException();
     114             :         }
     115             :         double prob = RandHelper::rand(myProb, which);
     116     2067642 :         for (int i = 0; i < (int)myVals.size(); i++) {
     117     2067642 :             if (prob < myProbs[i]) {
     118      780363 :                 return myVals[i];
     119             :             }
     120      745075 :             prob -= myProbs[i];
     121             :         }
     122           0 :         return myVals.back();
     123             :     }
     124             : 
     125             :     /** @brief Return the sum of the probabilites assigned to the members.
     126             :      *
     127             :      * This should be zero if and only if the distribution is empty.
     128             :      *
     129             :      * @return the total probability
     130             :      */
     131             :     double getOverallProb() const {
     132     2559964 :         return myProb;
     133             :     }
     134             : 
     135             :     /// @brief Clears the distribution
     136             :     void clear() {
     137             :         myProb = 0;
     138             :         myVals.clear();
     139             :         myProbs.clear();
     140             :     }
     141             : 
     142             :     /** @brief Returns the members of the distribution.
     143             :      *
     144             :      * See getProbs for the corresponding probabilities.
     145             :      *
     146             :      * @return the members of the distribution
     147             :      * @see RandomDistributor::getProbs
     148             :      */
     149             :     const std::vector<T>& getVals() const {
     150       23418 :         return myVals;
     151             :     }
     152             : 
     153             :     /** @brief Returns the probabilities assigned to the members of the distribution.
     154             :      *
     155             :      * See getVals for the corresponding members.
     156             :      *
     157             :      * @return the probabilities assigned to the distribution
     158             :      * @see RandomDistributor::getVals
     159             :      */
     160             :     const std::vector<double>& getProbs() const {
     161         198 :         return myProbs;
     162             :     }
     163             : 
     164             : private:
     165             :     /// @brief the total probability
     166             :     double myProb;
     167             :     /// @brief the members
     168             :     std::vector<T> myVals;
     169             :     /// @brief the corresponding probabilities
     170             :     std::vector<double> myProbs;
     171             : 
     172             : };

Generated by: LCOV version 1.14