init
This commit is contained in:
commit
83ffa41771
8
config.json
Normal file
8
config.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"probability_table": [
|
||||
[1,0.008],
|
||||
[73,0.008],
|
||||
[90,1]
|
||||
],
|
||||
"num_trials": 10000000
|
||||
}
|
86
main.py
Normal file
86
main.py
Normal file
@ -0,0 +1,86 @@
|
||||
import json
|
||||
import random
|
||||
import csv
|
||||
from tqdm import tqdm
|
||||
|
||||
|
||||
class ProbabilityTable:
|
||||
def __init__(self, table):
|
||||
self.table = table
|
||||
self.maximum_draws = table[-1][0]
|
||||
|
||||
def get_probability(self, n):
|
||||
for i in range(len(self.table) - 1):
|
||||
if n < self.table[i + 1][0]:
|
||||
return self.table[i][1] + (self.table[i + 1][1] - self.table[i][1]) * (
|
||||
n - self.table[i][0]
|
||||
) / (self.table[i + 1][0] - self.table[i][0])
|
||||
return self.table[-1][1]
|
||||
|
||||
|
||||
class CardGame:
|
||||
def __init__(self, probability_table):
|
||||
self.probability_table = probability_table
|
||||
|
||||
def play(self):
|
||||
n = 1
|
||||
while True:
|
||||
if n > self.probability_table.maximum_draws:
|
||||
raise ValueError(
|
||||
"Reached maximum number of draws without finding a match"
|
||||
)
|
||||
r = random.random()
|
||||
p = self.probability_table.get_probability(n)
|
||||
if r < p:
|
||||
return n
|
||||
n += 1
|
||||
|
||||
|
||||
class Statistics:
|
||||
def __init__(self, game, num_trials):
|
||||
self.game = game
|
||||
self.num_trials = num_trials
|
||||
|
||||
def run(self):
|
||||
results = {}
|
||||
maximum_draws = self.game.probability_table.maximum_draws
|
||||
for n in range(1, maximum_draws + 1):
|
||||
results[n] = {"count": 0, "samples": []}
|
||||
|
||||
with tqdm(total=self.num_trials, desc="Running simulations") as pbar:
|
||||
for i in range(self.num_trials):
|
||||
n = self.game.play()
|
||||
results[n]["count"] += 1
|
||||
results[n]["samples"].append(i + 1)
|
||||
pbar.update()
|
||||
|
||||
with open("results_full.csv", "w", newline="") as f:
|
||||
writer = csv.writer(f)
|
||||
writer.writerow(["抽数", "该抽出金的概率", "刚好在该抽出金的概率", "该抽出金的样本数量", "该抽出金的样本号"])
|
||||
for n in range(1, maximum_draws + 1):
|
||||
p = self.game.probability_table.get_probability(n)
|
||||
probability_of_exact_n = results[n]["count"] / self.num_trials
|
||||
samples_str = ", ".join(str(s) for s in results[n]["samples"])
|
||||
writer.writerow(
|
||||
[n, p, probability_of_exact_n, results[n]["count"], samples_str]
|
||||
)
|
||||
|
||||
with open("results_no_samples.csv", "w", newline="") as f_no_samples:
|
||||
writer_no_samples = csv.writer(f_no_samples)
|
||||
writer_no_samples.writerow(["抽数", "该抽出金的概率", "刚好在该抽出金的概率", "该抽出金的样本数量"])
|
||||
for n in range(1, maximum_draws + 1):
|
||||
p = self.game.probability_table.get_probability(n)
|
||||
probability_of_exact_n = results[n]["count"] / self.num_trials
|
||||
writer_no_samples.writerow(
|
||||
[n, p, probability_of_exact_n, results[n]["count"]]
|
||||
)
|
||||
|
||||
|
||||
with open("config.json", "r") as f:
|
||||
config = json.load(f)
|
||||
|
||||
table = ProbabilityTable(config["probability_table"])
|
||||
game = CardGame(table)
|
||||
statistics = Statistics(game, config["num_trials"])
|
||||
|
||||
statistics.run()
|
1
requirements.txt
Normal file
1
requirements.txt
Normal file
@ -0,0 +1 @@
|
||||
tqdm==4.66.1
|
Loading…
x
Reference in New Issue
Block a user