Структура даних для завантажених кісток?


130

Припустимо, що у мене є n-сторона, завантажена штампом, де кожна сторона k має певну ймовірність p k, що підніметься, коли я її перекидаю. Мені цікаво, чи є хороший алгоритм для стаціонарного зберігання цієї інформації (тобто для фіксованого набору ймовірностей), щоб я міг ефективно імітувати випадковий рулон матриці.

Наразі у мене є рішення O (lg n) для цієї проблеми. Ідея полягає в тому, щоб зберегти таблицю сукупної ймовірності перших k сторін для всіх k, щоб вони генерували випадкове дійсне число в діапазоні [0, 1) і здійснювали двійковий пошук над таблицею, щоб отримати найбільший індекс, кумулятивний значення не більше вибраного значення. Мені більше подобається це рішення, але здається дивним, що час виконання не враховує ймовірності. Зокрема, у крайніх випадках, коли одна сторона завжди піднімається або значення розподіляються рівномірно, можна генерувати результат рулону в O (1), використовуючи наївний підхід, хоча моє рішення все-таки буде робити логарифмічні багато кроків.

Хтось має якісь пропозиції, як вирішити цю проблему способом, який якимось чином "адаптується" під час виконання?

EDIT : На основі відповідей на це питання я написав статтю, в якій описував багато підходів до цієї проблеми , разом з їх аналізами. Схоже, реалізація методу псевдоніма Vose дає Θ (n) час попередньої обробки та час (O) (1) час за відкат, що справді вражає. Сподіваємось, це корисне доповнення до інформації, що міститься у відповідях!


2
Доцільно, що існує рішення O (1) для кожного конкретного випадку .
Тим

Відповіді:


117

Ви шукаєте метод псевдоніму, який забезпечує метод O (1) для генерування фіксованого дискретного розподілу ймовірностей (якщо припустити, що ви можете отримати доступ до записів у масиві довжини n в постійному часі) з одноразовим налаштуванням O (n) . Ви можете знайти його задокументовані в розділі 3 (PDF) з «Non-Uniform Random Generation» випадкова величина Люк Devroye.

Ідея полягає у тому, щоб взяти свій масив ймовірностей p k та створити три нові масиви n-елементів, q k , a k і b k . Кожен q k є ймовірністю між 0 і 1, а кожен a k і b k - ціле число між 1 і n.

Ми генеруємо випадкові числа між 1 і n, генеруючи два випадкових числа, r і s, між 0 і 1. Нехай i = підлогу (r * N) +1. Якщо q i <s, тоді поверніть a i else поверніть b i . Робота методу псевдоніму полягає у з'ясуванні способів отримання q k , a k та b k .


Для такого корисного алгоритму метод Alias ​​напрочуд не дуже відомий.
mhum

Для запису: я опублікував невелику бібліотеку С для випадкового відбору з використанням методу псевдоніму apps.jcns.fz-juelich.de/ransampl .
Йоахім Ш

1
конкретна реалізація методу псевдоніму може бути повільнішою, ніж метод з гіршою складністю в часі, наприклад, колесо рулетки для заданої кількості nта вибране число випадкових чисел для генерування за рахунок постійних факторів, що беруть участь у реалізації алгоритмів.
jfs

4

Використовуйте збалансоване дерево бінарного пошуку (або двійковий пошук у масиві) і отримайте складність O (log n). Майте по одному вузлу для кожного результату матриці, а ключі - інтервал, який запустить цей результат.

function get_result(node, seed):
    if seed < node.interval.start:
        return get_result(node.left_child, seed)
    else if seed < node.interval.end:
        // start <= seed < end
        return node.result
    else:
        return get_result(node.right_child, seed)

Хороша річ у цьому рішенні - це те, що він дуже простий у виконанні, але все ще має складні труднощі.


Бінарне дерево, виготовлене на зразок вище, просте у виконанні, але воно не гарантується збалансованим
1818

Ви можете гарантувати його збалансованість, якщо побудувати його в правильному порядку.
хугомг

3

Я думаю про грануляцію вашого столу.

Замість того, щоб мати таблицю із сукупним значенням для кожного штампу, ви можете створити цілий масив довжини xN, де x в ідеалі є високим числом для збільшення точності ймовірності.

Заселіть цей масив, використовуючи індекс (нормалізований на xN) як сукупне значення, і, у кожному слоті в масиві, зберігайте потенційний рулон кубиків, якщо цей індекс з'явиться.

Можливо, я міг би пояснити простіше на прикладі:

Використовуючи три кубики: P (1) = 0,2, P (2) = 0,5, P (3) = 0,3

Створіть масив, у цьому випадку я виберу просту довжину, скажімо, 10. (тобто x = 3.33333)

arr[0] = 1,
arr[1] = 1,
arr[2] = 2,
arr[3] = 2,
arr[4] = 2,
arr[5] = 2,
arr[6] = 2,
arr[7] = 3,
arr[8] = 3,
arr[9] = 3

Потім, щоб отримати ймовірність, просто рандомізуйте число від 0 до 10 і просто отримайте доступ до цього індексу.

Цей метод може втратити точність, але збільшення x та точності буде достатнім.


1
Для повної точності ви можете виконати пошук масиву як перший крок, а для інтервалів масиву, які відповідають декільком сторонам, виконайте пошук там.
ааз

1

Існує багато способів генерування випадкових цілих чисел за допомогою спеціального розподілу (також відомий як дискретний розподіл ). Вибір залежить від багатьох речей, у тому числі кількості цілих чисел, форми розподілу та того, чи зміниться розподіл з часом.

Одним із найпростіших способів вибору цілого числа із власною функцією ваги f(x)є метод вибірки відхилення . Далі передбачається, що максимально можливе значення fмає max. Складність у часі для відбору проб відхилення в середньому є постійною, але сильно залежить від форми розподілу і має найгірший випадок, коли вона працює назавжди. Щоб вибрати ціле число в [1, k] за допомогою вибірки відхилення:

  1. Виберіть єдине випадкове ціле число iв [1, k].
  2. З вірогідністю f(i)/maxповернення i. В іншому випадку перейдіть до кроку 1.

Інші алгоритми мають середній час вибірки, який не так сильно залежить від розподілу (як правило, постійного або логарифмічного), але часто вимагають від вас попереднього розрахунку ваг на етапі налаштування та збереження їх у структурі даних. Деякі з них також є економічними щодо кількості випадкових бітів, які вони в середньому використовують. Багато з цих алгоритмів були введені після 2011 року, і вони включають:

  • лаконічна структура даних Брінгмана - Ларсена ("Короткий вибірки з дискретних розподілів", 2012),
  • Багаторівневий пошук Юнпенг Танга ("Емпіричне дослідження випадкових методів вибірки для зміни дискретних розподілів", 2019) та
  • ролик з швидким завантаженням кістки (2020).

Інші алгоритми включають метод псевдоніму (вже згадується у вашій статті), алгоритм Knuth – Yao, структура даних MVN тощо. Дивіться мій розділ " Примітка про алгоритми зваженого вибору " для опитування.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.