From 83ffa41771704521ff19f6af02a45d72aa8cb5aa Mon Sep 17 00:00:00 2001 From: Zichao Lin Date: Fri, 1 Sep 2023 20:18:01 +0800 Subject: [PATCH] init --- config.json | 8 +++++ main.py | 86 ++++++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 1 + 3 files changed, 95 insertions(+) create mode 100644 config.json create mode 100644 main.py create mode 100644 requirements.txt diff --git a/config.json b/config.json new file mode 100644 index 0000000..5e5b9f9 --- /dev/null +++ b/config.json @@ -0,0 +1,8 @@ +{ + "probability_table": [ + [1,0.008], + [73,0.008], + [90,1] + ], + "num_trials": 10000000 +} diff --git a/main.py b/main.py new file mode 100644 index 0000000..00eec54 --- /dev/null +++ b/main.py @@ -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() \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..26f474f --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +tqdm==4.66.1 \ No newline at end of file