2012-05-23 39 views
0

以下問題:擁有基礎三元組(0,1,0)創建概率列表

現在我嘗試在給定範圍內創建已更改三元組的列表。

約束:

  1. 三重[0]和三[2]具有應該有一個最大R,例如爲R = 0.2
  2. 總和(三重)= 1
  3. 三重[0 ]不需要是等於三倍[1],並應通過一個給定的臺階狀參數s被增加,如S = 0.02

在該上述實施例提供了梅索德應該創建

lst = [(0.0, 1, 0.0),(0.02, 0.98, 0.), (0.04, 0.96,0), (0.04,0.94, 0.02), (0.06,0.94,0), (0.06, 0.92, 0.02), (0.06, 0.9, 0.04), ...] 

有沒有什麼漂亮的方法可以做到這一點?

也許你有一個想法,創建這些列表沒有嵌套循環(可能與numpy?)。

非常感謝!

+2

究竟是你想做些什麼?你有什麼嘗試? –

+0

非常複雜的細節,但我需要此列表進行模擬切換參數 –

+0

您似乎暗示三重[0]>三重[2]的約束......是故意的嗎? –

回答

1

下面是一個列表理解,應該提供滿足約束條件的所有3元組(根據我的理解)。它更有點笨重,比我想由於範圍函數只接受整數:

r = 0.2 
s = 0.02 
steps = int(math.ceil(r/s)) 
lst = [(a*s, 1-(a+b)*s, b*s) for b in range(steps) for a in range(steps)] 

結果:

>>> lst[0:4] 
[(0.0, 1.0, 0.0), (0.02, 0.98, 0.0), (0.04, 0.96, 0.0), (0.06, 0.94, 0.0)] 
>>> lst[90:94] 
[(0.0, 0.8200000000000001, 0.18), (0.02, 0.8, 0.18), (0.04, 0.78, 0.18), (0.06, 0.76, 0.18)] 

的第一和最後一個值只上升到0.18這個代碼,我不確定這是否合意(是否約束< r或< = r?)。如果你想用另一種方式調整它,不應該太難調整。

+0

很好的理解使用! – James

+0

好的答案! +1這就是我稱之爲「漂亮的解決方案」。我以前做的檢查,如果的調整僅僅是:「步驟= INT(math.ceil(R/S))+ 1」非常感謝 –

+0

我覺得加1無條件將錯的,如果r是不是S的整數倍。嘗試「steps = int(math.floor(r/s))+ 1」。這將在所有情況下獲得下一個更高的整數(即使分割後已經有整數)。另外,我對這個問題發表了一些評論,值得注意的是,列表理解(有兩個「for _ in _」子句)相當於一對嵌套循環。 – Blckknght

1

您可以創建一個功能,使三聯你描述......一些諸如:

def make_triple(r=0.2, s=0.02): 
    element_one = round(random.uniform(0, r), 2) 
    max_s = r/s 
    element_three = random.randint(0, max_s) * s 
    element_two = round(1 - element_one - element_three, 2) 
    return (element_one, element_two, element_three) 

然後就是創建一個單一的循環中調用該函數:

list_of_triples = [] 
for i in range(5): 
    list_of_triples.append(make_triple(0.2, 0.02)) 

而且你去!沒有必要的嵌套循環。

+0

這個功能看起來不錯,但不適合給定約束 –

+0

我剛纔編輯的max_s變量,以適應​​第三個元素是小於r的constrant。還有我錯過了嗎? – James

0

這是一個NumPy解決方案,沒有for循環,根據要求。它使用3D數組和NumPy廣播規則逐行和逐列地分配比例。 scale是一個單列的二維數組,因此它可以方便地被.T轉換。最後,3D陣列被重塑爲2D。

import numpy as np 

r = .2 
s = .02 

scale = np.arange(r, step=s, dtype=float).reshape(-1,1) 
a = np.empty((len(scale),len(scale),3), dtype=float) 
a[:,:,0] = scale 
a[:,:,2] = scale.T 
a[:,:,1] = 1 - a[:,:,0] - a[:,:,2] 

print a.reshape(-1,3) 
1

另一個numpy的答案只是踢:

import numpy as np 
r = .2 
s = .02 

a, b = np.mgrid[0:r:s, 0:r:s] 
lst = np.dstack([a, 1 - (a+b), b]).reshape(-1, 3)