R - 所有匹配的向量元素对

时间:2015-08-19 22:54:57

标签: r

我希望识别矢量元素的所有可能的成对匹配。我现在不会看向量的元素数,所以长度(向量)= n,但我只知道n是偶数。顺序无关紧要,但每次都需要加起来对初始向量。

举例x<-c(1,2,3,4)答案为3,即:

1) (1,2)(3,4)
2) (1,3)(2,4)
3) (1,4)(2,3)

有相当多的类似线程,但是我错过了将对分组以形成初始向量的部分。

谢谢!

1 个答案:

答案 0 :(得分:1)

n个元素的每个有序配对(其中n是偶数)等价于(1:n) %% (n/2)的随机排列。另外,由于对的顺序并不重要,因此与标记相等的排列实际上是等同的。例如,c(1,1,0,0)相当于c(0,0,1,1) - 它们都将前两个元素组合在一起,最后两个元素组合在一起。因此,我们可以通过扩展每个排列来获得唯一集合,然后按照它们出现的顺序重新标记每个排列的元素,然后从结果中获取唯一的排列:

library(magrittr)
library(combinat)

all_pairings <- function(n) {
    if (n %% 2 != 0)
        stop("n must be even")
    allperms <- permn((1:n) %% (n/2))
    allperms %<>% lapply(. %>% factor(levels=unique(.)) %>% as.numeric)
    unique(allperms)
}

这给出了n = 4的正确结果:

> all_pairings(4)
[[1]]
[1] 1 2 1 2

[[2]]
[1] 1 2 2 1

[[3]]
[1] 1 1 2 2

要实际获取对,请使用split函数:

> lapply(all_pairings(4), split, x=letters[1:n])
[[1]]
[[1]]$`1`
[1] "a" "c"

[[1]]$`2`
[1] "b" "d"


[[2]]
[[2]]$`1`
[1] "a" "d"

[[2]]$`2`
[1] "b" "c"


[[3]]
[[3]]$`1`
[1] "a" "b"

[[3]]$`2`
[1] "c" "d"

如果您只需要唯一配对的数量而不是完整列表,则有一个明确的公式:http://www.regentsprep.org/regents/math/algebra/apr2/LpermRep.htm

在这种情况下,N个元素的唯一配对公式为factorial(n) / 2^(n/2) / factorial(n/2)。第一项表示所有排列,第二项表示由于等同的对内重新排序而导致的冗余,第三项表示由于对的重新排序而导致的冗余。

num_pairings <- function(n) {
    if (any(n %% 2 != 0))
        stop("n must be even")
    factorial(n) / (2^(n/2)) / factorial(n/2)
}


> n <- seq(2,20, by=2); data.frame(n=n, NumPairings=num_pairings(n))
data.frame with 10 rows and 2 columns
           n NumPairings
   <numeric>   <numeric>
1          2           1
2          4           3
3          6          15
4          8         105
5         10         945
6         12       10395
7         14      135135
8         16     2027025
9         18    34459425
10        20   654729075