Supongamos que tengo una de n lados cargado de morir, donde de cada lado k tiene una cierta probabilidad de pk de cuando hago rodar. Tengo curiosidad por ver si hay buen algoritmo para almacenar esta información de forma estática (es decir, para un conjunto fijo de probabilidades) para que yo pueda simular eficazmente al azar rollo de morir.

Actualmente, tengo un O(lg n) solución para este problema. La idea es almacenar una tabla de la probabilidad acumulada de la primera k lados para todos los k, para generar un número real aleatorio en el rango [0, 1) y realizar una búsqueda binaria sobre la mesa para obtener el mayor índice cuyo valor acumulado no es mayor que el valor elegido. Me gusta esta solución, pero parece extraño que el tiempo de ejecución no toma las probabilidades en cuenta. En particular, en el extremal de los casos de un lado siempre o los valores que se están distribuidos de manera uniforme, es posible generar el resultado de la tirada en O(1) el uso de un enfoque ingenuo, a pesar de que mi solución aún logarithmicallh muchos pasos.

¿Alguien tiene alguna sugerencia de cómo resolver este problema en una forma que es de alguna manera «adaptación» en tiempo de ejecución?

EDITAR: Basado en las respuestas a esta pregunta, me han escrito hasta un artículo que describe varios enfoques a este problema, junto con su análisis. Parece Vose de la aplicación del método alias da Θ(n) preprocesamiento de tiempo y O(1) vez por tirada de dados, que es realmente impresionante. Esperemos que esta es una adición útil a la información contenida en las respuestas!

  • Es razonable que exista un O(1) solución para cada caso específico.

3 Comentarios

  1. 111

    Usted está buscando para la método alias que proporciona una O(1) método para la generación de un fijo de distribución de probabilidad discreta (suponiendo que usted puede acceder a las entradas de una matriz de longitud n en tiempo constante) con un tiempo de O(n) set-up. Usted puede encontrar documentado en el capítulo 3 (PDF) de «No Aleatorio Uniforme De La Variable Aleatoria Generación» por Luc Devroye.

    La idea es tomar la matriz de probabilidades pk y producir tres nuevos n-elemento de las matrices, pk, unk y bk. Cada pk es una probabilidad entre 0 y 1, y cada unak y bk es un número entero entre 1 y n.

    Podemos generar números aleatorios entre 1 y n por generar dos números aleatorios, r y s, entre 0 y 1. Sea i = floor(r*N)+1. Si qyo < s, a continuación, volver ayo else return byo. El trabajo en el alias método consiste en averiguar cómo producir pk, unk y bk.

  2. 4

    Uso equilibrado árbol de búsqueda binario (o binario de búsqueda en un array) y obtener O(log n) la complejidad. Tiene un nodo para cada dado resultado y tiene las teclas ser el intervalo que va a desencadenar ese resultado.

    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)
    

    La cosa buena acerca de esta solución es que es muy simple de implementar, pero todavía tiene buena complejidad.

    • Hechos a mano de árbol binario de arriba es simple de implementar, pero no se garantiza equilibrada
    • Usted puede garantizar que es equilibrado si se construye en el orden correcto.
  3. 3

    Estoy pensando de granulación de la tabla.

    Lugar de tener una tabla con el acumulado de cada uno de los troqueles de valor, puede crear una matriz de enteros de longitud xN, donde x es, idealmente, un número alto para aumentar la precisión de la probabilidad.

    Llenar esta matriz mediante el uso del índice (normalizado por xN) como el valor acumulado y, en cada «slot» en la matriz, de la tienda a la tirada de dados si este índice sube.

    Tal vez me podría explicar más fácil con un ejemplo:

    Con tres dados: P(1) = 0.2, P(2) = 0.5, P(3) = 0.3

    Crear una matriz, en este caso voy a elegir una simple longitud, digamos 10. (es decir, 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
    

    A continuación, obtener la probabilidad de que, justo selección aleatoria de un número entre 0 y 10 y simplemente el acceso a dicho índice.

    Este método puede perder exactitud, pero aumentar la x y la precisión será suficiente.

    • Para la veracidad de los datos que usted puede hacer la matriz de búsqueda, como primer paso, y para la serie de intervalos que corresponden a varios lados de hacer una búsqueda allí.

Dejar respuesta

Please enter your comment!
Please enter your name here