我被一个朋友问了一个编程问题,关于如何确定所有可能的组合值可以被添加到一个所需的总和。我有一个解决方案,但它不够优雅(它基本上只是一系列for循环和if语句)。我相信dplyr有一个我无法想到的解决方案,因为我知道它有多有用,但我还没有很好的解决它。我将在下面发布问题和我的脚本。确定所有可能的组合的值,总和为所需的总数
问题: 有一个有六个环的目标,每个环都值不同的值。这些值是1,2,3,4,5或6.您可以使用多少种不同的戒指组合来得分为9分?
所以要考虑: 顺序并不重要 只要你想 您可以使用尽可能少或尽可能多的价值可以得到相同的值不止一次(所以9 1的是一个完全有效的选项)
我考虑过首先使用combinat包中的combn(),但combn()不会替换值。
然后我决定使用一系列嵌套for循环和if语句(我将它截断为只能使用最多6个值的地方,因为虽然我可能有空闲时间,但我不是一个受虐狂的人编写一个允许最多9个值的循环)。所以基本上,它通过6个for-loops值得可能的值。我包含数字0到可能值的列表中以表示没有尝试,因为我只需要2个值而不是6个(因此4 + 5 + 0 + 0 + 0 + 0是此循环中的有效输出,但不会能够做4 + 5,因为它总是会尝试添加更多的非零值)。
## Create a vector x with possible values
x = c(1,2,3,4,5,6)
## Add in value 0 because I need to be able to write this dumb loop that allows many terms to be used, but also allows smaller amounts of terms to be used
x = c(x,0);x
## Creating empty data.frame to input solutions to so that I can check for uniqueness of solution
df = data.frame("a" = as.numeric(),
"b" = as.numeric(),
"c" = as.numeric(),
"d" = as.numeric(),
"e" = as.numeric(),
"f" = as.numeric())
for (a in x){
for (b in x){
for (c in x){
for (d in x){
for (e in x){
for (f in x){
m = sum(a,b,c,d,e,f)
if(m == 9) {
p = 0
n = c(a,b,c,d,e,f)
if (nrow(df) == 0){
df[1,] = n
}
if (nrow(df) >= 1){
for (i in (1:nrow(df))){
if(setequal(n,df[i,]) == TRUE){
p = p+1
}}
if(p == 0){
df = rbind(df,n)
}
}
}
}
}
}
}
}
}
## Convert any 0 values to NA
df[df==0] = NA
## Check Solutions
df
我创建了一个空data.frame存储解决方案,然后在循环中,我创建了一个测试,看看在回路中的新的解决方案以前发现的值的组合匹配,如果是这样,它不会将()绑定到data.frame。
我相信有一个更好的方法来做到这一点,允许动态最大数量的值(所以在这种情况下可以软编码,以将每个解决方案中的最大值数量改为9,而不是我的硬编码6,或者如果我想要的总数是5而不是9,则将其降至5)。如果您有任何建议可以减少这种笨拙的循环填充,我们将不胜感激!
相关:[查找所有组合总和到目标的数字](https:// stackoverflow .COM /问题/ 30858688 /发现,所有组合-的号码 - 那森对一个目标); [生成所有排列的N球在M箱](https://stackoverflow.com/questions/27064675/generating-all-permutations-of-n-balls-in-m-bins) – Henrik
E.g. '库(分区)'; 'p < - 部分(9)'; 'p [,colSums(p> 6)== 0]'。 – Henrik
[所有可能的组合总和到目标值](https://stackoverflow.com/questions/32617501/all-possible-combinations-of-a-set-that-sum-to-a-target-价值) – Henrik