web-dev-qa-db-fra.com

Génération de nombres aléatoires uniques (entiers) entre 0 et 'x'

J'ai besoin de générer un ensemble d'entiers uniques (pas de doublons), et entre 0 et un nombre donné.

C'est:

var limit = 10;
var amount = 3;

Comment puis-je utiliser Javascript pour générer 3 nombres uniques entre 1 et 10?

47
benhowdle89

Utilisez les méthodes de base Math:

  • Math.random() renvoie un nombre aléatoire compris entre 0 et 1 (y compris 0, à l'exclusion de 1).
  • Multipliez ce nombre par le nombre le plus élevé souhaité (par exemple 10)
  • Autour de ce nombre

    Math.floor(Math.random()*10) + 1
    

Exemple:

//Example, including customisable intervals [lower_bound, upper_bound)
var limit = 10,
    amount = 3,
    lower_bound = 1,
    upper_bound = 10,
    unique_random_numbers = [];

if (amount > limit) limit = amount; //Infinite loop if you want more unique
                                    //Natural numbers than exist in a
                                    // given range
while (unique_random_numbers.length < limit) {
    var random_number = Math.floor(Math.random()*(upper_bound - lower_bound) + lower_bound);
    if (unique_random_numbers.indexOf(random_number) == -1) { 
        // Yay! new random number
        unique_random_numbers.Push( random_number );
    }
}
// unique_random_numbers is an array containing 3 unique numbers in the given range
70
Rob W
Math.floor(Math.random() * (limit+1))

Math.random() génère un nombre à virgule flottante compris entre 0 et 1, Math.floor() l'arrondit à un entier.

En le multipliant par un nombre, vous créez effectivement la plage 0..number-1. Si vous souhaitez le générer dans une plage de num1 À num2, Faites:

Math.floor(Math.random() * (num2-num1 + 1) + num1)

Pour générer plus de nombres, utilisez simplement une boucle for et placez les résultats dans un tableau ou écrivez-les directement dans le document.

19
Llamageddon
function generateRange(pCount, pMin, pMax) {
    min = pMin < pMax ? pMin : pMax;
    max = pMax > pMin ? pMax : pMin;
    var resultArr = [], randNumber;
    while ( pCount > 0) {
        randNumber = Math.round(min + Math.random() * (max - min));
        if (resultArr.indexOf(randNumber) == -1) {
            resultArr.Push(randNumber);
            pCount--;
        }
    }
    return resultArr;
}

Selon la plage nécessaire, la méthode de retour de l'entier peut être modifiée en: ceil (a, b], round [a, b], floor = [a, b), car (a, b) consiste à ajouter 1 à min avec plancher.

6
Bakudan
Math.floor(Math.random()*limit)+1
4
Pål Brattberg
for(i = 0;i <amount; i++)
{
    var randomnumber=Math.floor(Math.random()*limit)+1
    document.write(randomnumber)
}
2
Neeta

Voici un autre algorithme pour garantir que les nombres sont uniques:

  1. générer un tableau de tous les nombres de 0 à x
  2. mélangez le tableau afin que les éléments soient dans un ordre aléatoire
  3. choisissez le premier n

Par rapport à la méthode de génération de nombres aléatoires jusqu'à ce que vous en obteniez un unique, cette méthode utilise plus de mémoire, mais elle a un temps d'exécution plus stable - les résultats sont garantis d'être trouvés en temps fini. Cette méthode fonctionne mieux si la limite supérieure est relativement basse ou si la quantité à prendre est relativement élevée.

Ma réponse utilise la bibliothèque Lodash pour plus de simplicité, mais vous pouvez également implémenter l'algorithme décrit ci-dessus sans cette bibliothèque.

// assuming _ is the Lodash library

// generates `amount` numbers from 0 to `upperLimit` inclusive
function uniqueRandomInts(upperLimit, amount) {
    var possibleNumbers = _.range(upperLimit + 1);
    var shuffled = _.shuffle(possibleNumbers);
    return shuffled.slice(0, amount);
}
2
Rory O'Kane

Quelque chose comme ça

var limit = 10;
var amount = 3;
var nums = new Array();

for(int i = 0; i < amount; i++)
{
    var add = true;
    var n = Math.round(Math.random()*limit + 1;
    for(int j = 0; j < limit.length; j++)
    {
        if(nums[j] == n)
        {
            add = false;
        }
    }
    if(add)
    {
        nums.Push(n)
    }
    else
    {
        i--;
    }
}
2
Ash Burlaczenko

Comme indiqué, la réponse acceptée est fausse. Voici un générateur de nombres de puces non répétitif avec pratiquement aucun impact sur la mémoire et aucun problème de O(n)) qui est bon pour 10 000 000 de numéros.

Voici un plunkr démontrant le port javascript ci-dessous du générateur aléatoire non répétitif trouvé ici github.com/preshing/RandomSequence .

var RandomSequenceOfUnique = (function() {      
  function RandomSequenceOfUnique(seedBase, seedOffset) {
    var prime = 4294967291,
        residue,
        permuteQPR = function(x) {
      if (x >= prime)
        return x; 
      residue = (x * x) % prime;
      return (x <= prime / 2) ? residue : prime - residue;
    }

    this.next = function() {
      return permuteQPR((permuteQPR(this.index++) + this.intermediateOffset) ^ 0x5bf03635);
    }

    this.index = permuteQPR(permuteQPR(seedBase) + 0x682f0161);
    this.intermediateOffset = permuteQPR(permuteQPR(seedOffset) + 0x46790905);
  }
  return RandomSequenceOfUnique;
}());

Construisez une instance et générez un nombre:

var generator = new RandomSequenceOfUnique(Date.now(), parseInt(Math.random() * 10000));

Utilisation du générateur:

 var num = generator.next();

Voici un article expliquant les mathématiques derrière le générateur, Comment générer une séquence d'entiers aléatoires uniques

1
RamblinRose
var randomNums = function(amount, limit) {
var result = [],
    memo = {};

while(result.length < amount) {
    var num = Math.floor((Math.random() * limit) + 1);
    if(!memo[num]) { memo[num] = num; result.Push(num); };
}
return result; }

Cela semble fonctionner, et sa recherche constante de doublons.

1
Patrik Torkildsen
/**
 * Generates an array with numbers between
 * min and max randomly positioned.
 */
function genArr(min, max, numOfSwaps){
  var size = (max-min) + 1;
  numOfSwaps = numOfSwaps || size;
  var arr = Array.apply(null, Array(size));

  for(var i = 0, j = min; i < size & j <= max; i++, j++) {
    arr[i] = j;
  }

  for(var i = 0; i < numOfSwaps; i++) {
    var idx1 = Math.round(Math.random() * (size - 1));
    var idx2 = Math.round(Math.random() * (size - 1));

    var temp = arr[idx1];
    arr[idx1] = arr[idx2];
    arr[idx2] = temp;
  }

  return arr;
}

/* generating the array and using it to get 3 uniques numbers */
var arr = genArr(1, 10);
for(var i = 0; i < 3; i++) {
  console.log(arr.pop());
}
1
Rayron Victor