1S Tのランダムバイナリーベクター私はK
はEigen
マトリックス(寸法pxp
)であり、es
が1Sとpx1
ランダムバイナリーベクターであるK*es
を計算します。固有:
例えばp=5
とt=2
可能であればes
が... [1,0,1,0,0]'
または[0,0,1,1,0]'
というようにである
どのように私は簡単にEigen
とes
を生成するのですか?
1S Tのランダムバイナリーベクター私はK
はEigen
マトリックス(寸法pxp
)であり、es
が1Sとpx1
ランダムバイナリーベクターであるK*es
を計算します。固有:
例えばp=5
とt=2
可能であればes
が... [1,0,1,0,0]'
または[0,0,1,1,0]'
というようにである
どのように私は簡単にEigen
とes
を生成するのですか?
あなたはEigenを使用しています。どの行列タイプを使用しているのかよく分かりませんが、クラスEigen::MatrixXd
に行く予定です。
何をする必要がある:
次のコードではこのトリックを行うべきですが、他の方法で実装することもできます。
//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;
}
t
がp
に近い場合には、ライアンの方法はt
乱数よりもはるかに多くを生成する必要があります。このパフォーマンスの劣化を避けるために、あなたは
が均一に生成するには、次の手順
によって
を配布されている[0、P)からt
異なる番号を見つけ、あなたの元の問題を解決できますt
均一に分布した乱数idx[t]
[0、p-t + 1]
ソートこれらの数字
idx[i]+i, i=0,...,t-1
idx[t]
は結果である
コード:私はstd::vector
、Egien::Map
とstd::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;
}
私の答えを見てください – justHelloWorld
。
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);
多分私は間違っていますが、このソリューションは以前のものよりもエレガントで効率的です。
良い見えます。シャッフルはO(n)で、ソートよりも優れています。しかし、あなたは、tよりむしろp個の乱数を生成する必要があります。 10や3のような固定数をpやtのような変数名に置き換えて読みやすくすることができますか? VectorXiは同じことをすることができるので、std :: vectorは必要ありません。 – kangshiyin
申し訳ありません。私は 'p'と' t'で数字を置き換えました。とにかく、 'std :: shuflle'を' Eigen :: VectorXi'(私は標準的なイテレータが必要です)や 'std :: fill_n'を使うことができないと確信しています。私が間違っている? – justHelloWorld
ポインタはイテレータです。私がstd :: sortと呼ぶ方法を見てください – kangshiyin
私の答えを見てください – justHelloWorld