随机地用特征置换矩阵的行/列

时间:2013-04-07 03:27:42

标签: c++ random matrix permutation eigen

我正在使用Eigen而且我有一个矩阵:

MatrixXi x = MatrixXi::Random(5);

我想使用随机抽取的排列随机置换行和列(对于行和列只有一个排列),即如果我有一个发送索引的排列[0,1,2,3,4] ] - > [3,4,2,1,0]比我想用相同的排列重新排序行和列。

第1部分:我无法在线找到PermutationMatrix的示例,而且我无法弄清楚语法。

第2部分:如何获得随机置换的索引向量传递给它?也许std :: random_shuffle?

更新

这是一种(可能效率低下)获得一组混乱索引的方法:

std::vector<int> perm;
for (int i=0; i<5; ++i) {
    perm.push_back(i);
}

std::random_shuffle(perm.begin(), perm.end());

所以现在的问题是我如何重新排序我的矩阵x,以便它的行/列按perm排序?

更新2:

越来越近,这有效(想法来源:cplusplus.com):

int myrandom (int i) { return std::rand()%i;}

PermutationMatrix<Dynamic,Dynamic> perm(5);

perm.setIdentity();
for (int i=dim-1; i>0; --i) {
    swap (perm.indices()[i],perm.indices()[myrandom(i+1)]);
}

cout << "original x" << x << endl << endl;
cout << "permuted x" << perm * x * perm << endl << endl;

任何人都知道如何使用random_shuffle做到这一点? (参见以下无效的尝试。)

(奖励:如果烫发是1e4 x 1e4矩阵,有关perm * x * perm是否有效的任何想法?)

2 个答案:

答案 0 :(得分:9)

使用std :: random_shuffle非常好,那么你必须使用PermutationMatrix:

PermutationMatrix<Dynamic,Dynamic> perm(size);
perm.setIdentity();
std::random_shuffle(perm.indices().data(), perm.indices().data()+perm.indices().size());
A_perm = A * perm; // permute columns
A_perm = perm * A; // permute rows

答案 1 :(得分:0)

如此处所述:Stackoverflow

如果可以使用C ++ 11,建议不要使用srand()random_shuffle()来实现;相反,您应该将<random>库与std::shuffle一起使用。

首先,应尽可能避免使用rand。除了通常它不是一个很好的pRNG之外,由于共享状态,它在线程安全性方面也存在问题。 <random>库通过为程序员提供对pRNG状态的显式控制并提供具有保证的性能,大小和质量特征的多个选项,解决了这两个问题。

第二,实际上并未指定random_shuffle使用rand,因此从理论上讲,使用srand进行播种以达到所需效果是合法的。为了获得random_shuffle的保证结果,您必须编写自己的生成器。移至shuffle可以解决此问题,因为您可以直接使用标准引擎。

#include <random>       //seed generation
#include <algorithm>    //shuffle()

int main() {

std::random_device r;
std::seed_seq rng_seed{r(), r(), r(), r(), r(), r(), r(), r()};

//create random engines with the rng seed
std::mt19937 eng1(rng_seed);

//create permutation Matrix with the size of the columns
Eigen::PermutationMatrix<Eigen::Dynamic, Eigen::Dynamic> permX(inputX.cols());
permX.setIdentity();
std::shuffle(permX.indices().data(), permX.indices().data()+permX.indices().size(), eng1);
inputX = inputX * permX;   //shuffle column wise

}

如果您想混排行,请使用inputX.rows()来代替置换矩阵。并改用inputX = permX * inputX