2012-02-18 19 views
16

n要素を含むベクトルを持っています。私は、反復せずにベクトルからランダムにm要素のサブセットを選択する必要があります。これを行う最も効率的な方法は何ですか?私は自分のコードでこれを何千回も実行する必要があります。n個の要素を含むベクトルからm個の要素をランダムに選択します。

rand()を使用して、0nの間の乱数kを生成することです。次にベクトルのk番目の要素を選択し、std::setに挿入します。セットのサイズがmに等しくなるまでこれを続けます。私は今セットがn要素のセットから無作為に選ばれたmのユニークな要素を含んでいることを保証しています。

その他の解決策はありますか?

ありがとうございました。

+4

'STDの操作を行います。 :random_shuffle() 'を呼び出し、最初に' m'要素を取り出します。 – jrok

+0

@jrok:シンプルでは、​​ 'm'が' n'よりずっと小さいときは非常に非効率です。 –

+0

[単一のランダムな値の組み合わせを選択するアルゴリズムの可能な重複?](http://stackoverflow.com/questions/2394246/algorithm-to-select-a-single-random-combination-of-values) –

答えて

29

あなたはFisher-Yates shuffle(M回の反復後に停止)したい:http://ideone.com/3A3cv

template<class BidiIter > 
BidiIter random_unique(BidiIter begin, BidiIter end, size_t num_random) { 
    size_t left = std::distance(begin, end); 
    while (num_random--) { 
     BidiIter r = begin; 
     std::advance(r, rand()%left); 
     std::swap(*begin, *r); 
     ++begin; 
     --left; 
    } 
    return begin; 
} 

デモ。これは、std::random_shuffleよりもはるかに高速です。セットから数個の乱数しか必要ない場合、N==Mであってもほぼ同じ速度でなければなりません。

+0

@バールありがとう!私は無作為に100要素だけを選ぶ必要がある私のベクトルに100万要素を持っています。これはまさに私が探していたものです。 – Vinay

+0

コードをありがとう!完璧に動作します。 – Danvil

+2

rand():http://codereview.stackexchange.com/questions/39001/fisher-yates-modern-shuffle-algorithm – dani

3

あなたがこれを行うことが一つの方法は、ベクトルのすべてのインデックスのリストを作成し、それらをシャッフルして、選択したオブジェクトのインデックスであることを最初nを取ることです。

struct rangegenerator { 
    rangegenerator(int init) : start(init) { } 

    int operator()() { 
     return start++; 
    } 

    int start; 
}; 

vector<T> numbers; // this is filled somewhere else 

vector<int> indices(numbers.size()); 

generate(begin(indices), end(indices), rangegenerator(0)); 

random_shuffle(begin(indices), end(indices)); 

// then take the first n elements of indices and use them as indices into numbers 
+3

を参照してください。 'm'が' n'よりずっと小さい場合、これは非常に非効率的です。すべての 'm '(' m'は 'n'より小さい)に対してこれよりも速い答えを思いつくのは難しくありません。 –

+0

@セス:Mooに同意しなければなりません。これはおそらく、与えられたタスクを達成するための最悪の方法の1つです。OPが答えとしてマークした理由は不明です。正解は明らかにバーの答えです。 –

+1

@ JaredKrumsie OPは "他の可能な解決策"を求めましたが、私が書いたことは間違いなく可能な解決策です。答えが正しくない唯一の方法は、まったく動作しない場合です。 –

関連する問題