基于Python 3.10:扩展卡组规模与抽取求和的概率对比
规则说明
- 基础卡组为
[2,3,4,5,6,7,8,9,10],定义为卡组规模1; - 每提升一级卡组规模,需复制一份基础卡组加入;
- 卡组构建完成后,需额外添加
[7,8,9,10]; - 示例:规模2的卡组为
[2,3,4,5,6,7,8,9,10,2,3,4,5,6,7,8,9,10,7,8,9,10],规模3的卡组以此类推; - 玩法:抽取次数等于卡组规模,结果为抽取卡牌的数值和,比如规模3卡组需计算3次抽取的和。
问题与实践
先编写了使用itertools生成符合规则卡组的代码,但不确定概率计算代码的正确性。最初的概率计算代码通过itertools.product遍历所有组合,对比不同卡组抽取和的获胜概率,但时间复杂度极高。随后尝试蒙特卡洛模拟方法,得到与全组合法相近的结果,最终问题已解决。
相关代码
卡组生成代码(版本1)
import itertools # define base deck base_deck = [2, 3, 4, 5, 6, 7, 8, 9, 10] # define deck sizes deck_a_size = 2 deck_b_size = 3 # create decks deck_a_cards = list(itertools.chain.from_iterable(itertools.repeat(base_deck, deck_a_size))) deck_a_cards.extend(floater) print(deck_a_cards) deck_b_cards = list(itertools.chain.from_iterable(itertools.repeat(base_deck, deck_b_size))) deck_a_cards.extend(floater) print(deck_b_cards)
全组合概率计算代码
import itertools # define base deck base_deck = [2, 3, 4, 5, 6, 7, 8, 9, 10] # define deck sizes deck_a_size = 1 deck_b_size = 3 # create decks deck_a_cards = list(itertools.chain.from_iterable(itertools.repeat(base_deck, deck_a_size))) deck_a_cards.extend(floater) print(deck_a_cards) deck_b_cards = list(itertools.chain.from_iterable(itertools.repeat(base_deck, deck_b_size))) deck_b_cards.extend(floater) print(deck_b_cards) deck_a_success = 0 deck_b_success = 0 total_combinations = 0 for i in itertools.product(deck_a_cards, repeat=deck_a_size): for j in itertools.product(deck_b_cards, repeat=deck_b_size): deck_a_sum = sum(i) deck_b_sum = sum(j) if deck_a_sum > deck_b_sum: deck_a_success += 1 elif deck_a_sum < deck_b_sum: deck_b_success += 1 else: deck_b_success += 1 total_combinations += 1 deck_a_prob = deck_a_success / total_combinations deck_b_prob = deck_b_success / total_combinations print("Probability of success with {} cards drawn:".format(deck_a_size + deck_b_size)) print("Deck A:", deck_a_prob) print("Deck B:", deck_b_prob)
蒙特卡洛模拟概率计算代码
import random base_deck = [2, 3, 4, 5, 6, 7, 8, 9, 10] deck_a_size = 2 deck_b_size = 3 num_trials = 1000000 deck_a_wins = 0 deck_b_wins = 0 for i in range(num_trials): deck_a_sum = sum(random.sample(base_deck, deck_a_size)) deck_b_sum = sum(random.sample(base_deck * deck_b_size, deck_b_size)) if deck_a_sum > deck_b_sum: deck_a_wins += 1 elif deck_b_sum > deck_a_sum: deck_b_wins += 1 deck_a_prob = deck_a_wins / num_trials deck_b_prob = deck_b_wins / num_trials print("Probability of success with {} cards drawn:".format(deck_a_size+deck_b_size)) print("Deck A:", deck_a_prob) print("Deck B:", deck_b_prob)
运行结果
全组合法
抽取5张卡牌的获胜概率:
Deck A: 0.1316926655146557
Deck B: 0.8683073344853444
运行时间:6.0s
蒙特卡洛法
抽取5张卡牌的获胜概率:
Deck A: 0.121357
Deck B: 0.837629
运行时间:3.8s
内容的提问来源于stack exchange,提问作者Thomas J Childers
相关产品推荐
相关产品推荐

