N以下の重複しない乱数(整数)の生成

C++

良い方法かは分からないけどiotaやeraseを使った例を見つけたのでメモ.やり方は一旦iotaで[0,1,...max]の配列を作って,それをシャッフルして,eraseで必要ない部分を消す.eraseはイテレータを2つ渡すと,開始位置から終了位置の1つ前までを消去できる.

#include <random>
#include <vector>

std::random_device rnd;
std::mt19937 mt(rnd());

std::vector<int> generateUniqueRandomIntegers(size_t max, int num)
{
  std::vector<int> v(max+1); // CAUTION "max+1" !!
  std::iota(v.begin(), v.end(), 0);
  std::shuffle(v.begin(), v.end(), mt);
  v.erase(v.begin()+num, v.end());
  return v;
}

Python

同じやり方をpythonでやる場合.sampleでシーケンスからの重複しないサンプリングが出来るのでそれを使う.

import random
def generateUniqueRandomNumbers(max, num):
    return random.sample(xrange(max+1), num)