此问题的背景是资产分配。如果我有N个资产,并且可以以5%的块分配它们,那么存在的排列是什么,使得分配的总和恰好等于100%。
例如,如果我有2个资产,则会有21个(使用我的函数" fMakeAllocationsWeb(2)"在此帖子底部的代码创建:
[,1] [,2]
[1,] 0 100
[2,] 5 95
[3,] 10 90
[4,] 15 85
[5,] 20 80
[6,] 25 75
[7,] 30 70
[8,] 35 65
[9,] 40 60
[10,] 45 55
[11,] 50 50
[12,] 55 45
[13,] 60 40
[14,] 65 35
[15,] 70 30
[16,] 75 25
[17,] 80 20
[18,] 85 15
[19,] 90 10
[20,] 95 5
[21,] 100 0
当资产数量增加时,问题当然是适度的。这是可以理解的,因为重复的排列数是n ^(n)并且我不能分配创建所有排列到存储器的中间步骤。例如,有20个资产,排列数为5.84258701838598E + 27 !!
我希望能够动态过滤这些(sum == 100),以免遇到内存分配问题。深入研究gtools :: permutations下面的代码,它似乎是矢量化的,干预过滤似乎是不可能的。
非常感谢任何想法 - 理想情况下更愿意坚持使用R代码和包。
非常感谢
拉斯
installifMissing <- function(sPackageName) {
if (!sPackageName %in% installed.packages()) install.packages(sPackageName)
}
fMakeAllocationsWeb<-function(iNumAssets=10,iIncrement=5){
installifMissing("gtools")
require(gtools)
iAlloc<-seq(0,100,by=iIncrement) #'the allocation increments eg 0,5,10...,95,100
#'generate permutations
permut<-permutations(n=length(iAlloc),r=iNumAssets,v=iAlloc,repeats.allowed=TRUE)
#'filter permuatations for those which sum to exactly 100'
permutSum<-apply(permut,MARGIN=1,FUN=sum)
permut100<-permut[which(permutSum==100),]
return(permut100)
}
答案 0 :(得分:1)
如果您安装了partitions
软件包,那么您将拥有restrictedparts
函数,该函数将枚举您可以将 n 数字加在一起以获得总和 S的所有方法。在您的情况下,您希望将加数限制为5的倍数,限制是加起来 S = 100 。相反,将您的加数除以5并使总加起来为20.如果您想要2个资产,那么代码restrictedparts(100/5,2) * 5
将为您提供10个无序对。
然后,您可以循环遍历列,并为每个列枚举资产分配的所有排列集。您必须仔细处理存在重复元素的情况 - 例如,我们生成{100,0},其表示&lt; 100,0&gt;和&lt; 0,100&gt;而{50,50}仅代表单个分配&lt; 50,50&gt;。您可以使用set
permuatations
属性来处理此问题
restrictedparts(100/5,20) * 5
提供了627个分区,最多可达100% - 而且您需要对每个分区进行置换以获取完整的分配列表。
答案 1 :(得分:1)