One option is to use RcppAlgos::compositionsGeneral()
which employs 'efficient algorithms for partitioning numbers under various constraints'.
library(RcppAlgos)
compositionsGeneral(3, 2, repetition = TRUE, target = 4)
[,1] [,2]
[1,] 1 3
[2,] 2 2
[3,] 3 1
As @ThomasIsCoding has pointed out, this approach can fail with the message:
compositionsGeneral(3, 6, repetition = TRUE, target = 10)
Error: Currently, there is no composition algorithm for this case.
Use permuteCount, permuteIter, permuteGeneral, permuteSample, or
permuteRank instead.
So to deal with this, we can catch errors and fall back on permuteGeneral()
with constraints in this event:
comps <- \(v, m, x) {
tryCatch(
compositionsGeneral(v,
m,
repetition = TRUE,
target = x),
error = function(e)
permuteGeneral(v,
m,
repetition = TRUE,
constraintFun = "sum",
comparisonFun = "==",
limitConstraints = x
)
)
}
comps(3, 6, 10)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 1 1 1 3 3
[2,] 1 1 1 3 1 3
[3,] 1 1 1 3 3 1
[4,] 1 1 3 1 1 3
[5,] 1 1 3 1 3 1
...
[85,] 2 2 1 1 2 2
[86,] 2 2 1 2 1 2
[87,] 2 2 1 2 2 1
[88,] 2 2 2 1 1 2
[89,] 2 2 2 1 2 1
[90,] 2 2 2 2 1 1
Note that the documentation includes the following about calculating permutations with contraints:
Finding all combinations/permutations with constraints is optimized by
organizing them in such a way that when constraintFun is applied, a
partially monotonic sequence is produced. Combinations/permutations
are added successively, until a particular combination exceeds the
given constraint value for a given constraint/comparison function
combo. After this point, we can safely skip several combinations
knowing that they will exceed the given constraint value.