ti-enxame.com

Gerando números aleatórios exclusivos (inteiros) entre 0 e 'x'

Preciso gerar um conjunto de números inteiros exclusivos (sem duplicata) e entre 0 e um determinado número.

Isso é:

var limit = 10;
var amount = 3;

Como posso usar o Javascript para gerar 3 números exclusivos entre 1 e 10?

47
benhowdle89

Use os métodos básicos Math:

  • Math.random() retorna um número aleatório entre 0 e 1 (incluindo 0, excluindo 1).
  • Multiplique esse número pelo número mais alto desejado (por exemplo, 10)
  • Arredondar este número

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

Exemplo:

//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() gera um número de ponto flutuante entre 0 e 1, Math.floor() arredonda para um número inteiro.

Ao multiplicá-lo por um número, você efetivamente faz o intervalo 0..number-1. Se você deseja gerá-lo no intervalo de num1 a num2, faça:

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

Para gerar mais números, basta usar um loop for e colocar os resultados em uma matriz ou gravá-los diretamente no documento.

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;
}

Dependendo do intervalo necessário, o método de retornar o número inteiro pode ser alterado para: ceil (a, b], round [a, b], floor = [a, b), pois (a, b) é questão de adicionar 1 a min com o piso.

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

Aqui está outro algoritmo para garantir que os números sejam únicos:

  1. gerar uma matriz de todos os números de 0 a x
  2. embaralhe a matriz para que os elementos estejam em ordem aleatória
  3. escolha o primeiro n

Comparado ao método de gerar números aleatórios até você obter um único, esse método usa mais memória, mas possui um tempo de execução mais estável - os resultados são garantidos em tempo finito. Esse método funciona melhor se o limite superior for relativamente baixo ou se a quantidade a ser consumida for relativamente alta.

Minha resposta usa a biblioteca Lodash para simplificar, mas você também pode implementar o algoritmo descrito acima sem essa biblioteca.

// 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

Algo assim

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

Como apontado, a resposta aceita está errada. Aqui está um gerador de número psuedo que não se repete, praticamente sem impacto na memória e sem O(n) problemas, que é bom para 10.000.000 de números.

Aqui está um plunkr demonstrando a porta javascript abaixo do gerador psuedo-random não repetitivo encontrado aqui 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;
}());

Construa uma instância e gere um número:

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

Uso do gerador:

 var num = generator.next();

Aqui está um artigo explicando a matemática por trás do gerador, Como gerar uma sequência de números inteiros aleatórios únicos

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; }

Isso parece funcionar, e sua constante busca por duplicatas.

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