I appreciate your help in advance.
I wrote a probability calculator with python. Prob I want to calculate is this: What's the prob of winning when you try 6 times of game that has winning chance of 1%. So this following code is what I wrote.
import random as rand
total = 0
count = 0
p = pSum = 0
k = 6
n = 10000
m = 100
def pick(attemptPerIteration):
global total, count
for _ in range(attemptPerIteration):
temp = rand.randint(1, 100)
if (temp == 1):
count += 1
total += 1
return 0
return 1
for t in range(m):
for u in range(n):
total += pick(k)
p = count / total
print(str(t + 1) + ": " + str(p * 100))
pSum += p
p = 0
print(pSum / m * 100)
In this code, I used randint function to simulate one in 100 chance. The prob I expected is about 5.8% but this program outputs about 6.3%. But if I use randint(1, 1000) % 6 + 1 insted of just randint(1, 6), program tell the prob is 5.8, which I expected.
What's going on in this randint function exactly? Why the old % trick works but randint doesn't?
Mathematical formula to this problem is this:
Looks like you made mistakes with incrementing count
and total
. I changed your code to compute correct result:
import random as rand
total = 0
count = 0
p = pSum = 0
k = 6
n = 10000
m = 100
def pick(attemptPerIteration):
for _ in range(attemptPerIteration):
temp = rand.randint(1, 100)
if (temp == 1):
return 1
return 0
for t in range(m):
for u in range(n):
count += pick(k)
total += 1
p = count / total
print(str(t + 1) + ": " + str(p * 100))
pSum += p
p = 0
print(pSum / m * 100)
Output:
.......
90: 5.822555555555556
91: 5.8221978021978025
92: 5.822608695652174
93: 5.824193548387097
94: 5.822446808510638
95: 5.822631578947368
96: 5.824166666666667
97: 5.825670103092784
98: 5.8254081632653065
99: 5.826969696969697
100: 5.8306
5.825542887205491
It looks like m = 100
and n = 10000
are too little for things to converge.
import random
def did_win(attempts):
return any(random.random() < .01 for attempt in range(attempts))
tries = [did_win(6) for x in range(1_000_000)]
print(tries.count(True) / len(tries))
prints out about 0.058039
which seems close enough.
If you want to watch the solution converge in more real time,
import random
import itertools
def did_win(attempts):
return any(random.random() < 0.01 for attempt in range(attempts))
wins = 0
for x in itertools.count(0):
if did_win(6):
wins += 1
if x and x % 10_000 == 0:
print(x, wins / x)
(hit ctrl-c to interrupt it – it'll otherwise happily run forever).
The formula is much simpler, actually. The probability of not winning is (99 / 100) ** 6
, that is approximately 0.941
. Its complement is the probability of winning 1 - 0.941... = 0.058...
.
Because you are increasing global counts in a weird way, it's very likely that you have off-by-one errors in more than one place. For instance
total += pick(k)
where pick
also modifies total
...
You should just return 0 or 1 and then count from outside.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.