[j]генерация случайных целых
От: Аноним  
Дата: 15.04.08 05:06
Оценка:
? генерит случайный вектор. А как создать вектор случайных целых, так чтобы каждому из возможных значений соответствовала своя верояность попадания?

спасибо
Re: [j]генерация случайных целых
От: Quintanar Россия  
Дата: 15.04.08 10:08
Оценка:
Здравствуйте, Аноним, Вы писали:

А>? генерит случайный вектор. А как создать вектор случайных целых, так чтобы каждому из возможных значений соответствовала своя верояность попадания?


Такого рода задачи решаются через равномерное распределение, к которому потом применяется функция.
В данном случае, можно сгенерировать вектор случайных чисел от 0 до p1+p2+...+pN=1 и маппинг типа (p1 -> N1;p1+p2 -> N2;...;p1+..+pN -> NN) и с помощью этого маппинга сгенерировать из равномерного вектора неравномерный.
Не знаю как в J, а в Q можно так:
p:(0.1;0.2;0.05;0.3;0.25;0.1)
q:(1;  2;  3;   4;   5; 6)
v:10?1.
q (+\[p]>/:v)?'1b / по вектору с накапливающейся суммой вероятностей найти место, где каждое случайное число становится
                  / больше текущей суммы, потом найти позицию этой 1 (true) и по ней определить в векторе q нужное значение.


Не супер эффективно, правда. Может есть подход побыстрее.
Re: [j]генерация случайных целых
От: Mr.Cat  
Дата: 15.04.08 10:23
Оценка:
Здравствуйте, Аноним, Вы писали:
А>? генерит случайный вектор. А как создать вектор случайных целых, так чтобы каждому из возможных значений соответствовала своя верояность попадания?

Т.е. нужна случайная величина с заданным законом распределения? По этой теме мне приглянулась книга Devroye L. Generation of non-uniform random variates.

Самый простой способ — метод инверсии. Надо на равномерно распределенный от 0 до 1 случайный вектор замаппить функцию, обратную желаемой функции распределения.
Re[2]: [j]генерация случайных целых
От: Аноним  
Дата: 15.04.08 11:38
Оценка:
Здравствуйте, Quintanar, Вы писали:


Q>Не знаю как в J, а в Q можно так:

Q>
Q>p:(0.1;0.2;0.05;0.3;0.25;0.1)
Q>q:(1;  2;  3;   4;   5; 6)
Q>v:10?1.
Q>q (+\[p]>/:v)?'1b / по вектору с накапливающейся суммой вероятностей найти место, где каждое случайное число становится
Q>                  / больше текущей суммы, потом найти позицию этой 1 (true) и по ней определить в векторе q нужное значение.
Q>


На J тот же алгоритм можно записать так:
v =: 2 : '({&u @ i.&1 @: ((+/\v)&>:))"0'  NB. conjunction которая будет производить глагол преобразующий вероятность в число (u - список чисел v - список вероятностей) 
ud =: (?@$&0)   NB. глагол производящий вектор равномерно распределенных чисел [0;1] (аргумент - длина вектора)

Далее пример использования (данные слямзены у Quintanar)
q =: 1 2 3 4 5 6
p =: 0.1 0.2 0.05 0.3 0.25 0.1
f =: q v p         NB. Искомый глагол (аргумент - случайная величина [0;1])
fn =: f@ud         NB. Это будет производить последовательность заданной длины

Протестируем
fn 50
5 5 4 4 4 5 2 5 4 5 6 5 4 6 5 5 1 4 2 2 5 4 4 5 2 5 2 4 5 4 6 1 2 1 1 5 5 1 2 5 5 4 2 3 5 2 2 5 4 4
NB. Проверим вероятности
(%+/) +/"1 = /:~ fn 1000
0.102 0.199 0.046 0.312 0.244 0.097
Re[3]: [j]генерация случайных целых
От: Аноним  
Дата: 15.04.08 17:21
Оценка:
а вот другой способ, который работает на порядок быстрей:
ts=: 6!:2, 7!:2@]
q =: 1 2 3 4 5 6
p =: 0.1 0.2 0.05 0.3 0.25 0.1
trunc =: >.`<.@.([: >&0.5 (>. - ])) NB. округление
g =: [: trunc"0 *&100 NB. точность
x =: (10 # 1) , (20 # 2) , (5 # 3) , (30 # 4) , (25 # 5) , (10 # 6)
NB. не получается получить x, используя глагол g :(

rnd =: ] {~ [: ? [ # [: # ]

100 ts '(%+/) +/"1 = /:~ fn 1000' NB. из предыдущего ответа
NB. => 0.00260541 29632
100 ts '(%+/) +/"1 = /:~ (rnd&x) 1000'
NB. => 0.00014256 30272


единственное, что — подскажите как получить вектор x, используя глагол g.
решение p ($~"0 [: g ]) q приводит к заполнению нулями недостающих частей вектора..
Re[4]: [j]генерация случайных целых
От: Mikl Kurkov Россия  
Дата: 15.04.08 22:18
Оценка:
Здравствуйте, Аноним, Вы писали:

А>а вот другой способ, который работает на порядок быстрей:

А> ...
А>единственное, что — подскажите как получить вектор x, используя глагол g.
А>решение p ($~"0 [: g ]) q приводит к заполнению нулями недостающих частей вектора..

Вот один из вариантов
gen =: (#/@[ , ])/ &. (, & 0 0) @ ,.
NB. слева - количество элементов, справа - сами элементы  
NB. использование: (g p) gen q
NB. Тест:
3 2 1 gen 1 2 3
  1 1 1 2 2 3


Ну и округление можно сделать гораздо проще:
round =: [: <. 0.5 + ]
round 1 1.2 1.5 1.8 2 
  1 1 2 2 2
(trunc"0 -: round) 1 1.2 1.5 1.8 2
  1

--
Mikl
Re[5]: [j]генерация случайных целых
От: Аноним  
Дата: 16.04.08 00:23
Оценка:
Здравствуйте, Mikl Kurkov, Вы писали:

MK>
MK>gen =: (#/@[ , ])/ &. (, & 0 0) @ ,.
MK>NB. слева - количество элементов, справа - сами элементы  
MK>NB. использование: (g p) gen q
MK>NB. Тест:
MK>3 2 1 gen 1 2 3
MK>  1 1 1 2 2 3
MK>


А разве gen не заменяется просто на # (Copy) ?
   3 2 1 # 1 2 3
1 1 1 2 2 3
Re[4]: [j]генерация случайных целых
От: Аноним  
Дата: 16.04.08 04:34
Оценка:
Здравствуйте, Аноним, Вы писали:

А>а вот другой способ, который работает на порядок быстрей


Да, более быстрый способ, согласен
Позволю себе лишь скомпилировать результаты трудов всех участников ветки в следующую компактную реализацию:
ts =: 6!:2 , 7!:2@]
q =: 1 2 3 4 5 6
p =: 0.1 0.2 0.05 0.3 0.25 0.1
prec =: 100

round =: [: <. 0.5 + ]
g =: [: round *
rnd =:(?@$ #) { ]
x =: q #~ prec g p

   (%+/) +/"1 = /:~ 1e6 rnd x
0.099964 0.199615 0.04999 0.29935 0.250774 0.100307
   10 ts '1e6 rnd x'
0.0472007 8.38957e6

Надеюсь, то и условие задачи автора топика мы поняли правильно
Re[6]: [j]генерация случайных целых
От: Mikl Kurkov Россия  
Дата: 16.04.08 07:01
Оценка:
Здравствуйте, Аноним, Вы писали:

А>...

А>А разве gen не заменяется просто на # (Copy) ?
А>
А>   3 2 1 # 1 2 3
А>1 1 1 2 2 3
А>

Да, забыл про эту возможность. Давно не брал в руки шашек

ЗЫ Странно, почему-то не могу у этого сообщения + поставить.

--
Mikl
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.