example:
import random
random.seed(10)
n1=random.randint(1,5)
n2=random.randint(1,5)
print(n1,n2) # => 5,1
I am not good at English, so I used a translator. Please understand if it's awkward.
If there is the same number in parentheses behind the 'seed' in the same expression, does the value always come out the same? I wonder what the numbers in parentheses do. Run a no number expression multiple times, the value change all the time.
똑같은 식에서 seed 뒤의 괄호 안에 같은 숫자가 들어가면 값도 무조건 똑같이 나오나요? 괄호 안에 들어가는 숫자가 무슨 역할을 하는지 궁금합니다. 숫자를 넣지 않은 식에서는 여러번 실행하면 값이 계속 바뀝니다.
Given two random instances within the same seed, the nth call to randint on the first instance will yield the same number as the nth call on the second instance.
That does not mean that the random value returned across multiple calls for the same instance will be the same.
You will see the same ordered series of values, meaning if you were to run your python program at some different time, you would see the output 5,1 once again.
Related
So, I'm in a project that uses Monte Carlo Method and I was studying the importance of the seed for pseudo-random numbers generation.
While doing experiments with python numpy random, I was trying to understand how the change in the seed affects the randomness, but I found something peculiar, at least for me. Using numpy.random.get_state() I saw that every time I run the script the seed starts different, changes once, but then keeps the same value for the entire script, as show in this code where it compares the state from two consecutive sampling:
import numpy as np
rand_state = [0]
for i in range(5):
rand_state_i = np.random.get_state()[1]
# printing only 3 state numbers, but comparing all of them
print(np.random.rand(), rand_state_i[:3], all(rand_state_i==rand_state))
rand_state = rand_state_i
# Print:
# 0.9721364306537633 [2147483648 2240777606 2786125948] False
# 0.0470329351113805 [3868808884 608863200 2913530561] False
# 0.4471038484385019 [3868808884 608863200 2913530561] True
# 0.2690477632739811 [3868808884 608863200 2913530561] True
# 0.7279016433547768 [3868808884 608863200 2913530561] True
So, my question is: how is the seed keeping the same value but returning different random values for each sampling? Does numpy uses other or more "data" to generate random numbers other than those present in numpy.random.get_state()?
You're only looking at part of the state. The big array of 624 integers isn't the whole story.
The Mersenne Twister only updates its giant internal state array once every 624 calls. The rest of the time, it just reads an element of that array, feeds it through a "tempering" pass, and outputs the tempered result. It only updates the array on the first call, or once it's read every element.
To keep track of the last element it read, the Mersenne Twister has an additional position variable that you didn't account for. It's at index 2 in the get_state() tuple. You'll see it increment in steps of 2 in your loop, because np.random.rand() has to fetch 2 32-bit integers to build a single double-precision floating point output.
(NumPy also maintains some additional state that's not really part of the Mersenne Twister state, to generate normally distributed values more efficiently. You'll find this in indexes 3 and 4 of the get_state() tuple.)
Let's say I have this code
import random
def fooFunc():
return 1
What is the overall chance of fooFunc being executed when using the code below?
if random.randrange(4096)==1:
fooFunc()
if random.randrange(256)==1:
fooFunc()
I'd suggest this isn't a python problem and better suited to https://math.stackexchange.com/ - to ask about probabilities.
As random.randrange(x) produces a number between 0 and x (including 0, but NOT including x), you have a 1/x probability of any specific number being produced.
Please see Neil Slater's answer for calculating the specific probability in your situation.
(Please see here if you want to look at the internals of random.randrange(): How does a randrange() function work?)
Each call to random.randrange can be treated as independent random selection, provided you don't know the seed and are happy to treat the output of a PRNG as a random variable.
What's the overall chance of fooFunc being executed?
Assuming you don't care about tracking whether fooFunc is called twice?
This is just the normal probability calculation, similar to "what is the chance of rolling at least one 6 when I roll two dice". To do this, it is easier to re-formulate the question as "What is the probability that I don't roll any 6", and subtract that from 1.0, because there is only one combination of failing both checks, whilst there are 3 combinations of succeeding one or other or both.
So p = 1 - ((4095/4096) * (255/256))
Consider two different strings to be of same length.
I am implementing robin-karp algorithm and using the hash function below:
def hs(pat):
l = len(pat)
pathash = 0
for x in range(l):
pathash += ord(pat[x])*prime**x # prime is global variable equal to 101
return pathash
It's a hash. There's, by definition, no guarantee there will be no collisions - otherwise, the hash would have to be as long as the hashed value, at least.
The idea behind what you're doing is based in number theory: powers of a number that is coprime to the size of your finite group (which probably the original author meant to be something like 2^N) can give you any number in that finite group, and it's hard to tell which one these were.
Sadly, the interesting part of this hash function, namely the size limiting/modulo operation of the hash, has been left out of this code – which makes one wonder where your code comes from. As far as I can immediately see, has little to do with Rabin-Karb.
I am working the text, "Genetic Algorithms with Python"by Clinton Sheppard and struggling to learn Python 3 at the same time.
I'm hoping someone out there can help me interpret some Python 3 code correctly. By that I mean, the code works - it does what it is supposed to do - but I need help understanding why. Here's the first block of code:
import random
geneSet = " abcdef....zA...Z!."
target = "Hello World!"
def generate_parent(length):
genes = []
while len(genes) < length: # limited to length number of iterations
sampleSize = min(length - len(genes), len(geneSet))
print("Current sample size: {}".format(sampleSize))
print(genes.extend(random.sample(geneSet, sampleSize)))
return ''.join(genes)
Basically, this method here is used to generate a random string from the gene set. I see that it takes as input parameter length. I'll assume length = 12. First, an empty list genes is created. Then the while loop ( which is limited to length iterations ) obtains a sampleSize by taking the minimum of (length - len(genes) and len(geneSet). Using 12 as length this works out to min(12 - 0, 54) the result being 12. A random sample of sampleSize (12) is sampled from the geneSet and the genes list is extended by such.
I'm having difficulty seeing the need for the final line of code "return ''.join(genes)". Or how it is this while loop ever goes through more than a single iteration since in the second to last line of code the genes list is extended from the geneSet by sampleSize.
.... and this is just hello world :) I think, as is usually the case, I'm overlooking the flat out obvious but if someone could take a few moments to explain this code in their own words I'd appreciate the different perspective.
Thanks!
"".join(genes) ist used to combine all the single entries of the genes list into one single string. str.join(sequence) takes takes all entries of sequence and seperates them be str. As the author needs one string only consisting of genes, "" is used as str so the single characters in the string are seperated by nothing.
The while loop is used (as jasonharper already mentioned) is used to create a string whose length is larger than the gene_set, as random.sample() can only pick as much samples as there are elements to be sampled from.
I am currently working on the same book, maybe we can help each other out.
By 'graph' I mean 'function' in the mathematical sense, where you always find one unchanging y value per x value.
Python's random.Random class's seed behaves as the x-coordinate of a random graph and each new call to random.random() gives a new random graph with all new x-y mappings.
Is there a way to directly refer to random.Random's nth graph, or in other words, the nth value in a certain seed's series without calling random.random() n times?
I am making a set of classes that I call Transformers that take any (x,y) coordinates as input and output another pair of (x,y) coordinates. Each transformer has two methods: transform and untransform. One of the transformers that I want adds a random value to the input y coordinate depending on the the input x coordinate. Say that I then want this transformer to untransform(x, y), now I need to subtract the same value I added from y if x is the same. This can be done by setting the seed to the same value it had when I added to y, so acting like the x value. Now say that I want two different instances of the transformer that adds random values to y. My question is about my options for making this new random transformer give different values than the first one.
Since Python 3.4 apparently removes jumpahead, here's some code that implements a convenient pseudorandom dictionary.
from hashlib import sha256 as _sha256
from hmac import HMAC as _HMAC
from math import ldexp as _ldexp
from os import urandom as _urandom
from sys import byteorder as _byteorder
class PRF():
def __init__(self):
digestmod = _sha256
self._h = _HMAC(_urandom(digestmod().block_size), digestmod=digestmod)
def __getitem__(self, key):
h = self._h.copy()
h.update(repr(key).encode())
b = h.digest()
return _ldexp(int.from_bytes(b, _byteorder), (len(b) * (- 8)))
Example usage:
>>> import prf
>>> f = prf.PRF()
>>> f[0]
0.5414241336009658
>>> f[1]
0.5238549618249061
>>> f[1000]
0.7476468534384274
>>> f[2]
0.899810590895144
>>> f[1]
0.5238549618249061
Is there a way to directly refer to random.Random's nth graph, or in other words, the nth value in a certain seed's series without calling random.random() n times?
Yes, sort of; you use Random.jumpahead(). There aren't really separate functions/graphs, though -- there's only one sequence generated by the PRNG -- but you can get into it at any point.
You seem to be still working on the same problem as your last question, and the code I posted in a comment there should cover this:
from random import Random
class IndependentRepeatableRandom(object):
def __init__(self):
self.randgen = Random()
self.origstate = self.randgen.getstate()
def random(self, val):
self.randgen.jumpahead(int(val))
retval = self.randgen.random()
self.randgen.setstate(self.origstate)
return retval
Well you're probably going to need to come up with some more detailed requirements but yes, there are ways:
pre-populate a dictionary with however many terms in the series you require for a given seed and then at run-time simply look the nth term up.
if you're not fussed about the seed values and/or do not require some n terms for any given seed, then find a O(1) way of generating different seeds and only use the first term in each series.
Otherwise, you may want to stop using the built-in python functionality & devise your own (more predictable) algo.
EDIT wrt the new infos:
Ok. so i also looked at your profile & so you are doing something (musical?) other than any new crypto thing. if that's the case, then it's unfortunately mixed blessings, because while you don't require security, you also still won't want (audible) patterns appearing. so you unfortunately probably do still need a strong prng.
One of the transformers that I want adds a random value to the input y
coordinate depending on the the input x coordinate
It's not yet clear to me if there is actually any real requirement for y to depend upon x...
Now say that I want two different instances of the transformer that
adds random values to y. My question is about my options for making
this new random transformer give different values than the first one.
..because here, i'm getting the impression that all you really require is for two different instances to be different in some random way.
But, assuming you have some object containing tuple (x,y) and you really do want a transform function to randomly vary y for the same x; and you want an untransform function to quickly undo any transform operations, then why not just keep a stack of the state changes throughout the lifetime of any single instance of an object; and then in the untransform implementation, you just pop the last transformation off the stack ?