Using RcppAlgos
(I am the author), this is trivial.
RcppAlgos::permuteGeneral(seq(0, 8, 1), 4,
constraintFun = "sum",
comparisonFun = "==",
limitConstraints = 6)
The algorithm underneath is optimized to quickly prune away solutions that are impossible. We also only considered checking combinations as addition/multiplication are commutative and order doesn't matter. Once we find a suitable combination, we generate all permutations of that specific combination. It also helps that we are using Rcpp
for major efficiency gains.
For the OP's real world problem with 200 numbers and 6 columns, feasibility will depend heavily on the sum needed. If we considered the average sum (which will occur the most), we may need to consider alternative approaches as the shear number of possible solutions exceed 2^31 - 1
. It will also take a considerable amount of time. Just with 5 columns and a desired sum of 500, I cannot even produce the permutations. I can, however produce combinations:
res <- RcppAlgos::comboGeneral(1:200, 5,
constraintFun = "sum",
comparisonFun = "==",
limitConstraints = 500,
upper = 1e8) ## upper argument constrains the output to a maximum number of results
nrow(res)
[1] 7669861
And given that there are no repeats, we can calculate the number of permutations to be:
7669861 * factorial(5) = 920,383,320
Here is the error I get:
res <- RcppAlgos::permuteGeneral(1:200, 5,
constraintFun = "sum",
comparisonFun = "==",
limitConstraints = 500,
upper = 921000000)
Show Traceback
Rerun with Debug
Error: vector memory exhausted (limit reached?)
If the desired sum is relatively small or large compared to the average sum, computation is possible. For example, if the desired sum is 100, we can quickly get all of the permutations:
system.time(res <- RcppAlgos::permuteGeneral(1:200, 6,
constraintFun = "sum",
comparisonFun = "==",
limitConstraints = 100,
upper = 1e8))
user system elapsed
2.213 0.525 2.753
nrow(res)
[1] 47395440