Ваш код не работает для предотвращения дубликатов, потому что, как только ваш тест на равенство пройдет успешно, вы найдете новый латинский квадрат, но тогда вы не протестируете этот новый с текущим списком латинских квадратов! Вы, вероятно, хотите некоторое время l oop, которое ломается только тогда, когда текущий латинский квадрат не идентичен всем предыдущим. Это можно оценить, используя 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