我的目标是构造每个给定大小n的唯一https://www.researchgate.net/post/What_is_the_best_SAT-solver_with_option_to_find_all_solutions_satisfied_given_CNF。 R命令rlatin(n)使用马尔可夫链构造大小为n x n的随机拉丁方。但是,此命令不仅会构造其大小的所有拉丁方。
下面是我的代码:
library(magic)
L <- function(n){
size <- factorial(n) * factorial(n-1)
l <- list()
l[[1]] <- rlatin(n)
for(k in 2:size){
new <- rlatin(n)
for(j in 1:(k-1)){
if(new == l[[j]]){
new <- rlatin(n)
}
}
l[[k]] <- new
}
l
}
这不能正常工作,我不明白为什么。有人可以说明我的错误吗?另外,一旦所有拉丁广场都建成后,有没有一种我可以组织它们的方式,以便在拉丁广场中有一些清晰的地方?
答案 0 :(得分:1)
您的代码无法防止重复,因为一旦相等性测试成功,您就会找到一个新的拉丁方,但是您就不会使用当前的拉丁方列表来测试该新方!您可能需要一个while循环,仅当当前拉丁方与之前所有拉丁方都不相同时才中断。可以使用sapply
进行评估,尽管当n变大时可能会很慢。
L <- function(n) {
size <- factorial(n) * factorial(n-1)
l <- list()
l[[1]] <- rlatin(n)
for(k in 2:size) {
new <- rlatin(n)
while(sum(sapply(l, function(x) any(identical(x, new)))) > 0) {
new <- rlatin(n)
}
l[[k]] <- new
}
l
}
对于n = 4(大小= 144),代码仅需几秒钟。但是对于n = 5(大小= 2880),代码将花费一整天的时间。也许有一个更快的解决方案。
L4 <- L(4) # About 10 seconds.
检查重复项:
x <- list()
for(i in 1:length(L4)) {
x[[i]] <- sapply(L4[-i], function(x) any(identical(x, L4[[i]])))
}
sum(sapply(x, sum))
# [1] 0
L5 <- L(5) # Still waiting... or as grampa used to say:
"you'll be wait'n til the cows come home".
啊,终于。
user system elapsed
816.16 0.54 827.20