例如, 该函数可能类似def RandABCD(n,.25,.34,。25,。25):
其中n是要生成的字符串的长度,以下数字是A,B,C,D的所需概率。
我认为这很简单,但是我在创建工作程序时遇到了麻烦。任何帮助将不胜感激。
答案 0 :(得分: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]))]
答案 1 :(得分:2)
随机类在python中非常强大。您可以使用适当的权重生成包含所需字符的列表,然后使用random.choice获取选择。
首先,确保随机导入。
例如,假设您想要一个来自A,B,C或D的真正随机字符串。 1.生成包含字符的列表 li = ['A','B','C','D']
你可以轻松地将这个函数作为n参数。
在上述情况下,您获得A,B,C或D的机会相等。
您可以使用列表中的重复条目为字符提供更高的概率。所以,举个例子,假设你想要A的概率为50%,B和C的概率为25%。你可以有这样一个数组:
li = ['A','A','B','C']
等等。
使用所需的权重参数化字符并不困难,以模拟我使用字典。
characterbasis = {'A':25,'B':25,'C':25,'D':25}
将它设为第一个参数,第二个参数为字符串的长度,并使用上面的代码生成字符串。
答案 2 :(得分:2)
对于四个字母,这里有一些快速的东西:
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)])
我毫不怀疑这可以变得更清洁/更短,我现在只是有点匆忙。
我不满足于Dakota使用重复字符列表的答案的原因是,根据您的概率,可能无法创建一个包含正确数字重复的列表来模拟您的概率想。 (好吧,我想这可能永远是可能的,但你可能最终需要一个巨大的清单 - 如果你的概率是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)])
答案 3 :(得分:0)
以下是您可能适合自己的概念
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)
答案 4 :(得分:0)
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()
应该让你大部分时间......
答案 5 :(得分:0)
谢谢大家的帮助,我能够解决一些问题,主要是这些信息。 根据我的特殊需要,我做了类似的事情:
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)