(这是受到另一个标记为重复的问题的启发。尽管我可能是 ignorant.),但我还是认为这是一个有趣的问题,尽管组合方法可能有一个简单的解决方案。
问题
对于长度为n
的向量,其中n mod 2
为零,请找到所有可能的方法将向量的所有元素划分为对,而无需替换,顺序无关紧要。
例如,对于向量c(1,2,3,4)
:
list(c(1,2), c(3,4))
list(c(1,3), c(2,4))
list(c(1,4), c(2,3))
我的方法如下(对于新手代码,请提前道歉):
# write a function that recursively breaks down a list of unique pairs (generated with combn). The natural ordering produced by combn means that for the first pass through, we take as the starting pair, all pairings with element 1 of the vector with all other elements. After that has been allocated, we iterate through the first p/2 pairs (this avoids duplicating).
pairer2 <- function(kn, pair_list) {
pair1_partners <- lapply(kn, function(x) {
# remove any pairs in the 'master list' that contain elements of the starting pair.
partners <- Filter(function(t) !any(t %in% x), pair_list)
if(length(partners) > 1) {
# run the function again
pairer2(kn = partners[1:(length(partners)/2)], partners)
} else {return(partners)}
})
# accumulate results into a nested list structure
return(mapply(function(x,y) {list(root = x, partners = y)}, kn, pair1_partners, SIMPLIFY = F))
}
# this function generates all possible unique pairs for a vector of length k as the starting point, then runs the pairing off function above
pair_combn <- function(k, n = 2) {
p <- combn(k, n, simplify = F)
pairer2(kn = p[1:(length(k)-1)], p)}
# so far a vector k = 4
pair_combn(1:4)
[[1]]
[[1]]$root
[1] 1 2
[[1]]$partners
[[1]]$partners[[1]]
[1] 3 4
[[2]]
[[2]]$root
[1] 1 3
[[2]]$partners
[[2]]$partners[[1]]
[1] 2 4
[[3]]
[[3]]$root
[1] 1 4
[[3]]$partners
[[3]]$partners[[1]]
[1] 2 3
据我所知,它也适用于较大的k
。这不是那么有效,可能是因为Filter
对于大列表来说很慢,并且我不得不承认我无法将嵌套列表(这是可能的解决方案的树形表示)折叠到每个分区的列表中。感觉应该有一个更优雅的解决方案(在 R 中)?
提醒您,有趣的是,此递归方法生成了可能解决方案的简约表示(尽管不方便)。
2 回答
这是一种方法:
感谢您继续我的问题(由于某些奇怪的原因被标记为重复)。我认为对于 k> = 10 来说,没有解决方案会很好。对于 k=6,盖茨基的答案对我不起作用(实际上有 15 种可能性时,它会返回 5 种可能性)。 Ista 的解在 k = 12 时失败。