R: Generating all permutations of N weights in multiples of P

前端 未结 2 1978
夕颜
夕颜 2020-12-17 05:10

I need to create a function (in R) which:
- given N possible variables to attribute weights to;
- creates all possible permuations of weights (summing to 10

2条回答
  •  生来不讨喜
    2020-12-17 06:02

    EDIT : function is updated, as it gave some results twice.

    You can try this function, based on recursive calculation. It will give you all possible combinations, regardless of the order. I've done it this way, as you otherwise get a multiple of the rows with all possible permutations.

    The calculation is based on integers. The minimum weight P is set as 1, and Pint becomes the number of weight units that can be divided. max.W will be the maximum amount of units that can be given to one variable.

    The algorithm goes as follows :

    • if N=2, then make all possible combinations for the given minimum and maximum weight.

    • if N > 2, apply this algorithm for N = 1 to ceiling(max.weight / N), with the maximum weight specified as the current maximum weight +1 minus N, and the minimum weight as N.

    This gives you all possible combinations of integers. Multiplication with P gives the original weights.

    Or in function :

    myfunc <- function(N,P){
      if(100%%(P*100) !=0){
        stop("100% cannot be divided in portions of P")
      }
      Pint <- 100/(P*100)
      max.W <- Pint- N + 1
    
      combs <- function(n,max.w,min){
        mw <- max.w + 1
    
        if(n==2){
    
          w <- seq.int(min,floor((mw)/2))
          out <- cbind(w,mw-w)
    
        } else if (n > 2){
    
          x <- lapply(1:ceiling(max.w/n),function(i){
    
            newcombs <- combs(n-1,mw-i,i)
            cbind(newcombs,rep(i,nrow(newcombs)))
    
          })
    
          out <- do.call("rbind",x)
        }
        colnames(out) <-rownames(out) <- NULL
        out
      }  
      res <- combs(N,max.W)
      apply(res,1,sort)*P
    }
    

    This gives the combinations in columns of a matrix :

    > Y <- myfunc(3,0.1)
    > Y
         [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
    [1,]  0.1  0.1  0.1  0.1  0.2  0.2  0.2  0.3
    [2,]  0.1  0.2  0.3  0.4  0.2  0.3  0.4  0.3
    [3,]  0.8  0.7  0.6  0.5  0.6  0.5  0.4  0.4
    

    Be warned! with the testcase you gave (7 variables, jumps of 0.01), you'll be calculating a very long time for the huge amounts of possibilities. With N=7 and P=0.04, you have already 3555 possible combinations. With N=0.2, that becomes 336,443 possibilities. And you have to take into account every possible permutation of these combinations if that is what you're after.

提交回复
热议问题