2016-07-12 12 views
1

1S Tのランダムバイナリーベクター私はKEigenマトリックス(寸法pxp)であり、esが1Sとpx1ランダムバイナリーベクターであるK*esを計算します。固有:

例えばp=5t=2可能であればesが... [1,0,1,0,0]'または[0,0,1,1,0]'というようにである

どのように私は簡単にEigenesを生成するのですか?

答えて

0

あなたはEigenを使用しています。どの行列タイプを使用しているのかよく分かりませんが、クラスEigen::MatrixXdに行く予定です。

何をする必要がある:

  • がすべて0
  • は0-pの間にある、0から1に反転するランダムスポットを選択し、その場所が一意であることを確認します1xp行列を作成します。 。

次のコードではこのトリックを行うべきですが、他の方法で実装することもできます。

//Your p and t 
int p = 5; 
int t = 2; 

//px1 matrix 
MatrixXd es(1, p); 

//Initialize the whole 1xp matrix 
for (int i = 0; i < p; ++i) 
     es(1, i) = 0; 

//Get a random position in the 1xp matrix from 0-p 
for (int i = 0; i < t; ++i) 
{ 
    int randPos = rand() % p; 

    //If the position was already a 1 and not a 0, get a different random position 
    while (es(1, randPos) == 1) 
     randPos = rand() % p; 

    //Change the random position from a 0 to a 1 
    es(1, randPos) = 1; 
} 
+0

私の答えを見てください – justHelloWorld

0

tpに近い場合には、ライアンの方法はt乱数よりもはるかに多くを生成する必要があります。このパフォーマンスの劣化を避けるために、あなたは

が均一に生成するには、次の手順

  1. によって

を配布されている[0、P)からt異なる番号を見つけ、あなたの元の問題を解決できますt均一に分布した乱数idx[t] [0、p-t + 1]

  • ソートこれらの数字

  • idx[i]+i, i=0,...,t-1idx[t]は結果である

  • コード:私はstd::vectorEgien::Mapstd::shuffleの組み合わせであっても、より良い解決策、思い付いた

    VectorXi idx(t); 
    VectorXd es(p); 
    es.setConstant(0); 
    
    for(int i = 0; i < t; ++i) { 
        idx(i) = int(double(rand())/RAND_MAX * (p-t+1)); 
    } 
    
    std::sort(idx.data(), idx.data() + idx.size()); 
    
    for(int i = 0; i < t; ++i) { 
        es(idx(i)+i) = 1.0; 
    } 
    
    +0

    私の答えを見てください – justHelloWorld

    2

    std::vector<int> esv(p,0); 
    std::fill_n(esv.begin(),t,1); 
    Eigen::Map<Eigen::VectorXi> es (esv.data(), esv.size()); 
    std::random_device rd; 
    std::mt19937 g(rd()); 
    std::shuffle(std::begin(esv), std::end(esv), g); 
    

    このソリューションは、効率的なメモリ(Eigen::Map以来esvをコピーしない)であり、我々は(この場合のように)es数回入れ替えたい場合は、その後、私たちはstd::shuffle(std::begin(esv), std::end(esv), g);

    を繰り返す必要があることは大きな利点を持っています

    多分私は間違っていますが、このソリューションは以前のものよりもエレガントで効率的です。

    +0

    良い見えます。シャッフルはO(n)で、ソートよりも優れています。しかし、あなたは、tよりむしろp個の乱数を生成する必要があります。 10や3のような固定数をpやtのような変数名に置き換えて読みやすくすることができますか? VectorXiは同じことをすることができるので、std :: vectorは必要ありません。 – kangshiyin

    +0

    申し訳ありません。私は 'p'と' t'で数字を置き換えました。とにかく、 'std :: shuflle'を' Eigen :: VectorXi'(私は標準的なイテレータが必要です)や 'std :: fill_n'を使うことができないと確信しています。私が間違っている? – justHelloWorld

    +0

    ポインタはイテレータです。私がstd :: sortと呼ぶ方法を見てください – kangshiyin