LCOV - code coverage report
Current view: top level - src/utils/distribution - RandomDistributor.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 93.8 % 32 30
Test Date: 2024-11-21 15:56:26 Functions: 94.4 % 18 17

            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           70 : class RandomDistributor {
      47              : public:
      48              :     /** @brief Constructor for an empty distribution
      49              :      */
      50       117077 :     RandomDistributor() :
      51       447548 :         myProb(0) {
      52              :     }
      53              : 
      54              :     /// @brief Destructor
      55       440937 :     ~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      1324493 :     bool add(T val, double prob, bool checkDuplicates = true) {
      69      1324493 :         myProb += prob;
      70              :         assert(myProb >= 0);
      71      1324493 :         if (checkDuplicates) {
      72      3181646 :             for (int i = 0; i < (int)myVals.size(); i++) {
      73      1863656 :                 if (val == myVals[i]) {
      74         4641 :                     myProbs[i] += prob;
      75              :                     assert(myProbs[i] >= 0);
      76         4641 :                     return false;
      77              :                 }
      78              :             }
      79              :         } else {
      80              :             assert(prob >= 0);
      81              :         }
      82      1319852 :         myVals.push_back(val);
      83      1319852 :         myProbs.push_back(prob);
      84      1319852 :         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       991153 :     T get(SumoRNG* which = nullptr) const {
     112       991153 :         if (myProb == 0) {
     113            0 :             throw OutOfBoundsException();
     114              :         }
     115              :         double prob = RandHelper::rand(myProb, which);
     116      1452726 :         for (int i = 0; i < (int)myVals.size(); i++) {
     117      1452726 :             if (prob < myProbs[i]) {
     118       458738 :                 return myVals[i];
     119              :             }
     120       461573 :             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      1884642 :         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        59150 :         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        58720 :         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 2.0-1