zoukankan      html  css  js  c++  java
  • python模块:random

      1 """Random variable generators.
      2 
      3     integers
      4     --------
      5            uniform within range
      6 
      7     sequences
      8     ---------
      9            pick random element
     10            pick random sample
     11            pick weighted random sample
     12            generate random permutation
     13 
     14     distributions on the real line:
     15     ------------------------------
     16            uniform
     17            triangular
     18            normal (Gaussian)
     19            lognormal
     20            negative exponential
     21            gamma
     22            beta
     23            pareto
     24            Weibull
     25 
     26     distributions on the circle (angles 0 to 2pi)
     27     ---------------------------------------------
     28            circular uniform
     29            von Mises
     30 
     31 General notes on the underlying Mersenne Twister core generator:
     32 
     33 * The period is 2**19937-1.
     34 * It is one of the most extensively tested generators in existence.
     35 * The random() method is implemented in C, executes in a single Python step,
     36   and is, therefore, threadsafe.
     37 
     38 """
     39 
     40 from warnings import warn as _warn
     41 from types import MethodType as _MethodType, BuiltinMethodType as _BuiltinMethodType
     42 from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
     43 from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin
     44 from os import urandom as _urandom
     45 from _collections_abc import Set as _Set, Sequence as _Sequence
     46 from hashlib import sha512 as _sha512
     47 import itertools as _itertools
     48 import bisect as _bisect
     49 
     50 __all__ = ["Random","seed","random","uniform","randint","choice","sample",
     51            "randrange","shuffle","normalvariate","lognormvariate",
     52            "expovariate","vonmisesvariate","gammavariate","triangular",
     53            "gauss","betavariate","paretovariate","weibullvariate",
     54            "getstate","setstate", "getrandbits", "choices",
     55            "SystemRandom"]
     56 
     57 NV_MAGICCONST = 4 * _exp(-0.5)/_sqrt(2.0)
     58 TWOPI = 2.0*_pi
     59 LOG4 = _log(4.0)
     60 SG_MAGICCONST = 1.0 + _log(4.5)
     61 BPF = 53        # Number of bits in a float
     62 RECIP_BPF = 2**-BPF
     63 
     64 
     65 # Translated by Guido van Rossum from C source provided by
     66 # Adrian Baddeley.  Adapted by Raymond Hettinger for use with
     67 # the Mersenne Twister  and os.urandom() core generators.
     68 
     69 import _random
     70 
     71 class Random(_random.Random):
     72     """Random number generator base class used by bound module functions.
     73 
     74     Used to instantiate instances of Random to get generators that don't
     75     share state.
     76 
     77     Class Random can also be subclassed if you want to use a different basic
     78     generator of your own devising: in that case, override the following
     79     methods:  random(), seed(), getstate(), and setstate().
     80     Optionally, implement a getrandbits() method so that randrange()
     81     can cover arbitrarily large ranges.
     82 
     83     """
     84 
     85     VERSION = 3     # used by getstate/setstate
     86 
     87     def __init__(self, x=None):
     88         """Initialize an instance.
     89 
     90         Optional argument x controls seeding, as for Random.seed().
     91         """
     92 
     93         self.seed(x)
     94         self.gauss_next = None
     95 
     96     def seed(self, a=None, version=2):
     97         """Initialize internal state from hashable object.
     98 
     99         None or no argument seeds from current time or from an operating
    100         system specific randomness source if available.
    101 
    102         If *a* is an int, all bits are used.
    103 
    104         For version 2 (the default), all of the bits are used if *a* is a str,
    105         bytes, or bytearray.  For version 1 (provided for reproducing random
    106         sequences from older versions of Python), the algorithm for str and
    107         bytes generates a narrower range of seeds.
    108 
    109         """
    110 
    111         if version == 1 and isinstance(a, (str, bytes)):
    112             x = ord(a[0]) << 7 if a else 0
    113             for c in a:
    114                 x = ((1000003 * x) ^ ord(c)) & 0xFFFFFFFFFFFFFFFF
    115             x ^= len(a)
    116             a = -2 if x == -1 else x
    117 
    118         if version == 2 and isinstance(a, (str, bytes, bytearray)):
    119             if isinstance(a, str):
    120                 a = a.encode()
    121             a += _sha512(a).digest()
    122             a = int.from_bytes(a, 'big')
    123 
    124         super().seed(a)
    125         self.gauss_next = None
    126 
    127     def getstate(self):
    128         """Return internal state; can be passed to setstate() later."""
    129         return self.VERSION, super().getstate(), self.gauss_next
    130 
    131     def setstate(self, state):
    132         """Restore internal state from object returned by getstate()."""
    133         version = state[0]
    134         if version == 3:
    135             version, internalstate, self.gauss_next = state
    136             super().setstate(internalstate)
    137         elif version == 2:
    138             version, internalstate, self.gauss_next = state
    139             # In version 2, the state was saved as signed ints, which causes
    140             #   inconsistencies between 32/64-bit systems. The state is
    141             #   really unsigned 32-bit ints, so we convert negative ints from
    142             #   version 2 to positive longs for version 3.
    143             try:
    144                 internalstate = tuple(x % (2**32) for x in internalstate)
    145             except ValueError as e:
    146                 raise TypeError from e
    147             super().setstate(internalstate)
    148         else:
    149             raise ValueError("state with version %s passed to "
    150                              "Random.setstate() of version %s" %
    151                              (version, self.VERSION))
    152 
    153 ## ---- Methods below this point do not need to be overridden when
    154 ## ---- subclassing for the purpose of using a different core generator.
    155 
    156 ## -------------------- pickle support  -------------------
    157 
    158     # Issue 17489: Since __reduce__ was defined to fix #759889 this is no
    159     # longer called; we leave it here because it has been here since random was
    160     # rewritten back in 2001 and why risk breaking something.
    161     def __getstate__(self): # for pickle
    162         return self.getstate()
    163 
    164     def __setstate__(self, state):  # for pickle
    165         self.setstate(state)
    166 
    167     def __reduce__(self):
    168         return self.__class__, (), self.getstate()
    169 
    170 ## -------------------- integer methods  -------------------
    171 
    172     def randrange(self, start, stop=None, step=1, _int=int):
    173         """Choose a random item from range(start, stop[, step]).
    174 
    175         This fixes the problem with randint() which includes the
    176         endpoint; in Python this is usually not what you want.
    177 
    178         """
    179 
    180         # This code is a bit messy to make it fast for the
    181         # common case while still doing adequate error checking.
    182         istart = _int(start)
    183         if istart != start:
    184             raise ValueError("non-integer arg 1 for randrange()")
    185         if stop is None:
    186             if istart > 0:
    187                 return self._randbelow(istart)
    188             raise ValueError("empty range for randrange()")
    189 
    190         # stop argument supplied.
    191         istop = _int(stop)
    192         if istop != stop:
    193             raise ValueError("non-integer stop for randrange()")
    194         width = istop - istart
    195         if step == 1 and width > 0:
    196             return istart + self._randbelow(width)
    197         if step == 1:
    198             raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))
    199 
    200         # Non-unit step argument supplied.
    201         istep = _int(step)
    202         if istep != step:
    203             raise ValueError("non-integer step for randrange()")
    204         if istep > 0:
    205             n = (width + istep - 1) // istep
    206         elif istep < 0:
    207             n = (width + istep + 1) // istep
    208         else:
    209             raise ValueError("zero step for randrange()")
    210 
    211         if n <= 0:
    212             raise ValueError("empty range for randrange()")
    213 
    214         return istart + istep*self._randbelow(n)
    215 
    216     def randint(self, a, b):
    217         """Return random integer in range [a, b], including both end points.
    218         """
    219 
    220         return self.randrange(a, b+1)
    221 
    222     def _randbelow(self, n, int=int, maxsize=1<<BPF, type=type,
    223                    Method=_MethodType, BuiltinMethod=_BuiltinMethodType):
    224         "Return a random int in the range [0,n).  Raises ValueError if n==0."
    225 
    226         random = self.random
    227         getrandbits = self.getrandbits
    228         # Only call self.getrandbits if the original random() builtin method
    229         # has not been overridden or if a new getrandbits() was supplied.
    230         if type(random) is BuiltinMethod or type(getrandbits) is Method:
    231             k = n.bit_length()  # don't use (n-1) here because n can be 1
    232             r = getrandbits(k)          # 0 <= r < 2**k
    233             while r >= n:
    234                 r = getrandbits(k)
    235             return r
    236         # There's an overridden random() method but no new getrandbits() method,
    237         # so we can only use random() from here.
    238         if n >= maxsize:
    239             _warn("Underlying random() generator does not supply 
    "
    240                 "enough bits to choose from a population range this large.
    "
    241                 "To remove the range limitation, add a getrandbits() method.")
    242             return int(random() * n)
    243         rem = maxsize % n
    244         limit = (maxsize - rem) / maxsize   # int(limit * maxsize) % n == 0
    245         r = random()
    246         while r >= limit:
    247             r = random()
    248         return int(r*maxsize) % n
    249 
    250 ## -------------------- sequence methods  -------------------
    251 
    252     def choice(self, seq):
    253         """Choose a random element from a non-empty sequence."""
    254         try:
    255             i = self._randbelow(len(seq))
    256         except ValueError:
    257             raise IndexError('Cannot choose from an empty sequence') from None
    258         return seq[i]
    259 
    260     def shuffle(self, x, random=None):
    261         """Shuffle list x in place, and return None.
    262 
    263         Optional argument random is a 0-argument function returning a
    264         random float in [0.0, 1.0); if it is the default None, the
    265         standard random.random will be used.
    266 
    267         """
    268 
    269         if random is None:
    270             randbelow = self._randbelow
    271             for i in reversed(range(1, len(x))):
    272                 # pick an element in x[:i+1] with which to exchange x[i]
    273                 j = randbelow(i+1)
    274                 x[i], x[j] = x[j], x[i]
    275         else:
    276             _int = int
    277             for i in reversed(range(1, len(x))):
    278                 # pick an element in x[:i+1] with which to exchange x[i]
    279                 j = _int(random() * (i+1))
    280                 x[i], x[j] = x[j], x[i]
    281 
    282     def sample(self, population, k):
    283         """Chooses k unique random elements from a population sequence or set.
    284 
    285         Returns a new list containing elements from the population while
    286         leaving the original population unchanged.  The resulting list is
    287         in selection order so that all sub-slices will also be valid random
    288         samples.  This allows raffle winners (the sample) to be partitioned
    289         into grand prize and second place winners (the subslices).
    290 
    291         Members of the population need not be hashable or unique.  If the
    292         population contains repeats, then each occurrence is a possible
    293         selection in the sample.
    294 
    295         To choose a sample in a range of integers, use range as an argument.
    296         This is especially fast and space efficient for sampling from a
    297         large population:   sample(range(10000000), 60)
    298         """
    299 
    300         # Sampling without replacement entails tracking either potential
    301         # selections (the pool) in a list or previous selections in a set.
    302 
    303         # When the number of selections is small compared to the
    304         # population, then tracking selections is efficient, requiring
    305         # only a small set and an occasional reselection.  For
    306         # a larger number of selections, the pool tracking method is
    307         # preferred since the list takes less space than the
    308         # set and it doesn't suffer from frequent reselections.
    309 
    310         if isinstance(population, _Set):
    311             population = tuple(population)
    312         if not isinstance(population, _Sequence):
    313             raise TypeError("Population must be a sequence or set.  For dicts, use list(d).")
    314         randbelow = self._randbelow
    315         n = len(population)
    316         if not 0 <= k <= n:
    317             raise ValueError("Sample larger than population or is negative")
    318         result = [None] * k
    319         setsize = 21        # size of a small set minus size of an empty list
    320         if k > 5:
    321             setsize += 4 ** _ceil(_log(k * 3, 4)) # table size for big sets
    322         if n <= setsize:
    323             # An n-length list is smaller than a k-length set
    324             pool = list(population)
    325             for i in range(k):         # invariant:  non-selected at [0,n-i)
    326                 j = randbelow(n-i)
    327                 result[i] = pool[j]
    328                 pool[j] = pool[n-i-1]   # move non-selected item into vacancy
    329         else:
    330             selected = set()
    331             selected_add = selected.add
    332             for i in range(k):
    333                 j = randbelow(n)
    334                 while j in selected:
    335                     j = randbelow(n)
    336                 selected_add(j)
    337                 result[i] = population[j]
    338         return result
    339 
    340     def choices(self, population, weights=None, *, cum_weights=None, k=1):
    341         """Return a k sized list of population elements chosen with replacement.
    342 
    343         If the relative weights or cumulative weights are not specified,
    344         the selections are made with equal probability.
    345 
    346         """
    347         random = self.random
    348         if cum_weights is None:
    349             if weights is None:
    350                 _int = int
    351                 total = len(population)
    352                 return [population[_int(random() * total)] for i in range(k)]
    353             cum_weights = list(_itertools.accumulate(weights))
    354         elif weights is not None:
    355             raise TypeError('Cannot specify both weights and cumulative weights')
    356         if len(cum_weights) != len(population):
    357             raise ValueError('The number of weights does not match the population')
    358         bisect = _bisect.bisect
    359         total = cum_weights[-1]
    360         return [population[bisect(cum_weights, random() * total)] for i in range(k)]
    361 
    362 ## -------------------- real-valued distributions  -------------------
    363 
    364 ## -------------------- uniform distribution -------------------
    365 
    366     def uniform(self, a, b):
    367         "Get a random number in the range [a, b) or [a, b] depending on rounding."
    368         return a + (b-a) * self.random()
    369 
    370 ## -------------------- triangular --------------------
    371 
    372     def triangular(self, low=0.0, high=1.0, mode=None):
    373         """Triangular distribution.
    374 
    375         Continuous distribution bounded by given lower and upper limits,
    376         and having a given mode value in-between.
    377 
    378         http://en.wikipedia.org/wiki/Triangular_distribution
    379 
    380         """
    381         u = self.random()
    382         try:
    383             c = 0.5 if mode is None else (mode - low) / (high - low)
    384         except ZeroDivisionError:
    385             return low
    386         if u > c:
    387             u = 1.0 - u
    388             c = 1.0 - c
    389             low, high = high, low
    390         return low + (high - low) * (u * c) ** 0.5
    391 
    392 ## -------------------- normal distribution --------------------
    393 
    394     def normalvariate(self, mu, sigma):
    395         """Normal distribution.
    396 
    397         mu is the mean, and sigma is the standard deviation.
    398 
    399         """
    400         # mu = mean, sigma = standard deviation
    401 
    402         # Uses Kinderman and Monahan method. Reference: Kinderman,
    403         # A.J. and Monahan, J.F., "Computer generation of random
    404         # variables using the ratio of uniform deviates", ACM Trans
    405         # Math Software, 3, (1977), pp257-260.
    406 
    407         random = self.random
    408         while 1:
    409             u1 = random()
    410             u2 = 1.0 - random()
    411             z = NV_MAGICCONST*(u1-0.5)/u2
    412             zz = z*z/4.0
    413             if zz <= -_log(u2):
    414                 break
    415         return mu + z*sigma
    416 
    417 ## -------------------- lognormal distribution --------------------
    418 
    419     def lognormvariate(self, mu, sigma):
    420         """Log normal distribution.
    421 
    422         If you take the natural logarithm of this distribution, you'll get a
    423         normal distribution with mean mu and standard deviation sigma.
    424         mu can have any value, and sigma must be greater than zero.
    425 
    426         """
    427         return _exp(self.normalvariate(mu, sigma))
    428 
    429 ## -------------------- exponential distribution --------------------
    430 
    431     def expovariate(self, lambd):
    432         """Exponential distribution.
    433 
    434         lambd is 1.0 divided by the desired mean.  It should be
    435         nonzero.  (The parameter would be called "lambda", but that is
    436         a reserved word in Python.)  Returned values range from 0 to
    437         positive infinity if lambd is positive, and from negative
    438         infinity to 0 if lambd is negative.
    439 
    440         """
    441         # lambd: rate lambd = 1/mean
    442         # ('lambda' is a Python reserved word)
    443 
    444         # we use 1-random() instead of random() to preclude the
    445         # possibility of taking the log of zero.
    446         return -_log(1.0 - self.random())/lambd
    447 
    448 ## -------------------- von Mises distribution --------------------
    449 
    450     def vonmisesvariate(self, mu, kappa):
    451         """Circular data distribution.
    452 
    453         mu is the mean angle, expressed in radians between 0 and 2*pi, and
    454         kappa is the concentration parameter, which must be greater than or
    455         equal to zero.  If kappa is equal to zero, this distribution reduces
    456         to a uniform random angle over the range 0 to 2*pi.
    457 
    458         """
    459         # mu:    mean angle (in radians between 0 and 2*pi)
    460         # kappa: concentration parameter kappa (>= 0)
    461         # if kappa = 0 generate uniform random angle
    462 
    463         # Based upon an algorithm published in: Fisher, N.I.,
    464         # "Statistical Analysis of Circular Data", Cambridge
    465         # University Press, 1993.
    466 
    467         # Thanks to Magnus Kessler for a correction to the
    468         # implementation of step 4.
    469 
    470         random = self.random
    471         if kappa <= 1e-6:
    472             return TWOPI * random()
    473 
    474         s = 0.5 / kappa
    475         r = s + _sqrt(1.0 + s * s)
    476 
    477         while 1:
    478             u1 = random()
    479             z = _cos(_pi * u1)
    480 
    481             d = z / (r + z)
    482             u2 = random()
    483             if u2 < 1.0 - d * d or u2 <= (1.0 - d) * _exp(d):
    484                 break
    485 
    486         q = 1.0 / r
    487         f = (q + z) / (1.0 + q * z)
    488         u3 = random()
    489         if u3 > 0.5:
    490             theta = (mu + _acos(f)) % TWOPI
    491         else:
    492             theta = (mu - _acos(f)) % TWOPI
    493 
    494         return theta
    495 
    496 ## -------------------- gamma distribution --------------------
    497 
    498     def gammavariate(self, alpha, beta):
    499         """Gamma distribution.  Not the gamma function!
    500 
    501         Conditions on the parameters are alpha > 0 and beta > 0.
    502 
    503         The probability distribution function is:
    504 
    505                     x ** (alpha - 1) * math.exp(-x / beta)
    506           pdf(x) =  --------------------------------------
    507                       math.gamma(alpha) * beta ** alpha
    508 
    509         """
    510 
    511         # alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2
    512 
    513         # Warning: a few older sources define the gamma distribution in terms
    514         # of alpha > -1.0
    515         if alpha <= 0.0 or beta <= 0.0:
    516             raise ValueError('gammavariate: alpha and beta must be > 0.0')
    517 
    518         random = self.random
    519         if alpha > 1.0:
    520 
    521             # Uses R.C.H. Cheng, "The generation of Gamma
    522             # variables with non-integral shape parameters",
    523             # Applied Statistics, (1977), 26, No. 1, p71-74
    524 
    525             ainv = _sqrt(2.0 * alpha - 1.0)
    526             bbb = alpha - LOG4
    527             ccc = alpha + ainv
    528 
    529             while 1:
    530                 u1 = random()
    531                 if not 1e-7 < u1 < .9999999:
    532                     continue
    533                 u2 = 1.0 - random()
    534                 v = _log(u1/(1.0-u1))/ainv
    535                 x = alpha*_exp(v)
    536                 z = u1*u1*u2
    537                 r = bbb+ccc*v-x
    538                 if r + SG_MAGICCONST - 4.5*z >= 0.0 or r >= _log(z):
    539                     return x * beta
    540 
    541         elif alpha == 1.0:
    542             # expovariate(1)
    543             u = random()
    544             while u <= 1e-7:
    545                 u = random()
    546             return -_log(u) * beta
    547 
    548         else:   # alpha is between 0 and 1 (exclusive)
    549 
    550             # Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle
    551 
    552             while 1:
    553                 u = random()
    554                 b = (_e + alpha)/_e
    555                 p = b*u
    556                 if p <= 1.0:
    557                     x = p ** (1.0/alpha)
    558                 else:
    559                     x = -_log((b-p)/alpha)
    560                 u1 = random()
    561                 if p > 1.0:
    562                     if u1 <= x ** (alpha - 1.0):
    563                         break
    564                 elif u1 <= _exp(-x):
    565                     break
    566             return x * beta
    567 
    568 ## -------------------- Gauss (faster alternative) --------------------
    569 
    570     def gauss(self, mu, sigma):
    571         """Gaussian distribution.
    572 
    573         mu is the mean, and sigma is the standard deviation.  This is
    574         slightly faster than the normalvariate() function.
    575 
    576         Not thread-safe without a lock around calls.
    577 
    578         """
    579 
    580         # When x and y are two variables from [0, 1), uniformly
    581         # distributed, then
    582         #
    583         #    cos(2*pi*x)*sqrt(-2*log(1-y))
    584         #    sin(2*pi*x)*sqrt(-2*log(1-y))
    585         #
    586         # are two *independent* variables with normal distribution
    587         # (mu = 0, sigma = 1).
    588         # (Lambert Meertens)
    589         # (corrected version; bug discovered by Mike Miller, fixed by LM)
    590 
    591         # Multithreading note: When two threads call this function
    592         # simultaneously, it is possible that they will receive the
    593         # same return value.  The window is very small though.  To
    594         # avoid this, you have to use a lock around all calls.  (I
    595         # didn't want to slow this down in the serial case by using a
    596         # lock here.)
    597 
    598         random = self.random
    599         z = self.gauss_next
    600         self.gauss_next = None
    601         if z is None:
    602             x2pi = random() * TWOPI
    603             g2rad = _sqrt(-2.0 * _log(1.0 - random()))
    604             z = _cos(x2pi) * g2rad
    605             self.gauss_next = _sin(x2pi) * g2rad
    606 
    607         return mu + z*sigma
    608 
    609 ## -------------------- beta --------------------
    610 ## See
    611 ## http://mail.python.org/pipermail/python-bugs-list/2001-January/003752.html
    612 ## for Ivan Frohne's insightful analysis of why the original implementation:
    613 ##
    614 ##    def betavariate(self, alpha, beta):
    615 ##        # Discrete Event Simulation in C, pp 87-88.
    616 ##
    617 ##        y = self.expovariate(alpha)
    618 ##        z = self.expovariate(1.0/beta)
    619 ##        return z/(y+z)
    620 ##
    621 ## was dead wrong, and how it probably got that way.
    622 
    623     def betavariate(self, alpha, beta):
    624         """Beta distribution.
    625 
    626         Conditions on the parameters are alpha > 0 and beta > 0.
    627         Returned values range between 0 and 1.
    628 
    629         """
    630 
    631         # This version due to Janne Sinkkonen, and matches all the std
    632         # texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution").
    633         y = self.gammavariate(alpha, 1.0)
    634         if y == 0:
    635             return 0.0
    636         else:
    637             return y / (y + self.gammavariate(beta, 1.0))
    638 
    639 ## -------------------- Pareto --------------------
    640 
    641     def paretovariate(self, alpha):
    642         """Pareto distribution.  alpha is the shape parameter."""
    643         # Jain, pg. 495
    644 
    645         u = 1.0 - self.random()
    646         return 1.0 / u ** (1.0/alpha)
    647 
    648 ## -------------------- Weibull --------------------
    649 
    650     def weibullvariate(self, alpha, beta):
    651         """Weibull distribution.
    652 
    653         alpha is the scale parameter and beta is the shape parameter.
    654 
    655         """
    656         # Jain, pg. 499; bug fix courtesy Bill Arms
    657 
    658         u = 1.0 - self.random()
    659         return alpha * (-_log(u)) ** (1.0/beta)
    660 
    661 ## --------------- Operating System Random Source  ------------------
    662 
    663 class SystemRandom(Random):
    664     """Alternate random number generator using sources provided
    665     by the operating system (such as /dev/urandom on Unix or
    666     CryptGenRandom on Windows).
    667 
    668      Not available on all systems (see os.urandom() for details).
    669     """
    670 
    671     def random(self):
    672         """Get the next random number in the range [0.0, 1.0)."""
    673         return (int.from_bytes(_urandom(7), 'big') >> 3) * RECIP_BPF
    674 
    675     def getrandbits(self, k):
    676         """getrandbits(k) -> x.  Generates an int with k random bits."""
    677         if k <= 0:
    678             raise ValueError('number of bits must be greater than zero')
    679         if k != int(k):
    680             raise TypeError('number of bits should be an integer')
    681         numbytes = (k + 7) // 8                       # bits / 8 and rounded up
    682         x = int.from_bytes(_urandom(numbytes), 'big')
    683         return x >> (numbytes * 8 - k)                # trim excess bits
    684 
    685     def seed(self, *args, **kwds):
    686         "Stub method.  Not used for a system random number generator."
    687         return None
    688 
    689     def _notimplemented(self, *args, **kwds):
    690         "Method should not be called for a system random number generator."
    691         raise NotImplementedError('System entropy source does not have state.')
    692     getstate = setstate = _notimplemented
    693 
    694 ## -------------------- test program --------------------
    695 
    696 def _test_generator(n, func, args):
    697     import time
    698     print(n, 'times', func.__name__)
    699     total = 0.0
    700     sqsum = 0.0
    701     smallest = 1e10
    702     largest = -1e10
    703     t0 = time.time()
    704     for i in range(n):
    705         x = func(*args)
    706         total += x
    707         sqsum = sqsum + x*x
    708         smallest = min(x, smallest)
    709         largest = max(x, largest)
    710     t1 = time.time()
    711     print(round(t1-t0, 3), 'sec,', end=' ')
    712     avg = total/n
    713     stddev = _sqrt(sqsum/n - avg*avg)
    714     print('avg %g, stddev %g, min %g, max %g
    ' % 
    715               (avg, stddev, smallest, largest))
    716 
    717 
    718 def _test(N=2000):
    719     _test_generator(N, random, ())
    720     _test_generator(N, normalvariate, (0.0, 1.0))
    721     _test_generator(N, lognormvariate, (0.0, 1.0))
    722     _test_generator(N, vonmisesvariate, (0.0, 1.0))
    723     _test_generator(N, gammavariate, (0.01, 1.0))
    724     _test_generator(N, gammavariate, (0.1, 1.0))
    725     _test_generator(N, gammavariate, (0.1, 2.0))
    726     _test_generator(N, gammavariate, (0.5, 1.0))
    727     _test_generator(N, gammavariate, (0.9, 1.0))
    728     _test_generator(N, gammavariate, (1.0, 1.0))
    729     _test_generator(N, gammavariate, (2.0, 1.0))
    730     _test_generator(N, gammavariate, (20.0, 1.0))
    731     _test_generator(N, gammavariate, (200.0, 1.0))
    732     _test_generator(N, gauss, (0.0, 1.0))
    733     _test_generator(N, betavariate, (3.0, 3.0))
    734     _test_generator(N, triangular, (0.0, 1.0, 1.0/3.0))
    735 
    736 # Create one instance, seeded from current time, and export its methods
    737 # as module-level functions.  The functions share state across all uses
    738 #(both in the user's code and in the Python libraries), but that's fine
    739 # for most programs and is easier for the casual user than making them
    740 # instantiate their own Random() instance.
    741 
    742 _inst = Random()
    743 seed = _inst.seed
    744 random = _inst.random
    745 uniform = _inst.uniform
    746 triangular = _inst.triangular
    747 randint = _inst.randint
    748 choice = _inst.choice
    749 randrange = _inst.randrange
    750 sample = _inst.sample
    751 shuffle = _inst.shuffle
    752 choices = _inst.choices
    753 normalvariate = _inst.normalvariate
    754 lognormvariate = _inst.lognormvariate
    755 expovariate = _inst.expovariate
    756 vonmisesvariate = _inst.vonmisesvariate
    757 gammavariate = _inst.gammavariate
    758 gauss = _inst.gauss
    759 betavariate = _inst.betavariate
    760 paretovariate = _inst.paretovariate
    761 weibullvariate = _inst.weibullvariate
    762 getstate = _inst.getstate
    763 setstate = _inst.setstate
    764 getrandbits = _inst.getrandbits
    765 
    766 if __name__ == '__main__':
    767     _test()
    python:random
    每天更新一点点,温习一点点点,进步一点点
  • 相关阅读:
    利用@media screen实现网页布局的自适应
    js判断手机的左右滑动
    文档流
    对文本段落操作的一些细节
    简易菜单的制作
    jQuery Scroll Follow
    node 监听接口
    浏览器通知
    webSocket
    前端学习路线
  • 原文地址:https://www.cnblogs.com/lmgsanm/p/8379762.html
Copyright © 2011-2022 走看看