В этой задаче вам нужно будет сохранить несколько фиктивных выходов (выбор отбраковки, как указано в @Gene), на котором вы повторяете выполненный эксперимент.
Здесь я представил две реализации. первый является субоптимальным, но его легче понять. второй более оптимальный, но немного сложнее. Наконец, я пробовал набросал доказательство и связался с ответом Math StackExchange.
Первый подход -
Шаг 1 - Запуск rand1()
x + 1
раз.
Шаг 2 - Проверьте, что выход разогревается. По одной горячей я имею в виду, только 1 из x + 1
работает в 1
и всех остальных 0
. Если это не так, повторите шаг 1. Остальное перейдите к этапу 3.
Шаг 3 - Индекс печати 1 как ваш выход.
код питона будет выглядеть следующим образом -
def randx(x):
choice = -1
while choice == -1:
for i in range(0, x+1):
c = rand1()
if c == 1 and choice == -1:
choice = i
elif c == 1 and choice != -1:
choice = -1
break
Второй подход -
Конечно, первый способ является неоптимальным. Вы можете сделать это намного лучше, но для этого потребуется намного больше кода. Предположим, мы хотим сделать прогноз между значениями x+1
(0
- x
). Вам нужно будет провести эксперимент по крайней мере k = ceil(log(x+1))
раз. Теперь каждый из результатов будет иметь равную вероятность 1/2^k
.
Из этих 2^k
возможностей присвоить номера номерам (из-за нашего выбора k
вы увидите, что вы можете присвоить номер, по крайней мере, половину возможностей). Позвоните другим возможностям манекен выход.
Когда вы получаете вывод dummy, вы просто повторяете эксперимент. Если вы этого не сделаете, вы выводите число, соответствующее этому результату.
В качестве примера, если x = 4, x + 1 = 5. Следовательно, нам нужно k = 3
. Назначьте 0, 1, 2, 3, 4 свои двоичные представления (от 000 до 101) и оставьте оставшиеся 3 в качестве соски.Псевдо-код будет выглядеть следующим образом,
function randx(x):
choice = -1
runs = ceil(log(x+1))
while choice == -1:
output = 0
for i in range(0, runs):
output += pow(2, i)*rand1()
if output <= x:
choice = output
Почему это работает?
Мы даем все числа равными вероятными событиями. Если ни одно из этих событий не произойдет, мы просто повторяем этот эксперимент. Если посмотреть на общую вероятность получения ряда i
,
Let p = 1/2^k
Let q = 1 - (x+1)*p
Total probability of getting i = p + q*p + q*q*p + q*q*q*p ...
= p/(1-q)
= 1/(x+1)
Hence this sums up to 1/(x+1).
Для более полного объяснения с MathJax см https://math.stackexchange.com/questions/2356/is-it-possible-to-split-coin-flipping-3-ways
http://math.stackexchange.com/questions/2356/is-it-possible-to-split-coin-flipping-3-ways – martianwars
hi martianwars, я редактировал вопрос, чтобы упомянуть, что 'randx' должен выводить 0,1, ..., x с равной вероятностью, поэтому я думаю, что ваш предыдущий подход может не работать. – yijiem
см. Новый ответ – martianwars