例如, 函數可能類似於def randABCD(n,.25,.34,.25, 0.25):我需要一個Python函數,當給出所需的字符概率時,它將輸出一個4個不同字符的隨機字符串
其中n是要生成的字符串的長度和下面的數字是A,B,C的期望概率,D.
我可以想象這是相當簡單的,但是我在創建工作程序時遇到困難。任何幫助將不勝感激。
例如, 函數可能類似於def randABCD(n,.25,.34,.25, 0.25):我需要一個Python函數,當給出所需的字符概率時,它將輸出一個4個不同字符的隨機字符串
其中n是要生成的字符串的長度和下面的數字是A,B,C的期望概率,D.
我可以想象這是相當簡單的,但是我在創建工作程序時遇到困難。任何幫助將不勝感激。
謝謝大家的幫助,我能夠找出一些東西,主要是這個信息。 對於我的特殊需求,我做了這樣的事情:
import random
#Create a function to randomize a given string
def makerandom(seq):
return ''.join(random.sample(seq, len(seq)))
def randomDNA(n, probA=0.25, probC=0.25, probG=0.25, probT=0.25):
notrandom=''
A=int(n*probA)
C=int(n*probC)
T=int(n*probT)
G=int(n*probG)
#The remainder part here is used to make sure all n are used, as one cannot
#have half an A for example.
remainder=''
for i in range(0, n-(A+G+C+T)):
ramainder+=random.choice("ATGC")
notrandom=notrandom+ 'A'*A+ 'C'*C+ 'G'*G+ 'T'*T + remainder
return makerandom(notrandom)
隨機類在Python中非常強大。您可以根據適當的權重生成所需字符的列表,然後使用random.choice來獲取選擇。
首先,確保你做一個隨機導入。
例如,假設您想要A,B,C或D中的一個真正的隨機字符串。 1.使用字符 li = ['A','B','C' 'd']
你可以很容易地用n作爲參數來創建一個函數。
在上述情況下,你獲得A,B,C或D.
您可以使用重複的條目列表中的給人物的概率更高的機會均等。所以,舉個例子,假設你想要A和B分別有50%的機會和25%的機會。你可以有一個這樣的數組:
LI = [ 'A', 'A', 'B', 'C']
等。
這將是不難的參數化字符進入期望的權重,以模型,我會用字典。
characterbasis = { 'A':25, 'B':25, 'C':25, 'd':25}
作出這樣的第一個參數,以及第二個是字符串的長度並使用上面的代碼來生成你的字符串。
對於四個字母,這裏的東西快了我的頭頂部:
from random import random
def randABCD(n, pA, pB, pC, pD):
# assumes pA + pB + pC + pD == 1
cA = pA
cB = cA + pB
cC = cB + pC
def choose():
r = random()
if r < cA:
return 'A'
elif r < cB:
return 'B'
elif r < cC:
return 'C'
else:
return 'D'
return ''.join([choose() for i in xrange(n)])
我毫不懷疑,這是可以做出更清潔/更短的,我只是有點着急權現在。
我不會滿足於David在達科塔的答案中使用重複字符列表的原因是,根據您的概率,可能無法在正確的數字中創建重複列表以模擬概率你要。 (好吧,我想這可能總是可能的,但是你可能需要一個巨大的清單 - 如果你的概率是0.11235442079,0.4072777384,0.2297927874,0.25057505341?)
編輯:這裏有一個更清潔的通用版本,與任意數量的字母與任何權重的工作原理:
from bisect import bisect
from random import uniform
def rand_string(n, content):
''' Creates a string of letters (or substrings) chosen independently
with specified probabilities. content is a dictionary mapping
a substring to its "weight" which is proportional to its probability,
and n is the desired number of elements in the string.
This does not assume the sum of the weights is 1.'''
l, cdf = zip(*[(l, w) for l, w in content.iteritems()])
cdf = list(cdf)
for i in xrange(1, len(cdf)):
cdf[i] += cdf[i - 1]
return ''.join([l[bisect(cdf, uniform(0, cdf[-1]))] for i in xrange(n)])
這裏是什麼可能適合你
import random as r
def distributed_choice(probs):
r= r.random()
cum = 0.0
for pair in probs:
if (r < cum + pair[1]):
return pair[0]
cum += pair[1]
一個粗略的想法參數probs
獲取表單(對象,概率)對的列表。假定概率之和是1(否則,它的平凡歸一化)。
要使用它,執行:
''.join([distributed_choice(probs)]*4)
下面是選擇單個加權值的代碼。你應該可以從這裏拿走它。它使用bisect和random來完成這項工作。
from bisect import bisect
from random import random
def WeightedABCD(*weights):
chars = 'ABCD'
breakpoints = [sum(weights[:x+1]) for x in range(4)]
return chars[bisect(breakpoints, random())]
這樣稱呼:WeightedABCD(.25, .34, .25, .25)
。
編輯:這裏是即使權重加起來也不到1.0可用的版本:
from bisect import bisect_left
from random import uniform
def WeightedABCD(*weights):
chars = 'ABCD'
breakpoints = [sum(weights[:x+1]) for x in range(4)]
return chars[bisect_left(breakpoints, uniform(0.0,breakpoints[-1]))]
嗯,是這樣的:
import random
class RandomDistribution:
def __init__(self, kv):
self.entries = kv.keys()
self.where = []
cnt = 0
for x in self.entries:
self.where.append(cnt)
cnt += kv[x]
self.where.append(cnt)
def find(self, key):
l, r = 0, len(self.where)-1
while l+1 < r:
m = (l+r)/2
if self.where[m] <= key:
l=m
else:
r=m
return self.entries[l]
def randomselect(self):
return self.find(random.random()*self.where[-1])
rd = RandomDistribution({"foo": 5.5, "bar": 3.14, "baz": 2.8 })
for x in range(1000):
print rd.randomselect()
應該讓你最的方式...
請發表您到目前爲止的代碼。當我們看到你嘗試過的東西時,幫助你更容易。 – 2009-04-13 14:49:49
檢測到家庭作業氣味。 – Welbog 2009-04-13 14:50:23
作爲示例,函數如何知道它需要哪些4個字符來衡量概率? – 2009-04-13 14:51:42