我的伴侣要求我按照以下规则帮助她设计毯子的图案:
我已经成功地完成了上面的步骤1-4(请参见下面的代码),但是我完全对如何以编程方式执行步骤5感到困惑。我知道我可以通过蛮力或反复试验(或者只是手工完成) ),但我希望有一种更聪明的方法来解决此问题。
任何人都可以提供帮助吗?
如果有可能解决,那么接下来有几个问题:
到目前为止,这是我的工作:
# Generate the entire list of unique colour combinations (regardless of order).
col_list_combination <- as.data.frame(t(combn(letters[1:13], 3)))
# There are 2 sets where no combination is allowed:
excl_sets <- t(combn(letters[1:4], 3)) %>%
rbind(t(combn(letters[c(7, 8, 10, 13)], 3))) %>%
as.data.frame()
# Setting the column names for my own sanity.
colnames(col_list_combination) <- colnames(excl_sets) <- c("Primary", "Secondary", "Tertiary")
# Removing those combinations that are not allowed
col_list_combination %<>%
anti_join(excl_sets, by = c("Primary", "Secondary", "Tertiary"))
# An attempt to figure out which combinations are allowed for a single square.
abe_neighbours <- col_list_combination %>%
filter(Primary != "a" & Secondary != "a" & Tertiary != "a") %>%
filter(Primary != "b" & Secondary != "b" & Tertiary != "b") %>%
filter(Primary != "e" & Secondary != "e" & Tertiary != "e")
编辑:所需的输出将是13 x 13矩阵,其中矩阵的每个单元格是一组三种颜色的三元代码,其位置受上述规则限制。例如,类似:
tibble(c("abe", "ghm"), c("cki", "adf"))
答案 0 :(得分:1)
经过几天的思考和工作,我相信我已经提出了一个解决方案:
# Generate the entire list of unique colour combinations (regardless of order). (Rule 3)
col_list_combination <- as.data.frame(t(combn(letters[1:13], 3)))
# There are 2 sets where no combination is allowed (Rule 4):
excl_sets <- t(combn(letters[1:4], 3)) %>%
rbind(t(combn(letters[c(7, 8, 10, 13)], 3))) %>%
as.data.frame()
# Setting the column names for my own sanity.
colnames(col_list_combination) <- colnames(excl_sets) <- c("Primary", "Secondary", "Tertiary")
# Removing those combinations that are not allowed (Rule 4)
col_list_combination %<>%
anti_join(excl_sets, by = c("Primary", "Secondary", "Tertiary")) %>%
mutate(con_cat = paste(Primary, Secondary, Tertiary)) %>%
select(con_cat)
到目前为止,我只是创建了可能的颜色三元组列表。现在,我将尝试创建毯子。
# First create the blank matrix of the size you wish (Rule 1 for this example).
output_matrix <- matrix(NA,13,13)
# Next set a random starting seed in the top left-most cell (this allows for random variations on output).
output_matrix[1,1] <- sample(col_list_combination %>% pull(con_cat), 1)
#create an empty vector for the "used" squares so that they do not get re-used (Rule 6).
used_combinations <- c()
#iterate over all columns and rows.
for(i in 1:nrow(output_matrix)) {
for(j in 1:ncol(output_matrix)) {
#for each cell, figure out the colours of the cell above and to the left (since we are working left to right and top to bottom)
split_cells <- strsplit(c(output_matrix[i, ifelse(j == 1, j, j-1)],
output_matrix[ifelse(i == 1, i, i-1), j]), " ") %>%
unlist()
split_cells <- split_cells[!is.na(split_cells)] #need to remove NAs since some cells do not have a cell above or to the left.
#the number of non-allowed neighbour colours will either be 3 or 6 (I am ignoring duplicates for simplicity)
if(length(split_cells) == 3) {
cell_neighbours <- col_list_combination %>%
filter(!con_cat %in% used_combinations) %>% #removes any that have been used already
filter(!grepl(split_cells[1], con_cat) &
!grepl(split_cells[2], con_cat) &
!grepl(split_cells[3], con_cat)) %>%
pull()
} else if(length(split_cells) == 6) {
cell_neighbours <- col_list_combination %>%
filter(!con_cat %in% used_combinations) %>% removes any that have been used already.
filter(!grepl(split_cells[1], con_cat) &
!grepl(split_cells[2], con_cat) &
!grepl(split_cells[3], con_cat) &
!grepl(split_cells[4], con_cat) &
!grepl(split_cells[5], con_cat) &
!grepl(split_cells[6], con_cat)) %>%
pull()
}
cell_neighbours
#select the new combination.
new_combination <- sample(cell_neighbours, 1)
#add the new combination to the appropriate cell.
output_matrix[i,j] <- new_combination
#update the used comnbination vector.
used_combinations <- c(used_combinations, new_combination)
}
}
output_matrix
我相信这可以按预期工作,并且可以扩展到任何矩阵大小,色号,并允许使用多个可变输出矩阵。
我很确定代码可以更高效地编写...