Básicamente, lo que está pidiendo es un generador de eventos "semi-aleatorio" que genere eventos con las siguientes propiedades:
La tasa promedio a la que ocurre cada evento se especifica de antemano.
Es menos probable que ocurra el mismo evento dos veces seguidas de lo que sería al azar.
Los eventos no son completamente predecibles.
Una forma de hacerlo es implementar primero un generador de eventos no aleatorio que satisfaga los objetivos 1 y 2, y luego agregar algo de aleatoriedad para satisfacer el objetivo 3.
Para el generador de eventos no aleatorio, podemos usar un algoritmo de interpolación simple . Específicamente, sea p 1 , p 2 , ..., p n las probabilidades relativas de los eventos 1 a n , y sea s = p 1 + p 2 + ... + p n la suma de los pesos. Luego podemos generar una secuencia no aleatoria de eventos con la máxima equidistribución utilizando el siguiente algoritmo:
Inicialmente, sea e 1 = e 2 = ... = e n = 0.
Para generar un evento, incremente cada e i por p i , y genere el evento k para el cual e k es más grande (rompiendo los lazos de la forma que desee).
Disminuya e k por s , y repita desde el paso 2.
Por ejemplo, dados tres eventos A, B y C, con p A = 5, p B = 4 y p C = 1, este algoritmo genera algo así como la siguiente secuencia de salidas:
A B A B C A B A B A A B A B C A B A B A A B A B C A B A B A
Observe cómo esta secuencia de 30 eventos contiene exactamente 15 As, 12 Bs y 3 Cs. No es bastante óptima distribuye - hay algunas ocurrencias de dos como en una fila, que podría haber sido evitado - pero se acerca.
Ahora, para agregar aleatoriedad a esta secuencia, tiene varias opciones (no necesariamente mutuamente excluyentes):
Puede seguir los consejos de Philipp y mantener un "mazo" de N próximos eventos, para un número N de tamaño apropiado . Cada vez que necesita generar un evento, elige un evento aleatorio del mazo y luego lo reemplaza con el siguiente evento de salida por el algoritmo de difuminado anterior.
Aplicando esto al ejemplo anterior, con N = 3, produce, por ejemplo:
A B A B C A B B A B A B C A A A A B B A B A C A B A B A B A
mientras que N = 10 produce el aspecto más aleatorio:
A A B A C A A B B B A A A A A A C B A B A A B A C A C B B B
Tenga en cuenta cómo los eventos comunes A y B terminan con muchas más carreras debido a la combinación, mientras que los eventos C raros todavía están bastante bien espaciados.
Puede inyectar algo de aleatoriedad directamente en el algoritmo de interpolación. Por ejemplo, en lugar de incrementar e i por p i en el paso 2, podría incrementarlo por p i × random (0, 2), donde random ( a , b ) es un número aleatorio distribuido uniformemente entre a y b ; esto produciría resultados como los siguientes:
A B B C A B A A B A A B A B A A B A A A B C A B A B A C A B
o podría incrementar e i por p i + random (- c , c ), lo que produciría (para c = 0.1 × s ):
B A A B C A B A B A B A B A C A B A B A B A A B C A B A B A
o, para c = 0.5 × s :
B A B A B A C A B A B A A C B C A A B C B A B B A B A B C A
Observe cómo el esquema aditivo tiene un efecto de aleatorización mucho más fuerte para los eventos raros C que para los eventos comunes A y B, en comparación con el multiplicativo; esto puede o no ser deseable. Por supuesto, también podría usar alguna combinación de estos esquemas, o cualquier otro ajuste a los incrementos, siempre que conserve la propiedad de que el incremento promedio de e i es igual a p i .
Alternativamente, podría perturbar la salida del algoritmo de interpolación reemplazando a veces el evento k elegido por uno aleatorio (elegido de acuerdo con los pesos brutos p i ). Siempre y cuando también use la misma k en el paso 3 que la salida en el paso 2, el proceso de interpolación aún tenderá a igualar las fluctuaciones aleatorias.
Por ejemplo, aquí hay algunos resultados de ejemplo, con un 10% de posibilidades de que cada evento sea elegido al azar:
B A C A B A B A C B A A B B A B A B A B C B A B A B C A B A
y aquí hay un ejemplo con un 50% de posibilidades de que cada salida sea aleatoria:
C B A B A C A B B B A A B A A A A A B B A C C A B B A B B C
También podría considerar alimentar una mezcla de eventos puramente aleatorios y difusos en una plataforma / grupo de mezcla, como se describió anteriormente, o tal vez aleatorizar el algoritmo de interpolación eligiendo k aleatoriamente, según lo ponderado por los e i s (tratando los pesos negativos como cero).
PD. Aquí hay algunas secuencias de eventos completamente al azar, con las mismas tasas promedio, para comparar:
A C A A C A B B A A A A B B C B A B B A B A B A A A A A A A
B C B A B C B A A B C A B A B C B A B A A A A B B B B B B B
C A A B A A B B C B B B A B A B A A B A A B A B A C A A B A
Tangente: Dado que en los comentarios se ha debatido si es necesario, para las soluciones basadas en plataformas, permitir que la plataforma se vacíe antes de que se vuelva a llenar, decidí hacer una comparación gráfica de varias estrategias de relleno de plataformas:
Trama de varias estrategias para generar lanzamientos de monedas semialeatorios (con una proporción de 50:50 de cara a cruz en promedio). El eje horizontal es el número de vueltas, el eje vertical es la distancia acumulativa de la relación esperada, medida como (caras - colas) / 2 = caras - vueltas / 2.
Las líneas rojas y verdes en la gráfica muestran dos algoritmos no basados en mazos para comparación:
- Línea roja, tramado determinista : los resultados pares son siempre cara, los resultados impares son siempre colas.
- Línea verde, cambios aleatorios independientes : cada resultado se elige de forma independiente al azar, con un 50% de posibilidades de caras y un 50% de posibilidades de colas.
Las otras tres líneas (azul, morado y cian) muestran los resultados de tres estrategias basadas en mazos, cada una implementada usando un mazo de 40 cartas, que inicialmente se llena con 20 cartas "caras" y 20 cartas "colas":
- Línea azul, rellenar cuando está vacío : las cartas se roban al azar hasta que el mazo esté vacío, luego el mazo se rellena con 20 cartas de "cabezas" y 20 cartas de "colas".
- Línea púrpura, llene cuando esté medio vacío : las cartas se roban al azar hasta que el mazo tenga 20 cartas restantes; entonces el mazo se completa con 10 cartas de "cabezas" y 10 cartas de "colas".
- Línea cian, rellena continuamente : las cartas se roban al azar; los sorteos pares se reemplazan inmediatamente con una carta de "cara" y los sorteos impares con una carta de "colas".
Por supuesto, la trama anterior es solo una realización única de un proceso aleatorio, pero es razonablemente representativa. En particular, puede ver que todos los procesos basados en mazos tienen un sesgo limitado y se mantienen bastante cerca de la línea roja (determinista), mientras que la línea verde puramente aleatoria finalmente se desvía.
(De hecho, la desviación de las líneas azul, púrpura y cian lejos de cero está estrictamente limitada por el tamaño de la plataforma: la línea azul nunca puede alejarse más de 10 pasos de cero, la línea púrpura solo puede alejarse 15 pasos de cero , y la línea cian puede desplazarse como máximo 20 pasos desde cero. Por supuesto, en la práctica, cualquiera de las líneas que realmente alcancen su límite es extremadamente improbable, ya que existe una fuerte tendencia a que vuelvan más cerca de cero si se alejan demasiado. apagado.)
De un vistazo, no hay una diferencia obvia entre las diferentes estrategias basadas en mazos (aunque, en promedio, la línea azul se mantiene algo más cerca de la línea roja, y la línea cian se mantiene un poco más lejos), pero una inspección más cercana de la línea azul revela un patrón determinista distinto: cada 40 dibujos (marcados por las líneas verticales grises punteadas), la línea azul se encuentra exactamente con la línea roja en cero. Las líneas moradas y cian no están tan estrictamente restringidas y pueden mantenerse alejadas de cero en cualquier punto.
Para todas las estrategias basadas en mazos, la característica importante que mantiene limitada su variación es el hecho de que, mientras las cartas se sacan del mazo al azar, el mazo se rellena de manera determinista. Si las cartas utilizadas para rellenar el mazo fueran elegidas al azar, todas las estrategias basadas en el mazo serían indistinguibles de la elección aleatoria pura (línea verde).