Hey guys
I have the following problem involving partitions.
I have the number X as input.
I would like to find the set of N integer of distinct elements that the sum equal the number X (my input).
Example:
X=15
N=5
Sets of N distinct elements: {5;4;3;2;1} because if we sum each element it results in X
From all the possibilities (with and without repetitions), the algorithm will extract only those formed by distinct numbers.
There is something missing: in your example for X=15, I can also answer N=1, for the set {15} because if we sum the single element we obtain X (and similarly there is an N=2 for {14;1} etc). So I guess you're looking for the highest N satisfying this?
One brute-force approach is to take every possible value of N smaller than X, compute all combinations of length N, and see if any of them has the right sum. If so, we can simply keep the highest:
X <- 15
N_match <- logical(X-1)
for(N in 1:(X-1)){
N_match[[N]] <- any(colSums(combn(X,N)) == X)
}
max(which(N_match))
#> [1] 5
Thanks for your feedback but my intentios is to indentify the set or sub set of numbers based in my inputs.
I don't need to find the highest N, I will just specify the size of my sub set by using N as input.
I thought to find a way to use the following:
List all combinations of length N with utils::combn() or gtools::combinations(), and only keep the one(s) that sum to X. That can be done changing a bit my code above.
List all partitions using partitions::parts(), and only keep the one(s) with no repetition.
The above solutions are inefficient in that they compute more than needed. For big X, that's a lot of partitions/combinations that you're not interested in. You can instead rewrite an algorithm yourself taking inspiration from nirgrahamuk's link, so that you stop computations as soon as you find a satisfying partition, thus saving a lot of computations.
So, for 1:
X <- 15
N <- 5
# find all combinations
all_combns <- combn(X,N,simplify = FALSE)
# compute sums
all_sums <- sapply(all_combns, sum)
# is it a partition?
is_partition <- all_sums == X
# extract the satisfying partition(s)
all_combns[is_partition]
And for 2:
# find all partitions that have the right number of elements
all_partitions <- partitions::restrictedparts(X,N,
include.zero = FALSE)
# find partitions with no duplicate
nb_duplicates <- apply(all_partitions, 2, anyDuplicated)
has_no_duplicate <- nb_duplicates == 0
# extract values
all_partitions[,has_no_duplicate]
The first code gives all these partitions as a list, the second one as a matrix with one column per partition, for example for X=15, N=4:
It is marvelous. It works perfectly. Thank you very much for your time and your knowledge sharing.
Thank you all guys, I hope to have a good knowledge in R language so I can help others as well.