【问题标题】:Randomly permute rows/columns of a matrix with eigen用特征随机排列矩阵的行/列
【发布时间】:2013-03-29 07:45:10
【问题描述】:

我正在使用 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 是否有效?)

【问题讨论】:

    标签: c++ random matrix permutation eigen


    【解决方案1】:

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

    【讨论】:

    • 谢谢 ggael。这很接近,但 perm.indices() 没有迭代器 AFAIK。我收到错误:‘Eigen::PermutationMatrix::IndicesType’没有名为‘begin’的成员。我用半生不熟的方式编辑了我的问题,但据我所知,工作代码,但我仍然想弄清楚如何让它使用 random_shuffle!
    • 对于在 Google 上找到此内容的任何人来说都是相当的更新:如果您想对需要使用的行和列应用相同的排列:perm.transpose() * x * perm
    • 这不是一种低效的方法吗?我认为置换行比乘法矩阵要快得多,尤其是在它们很大的情况下。
    • 这正是 PermutationMatrix::operator* 正在做的事情!如果你写:A = perm * A,它甚至可以就地工作。
    • 由于某种原因,“就地”操作符比非就地操作符慢很多.. :|
    【解决方案2】:

    如此处所述:Stackoverflow:

    如果您可以使用 C++11,我建议您在不使用 srand()random_shuffle() 的情况下实现它;相反,您应该将&lt;random&gt; 库与std::shuffle 一起使用。

    首先,如果可能,应避免使用rand。除了它通常不是一个很好的 pRNG 之外,由于共享状态,它还存在线程安全问题。 &lt;random&gt; 库通过为程序员提供对 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

    【讨论】:

      猜你喜欢
      • 2017-08-26
      • 2017-08-23
      • 2011-09-29
      • 2015-08-24
      • 1970-01-01
      • 2018-08-11
      • 2017-02-03
      • 2022-11-08
      相关资源
      最近更新 更多