Получите все возможные комбинации в рамках заданной суммы продукта - PullRequest
2 голосов
/ 21 июня 2020

Я хочу написать сценарий R, который сгенерирует все возможные комбинации номеров коллекции, для которых сумма их продуктов меньше определенной суммы.

Например, у меня есть эти два вектора, x представляющие элементы, для которых я хочу сгенерировать комбинации, y представляющие элементы, чтобы найти сумму продукта.

x <- c(2,4,6) #elements to find combinations

y <- c(24,48,72) #elements to find product sum

Мое основное ограничение здесь заключается в том, что общая сумма произведений любой комбинации x должна быть меньше или равна 1244.

Пример желаемого результата

|--------------|--------------|--------------|---------------------|
|  Total of 2  |  Total of 4  |  Total of 6  |  Total Product Sum  |
|--------------|--------------|--------------|---------------------|
|       1      |      1       |       1      |         144         |
|--------------|--------------|--------------|---------------------|
|       2      |      2       |       2      |         288         |    
|--------------|--------------|--------------|---------------------|
|       3      |      3       |       3      |         432         |    
|--------------|--------------|--------------|---------------------|
|       4      |      4       |       4      |         576         |    
|--------------|--------------|--------------|---------------------|
|       5      |      5       |       5      |         720         |    
|--------------|--------------|--------------|---------------------|
|      ...     |      ...     |      ...     |         ...         |    
|--------------|--------------|--------------|---------------------|

Пример кода в R

Я пробовал использовать следующий код, но он работает только линейно вместо генерации всех возможных комбинаций, которые меньше или равны 1244.

n_trials <- 30
# data frame to store all possible combinations and their product sum
combo_data <- data.frame(total_of_2 = rep(0,n_trials)
                             , total_of_4 = rep(0,n_trials)
                             , total_of_6 = rep(0,n_trials)
                             , total_product_sum = rep(0,n_trials))

 for (i in 1:n_trials) {
 # check that combination is at most 1244 sqft
   if (i*24 + i*48 + i*72 <= 1244) {
     # track number of each element in x
     combo_data$total_of_2[i] <- i
     combo_data$total_of_4[i] <- i
     combo_data$total_of_6[i] <- i

     # add total product sum
     combo_data$total_product_sum[i] <- i*24 + i*48 + i*72
   }
 }

 view(combo_data)

Ответы [ 3 ]

2 голосов
/ 21 июня 2020

Количество допустимых комбинаций до 1244 будет увеличиваться по мере увеличения n, поэтому я не совсем понимаю цель здесь. Тем не менее, вот версия, которая использует базу R:

y <- c(24,48,72) #elements to find product sum
n <- 30
instances <- expand.grid(1:n, 1:n, 1:n)
instances$product_sum = rowSums(data.frame(Map('*', instances, y)))
instances <- subset(instances, product_sum <= 1244 )

Первые несколько строк результата:

  Var1 Var2 Var3 product_sum
1    1    1    1         144
2    2    1    1         168
3    3    1    1         192
4    4    1    1         216
5    5    1    1         240
6    6    1    1         264

Если вместо 1:n вы используете только исходный x значения 2, 4 и 6, вы должны получить 27 допустимых комбинаций.

2 голосов
/ 21 июня 2020

Начните с expand.grid, чтобы получить все возможные комбинации, а затем используйте матричное умножение.

x <- c(24, 48, 72)
e <- expand.grid(X = seq_len(30), Y = seq_len(30), Z = seq_len(30))

y <- as.vector(x %*% t(e))
z <- cbind(e[y < 1244, ], Prod = y[y < 1244])

head(z)
#  X Y Z Prod
#1 1 1 1  144
#2 2 1 1  168
#3 3 1 1  192
#4 4 1 1  216
#5 5 1 1  240
#6 6 1 1  264
1 голос
/ 21 июня 2020

Если я вас правильно понимаю:

tibble(X=1:30, Y=1:30, Z=1:30) %>% 
  expand(X, Y, Z) %>% 
  mutate(Total=X*24 + Y*48 + Z*72) %>% 
  filter(Total <= 1244)
# A tibble: 2,990 x 4
       X     Y     Z Total
   <int> <int> <int> <dbl>
 1     1     1     1   144
 2     1     1     2   216
 3     1     1     3   288
 4     1     1     4   360
 5     1     1     5   432
 6     1     1     6   504
 7     1     1     7   576
 8     1     1     8   648
 9     1     1     9   720
10     1     1    10   792
# … with 2,980 more rows

Ваше решение не удается, потому что вы не oop по total_of_<x> отдельно. Для этого вам понадобятся три вложенных цикла. Мое решение скрывает петли под капотом, но все еще является решением грубой силы.

...