这更多是好奇心练习...
如果您还没有听说过The Monty Hall问题,请在出色的youtube video中进行解释。
我使用numpy在python中对其进行了仿真:
import numpy as np
num_games = 100000
options = np.arange(1, 4, 1)
stick_result = 0
switch_result = 0
for i in range(1, num_games + 1):
winning_door = np.random.randint(1, 4)
first_choice = np.random.randint(1, 4)
if winning_door == first_choice:
stick_success += 1
# remove a door that isn't the winning_door or the first_choice
door_to_remove = np.random.choice(options[~np.isin(options, [winning_door, first_choice])])
options_with_one_door_removed = options[~np.isin(options, door_to_remove)]
# switch door to remaining option that isn't the first choice
second_choice_after_switch = options_with_one_door_removed[~np.isin(options_with_one_door_removed, first_choice)]
if winning_door == second_choice_after_switch:
switch_result += 1
这是否可能没有for循环?到目前为止,这是我所拥有的,但是我不确定如何进行门开关。
import numpy as np
num_games = 100000
options = np.arange(1, 4, 1)
winning_door = np.random.randint(1, 4, num_games)
first_choice = np.random.randint(1, 4, num_games)
stick_successes = (winning_door == first_choice).sum()
# remove a door that isn't the winning_door or the first_choice
door_to_remove = ???
options_with_one_door_removed = ???
# switch door to remaining option that isn't the first choice
second_choice_after_switch = ???
switch_successes = (winning_door == second_choice_after_switch).sum()
您必须确定游戏节目主持人从游戏的每个实例(winning_door
和first_choice
阵列的每一行)上卸下的门,然后将first_choice
切换到其余的门。)
有什么想法吗?
答案 0 :(得分:2)
您这里最大的问题是用遮罩对choice
进行向量化。看起来可能像这样:
def take_masked_along_axis(arr, where, index, axis):
""" Take the index'th non-masked element along each 1d slice along axis """
assert where.dtype == bool
assert index.shape[axis] == 1
# np.searchsorted would be faster, but does not vectorize
unmasked_index = (where.cumsum(axis=axis) > index).argmax(axis=axis)
unmasked_index = np.expand_dims(unmasked_index, axis=axis) # workaround for argmax having no keepdims
return np.take_along_axis(arr, unmasked_index, axis=axis)
def random_choice_masked_along_axis(arr, where, axis):
""" Like the above, but choose the indices via a uniform random number """
assert where.dtype == bool
index = np.random.sample(arr.shape[:axis] + (1,) + arr.shape[axis+1:]) * where.sum(axis=axis, keepdims=True)
return take_masked_along_axis(arr, where, index, axis=axis)
使代码的第一部分类似
options_broadcast = np.broadcast_to(options, (3, num_games))
removable = (options != options_broadcast) & (options != options_broadcast)
door_to_remove = random_choice_masked_along_axis(options_broadcast, where=removable, axis=0)