Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 从求和到所需总数的值列表中确定所有可能的组合_R_For Loop_Combinations - Fatal编程技术网

R 从求和到所需总数的值列表中确定所有可能的组合

R 从求和到所需总数的值列表中确定所有可能的组合,r,for-loop,combinations,R,For Loop,Combinations,我的一个朋友问我一个编程问题,关于如何确定一个集合中所有可能的值组合可以相加,以得到所需的总数。我有一个解决方案,但它不够优雅(它基本上只是一系列for循环和if语句)。我确信dplyr有一个我想不出的解决方案,因为我知道它有多有用,但我只是还没有在这方面做得很好。我将把问题和我的脚本贴在下面 问题: 有一个目标上有六个环,每个环值不同。这些值为1、2、3、4、5或6。你可以使用多少种不同的戒指组合来获得9分 因此,我们要考虑: 秩序并不重要 您可以使用任意数量的值 您可以多次获得相同的值(因此

我的一个朋友问我一个编程问题,关于如何确定一个集合中所有可能的值组合可以相加,以得到所需的总数。我有一个解决方案,但它不够优雅(它基本上只是一系列for循环和if语句)。我确信dplyr有一个我想不出的解决方案,因为我知道它有多有用,但我只是还没有在这方面做得很好。我将把问题和我的脚本贴在下面

问题: 有一个目标上有六个环,每个环值不同。这些值为1、2、3、4、5或6。你可以使用多少种不同的戒指组合来获得9分

因此,我们要考虑: 秩序并不重要 您可以使用任意数量的值 您可以多次获得相同的值(因此9 1是一个完全有效的选项)

我曾考虑过首先使用combinat包中的combn(),但combn()并不替换值

然后我决定使用一系列嵌套的for循环和if语句(我将其截断为最多只能使用6个值,因为虽然我可能有空闲时间,但我不是一个将要编写最多允许9个值的循环的受虐狂)。所以本质上,它是通过6个循环运行的,循环值可能是多少。当我只需要2个值而不是6个值时,我将数字0包括在可能值列表中,以表示不尝试(因此4+5+0+0+0+0在这个循环中是有效的输出,但它无法执行4+5,因为它总是尝试添加更多的非零值)

我创建了一个空的data.frame来存储解决方案,然后在循环中,我创建了一个测试,以查看循环中的新解决方案是否匹配以前找到的值的组合,如果匹配,则不会将其rbind()绑定到data.frame


我相信有更好的方法可以做到这一点,它允许动态最大值(因此在这种情况下可以软编码,将每个解决方案中的最大值更改为9,而不是硬编码的6,或者如果我想要的总数是5而不是9,则将其降低到5)。如果您有任何建议,以使这不是一个笨重的,循环填充混乱,将不胜感激

您可以尝试以下方法:

    library(modelr)
    library(dplyr)
    range = 1:6
    df = data.frame("a" = range,
              "b" =  range,
              "c" =  range,
              "d" =  range,
              "e" =  range,
              "f" =  range)
    data_grid(df,a,b,c,d,e,f) %>% 
      mutate(sum = a+b+c+d+e+f) %>% 
      filter(sum == 9) %>% nrow
这就是功能:

foo <- function(sum_needed, max_value){
  range <- 1:max_value
  df = data.frame("a" = range,
                "b" =  range,
                "c" =  range,
                "d" =  range,
                "e" =  range,
                "f" =  range)
  result <- data_grid(df,a,b,c,d,e,f) %>% 
    mutate(sum = a+b+c+d+e+f) %>% 
    filter(sum == sum_needed) %>% nrow
  return(result)
}
foo(9,6)
#[1] 56
foo%n现在
返回(结果)
}
傅(9,6)
#[1] 56
以下应列出所有组合

sapply(1:max(floor(mysum/x)), function(i){
    temp2 = unique(t(combn(temp, i)))
    temp2[rowSums(temp2) == mysum,]
    })

相关:;例如
库(分区)
<代码>p6)==0]。这看起来很棒!谢谢我也要用一些其他数字来试试。最初的问题有值(16,17,23,24,39,40)和期望的总数100,我只选择了这些值,因为特定的数字集只有一个答案,所以它不是很有趣(16+16+17+17+17)。从外观上看,此解决方案也适用于这组数字。谢谢!我喜欢dplyr的管道,这真的是我没有花时间去真正习惯使用的东西。值得注意的是,你和下面的d.b得出了不同的数字,我认为你的数字是错误的。我认为目前的问题是排列与组合。这里将1+1+1+1+1+4识别为不同于4+1+1+1+1+1。我认为,如果管道在过滤器之后结束,那么您将得到所有可行解决方案的data.frame,然后您将找到一种方法来检查唯一的组合,这应该可以做到,而不是直接对非唯一的组合进行检查。
x = 1:6
mysum = 9

#Repeat each element of x as long the sum of repetitions does not exceed mysum
temp = rep(x, floor(mysum/x))

#Calculate total unique combinations of temp that sum up to mysum
sum(sapply(1:max(floor(mysum/x)),
           function(i) sum(rowSums(unique(t(combn(temp, i)))) == mysum)))
#[1] 26
sapply(1:max(floor(mysum/x)), function(i){
    temp2 = unique(t(combn(temp, i)))
    temp2[rowSums(temp2) == mysum,]
    })