我正在尝试制作一个矩阵,其中包含1到100之间的5个数字的所有组合(整数),总和为100.如果我可以为每个5个数字设置最小值和最大值,那么这个数字会更大。 我做的简单方法是做5个嵌套循环。
for (a in min:max )
{
for (b in min:max )
{
for (c in min:max)
{
for(d in min:max)
{
for (e in min:max)
{
for (f in min:max)
{
for (g in min:max)
{
for (h in min:max)
{
port <- c (a,b,c,d,e,f,g,h)
if(a+b+c+d+e+f+g+h==100) {portif <- rbind(port,portif)}
}}}}}}}}
但我很确定在R中有一种比这些预处理慢速循环更好的方法。
编辑: - 是的,订单很重要
如果我可以为每个a,b,c设置不同的最小值和最大值,那就更大了。
非常感谢你的帮助
答案 0 :(得分:4)
获取所有(choose(100, 5)
生成75287520
)组合:
x <- combn(1L:100L, 5)
计算列总和并检查哪个等于100
:
x[, colSums(x) == 100]
导致25337
组合,例如:
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 4 90
[2,] 1 2 3 5 89
[3,] 1 2 3 6 88
[4,] 1 2 3 7 87
[5,] 1 2 3 8 86
...
答案 1 :(得分:1)
动态编程对您来说可能更快,但实施起来更难。这是一个递归解决方案:
f <- function(min, max, cnt) {
if(max < min) return(NULL)
if(cnt == 1) return(max)
do.call(rbind, lapply(min:max,
function(i){
X <- f(min, max-i, cnt-1)
if(!is.null(X)) cbind(i, X)
})
)
}
要不包含同一组的排列,可以将递归更改为
X <- f(i+1, max-i, cnt-1)
//编辑:要为每个图层设置不同的最小值和最大值,您可以创建最小和最大矢量,然后将使用情况更改为例如min[cnt]
;您可能还想将订单交换到cbind(X,i)以获得理智。
答案 2 :(得分:0)
比你,你的两个代码都快得多 我找到了另外一些看起来非常好的代码
library("partitions")
numparts <- 8
sumparts <- 20
weights <- compositions(n=sumparts, m=numparts, include.zero=TRUE)/sumparts