相似对象的循环排列

circular permutation of similar objects

我需要一个用于相似对象循环排列的 R 代码,它精确地定义了这个代码。 使用 'n' 个对象可以形成的循环排列的数量,其中 'p' 相同且属于一种,'q' 相同且属于另一种。

(n-1)!/p!q!

这是我找到的最好的代码,但它并不是我想要的

library(arrangements)
permutations(x =  c("A","B","C"), freq = c(2,1,1))

output:


    [,1] [,2] [,3] [,4]
 [1,] "A"  "A"  "B"  "C" 
 [2,] "A"  "A"  "C"  "B" 
 [3,] "A"  "B"  "A"  "C" 
 [4,] "A"  "B"  "C"  "A" 
 [5,] "A"  "C"  "A"  "B" 
 [6,] "A"  "C"  "B"  "A" 
 [7,] "B"  "A"  "A"  "C" 
 [8,] "B"  "A"  "C"  "A" 
 [9,] "B"  "C"  "A"  "A" 
[10,] "C"  "A"  "A"  "B"     
[11,] "C"  "A"  "B"  "A" 
[12,] "C"  "B"  "A"  "A"

我不想"A""A"彼此挨着

事实证明,递归函数可以很好地解决这个问题。该函数将旅程进行到现在为止,计算出接下来可以访问哪些剩余的城镇,然后为每个城镇调用自身。如果没有剩余的城镇,它会报告路线。

# recursive function to visit remaining towns
journey <- function(remaining, visited){
  # possible towns to visit next
  possible <- setdiff(remaining, tail(visited, 1))
  if (length(possible)==0){
    if (length(remaining)==0){
      # report and store journey
      print(visited)
      routei <<- routei + 1
      routes[[routei]] <<- visited
    } else {
      # route failed to visit all towns
    }
  } else {
    # loop through options
    for (i in possible){
      # continue journey
      journey(remaining[-match(i, remaining)], c(visited, i))
    }
  }
}

remaining <- c("A", "A", "B", "B", "C")
visited <- character(0)

routes <- vector("list", length(remaining)^2)
routei <- 0

journey(remaining, visited)
#> [1] "A" "B" "A" "B" "C"
#> [1] "A" "B" "A" "C" "B"
#> [1] "A" "B" "C" "A" "B"
#> [1] "A" "B" "C" "B" "A"
#> [1] "A" "C" "B" "A" "B"
#> [1] "B" "A" "B" "A" "C"
#> [1] "B" "A" "B" "C" "A"
#> [1] "B" "A" "C" "A" "B"
#> [1] "B" "A" "C" "B" "A"
#> [1] "B" "C" "A" "B" "A"
#> [1] "C" "A" "B" "A" "B"
#> [1] "C" "B" "A" "B" "A"

reprex package (v0.3.0)

于 2019-07-22 创建