从for循环中删除重复的数字
我在R中有以下代码(由Mark-)允许我将数字添加到目标值。 但是,我希望代码返回所有可能的组合,而不重复相同的数字,并将删除的数字存储在单独的列表中。我需要分配索引值吗从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
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:谢谢你的指导,我会调查的!