我想在一条线上安排3个红球,2个蓝球和2个绿球,这样就不会有两个相同颜色的球相邻。如果没有这样的限制,那么这种独特安排的数量是
下面是我用来解决这个问题的R中的代码。我们的想法是获得所有210个独特的排列,然后计算连续两个相邻单元格具有相同颜色的情况。使用这个算法,我得到38作为答案。我觉得我的代码是如此丑陋的黑客。你会如何用R(或你的首选语言)做到这一点?
colors <- c("R", "R", "R", "B", "B", "G", "G")
n <- 1:10000
x <- matrix(rep(NA, times=70000), ncol=7)
for (i in n) x[i,] <- sample(colors)
x <- unique(x)
rows <- nrow(x)
y <- rep(NA, times =rows)
for (i in 1:rows) {
y[i] <- x[i,1]==x[i,2] |
x[i,2]==x[i,3] |
x[i,3]==x[i,4] |
x[i,4]==x[i,5] |
x[i,5]==x[i,6] |
x[i,6] == x[i,7]
}
table(y)
## y
## FALSE TRUE
## 38 172
答案 0 :(得分:5)
这应该以更简单的格式为您提供相同的值:
library(DescTools)
library(Hmisc)
out = Permn(colors)
table(apply(out,1,function(x) any(x==Lag(x))))
答案 1 :(得分:1)
@timfaber的答案很棒。我将添加一些更复杂的答案,使您能够从过程中获得更多信息。它将告诉您颜色系列(排列)的外观以及相邻颜色的次数:
library(tidyverse)
library(DescTools)
# vector of colors
colors <- c("R", "R", "R", "B", "B", "G", "G")
Permn(colors) %>% # permute colors
tbl_df() %>% # save it as dataframe
mutate(id = row_number()) %>% # create permutation id
gather(v, color, -id) %>% # reshape data
select(-v) %>% # remove unecessary column
group_by(id) %>% # for each permutation id
mutate(color_series = paste0(color, collapse = "_"), # create the series of colors
color_lag = lag(color), # get the previous color
IsSameColor = if_else(color == color_lag, 1, 0, missing = 0)) %>% # check if you have adjacent colors
group_by(id, color_series) %>% # for each permutation id and color series
summarise(CountSameColor = sum(IsSameColor)) %>% # count number of adjacent colors
ungroup()
# # A tibble: 210 x 3
# id color_series CountSameColor
# <int> <chr> <dbl>
# 1 1 R_R_R_B_B_G_G 4
# 2 2 R_R_B_R_B_G_G 2
# 3 3 R_B_R_R_B_G_G 2
# 4 4 B_R_R_R_B_G_G 3
# 5 5 R_R_B_B_R_G_G 3
# 6 6 R_B_R_B_R_G_G 1
# 7 7 B_R_R_B_R_G_G 2
# 8 8 R_B_B_R_R_G_G 3
# 9 9 B_R_B_R_R_G_G 2
# 10 10 B_B_R_R_R_G_G 4
# # ... with 200 more rows
如果您只想要使用现在相邻颜色的情况(排列),最后添加一个过滤器filter(CountSameColor == 0)
。
答案 2 :(得分:1)
你也可以使用游程长度编码:
library(DescTools)
# 3 red balls, 2 blue balls, and 2 green
m <- Permn(rep(c("R","B","G"), times=c(3,2,2)))
# use run length encoding to find adjacent elements
table(apply(m, 1, function(x)
(length(rle(x)$lengths)!=7)))