【问题标题】:Generating inverse permutation生成逆排列
【发布时间】:2013-01-03 23:39:17
【问题描述】:

假设给定一个向量 foo,我们必须暂时置换它(排序或重新排序),在它的基础上计算一些向量 bar,最后置换将foobar 都返回到foo 的原始顺序——这意味着逆排列:

foo <- c(1, 7, 3, 5, 2)
o <- order(foo)
foo <- foo[o] # Now foo is permuted, and sorted: foo == 1 2 3 5 7
bar = 2 * foo # bar == 2 4 6 10 14

这里应该是你的答案,这样我们就有了以下期望的最终值:

foo == 1 7 3 5 2
bar == 2 14 6 10 4

如何做到这一点?

请不要回复:“你可以做bar = 2 * foo而不是置换它”。这只是一个简单的例子。在某些情况下,我们必须对foo 进行排序以提高效率(快速搜索它)或类似的东西。

【问题讨论】:

    标签: r vector permutation


    【解决方案1】:

    这会起作用,因为[order(o)] 反转了[o] 的操作:

    foo <- c(1, 7, 3, 5, 2)
    o <- order(foo)
    
    (foo[o]*2)[order(o)]
    # [1]  2 14  6 10  4
    

    为了表明它更普遍地工作:

    testAlgorithm <- function(foo) {
        o <- order(foo)
        identical(foo, foo[o][order(o)])
    }
    
    x <- c(1, 7, 3, 5, 2)
    y <- c(1,2,5,7,4, 99, 88, 3, 0)
    z <- sample(1000)                  ## (No ties)
    zz <- sample(1000, replace=TRUE)   ## (Many ties)
    all(sapply(list(x,y,z,zz), testAlgorithm))
    [1] TRUE
    

    【讨论】:

    • 证明:1) foo[o][order(o)]foo[o[order(o)]] 相同,通过 [ 运算符的关联性。 2) o[order(o)]seq_along(o) 相同。所以我们有foo[o][order(o)] &lt;=&gt; foo[o[order(o)]] &lt;=&gt; foo[seq_along(foo)] &lt;=&gt; foo
    • @flodel -- 是的。真的只是 the associativity of permutation 的另一种形式。
    【解决方案2】:

    要恢复原始订单,请使用order(o)

    > (foo[o]*2)[order(o)]
    [1]  2 14  6 10  4
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-06
      • 1970-01-01
      • 2019-10-22
      • 1970-01-01
      • 2020-04-04
      • 1970-01-01
      • 2014-03-15
      相关资源
      最近更新 更多