7

我正在使用 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 是否有效的任何想法?)

4

2 回答 2

14

使用 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
于 2013-04-07T18:34:39.990 回答
0

如此处所述:Stackoverflow

如果您可以使用 C++11,我建议您在不使用srand()and 的情况下实现它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改为使用。

于 2020-05-25T07:33:12.080 回答