2015-01-25 2 views
1

У меня есть переменная, между 0 и 1, которая должна диктовать вероятность, что вторая переменная, случайное число от 0 до 1, больше 0,5. Другими словами, если бы я должен был генерировать вторую переменную 1000 раз, среднее значение должно быть приблизительно равно значению первой переменной. Как мне сделать этот код?Psuedo-Random Variable

О, и вторая переменная всегда должна быть способна производить либо 0, либо 1 в любом состоянии, что более или менее вероятно в зависимости от значения первой переменной. Вот link to a graph, который приблизительно моделирует, как я хотел бы, чтобы программа вела себя. Каждое уравнение представляет собой отдельное значение для первой переменной.

+0

Я пытался что-то связанное с й^(1/(2^у)), где х является первым переменным и у является второй один. Но я как бы застрял там и не добился большого прогресса. – Maurdekye

+0

Что вам больше всего нравится? Если var1 равно 1, var2 будет больше 0,5, если var1 равно 0, var 2 не будет больше 0,5? –

+0

Вот график, представляющий, что я пытался выработать; https://www.desmos.com/calculator/jf9mnw3yum Каждое уравнение представляет собой другое значение первой переменной, а ось x представляет собой средний возможный результат для каждого значения первой переменной. – Maurdekye

ответ

3

У вас есть переменная p и вы ищете функции отображения f(x), которая отображает случайные рулоны между x in [0, 1] в том же интервале [0, 1] такое, что ожидаемое значение, то есть в среднем по всем броскам, является p.

Вы выбрали прототип функции

f(x) = pow(x, c) 

где c должны быть выбраны соответствующим образом.Если x равномерно распределены в [0, 1], среднее значение:

int(f(x) dx, [0, 1]) == p 

С интегралом:

int(pow(x, c) dx) == pow(x, c + 1)/(c + 1) + K 

один получает:

c = 1/p - 1 

Другой подход, чтобы сделать p медианный значение распределения, так что половина рулонов опускается ниже p, другая половина выше p. Это дает другое распределение. (Я знаю, что ты не просил этого.) Теперь, мы должны удовлетворять условию:

f(0.5) == pow(0.5, c) == p 

что дает:

c = log(p)/log(0.5) 

С текущей прототип функции, вы не можете удовлетворить обе требования. Ваша функция также асимметрична (f(x, p) != f(1-x, 1-p)).

функция Python ниже:

def medianrand(p): 
    """Random number between 0 and 1 whose median is p""" 

    c = math.log(p)/math.log(0.5) 
    return math.pow(random.random(), c) 

def averagerand(p): 
    """Random number between 0 and 1 whose expected value is p""" 

    c = 1/p - 1 
    return math.pow(random.random(), c) 
+0

Боже мой, ты это сделал. Я точно не знаю, как вы это сделали, но работает безупречно. Может быть, я должен изучить исчисление и вероятность больше, так что мне не нужно делать так много глупых сообщений SO. – Maurdekye

0

Вы можете сделать это, используя манекен. Сначала установите первую переменную в значение от 0 до 1. Затем создайте случайное число в манекене между 0 и 1. Если этот макет больше, чем первая переменная, вы генерируете случайное число от 0 до 0,5 и в противном случае вы генерируете число в диапазоне от 0,5 до 1.

В псевдокоде:

real a = 0.7 
real total = 0.0 
for i between 0 and 1000 begin 
    real dummy = rand(0,1) 
    real b 
    if dummy > a then 
    b = rand(0,0.5) 
    else 
    b = rand(0.5,1) 
    end if 
    total = total + b 
end for 
real avg = total/1000 

Пожалуйста, обратите внимание, что этот алгоритм будет генерировать средние значения от 0,25 до 0,75. При a = 1 он генерирует только случайные значения от 0,5 до 1, что должно составлять 0,75. При a = 0 он будет генерировать только случайные числа от 0 до 0,5, что должно составлять 0,25.

+0

Единственная функция ключевого слова 'yield', о котором я знаю, это его использование в Python, которое постепенно возвращает элементы для ленивого итератора. Этот тип использования не имеет смысла в этом контексте, поэтому я не совсем уверен, что вы имеете в виду здесь. Кроме того, это кажется довольно ресурсоемким способом решения проблемы. Я думал об использовании возведения в степень для изменения нормально распределенного случайного числа путем увеличения или уменьшения его значения. – Maurdekye

+0

Вместо 1 случайного числа, которое вы генерируете 2. Я не думаю, что он должен потреблять -что многие циклы процессора генерируют лишнее случайное число. Я помню презентацию некоторое время назад, когда кто-то показывал, что истинно случайные rng в c или C++ заняли довольно много времени, чтобы настроить, но только слишком 6 циклов процессора, чтобы получить число. Я сомневаюсь, что вы можете сделать гораздо лучше, используя математическую конструкцию. Кроме того, как вы определили свой алгоритм, он будет генерировать средние значения между 0,25 и 0,75 для между 0 и 1. – Sumurai8

+0

Пожалуйста, перечитайте мой основной пост, я включил дополнительную информацию о том, как я хотел бы, чтобы алгоритм работал. – Maurdekye

0

Я сделал своеобразное псевдо-решение этой проблемы, которое, я думаю, приемлемо.

Вот алгоритм, который я сделал;

a = 0.2 # variable one 
b = 0 # variable two 

b = random.random() 
b = b^(1/(2^(4*a-1))) 

На самом деле это не дает среднего результата, который я хотел, но он достаточно близко для моих целей.

Редактировать: Here's a graph Я сделал то, что состоит из большого количества datapoints, которые я сгенерировал с помощью скрипта python, используя этот алгоритм;

import random 

mod = 6 
div = 100 

for z in xrange(div): 
    s = 0 
    for i in xrange (100000): 
     a = (z+1)/float(div) # variable one 

     b = random.random() # variable two 
     c = b**(1/(2**((mod*a*2)-mod))) 
     s += c 
    print str((z+1)/float(div)) + "\t" + str(round(s/100000.0, 3)) 

Каждая точка таблицы является результатом 100000 случайно генерируемых точек из алгоритма; их позиции x являются заданными значениями, а их позиции y являются их средними. В идеале они подходят к прямой линии y = x, но, как вы можете видеть, они подходят ближе к уравнению арктана. Я пытаюсь возиться с алгоритмом, чтобы средние значения соответствовали линии, но пока у меня не было большой удачи.

Смежные вопросы