Как найти значения вектора (только целые числа), которые удовлетворяют некоторым линейным ограничениям в R? - PullRequest
1 голос
/ 04 апреля 2019

Учитывая вектор и сумму, например пределы = c (1,2,5,6,7,6) и сумма = 10. Данные ограничения:

  1. x1 <= пределы [1] </p>

  2. x2 <= пределы [2] </p>

  3. x3 <= пределы [3] </p>

  4. x4 <= пределы [4] </p>

  5. x5 <= пределы [5] </p>

  6. x6 <= пределы [6] </p>

  7. x1 + x2 + x3 + x4 + x5 + x6 = sum

Я хотел бы найти один вектор: c(x1, x2, x3, x4, x5, x6), которые удовлетворяют этим ограничениям.Я написал это:

get_vector <-function(sum, limits){

  res_vec <-c()
  left <- sum

  for (i in seq(1:(length(limits)-1))){
    res_vec<-c(res_vec, sample(c(0:min(limits[i],left)), 1))
    left <- left - res_vec[i]
  }

   res_vec[length(limits)] <- left

  }

  return (res_vec)
}

, но, похоже, время от времени происходит сбой (я проверял это).Может кто-нибудь дать более точное предложение, как решить эту проблему?

Спасибо

Ответы [ 2 ]

1 голос
/ 04 апреля 2019
limits = c(1,2,5,6,7,6)
mysum = 10

set.seed(42)
ans = setNames(limits, paste0("x", 1:length(limits)))
while(sum(ans) > mysum){
    ind = sample(which(ans > 1), 1)
    ans[ind] = ans[ind] - 1
}

ans
#x1 x2 x3 x4 x5 x6 
# 1  1  4  2  1  1 

sum(ans)
#[1] 10
0 голосов
/ 04 апреля 2019

Вот способ получить все возможные решения.

library(partitions)

allPartitions <- compositions(10, 6, include.zero = FALSE)
limits <- c(1, 2, 5, 6, 7, 6) 
good <- apply(allPartitions, 2, function(x) all(x <= limits))
results <- allPartitions[, good]

> t(results)
      [,1] [,2] [,3] [,4] [,5] [,6]
 [1,]    1    2    4    1    1    1
 [2,]    1    1    5    1    1    1
 [3,]    1    2    3    2    1    1
 [4,]    1    1    4    2    1    1
 [5,]    1    2    2    3    1    1
 [6,]    1    1    3    3    1    1
 [7,]    1    2    1    4    1    1
 [8,]    1    1    2    4    1    1
 [9,]    1    1    1    5    1    1
[10,]    1    2    3    1    2    1
[11,]    1    1    4    1    2    1
[12,]    1    2    2    2    2    1
[13,]    1    1    3    2    2    1
[14,]    1    2    1    3    2    1
[15,]    1    1    2    3    2    1
[16,]    1    1    1    4    2    1
[17,]    1    2    2    1    3    1
[18,]    1    1    3    1    3    1
[19,]    1    2    1    2    3    1
[20,]    1    1    2    2    3    1
[21,]    1    1    1    3    3    1
[22,]    1    2    1    1    4    1
[23,]    1    1    2    1    4    1
[24,]    1    1    1    2    4    1
[25,]    1    1    1    1    5    1
[26,]    1    2    3    1    1    2
[27,]    1    1    4    1    1    2
[28,]    1    2    2    2    1    2
[29,]    1    1    3    2    1    2
[30,]    1    2    1    3    1    2
[31,]    1    1    2    3    1    2
[32,]    1    1    1    4    1    2
[33,]    1    2    2    1    2    2
[34,]    1    1    3    1    2    2
[35,]    1    2    1    2    2    2
[36,]    1    1    2    2    2    2
[37,]    1    1    1    3    2    2
[38,]    1    2    1    1    3    2
[39,]    1    1    2    1    3    2
[40,]    1    1    1    2    3    2
[41,]    1    1    1    1    4    2
[42,]    1    2    2    1    1    3
[43,]    1    1    3    1    1    3
[44,]    1    2    1    2    1    3
[45,]    1    1    2    2    1    3
[46,]    1    1    1    3    1    3
[47,]    1    2    1    1    2    3
[48,]    1    1    2    1    2    3
[49,]    1    1    1    2    2    3
[50,]    1    1    1    1    3    3
[51,]    1    2    1    1    1    4
[52,]    1    1    2    1    1    4
[53,]    1    1    1    2    1    4
[54,]    1    1    1    1    2    4
[55,]    1    1    1    1    1    5

Или, более кратко и, возможно, более эффективно:

> results <- sweep(blockparts(limits-1,10-6), 1, c(1,1,1,1,1,1), "+")
> t(results)

 [1,] 1 2 4 1 1 1
 [2,] 1 1 5 1 1 1
 [3,] 1 2 3 2 1 1
 [4,] 1 1 4 2 1 1
 [5,] 1 2 2 3 1 1
 [6,] 1 1 3 3 1 1
 [7,] 1 2 1 4 1 1
 [8,] 1 1 2 4 1 1
 [9,] 1 1 1 5 1 1
[10,] 1 2 3 1 2 1
[11,] 1 1 4 1 2 1
[12,] 1 2 2 2 2 1
[13,] 1 1 3 2 2 1
[14,] 1 2 1 3 2 1
[15,] 1 1 2 3 2 1
[16,] 1 1 1 4 2 1
[17,] 1 2 2 1 3 1
[18,] 1 1 3 1 3 1
[19,] 1 2 1 2 3 1
[20,] 1 1 2 2 3 1
[21,] 1 1 1 3 3 1
[22,] 1 2 1 1 4 1
[23,] 1 1 2 1 4 1
[24,] 1 1 1 2 4 1
[25,] 1 1 1 1 5 1
[26,] 1 2 3 1 1 2
[27,] 1 1 4 1 1 2
[28,] 1 2 2 2 1 2
[29,] 1 1 3 2 1 2
[30,] 1 2 1 3 1 2
[31,] 1 1 2 3 1 2
[32,] 1 1 1 4 1 2
[33,] 1 2 2 1 2 2
[34,] 1 1 3 1 2 2
[35,] 1 2 1 2 2 2
[36,] 1 1 2 2 2 2
[37,] 1 1 1 3 2 2
[38,] 1 2 1 1 3 2
[39,] 1 1 2 1 3 2
[40,] 1 1 1 2 3 2
[41,] 1 1 1 1 4 2
[42,] 1 2 2 1 1 3
[43,] 1 1 3 1 1 3
[44,] 1 2 1 2 1 3
[45,] 1 1 2 2 1 3
[46,] 1 1 1 3 1 3
[47,] 1 2 1 1 2 3
[48,] 1 1 2 1 2 3
[49,] 1 1 1 2 2 3
[50,] 1 1 1 1 3 3
[51,] 1 2 1 1 1 4
[52,] 1 1 2 1 1 4
[53,] 1 1 1 2 1 4
[54,] 1 1 1 1 2 4
[55,] 1 1 1 1 1 5
...