随机排列具有特征矩阵的行/列

Randomly permute rows/columns of a matrix with eigen

本文关键字:排列 特征 随机      更新时间:2023-10-16

我用的是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吗?(见下面的尝试失败)

(附加:如果perm是1e4 x 1e4矩阵,那么perm * x * perm是否有效?)

使用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

如下所述:

如果你可以使用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代替。