Obtenga un número aleatorio centrado en el centro

8 minutos de lectura

avatar de usuario
Darryl Huffmann

¿Es posible obtener un número aleatorio entre 1 y 100 y mantener los resultados principalmente dentro del rango de 40 a 60? Quiero decir, rara vez saldrá de ese rango, pero quiero que esté principalmente dentro de ese rango… ¿Es posible con JavaScript/jQuery?

En este momento solo estoy usando el básico Math.random() * 100 + 1.

  • es.wikipedia.org/wiki/…

    – Roko C. Bulján

    27 mayo 2015 a las 20:18

  • codetheory.in/…

    – José

    27 mayo 2015 a las 20:19

  • posible duplicado: stackoverflow.com/questions/1527803/…

    – Mahedi Sabuj

    27 mayo 2015 a las 20:26

  • Me gusta a dónde va esta pregunta, pero creo que debería ser más específica. ¿Desea una distribución Z (curva de campana), una distribución triangular o algún tipo de distribución de diente de sierra? Hay múltiples posibilidades para responder a esta pregunta en mi opinión.

    –Patrick Roberts

    27 mayo 2015 a las 20:30

  • Esto se puede hacer en javascript pero seguro que no tiene nada que ver con jQuery… 🙂

    – A. Wolff

    27 mayo 2015 a las 20:41

avatar de usuario
BlueRaja – Danny Pflughoeft

La forma más sencilla sería generar dos números aleatorios del 0 al 50 y sumarlos.

Esto da una distribución sesgada hacia 50, de la misma manera que tirar dos dados sesga hacia 7.

De hecho, al utilizar un mayor número de “dados” (como sugiere @Falco)puede hacer una aproximación más cercana a una curva de campana:

function weightedRandom(max, numDice) {
    let num = 0;
    for (let i = 0; i < numDice; i++) {
        num += Math.random() * (max/numDice);
    }    
    return num;
}

números aleatorios ponderados

JSFiddle: http://jsfiddle.net/797qhcza/1/

  • Esta es una solución fácil y rápida, que se puede ponderar fácilmente agregando más números, por ejemplo, 4 x (0-25) y le dará una buena curva de campana para la distribución.

    – Falco

    28 de mayo de 2015 a las 12:29

  • Este es un código fantástico. Creo que estoy enamorado de él. Simple, rápido, eficiente; gran respuesta. Gracias por publicar esto.

    – ruedas dentadas

    28 de mayo de 2015 a las 14:17

  • Gran respuesta, pero en caso de que alguien tenga la intención de usar esto para generar una distribución Normal, es bastante ineficiente (y necesita transformarlo para obtener la media y la desviación estándar deseadas). Una opción más eficiente sería la transformada de Box-Muller, que es bastante fácil de implementar y comprender si sabes un poco de matemáticas.

    – Brendon

    29 de mayo de 2015 a las 15:04

  • @RaziShaban Es bastante intuitivo: solo hay una combinación de lanzamientos de dados que suman 2 (solo ojos de serpiente), pero hay 6 combinaciones diferentes que suman 7 (6-1, 5-2, 4-3, 3- 4, 2-5, 1-6). Si generaliza a dados de N caras, el pico siempre es N+1.

    – Barmar

    2 jun 2015 a las 20:56

  • @RaziShaban El estudio de variables aleatorias es una parte central de las estadísticas. El hecho de que a medida que aumentamos los dados nos acerquemos a una distribución normal es el famoso Teorema del límite central.

    – Blue Raja – Danny Pflughoeft

    2 jun 2015 a las 21:03

Tiene algunas buenas respuestas aquí que brindan soluciones específicas; déjame describirte la solución general. El problema es:

  • Tengo una fuente de más o menos uniformemente números aleatorios distribuidos entre 0 y 1.
  • Deseo producir una secuencia de números aleatorios que sigan una distribución diferente.

La solución general a este problema es calcular el función cuantil de su distribución deseada, y luego aplique la función cuantil a la salida de su fuente uniforme.

La función cuantil es la inverso del integral de tu deseado función de distribución. La función de distribución es la función en la que el área bajo una parte de la curva es igual a la probabilidad de que el elemento elegido al azar esté en esa parte.

Doy un ejemplo de cómo hacerlo aquí:

http://ericlippert.com/2012/02/21/generating-random-non-uniform-data/

El código está en C#, pero los principios se aplican a cualquier idioma; debería ser sencillo adaptar la solución a JavaScript.

  • Me gusta este enfoque. Es posible que desee agregar que existe una biblioteca de JavaScript que genera distribuciones gaussianas (y otras no normales): simjs.com/random.html

    – Floris

    31 de mayo de 2015 a las 3:56

avatar de usuario
icaramba

Tomar matrices de números, etc. no es eficiente. Debe tomar una asignación que tome un número aleatorio entre 0 y 100 y se asigne a la distribución que necesita. Entonces, en su caso, podría tomar f(x)=-(1/25)x2+4x para obtener una distribución con la mayor cantidad de valores en el medio de su rango.

Distribución

  • En realidad, no sabemos qué distribución se necesita. “Principalmente 40-60” implica una curva de campana para mí.

    – Zurdo

    28 de mayo de 2015 a las 8:06

  • sí, tienes razón, tal vez necesites un mejor mapeo, pero eso es trivial

    – iCaramba

    28 de mayo de 2015 a las 8:45

  • Confío en su palabra porque esta no es mi área de especialización. ¿Podría ajustar la función y mostrar la nueva curva?

    – Zurdo

    28 de mayo de 2015 a las 8:59

  • @Lefty – Curva de campana simplificada para x entre 0 y 100 (tomado de esta pregunta): y = (Math.sin(2 * Math.PI * (x/100 - 1/4)) + 1) / 2

    – Esfinxxx

    28 de mayo de 2015 a las 12:17


  • @Sphinxxx Esa no es una curva de campana, es una curva de pecado. Una curva de campana nunca toca el eje x.

    – Blue Raja – Danny Pflughoeft

    17 de julio de 2018 a las 22:19


avatar de usuario
Creatividad bit a bit

Podría hacer algo como configurar una “oportunidad” para que el número pueda “salir de los límites”. En este ejemplo, una probabilidad del 20% de que el número sea 1-100, de lo contrario, 40-60:

$(function () {
    $('button').click(function () {
        var outOfBoundsChance = .2;
        var num = 0;
        if (Math.random() <= outOfBoundsChance) {
            num = getRandomInt(1, 100);
        } else {
            num = getRandomInt(40, 60);
        }
        $('#out').text(num);
    });
    
    function getRandomInt(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<button>Generate</button>
<div id="out"></div>

violín: http://jsfiddle.net/kbv39s9w/

Necesitaba resolver este problema hace unos años y mi solución fue más fácil que cualquiera de las otras respuestas.

Generé 3 aleatorios entre los límites y los promedié. Esto tira del resultado hacia el centro pero deja completamente posible llegar a los extremos.

  • ¿Cómo es esto mejor/diferente a la respuesta de BlueRaja? Allí, toma la suma de (2,3,… cualquier número que quieras) números aleatorios y saca el promedio. El resultado es idéntico al tuyo cuando usas un BellFactor de 3.

    – Floris

    31 de mayo de 2015 a las 3:31

  • @floris bueno, no codifico en la familia de lenguajes c, por lo que esa respuesta ni siquiera parecía estar haciendo lo mismo que mi respuesta hasta que la volví a leer ahora. Creé mi método con un poco de ensayo y error y descubrí que 3 números aleatorios era el número correcto. Además, el mío se puede hacer en una sola línea y seguir siendo fácil de entender.

    – Zurdo

    31 de mayo de 2015 a las 7:33

  • ¿En serio? ¿No crees que hay alguna similitud entre JS y C? OK, bueno, digamos que no puedo hablar NINGUNO de esos lenguajes, ni Java, que, para mí, son todos similares en comparación con los lenguajes con los que estoy familiarizado.

    – Zurdo

    31 de mayo de 2015 a las 13:41

  • Buen punto, en realidad solo me atraía el título como algo que había resuelto yo mismo y estaba bastante orgulloso de la forma en que lo hice. Nuevamente, no sabía que era una pregunta de js hasta que lo dijiste. Realmente afortunado, porque mi técnica no depende del idioma y algunas personas parecen pensar que es una respuesta útil.

    – Zurdo

    31 de mayo de 2015 a las 14:37

  • JavaScript en realidad es un lenguaje de la familia C… pero bueno.

    – Joren

    31 de mayo de 2015 a las 17:21

avatar de usuario
max890

Eso aspecto estúpido pero puedes usar rand dos veces:

var choice = Math.random() * 3;
var result;

if (choice < 2){
    result = Math.random() * 20 + 40; //you have 2/3 chance to go there
}
else {
    result = Math.random() * 100 + 1;
}

  • ¿Cómo es esto mejor/diferente a la respuesta de BlueRaja? Allí, toma la suma de (2,3,… cualquier número que quieras) números aleatorios y saca el promedio. El resultado es idéntico al tuyo cuando usas un BellFactor de 3.

    – Floris

    31 de mayo de 2015 a las 3:31

  • @floris bueno, no codifico en la familia de lenguajes c, por lo que esa respuesta ni siquiera parecía estar haciendo lo mismo que mi respuesta hasta que la volví a leer ahora. Creé mi método con un poco de ensayo y error y descubrí que 3 números aleatorios era el número correcto. Además, el mío se puede hacer en una sola línea y seguir siendo fácil de entender.

    – Zurdo

    31 de mayo de 2015 a las 7:33

  • ¿En serio? ¿No crees que hay alguna similitud entre JS y C? OK, bueno, digamos que no puedo hablar NINGUNO de esos lenguajes, ni Java, que, para mí, son todos similares en comparación con los lenguajes con los que estoy familiarizado.

    – Zurdo

    31 de mayo de 2015 a las 13:41

  • Buen punto, en realidad solo me atraía el título como algo que había resuelto yo mismo y estaba bastante orgulloso de la forma en que lo hice. Nuevamente, no sabía que era una pregunta de js hasta que lo dijiste. Realmente afortunado, porque mi técnica no depende del idioma y algunas personas parecen pensar que es una respuesta útil.

    – Zurdo

    31 de mayo de 2015 a las 14:37

  • JavaScript en realidad es un lenguaje de la familia C… pero bueno.

    – Joren

    31 de mayo de 2015 a las 17:21

avatar de usuario
Luka Krajnc

Seguro que es posible. Haz un 1-100 al azar. Si el número es

¿Ha sido útil esta solución?