2014-03-24 31 views
0

此問題的上下文是資產分配。如果我有N個資產,並且可以以5%的塊來分配它們,那麼存在的排列是什麼,使得分配的總和恰好等於100%。過濾排列以避免內存不足

例如,如果我有2個資產會有用我的功能「fMakeAllocationsWeb(2)」的代碼在這個崗位的底部是21(創建:

 [,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) 
} 
+1

要做的第一件事:你想解決什麼問題?顯而易見,你不能對所有可能的組合做任何有用的事情(排列無關緊要)。那就是:你期望如何處理這些潛在的資產配置?例如,是否存在你想阻止的「非法」集?通過隨機添加資產來「移除」非100%連擊是很簡單的,直到您達到100%或者將最後剩下的選項強制爲一個使當前設置爲100%的值。 –

+0

好吧,公平點。我試圖解決的問題是繪製每個投資組合的預期回報與風險的雲。部分是管理的圖形化演示(「這是我們目前的投資組合相對於所有」可能的「投資組合),部分是爲了在數字上定義有效邊界。我爲保險公司工作,所以」風險「軸不是波動的,因此分析解決方案不是我可以看到你的隨機解決方案 - 我已經有類似的東西了,但不相信它涵蓋了全套「可能的」投資組合。 – russfx

+0

好吧,你的「雲」將會有儘可能多的維度與資產相關,因此基本上不可能可視化或顯示,如果您可以按照風險類(Vanguard和其他共同基金公司爲其客戶所做的事情)對資產進行分組,您可以顯着減少您需要的功能空間也就是說,如果有20個資產的所有風險都是'x',那麼選擇哪個資產並不重要,只是它們的總和爲%。 –

回答

1

如果你安裝了partitions包,你有restrictedparts功能將枚舉所有的方式,你可以添加ň數相加得到一個總和小號。在你的情況下,你想限制加數爲5的倍數,限制是加起來S = 100。相反,你的加權除以5,總加起來最多20.如果你想要2個資產,那麼代碼restrictedparts(100/5,2) * 5會給你10個無序對。

然後,您可以遍歷列並枚舉資產分配的所有排列組。您必須仔細處理存在重複元素的情況 - 例如,我們生成代表< 100,0>和< 0,100>的{100,0},而{50,50}僅代表單個分配< 50 ,50>。您可以處理這種通過使用permuatations

restrictedparts(100/5,20) * 5set屬性給出了627周的分區,加起來就是100% - 而你需要每個置換這些讓你分配的完整列表。

+0

非常感謝您花時間回答並解釋輸出。我可以按照你的建議生成分區。我並不真正遵循「你可以通過使用permuatations的set屬性來處理這個問題」和「你需要對這些中的每一個進行排列以獲得你的完整分配列表」......我會非常感謝,如果你能舉一個例子來說明如何把這個集合變成受限制的排列。我感謝你的耐心;我是一名精通精算師的工程師,而不是數學家! – russfx

+0

例如,對於3個資產,您將{80,10,10}作爲'restrictedparts(100/5,3)* 5'中的一列。然後你使用'permutations(3,3,c(80,10,10),set = FALSE)'產生所有這些排列 - 我們用set = FALSE來停止兩個10的合併。你可以把它包裝在一個「獨特的(...)」中以得到三個真正的排列。 –

+0

很清楚,謝謝! – russfx

1

在你的問題中,即使在過濾之後,仍然會有大量的組合處理。

您的問題,基本上如所描述here 你要選擇5%權重的K = 20個插槽各以從n個資產分配歸結爲n multichoose k問題。

所以在20個資產的例子情況下,你的組合數仍然會

choose(39, 20) 
## [1] 68923264410 

我建議你看看DEoptim包,其中有直接關係,在手你的問題的具體例子。它使用差分進化。

+0

哼哈哈,這是一個非常大的數字!正如你所建議的,我可能不得不適應(沒有雙關語意圖)我的方法。我們可以使用evolver模型,但需要一些工作。可悲的是,投資組合模型目前在Excel中(對不起,我可以做的不多!!)感謝您的幫助! – russfx

相關問題