Processing math: 100%

1 votos

Cómo suavizar una distribución hacia un número específico

Estoy trabajando en un videojuego en el que las unidades enemigas deben ser enviadas a la pantalla en un intervalo regular, pero deben permanecer algo aleatorias. Así que digamos que tengo que ponerlos en la pantalla a un ritmo de 30 por minuto.

Actualmente elijo al azar un número entero entre [1 - 100] cada 600 ms. Si el número es 30 o menos, se envía una unidad. Si el número es mayor que 30, no se envía la unidad. Como hay 100 intervalos de 600 ms en 60 segundos, llego al objetivo de 30 unidades por minuto.

El problema es que la distribución no es tan uniforme. A veces hay periodos en los que no se envían muchas unidades, y otras veces en los que hay demasiadas.

¿Hay alguna forma de suavizar la distribución para que siga siendo aleatoria pero permita un flujo de unidades más consistente?

EDIT: He seguido los consejos de @Ross Millikan y a continuación están los resultados. Definitivamente mucho más suave usando su algoritmo.

3 unidades distribuidas aleatoriamente cada 10 ranuras ___X___X_X___XXX_____X_____X_X______XX_X_X_____XX_X_X______X__X__XX____X____X__X_____XX_X____X_XX___X___X___X___X___X__X___X_X___X_____XX_X_X__XX______XXX_________X__X__X_____XX_X______X_XX___X_X___X_X___X_X____X_____XX__X_X_X________XXX_____X____X_X_X_X___X___X_X___X__X_X____X____XX_X_____XX_____X____X___XX______XX_X_X____X___X____X_X_X____X__X__X__X____XX__XX___X_______X__X_XX______X_X____X__X_X_X_X_X_____X___X__X____X___XX___X____X_XX_X___X___X_X______XX__X_X_____X______XX_X__X_X_________XX_X____X_X_X_XX___X_____X_X__X___X_____X__X_X_____XX_X_X_X_____X____X___XX__X_X_____X___X_X__X_X_X________XX___X_____X__XX__X__X__X____X__X___XX_______XXX_______XXX_X__X________X___XXX____XX_______X_X__X__XX____X__X__X____X_____XX_X_____X_XX___X__X___X___X_X_X____X__X____X__X__X__X_X___XX______X___XX______X_XX____XX_____X_X____XX__X_X____X__XX___X_____X___X__X___X__X_X__X___XX____X___X_X_____X____XX_X______X_XX__X_____X_X______XX___X_X___XX_____XX__X__X_____X___X_X__X___X_XX____X_____XX__XXX_______

30 de 100 posibilidades de una unidad en cada ranura X__XX___X__XXX___XX_XX__X_______X_XX_____X_XX_X_______X__X_XX_____________X___X___X______X_X__XX____X____X___XX_X_XX___XX______X________X__X______X_________________X___X____X__________XX__X________XX__X_______X_XX_X__XX_X_X_XXX__________X____X____________X__X______XX__XXXXXX_X_____X______X___XXX__X_XX__XX_X__X____X___XXX__X_X__XX____XX____X___XX_______X______X__X_XX_____XX_X__XX_XXX__XXX_____XX___XXXXX___X_XXX_____X_X_____X__X__XX_________XXX_______X___XX___XX_X____XX__XX___X___XX_____X_______X__________X_________X_____________XX___XX__X_X_X___X_XXX_______XXXX_X_XX__X_X___X______XX_______XXX______X_X_X____X____X_X___X_XXX_XXX_X__X___XX___X____X_____X_X_X__X_____________X_X______X_XX_____XXX_____XXX___X________X____X_X___X_____X_X_X___XXXX________X____X__X__X__X___________X______XXX____X__X______X___XX_XX__________XXX_____X__X______XX_XX___X____XXXX______X___X______X____X__X___X__X______X_XX__X____X__XX_XX_____X____XX______X___X_X___X_X_____X__X__XX__XX_XX_X__XXX_X_X___X___X___X___X_X__

A continuación se muestra el código java. Como tengo que calcular estas cosas entre fotogramas en un videojuego, me alejo de las matemáticas decimales. Así que toda la implementación se hace usando int's.

public static void main(String[] args) throws InterruptedException {
    nonUniformDispatch();
    uniformDispatch();
}

static void nonUniformDispatch() throws InterruptedException {
    Random rand = new Random();
    double it = 1_000;
    int goal = 30;
    int dispatches = 0;
    for (int i = 0; i < it; i++) {
        if (goal > rand.nextInt(100)) {
            dispatches++;
            System.out.print("X");
        } else {
            System.out.print("_");
        }
    }
    System.out.println("\n\ndispatches = " + dispatches);
}

static void uniformDispatch() throws InterruptedException {
    int totalUnits = 3;
    Random rand = new Random();
    double it = 1_000;
    int dispatches = 0;
    int totalSlots = 10;
    int unitsRemaining = totalUnits;
    int slotsRemaining = totalSlots;
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < it; i++) {
//            System.out.println("slotsRemaining = " + slotsRemaining + ", unitsRemaining = " + unitsRemaining);
        if (slotsRemaining <= unitsRemaining) {
            dispatches++;
            unitsRemaining--;
            sb.append("X");
        } else if (unitsRemaining > 0) {
            int x = (unitsRemaining * 100) / slotsRemaining;
            if (x > rand.nextInt(100)) {
                dispatches++;
                unitsRemaining--;
                sb.append("X");
//                    System.out.println("x = " + x + ", hit");
            } else {
                sb.append("_");
//                    System.out.println("x = " + x + ", miss");
            }
        } else {
            sb.append("_");
//                System.out.println("miss");
        }
        slotsRemaining--;
        if (slotsRemaining == 0) {
            slotsRemaining = totalSlots;
            unitsRemaining = totalUnits;
        }
    }
    System.out.println(sb.toString());
    System.out.println("\n\ndispatches = " + dispatches);
    TimeUnit.SECONDS.sleep(10);
}

1voto

Shabaz Puntos 403

Podría tomar intervalos de tiempo más largos. Si se toma un intervalo de 6 segundos quiere una media de 3 unidades por intervalo. Ahora toma un número al azar 1 a 5 para el número real que va a despachar, luego elija esa cantidad de veces al azar en el intervalo para las horas exactas en que los despacha.

1voto

Ashley Steel Puntos 405

¿Qué tal si planeas despachar exactamente una unidad en cada intervalo de tiempo de 2 segundos utilizando el generador de números aleatorios para determinar con precisión cuándo se despacha la unidad?

De este modo, nunca habrá más de dos unidades enviadas simultáneamente y el tiempo entre envíos nunca será superior a 4 segundos.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X