web-dev-qa-db-ja.com

0と 'x'の間の一意の乱数(整数)を生成する

一意の(重複しない)整数のセットを生成する必要があり、0から指定された数値までの間です。

あれは:

var limit = 10;
var amount = 3;

Javascriptを使用して、1から10までの3つの一意の番号を生成するにはどうすればよいですか?

47
benhowdle89

基本的なMathメソッドを使用します。

  • Math.random()は、0から1(1を除く0を含む)の間の乱数を返します。
  • この数値に必要な最高の数値(10など)を掛けます
  • この数を丸める

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

例:

//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()は、0〜1の浮動小数点数を生成します。Math.floor()は、整数に切り捨てます。

それに数値を掛けることで、範囲_0..number-1_を効果的に作成できます。 _num1_から_num2_の範囲で生成する場合は、次のようにします。

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

さらに数を生成するには、forループを使用して結果を配列に入れるか、ドキュメントに直接書き込みます。

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

必要な範囲に応じて、整数を返す方法を次のように変更できます。 ceil (a、b]、 round [a、b]、 floor = [a、b)、(a、b)は、床の最小値に1を加算することです。

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

番号が一意であることを確認する別のアルゴリズムを次に示します。

  1. 0からxまでのすべての数値の配列を生成します
  2. 要素がランダムな順序になるように配列をシャッフルします
  3. 最初のnを選択

一意の乱数を取得するまで乱数を生成する方法と比較すると、この方法はより多くのメモリを使用しますが、実行時間がより安定しています。結果は有限時間で見つかることが保証されています。この方法は、上限が比較的低い場合、または摂取量が比較的多い場合に効果的です。

私の答えは、簡単にするために Lodash ライブラリを使用していますが、そのライブラリなしで上記のアルゴリズムを実装することもできます。

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

このようなもの

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

指摘したように、受け入れられた答えは間違っています。これは、メモリに実質的に影響を与えず、10,000,000の数字に適したO(n)の問題のない、繰り返しのない擬似番号ジェネレーターです。

ここにある plunkr は、ここにある繰り返しのない擬似乱数ジェネレーターのJavaScriptポートを示しています 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;
}());

インスタンスを作成し、数値を生成します。

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

ジェネレーターの使用:

 var num = generator.next();

ジェネレーターの背後にある数学を説明する記事があります 一意のランダムな整数のシーケンスを生成する方法

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

これは機能しているようで、重複を常に検索します。

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