diff env/lib/python3.9/site-packages/networkx/utils/random_sequence.py @ 0:4f3585e2f14b draft default tip

"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author shellac
date Mon, 22 Mar 2021 18:12:50 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/env/lib/python3.9/site-packages/networkx/utils/random_sequence.py	Mon Mar 22 18:12:50 2021 +0000
@@ -0,0 +1,155 @@
+"""
+Utilities for generating random numbers, random sequences, and
+random selections.
+"""
+
+import networkx as nx
+from networkx.utils import py_random_state
+
+
+# The same helpers for choosing random sequences from distributions
+# uses Python's random module
+# https://docs.python.org/3/library/random.html
+
+
+@py_random_state(2)
+def powerlaw_sequence(n, exponent=2.0, seed=None):
+    """
+    Return sample sequence of length n from a power law distribution.
+    """
+    return [seed.paretovariate(exponent - 1) for i in range(n)]
+
+
+@py_random_state(2)
+def zipf_rv(alpha, xmin=1, seed=None):
+    r"""Returns a random value chosen from the Zipf distribution.
+
+    The return value is an integer drawn from the probability distribution
+
+    .. math::
+
+        p(x)=\frac{x^{-\alpha}}{\zeta(\alpha, x_{\min})},
+
+    where $\zeta(\alpha, x_{\min})$ is the Hurwitz zeta function.
+
+    Parameters
+    ----------
+    alpha : float
+      Exponent value of the distribution
+    xmin : int
+      Minimum value
+    seed : integer, random_state, or None (default)
+        Indicator of random number generation state.
+        See :ref:`Randomness<randomness>`.
+
+    Returns
+    -------
+    x : int
+      Random value from Zipf distribution
+
+    Raises
+    ------
+    ValueError:
+      If xmin < 1 or
+      If alpha <= 1
+
+    Notes
+    -----
+    The rejection algorithm generates random values for a the power-law
+    distribution in uniformly bounded expected time dependent on
+    parameters.  See [1]_ for details on its operation.
+
+    Examples
+    --------
+    >>> nx.utils.zipf_rv(alpha=2, xmin=3, seed=42)
+    8
+
+    References
+    ----------
+    .. [1] Luc Devroye, Non-Uniform Random Variate Generation,
+       Springer-Verlag, New York, 1986.
+    """
+    if xmin < 1:
+        raise ValueError("xmin < 1")
+    if alpha <= 1:
+        raise ValueError("a <= 1.0")
+    a1 = alpha - 1.0
+    b = 2 ** a1
+    while True:
+        u = 1.0 - seed.random()  # u in (0,1]
+        v = seed.random()  # v in [0,1)
+        x = int(xmin * u ** -(1.0 / a1))
+        t = (1.0 + (1.0 / x)) ** a1
+        if v * x * (t - 1.0) / (b - 1.0) <= t / b:
+            break
+    return x
+
+
+def cumulative_distribution(distribution):
+    """Returns normalized cumulative distribution from discrete distribution."""
+
+    cdf = [0.0]
+    psum = float(sum(distribution))
+    for i in range(0, len(distribution)):
+        cdf.append(cdf[i] + distribution[i] / psum)
+    return cdf
+
+
+@py_random_state(3)
+def discrete_sequence(n, distribution=None, cdistribution=None, seed=None):
+    """
+    Return sample sequence of length n from a given discrete distribution
+    or discrete cumulative distribution.
+
+    One of the following must be specified.
+
+    distribution = histogram of values, will be normalized
+
+    cdistribution = normalized discrete cumulative distribution
+
+    """
+    import bisect
+
+    if cdistribution is not None:
+        cdf = cdistribution
+    elif distribution is not None:
+        cdf = cumulative_distribution(distribution)
+    else:
+        raise nx.NetworkXError(
+            "discrete_sequence: distribution or cdistribution missing"
+        )
+
+    # get a uniform random number
+    inputseq = [seed.random() for i in range(n)]
+
+    # choose from CDF
+    seq = [bisect.bisect_left(cdf, s) - 1 for s in inputseq]
+    return seq
+
+
+@py_random_state(2)
+def random_weighted_sample(mapping, k, seed=None):
+    """Returns k items without replacement from a weighted sample.
+
+    The input is a dictionary of items with weights as values.
+    """
+    if k > len(mapping):
+        raise ValueError("sample larger than population")
+    sample = set()
+    while len(sample) < k:
+        sample.add(weighted_choice(mapping, seed))
+    return list(sample)
+
+
+@py_random_state(1)
+def weighted_choice(mapping, seed=None):
+    """Returns a single element from a weighted sample.
+
+    The input is a dictionary of items with weights as values.
+    """
+    # use roulette method
+    rnd = seed.random() * sum(mapping.values())
+    for k, w in mapping.items():
+        rnd -= w
+        if rnd < 0:
+            return k