Home > Back-end >  Obtaining all possible combinations with a minimum number per group
Obtaining all possible combinations with a minimum number per group

Time:02-10

Apologies for lack of a reproducible example as I'm not too sure how to code this.

Let's say I have four groups: red, yellow, green, and blue.

I have fifteen marbles to distribute to each group, with a constraint that each group must have at least two marbles. How can I get all possible combinations that can be allotted to each group? My desired end result is a data frame along the following lines, where the number represents the number of marbles allocated to that group:

combo_id   red   yellow   green   blue
1          3     3        5       4
2          3     5        4       3
3          5     2        5       3

And so on until all combinations have been enumerated.

CodePudding user response:

I think you can achieve this using permuteGeneral from the RcppAlgos package.

Stating the problem as: what permutations of 4 numbers in the range 2-9 sum to 15. If the minimum per group is 2 then the maximum per group has to be 9, since 2 2 2 9 = 15.

library(RcppAlgos)
dataset <- permuteGeneral(2:9, 
                          m = 4, 
                          TRUE, 
                          constraintFun = "sum", 
                          comparisonFun = "==", 
                          limitConstraints = 15)

head(dataset)

     [,1] [,2] [,3] [,4]
[1,]    2    2    2    9
[2,]    2    2    9    2
[3,]    2    9    2    2
[4,]    9    2    2    2
[5,]    2    2    3    8
[6,]    2    2    8    3

nrow(dataset)
[1] 120

To get a data frame:

dataset <- as.data.frame(dataset)
names(dataset) <- c("red", "yellow", "green", "blue")

CodePudding user response:

library(purrr)
library(dplyr, warn.conflicts = FALSE)

colors <- c("red", "yellow", "green", "blue")
names(colors) <- colors

all_possible_combinations <- expand.grid(map(colors, function(x) 2:9))

all_possible_combinations$sum <- rowSums(all_possible_combinations)

# Get all distributions that sum to 15 and therefore give out all marbles
all_possible_combinations %>%
  filter(sum == 15) %>%
  as_tibble()
#> # A tibble: 120 × 5
#>      red yellow green  blue   sum
#>    <int>  <int> <int> <int> <dbl>
#>  1     9      2     2     2    15
#>  2     8      3     2     2    15
#>  3     7      4     2     2    15
#>  4     6      5     2     2    15
#>  5     5      6     2     2    15
#>  6     4      7     2     2    15
#>  7     3      8     2     2    15
#>  8     2      9     2     2    15
#>  9     8      2     3     2    15
#> 10     7      3     3     2    15
#> # … with 110 more rows

# Include combinations where some of the marbles might be retained.
all_possible_combinations %>%
  filter(sum <= 15) %>%
  as_tibble()
#> # A tibble: 330 × 5
#>      red yellow green  blue   sum
#>    <int>  <int> <int> <int> <dbl>
#>  1     2      2     2     2     8
#>  2     3      2     2     2     9
#>  3     4      2     2     2    10
#>  4     5      2     2     2    11
#>  5     6      2     2     2    12
#>  6     7      2     2     2    13
#>  7     8      2     2     2    14
#>  8     9      2     2     2    15
#>  9     2      3     2     2     9
#> 10     3      3     2     2    10
#> # … with 320 more rows
  •  Tags:  
  • r
  • Related