Generar al azar Cartas De acuerdo con su frecuencia de uso?

votos
10

¿Cómo puedo generar aleatoriamente las cartas de acuerdo con su frecuencia de uso en el lenguaje común?

Cualquier pseudo-código apreciado, pero una implementación en Java sería fantástico. De lo contrario sólo un piquete en la dirección correcta sería de gran ayuda.

Nota: No es necesario para generar las frecuencias de uso - Estoy seguro de que puedo mirar eso con bastante facilidad.

Publicado el 27/01/2010 a las 21:11
fuente por usuario
En otros idiomas...                            


5 respuestas

votos
11

Una forma rápida de hacerlo sería para generar una lista de letras, donde cada letra aparecía en la lista de acuerdo con su frecuencia. Decir, si "e" se ha utilizado el 25,6% del tiempo, y su lista tenía longitud 1000, que tendría 256 "e" s.

A continuación, usted podría escoger al azar los puntos de la lista utilizando (int) (Math.random() * 1000)para generar números aleatorios entre 0 y 999.

Respondida el 27/01/2010 a las 21:14
fuente por usuario

votos
18

Estoy asumiendo que almacene las frecuencias como números de punto flotante entre 0 y 1 que el total para hacer 1.

En primer lugar debe preparar una tabla de frecuencias acumulativas, es decir, la suma de la frecuencia de esa carta y todas las cartas antes de ella.

Para simplificar, si se inicia con esta distribución de frecuencias:

A  0.1
B  0.3
C  0.4
D  0.2

Su tabla de frecuencia acumulativa sería:

A  0.1
B  0.4 (= 0.1 + 0.3)
C  0.8 (= 0.1 + 0.3 + 0.4)
D  1.0 (= 0.1 + 0.3 + 0.4 + 0.2)

Ahora generar un número aleatorio entre 0 y 1 y ver dónde en esta lista que se encuentra número. Elegir la letra que tiene la frecuencia acumulada más pequeño más grande que su número al azar. Algunos ejemplos:

Digamos que usted escoge al azar 0.612. Esta se encuentra entre 0,4 y 0,8, es decir, entre B y C, por lo que elegiría C.

Si su número al azar fue 0,039, lo que viene antes de 0,1, es decir, antes de que A, así que elige A.

Espero que tiene sentido, si no se siente libre de pedir aclaraciones!

Respondida el 27/01/2010 a las 21:20
fuente por usuario

votos
4

Ni siquiera un pseudo-código, pero un posible enfoque es el siguiente:

Permiten p1, p2, ..., pk sean las frecuencias que desea igualar.

  1. Calcular las frecuencias acumuladas: P1, P1 + P2, P1 + P2 + P3, ..., 1
  2. Generar un uniforme aleatorio (0,1) número x
  3. Comprobar qué intervalo de las frecuencias acumuladas x pertenece a: si se trata de entre, por ejemplo, p1 + .. + pi y p1 + ... + PI + P (i + 1), entonces la salida del (i + 1) carta st

Dependiendo de cómo se implemente el intervalo de los hechos, el procedimiento suele ser más eficiente si los P1, P2, ... están ordenados en orden decreciente, ya que se suele encontrar el intervalo que contiene x antes.

Respondida el 27/01/2010 a las 21:20
fuente por usuario

votos
5

Lo que quiero hacer es escalar las frecuencias relativas como números de punto flotante de tal manera que su suma es de 1,0. A continuación, me gustaría crear una matriz de los acumulados totales por carta, es decir, el número que debe ser cubierto para conseguir que la carta y todos los "de abajo" la misma. Diga la frecuencia de A es 10%, b es 2% y z es 1%; entonces su mesa sería algo como esto:

0.000 A ; from 0% to 10% gets you an A
0.100 B ; above 10% is at least a B
0.120 C ; 12% for C...
...
0.990 Z ; if your number is >= 99% then you get a Z

Entonces se genera a sí mismo un número aleatorio entre 0.0 y 1.0 y hace una búsqueda binaria en la matriz para el primer número más pequeño que su número al azar. A continuación, elija la letra en esa posición. Hecho.

Respondida el 27/01/2010 a las 21:23
fuente por usuario

votos
2

El uso de un árbol binario le da una forma agradable, limpio para encontrar la entrada correcta. A continuación, se inicia con un frequencymapa, donde las claves son los símbolos (letras en inglés), y los valores son la frecuencia de su ocurrencia. Esto se invierte, y NavigableMapse crea dónde están las llaves probabilidad acumulada, y los valores son símbolos. Eso hace que las operaciones de búsqueda fácil.

  private final Random generator = new Random();

  private final NavigableMap<Float, Integer> table = 
    new TreeMap<Float, Integer>();

  private final float max;

  public Frequency(Map<Integer, Float> frequency)
  {
    float total = 0;
    for (Map.Entry<Integer, Float> e : frequency.entrySet()) {
      total += e.getValue();
      table.put(total, e.getKey());
    }
    max = total;
  }

  /** 
   * Choose a random symbol. The choices are weighted by frequency.
   */ 
  public int roll()
  {
    Float key = generator.nextFloat() * max;
    return table.higherEntry(key).getValue();
  }
Respondida el 27/01/2010 a las 22:10
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more