From what I've analyzed for your code, your suspicion is correct: the perm
function is what is slowing down the code. I came to this conclusion by testing the runtime of the topswops
function:
library(rbenchmark)
benchmark(topswops(sample(1:i, 10)), replications = 100000)
test replications elapsed relative user.self sys.self user.child sys.child
1 topswops(sample(1:i, 10)) 100000 2.388 1 2.253 0.107 0 0
Repeat% with 100,000 times in random vectors of size 10, with elements from 1 to 10, took 2.388 seconds. That is, the bottleneck is not here.
That said, I looked for other ways to generate all possible permutations for a sequence of numbers. In addition to topswops
, Deducer
and combinat
packets can also generate all permutations of a sequence of numbers. The results of my test were as follows:
library(Deducer)
inicio <- Sys.time()
resultado.Deducer <- NULL
for(i in 1:10){
A <- perm(1:i)
A <- data.frame(A)
A$flips <- apply(A, 1, topswops)
resultado.Deducer <- rbind(resultado.Deducer, c(i, max(A$flips)))
}
fim <- Sys.time()
fim - inicio
Time difference of 4.131159 mins
library(combinat)
inicio <- Sys.time()
resultado.combinat <- NULL
for(i in 1:10){
A <- as.data.frame(matrix(unlist(permn(1:i)), ncol=i, byrow=TRUE))
A$flips <- apply(A, 1, topswops)
resultado.combinat <- rbind(resultado.combinat, c(i, max(A$flips)))
}
fim <- Sys.time()
fim - inicio
Time difference of 2.371664 mins
library(gtools)
inicio <- Sys.time()
resultado.gtools <- NULL
for(i in 1:10){
A <- permutations(i, i, 1:i)
A$flips <- apply(A, 1, topswops)
resultado.gtools <- rbind(resultado.gtools, c(i, max(A$flips)))
}
Warning messages:
1: In A$flips <- apply(A, 1, topswops) : Coercing LHS to a list
2: In A$flips <- apply(A, 1, topswops) : Coercing LHS to a list
3: In A$flips <- apply(A, 1, topswops) : Coercing LHS to a list
4: In A$flips <- apply(A, 1, topswops) : Coercing LHS to a list
5: In A$flips <- apply(A, 1, topswops) : Coercing LHS to a list
6: In A$flips <- apply(A, 1, topswops) : Coercing LHS to a list
7: In A$flips <- apply(A, 1, topswops) : Coercing LHS to a list
8: In A$flips <- apply(A, 1, topswops) : Coercing LHS to a list
9: In A$flips <- apply(A, 1, topswops) : Coercing LHS to a list
10: In A$flips <- apply(A, 1, topswops) : Coercing LHS to a list
fim <- Sys.time()
fim - inicio
Time difference of 1.849558 mins
Therefore, one way to optimize code is by precisely improving the permutations. In my test, the function that worked best was gtools
, taking 1.849558 minutes to run. This equals 44% of the time used by the original function.
You may be able to further improve this performance by optimizing the generation of permutations. Since there are millions of replications, I believe that any improvement in the generation of permutations is something that counts for the end.
If the search is for the shortest execution time and not necessarily the best algorithm, it is also possible to shorten the execution time by parallelizing the code. But then I leave this exercise to the reader:)