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

问题描述 投票:6回答:2

我正在使用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进行重新排序,以便其行/列按烫发进行排序?

更新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是否有效的任何想法?]

c++ random matrix permutation eigen
2个回答
12
投票

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

0
投票

如此处所述:bames53的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()

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);
auto eng2 = eng1;

//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

© www.soinside.com 2019 - 2024. All rights reserved.