日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python 求组合数最快方法_Python-生成符合条件的大集合组合的最有效方法?

發(fā)布時間:2024/9/27 python 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python 求组合数最快方法_Python-生成符合条件的大集合组合的最有效方法? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

我正在嘗試根據(jù)邊界條件生成投資組合中金融工具的所有可能組合.

例如,假設(shè)我有一個列表集合,這些列表代表對投資組合的分配,但要以每種工具在投資組合總規(guī)模中的最小和最大百分比為準(zhǔn):

"US Bonds" = {0.10,0.15,0.20,0.25,0.30}

"US Equities" = {0.25, 0.30, 0.35, 0.40, 0.45, 0.50}

"European Bonds" = {0.10, 0.15, 0.20}

"European Equities = {0.20,0.25,0.30,0.35,0.40,0.45,0.50}

...

"Cash" = {0.0, 0.05, 0.10, 0.15,...0.95}

我的清單資產(chǎn)因此如下所示:

[In]

Asset

[Out]

[[0.1, 0.15, 0.2, 0.25, 0.30],

[0.25, 0.30,0.35, 0.40, 0.45, 0.50],

[0.1, 0.15, 0.2],

[0.20, 0.25, 0.30,0.35, 0.40, 0.45, 0.50]

...

[0.0, 0.05, 0.1, 0.15, 0.2, 0.25,...0.95]]

在所有工具組合的總和必須等于1的標(biāo)準(zhǔn)下,產(chǎn)生所有可能的投資組合的最有效方法是什么?

現(xiàn)在,我將創(chuàng)建一個列表“投資組合”,如下所示:

portfolios = [item for item in itertools.product(*asset) if np.isclose(sum(item),1)]

(nb,“ np.isclose”用于處理時髦的fp算法).

我已經(jīng)將資產(chǎn)類別和可能的分配表示為列表的集合,但想知道是否存在其他更快的數(shù)據(jù)表示形式(例如NumPY數(shù)組).

關(guān)于各種組合的最佳執(zhí)行存在一些問題,但是我沒有看到任何具有任何邊界條件的情況.

解決方法:

首先,我將百分比表示為整數(shù)值,以避免浮點舍入錯誤.

其次,最有效的方法將使用邊界來避免查看可能無法滿足== 1約束的投資組合.

您要編寫的循環(huán)將這樣運行:

def portfolios():

for us_bonds in [ 10, 15, 20, 25, 30 ]:

if us_bonds > 100: break

for us_equaties in [ 25, 30, 35, 40, 45, 50 ]:

if us_bonds + us_equaties > 100: break

for euro_bonds in [ 10, 15, 20 ]:

if us_bonds + us_equaties + euro_bonds > 100: break

for euro_equaties in [ 20, 25, 30, 35, 40, 45, 50 ]:

if us_bonds + us_equaties + euro_bonds + euro_equaties > 100: break

cash = 100 - (us_bonds + us_equaties + euro_bonds + euro_equaties)

yield [us_bonds, us_equaties, euro_bonds, euro_equaties, cash]

這定義了一個生成器,您可以在for循環(huán)中使用它,如下所示:

for x in portfolios(): print x

這種方法之所以有效,是因為它避免構(gòu)造超過== 100約束的投資組合.

還要注意,我們利用了“現(xiàn)金”百分比基本上可以是任何東西這一事實,因此它只占用了100%與其他投資類別的總和之間的差額.

以下函數(shù)針對任意數(shù)量的投資類別概括了此循環(huán):

def gen_portfolio(categories):

n = len(categories)

tarr = [0] * (n+1)

parr = [0] * (n+1)

karr = [0] * (n+1)

marr = [ len(c) for c in categories ]

i = 0

while True:

while True:

if i < n:

p = categories[i][ karr[i] ]

t = tarr[i] + p

if t <= 100:

parr[i] = p

tarr[i+1] = t

i += 1

karr[i] = 0

continue

else:

break # backup

else:

parr[n] = 100 - tarr[n] # set the Cash percentage

yield parr[:] # yield a copy of the array parr

break

# backup

while True:

if i > 0:

i -= 1

karr[i] += 1

if karr[i] < marr[i]: break

else:

return # done!

def portfolios2():

cats = [ [ 10, 15, 20, 25, 30 ], [ 25, 30, 35, 40, 45, 50 ], [ 10, 15, 20 ], [ 20, 25, 30, 35, 40, 45, 50 ] ]

return gen_portfolio(cats)

這是一個測試,表明它們產(chǎn)生了相同的結(jié)果:

def compareTest():

ports1 = [ x for x in portfolios() ]

ports2 = [ x for x in portfolios2() ]

print "ports1 length:", len(ports1)

print "ports2 length:", len(ports2)

for x in ports1:

if x not in ports2: print "not in ports2:", x

for x in ports2:

if x not in ports1: print "not in ports1:", x

更新資料

這是一個示例,演示了此方法與itertools.product之間的區(qū)別.

假設(shè)有10個投資類別,每個類別的百分比為[90,91,..,99].帶break語句的嵌套循環(huán)將按以下步驟進行:

start the loop: for p1 in [90,91,..,99]

set p1 = 90

p1 < 100 so continue

start the loop: for p2 in [90,91,..,99]

set p2 = 90

p1 + p2 > 100, so break out of the p2 loop

set p1 = 91

p1 < 100 so continue

start the loop: for p2 in [90,91,..,99]

set p2 = 90

p1 + p2 > 100, so break out of the p2 loop

set p1 = 92

...

因此帶有break語句的嵌套循環(huán)僅查看10種情況-p1 = 90、91,..,99和p2 =90.p2的值永遠不會大于90,并且永遠不會嘗試將任何內(nèi)容分配給p3,p4,… ,第10頁.

另一方面,itertools.product將生成所有100個案例,然后您必須過濾出總和大于的那些組合. 100

對于某些輸入,itertools.product可能會更快,因為它是用C編寫的,但它不會根據(jù)當(dāng)前選擇的總和對大小寫進行任何修剪.

標(biāo)簽:combinations,combinatorics,python,numpy

來源: https://codeday.me/bug/20191119/2036168.html

總結(jié)

以上是生活随笔為你收集整理的python 求组合数最快方法_Python-生成符合条件的大集合组合的最有效方法?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。