【问题标题】:sapply to create unique permutations without overlapsapply 创建不重叠的独特排列
【发布时间】:2021-08-14 19:12:59
【问题描述】:

我正在尝试创建一个执行以下操作的函数:

input: 1:3
output: 1 2 3 2 3 1 3 1 2 

通过这种方式,我想生成输入的所有排列,其中每个给定索引的元素永远不会重叠

1 2 3 and  2 3 1 and 3 1 2

我已经做到了:

sapply(1:4,(function(i){paste0(i,i+1,i+2,i+3)}))

但这不会产生我正在寻找的输出。

【问题讨论】:

标签: r


【解决方案1】:

如果我理解正确

  combinat::permn(x = 1:3)

[[1]]
[1] 1 2 3

[[2]]
[1] 1 3 2

[[3]]
[1] 3 1 2

[[4]]
[1] 3 2 1

[[5]]
[1] 2 3 1

[[6]]
[1] 2 1 3

【讨论】:

    【解决方案2】:

    您还可以使用 gtools 包中的 permutations 函数:

    permutations(n=3,r = 3,v = 1:3)
    

    输出是

         [,1] [,2] [,3]
    [1,]    1    2    3
    [2,]    1    3    2
    [3,]    2    1    3
    [4,]    2    3    1
    [5,]    3    1    2
    [6,]    3    2    1
    

    【讨论】:

      【解决方案3】:

      阅读您的评论看起来您可以使用matrix 生成想要的数字,例如:

      n <- 2
      matrix(1:n, n+1, n)[1:n,]
      #     [,1] [,2]
      #[1,]    1    2
      #[2,]    2    1
      
      n <- 3
      matrix(1:n, n+1, n)[1:n,]
      #     [,1] [,2] [,3]
      #[1,]    1    2    3
      #[2,]    2    3    1
      #[3,]    3    1    2
      
      n <- 4
      matrix(1:n, n+1, n)[1:n,]
      #     [,1] [,2] [,3] [,4]
      #[1,]    1    2    3    4
      #[2,]    2    3    4    1
      #[3,]    3    4    1    2
      #[4,]    4    1    2    3
      
      n <- 5
      matrix(1:n, n+1, n)[1:n,]
      #     [,1] [,2] [,3] [,4] [,5]
      #[1,]    1    2    3    4    5
      #[2,]    2    3    4    5    1
      #[3,]    3    4    5    1    2
      #[4,]    4    5    1    2    3
      #[5,]    5    1    2    3    4
      

      我使用expand.gridbase 中生成all 排列的第一个答案是:

      x <- 1:3
      do.call(expand.grid, lapply(x, \(i) x)) ->.
        .[apply(., 1, anyDuplicated) == 0,]
      #   Var1 Var2 Var3
      #6     3    2    1
      #8     2    3    1
      #12    3    1    2
      #16    1    3    2
      #20    2    1    3
      #22    1    2    3
      

      【讨论】:

      • 完美!谢谢!
      【解决方案4】:

      我假设问题是给定 n 并且我们想要一个包含 1:n 的向量,后跟 1:n 的每个排列,其中每个排列的第 i 个元素不是 i。我们生成所有排列,然后针对 1:n 中的所有 i 消除第 i 个位置等于 i 的排列,即如果 P 是 1:n 的排列,那么我们仅在 all(P != 1:n) 为 TRUE 时才接受它。下面的计算会很快变大,但对于小的 n 应该没问题。

      library(RcppAlgos)
      
      n <- 2
      p <- permuteGeneral(n)
      c(cbind(1:n, t(p[apply(t(p) != 1:n, 2, all), , drop = FALSE])))
      ## [1] 1 2 2 1
      
      n <- 3
      p <- permuteGeneral(n)
      c(cbind(1:n, t(p[apply(t(p) != 1:n, 2, all), , drop = FALSE])))
      ## [1] 1 2 3 2 3 1 3 1 2
      
      n <- 4
      p <- permuteGeneral(n)
      c(cbind(1:n, t(p[apply(t(p) != 1:n, 2, all), , drop = FALSE])))
      ## [1] 1 2 3 4 2 1 4 3 2 3 4 1 2 4 1 3 3 1 4 2 3 4 1 2 3 4 2 1 4 1 2 3 4 3 1 2 4 3 2 1
      

      【讨论】:

      • 嗨!对于 n =2 和 n =3,此功能适用于我。 n=4 的期望输出将是序列 1 2 3 4 2 3 4 1 3 4 1 2 4 1 2 3 ,所以 1234 2341 3412 4123 列明智的数字之间没有重叠我现在意识到我的解释不清楚(我发现很难正确制定,但我希望现在很清楚) n=2 12 21 n= 3 123 231 312 n= 4 1234 2341 3412 4123 n= 5 12345 23451 34512 45123 51234
      • 但是,您的方法启发了我! n = 5 cbind(matrix(rep(1:n, n-1), ncol = n-1, byrow = T), rev(1:n)) 这对我有用!谢谢!
      • @Hugo,您评论中的代码恰好给出了 n=2 和 n=3 的正确答案,但通常只会给出不正确的 n-1 个排列。
      • 我明白了!我没有正确地表述我的问题,但我现在有了答案!谢谢!
      猜你喜欢
      • 1970-01-01
      • 2016-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-21
      • 2016-05-07
      • 2015-02-26
      相关资源
      最近更新 更多