从for循环中删除重复的数字

从for循环中删除重复的数字,r,recursion,mathematical-optimization,subset-sum,bin-packing,R,Recursion,Mathematical Optimization,Subset Sum,Bin Packing,我在R中有以下代码(由Mark-)允许我将数字添加到目标值。 但是,我希望代码返回所有可能的组合,而不重复相同的数字,并将删除的数字存储在单独的列表中。我需要分配索引值吗 x <- c(55,10,13,26,34,72,51,96,13) subset_sum = function(numbers,target,partial=0){ if(any(is.na(partial))) return() s = sum(partial) if(s > target) re

我在R中有以下代码(由Mark-)允许我将数字添加到目标值。 但是,我希望代码返回所有可能的组合,而不重复相同的数字,并将删除的数字存储在单独的列表中。我需要分配索引值吗

x <- c(55,10,13,26,34,72,51,96,13)

subset_sum = function(numbers,target,partial=0){
  if(any(is.na(partial))) return()
  s = sum(partial)
  if(s > target) return()
  if(between(s,target-3,target)) print(sprintf("%s = %s",paste(partial[-1],collapse=" "),s))
  for(i in seq_along(numbers)){
      n = numbers[i]
      remaining = numbers[(i+1):length(numbers)]
      subset_sum(remaining,target,c(partial,n))
    }
}

subset_sum(x,60)

#The actual output is:
[1] "10 13 34 = 57"
[1] "26 34 = 60"

#I expect the output as (no repetition of 34):
[1] 26 34 = 60
x目标)返回()
如果(在(s,target-3,target)之间)打印(sprintf(“%s=%s”),粘贴(部分[-1],折叠=”),s))
对于(沿(数字)顺序排列的i){
n=数字[i]
剩余=数量[(i+1):长度(数量)]
子集_和(剩余,目标,c(部分,n))
}
}
子集和(x,60)
#实际输出为:
[1] "10 13 34 = 57"
[1] "26 34 = 60"
#我希望输出为(不重复34次):
[1] 26 34 = 60

提前谢谢

这个包
RcppAlgos
(我是作者)是专门为这个任务构建的。下面是一个利用
comboGeneral
的解决方案,该解决方案用于生成有无重复的组合以及多集。我们还可以使用
constraintFun
comparisonFun
limitConstraints
来约束输出:

library(RcppAlgos)
mySubsetSum <- function(x, myTarget, repeats = FALSE) {
    if (0 %in% x)
        x <- x[-which(x == 0)]

    if (repeats) {
        tbl <- table(x)
        vals <- as.numeric(names(tbl))
        myfreqs <- unname(tbl)
    } else {
        vals <- unique(x)
        myfreqs <- rep(1, length(vals))
    }

    ## Add zero length(vals) - 1 times
    myfreqs <- c(length(vals) - 1, myfreqs)
    vals <- c(0L, vals)

    combs <- comboGeneral(vals, length(vals), freqs = myfreqs, 
                          constraintFun = "sum", 
                          comparisonFun = "==", 
                          limitConstraints = myTarget)

    lapply(1:nrow(combs), function(x) combs[x, combs[x,] != 0])
}

mySubsetSum(x, 60)
[[1]]
[1] 26 34

mySubsetSum(x, 60, TRUE)
[[1]]
[1] 26 34

[[2]]
[1] 13 13 34
下面是
bigTest

bigTest[1:5]
[[1]]
[1] -41 -38 -28 -22 -10  -5  11  12  14  19  30  31  33  38  41  42  43

[[2]]
[1] -41 -38 -28 -22  -9  -5  -1  11  12  14  19  30  31  33  38  41  42  43

[[3]]
[1] -41 -38 -28 -22  -1  11  12  19  30  31  33  38  41  42  43

[[4]]
[1] -41 -38 -28 -11 -10  -5  12  14  19  30  31  33  38  41  42  43

[[5]]
[1] -41 -38 -28 -11  -9  -5  -1  12  14  19  30  31  33  38  41  42  43

## View the last 5 combinations
bigTest[length(bigTest) - 4:0]
[[1]]
[1] 12 14 31 33 38 42

[[2]]
[1] 14 19 30 31 33 43

[[3]]
[1] 11 12 14 19 30 41 43

[[4]]
[1] 11 12 14 19 31 41 42

[[5]]
[1] 11 12 14 19 33 38 43


all(sapply(bigTest, sum) == 170)
[1] TRUE
您还可以找到在一个范围内具有和的组合。看起来OP最初就是这样想的,因为OP使用了
dplyr
中的
between
(至少我认为它来自
dplyr

sumRange 155和行和(sumRange)<165)
[1] 真的

这个包
RcppAlgos
(我是作者)是专门为这个任务构建的。下面是一个利用
comboGeneral
的解决方案,该解决方案用于生成有无重复的组合以及多集。我们还可以使用
constraintFun
comparisonFun
limitConstraints
来约束输出:

library(RcppAlgos)
mySubsetSum <- function(x, myTarget, repeats = FALSE) {
    if (0 %in% x)
        x <- x[-which(x == 0)]

    if (repeats) {
        tbl <- table(x)
        vals <- as.numeric(names(tbl))
        myfreqs <- unname(tbl)
    } else {
        vals <- unique(x)
        myfreqs <- rep(1, length(vals))
    }

    ## Add zero length(vals) - 1 times
    myfreqs <- c(length(vals) - 1, myfreqs)
    vals <- c(0L, vals)

    combs <- comboGeneral(vals, length(vals), freqs = myfreqs, 
                          constraintFun = "sum", 
                          comparisonFun = "==", 
                          limitConstraints = myTarget)

    lapply(1:nrow(combs), function(x) combs[x, combs[x,] != 0])
}

mySubsetSum(x, 60)
[[1]]
[1] 26 34

mySubsetSum(x, 60, TRUE)
[[1]]
[1] 26 34

[[2]]
[1] 13 13 34
下面是
bigTest

bigTest[1:5]
[[1]]
[1] -41 -38 -28 -22 -10  -5  11  12  14  19  30  31  33  38  41  42  43

[[2]]
[1] -41 -38 -28 -22  -9  -5  -1  11  12  14  19  30  31  33  38  41  42  43

[[3]]
[1] -41 -38 -28 -22  -1  11  12  19  30  31  33  38  41  42  43

[[4]]
[1] -41 -38 -28 -11 -10  -5  12  14  19  30  31  33  38  41  42  43

[[5]]
[1] -41 -38 -28 -11  -9  -5  -1  12  14  19  30  31  33  38  41  42  43

## View the last 5 combinations
bigTest[length(bigTest) - 4:0]
[[1]]
[1] 12 14 31 33 38 42

[[2]]
[1] 14 19 30 31 33 43

[[3]]
[1] 11 12 14 19 30 41 43

[[4]]
[1] 11 12 14 19 31 41 42

[[5]]
[1] 11 12 14 19 33 38 43


all(sapply(bigTest, sum) == 170)
[1] TRUE
您还可以找到在一个范围内具有和的组合。看起来OP最初就是这样想的,因为OP使用了
dplyr
中的
between
(至少我认为它来自
dplyr

sumRange 155和行和(sumRange)<165)
[1] 真的

如果不重复编号,这与箱子包装问题非常相似。调查可能会有帮助。@Shree:谢谢你的指导,我会调查的!如果不重复编号,这将非常类似于装箱问题。调查可能会有帮助。@Shree:谢谢你的指导,我会调查的!