python – 使用概率表生成长度为K的N“随机”字符串

如何使用概率表创建长度为K的N“随机”字符串? K会是偶数.

prob_table = {'aa': 0.2, 'ab': 0.3, 'ac': 0.5}

假设K = 6,’acacab’的可能性高于’aaaaaa’.

这是我用于基于概率表生成合成序列的更大问题的子问题.我不确定如何使用概率表生成“随机”字符串?

到目前为止我所拥有的:

def seq_prob(fprob_table,K= 6, N= 10):
    #fprob_table is the probability dictionary that you input
    #K is the length of the sequence
    #N is the amount of sequences
    seq_list = []
    #possibly using itertools or random to generate the semi-"random" strings based on the probabilities 
    return seq_list

解决方法:

有一些很好的方法来制作at the end of the documentation for the builtin random module描述的加权随机选择:

A common task is to make a random.choice() with weighted probabilities.

If the weights are small integer ratios, a simple technique is to build a sample population with repeats:

>>> weighted_choices = [('Red', 3), ('Blue', 2), ('Yellow', 1), ('Green', 4)]
>>> population = [val for val, cnt in weighted_choices for i in range(cnt)]
>>> random.choice(population)
'Green'

A more general approach is to arrange the weights in a cumulative distribution with itertools.accumulate(), and then locate the random value with bisect.bisect():

>>> choices, weights = zip(*weighted_choices)
>>> cumdist = list(itertools.accumulate(weights))
>>> x = random.random() * cumdist[-1]
>>> choices[bisect.bisect(cumdist, x)]
'Blue'

为了使后一种方法适应您的具体问题,我会这样做:

import random
import itertools
import bisect

def seq_prob(fprob_table, K=6, N=10):
    choices, weights = fprob_table.items()
    cumdist = list(itertools.accumulate(weights))

    results = []
    for _ in range(N):
        s = ""
        while len(s) < K:
            x = random.random() * cumdist[-1]
            s += choices[bisect.bisect(cumdist, x)]
        results.append(s)

    return results

这假设概率表中的关键字符串长度相同如果它们有多个不同的长度,则此代码有时(可能大部分时间!)给出长于K个字符的答案.我想它也假设K是密钥长度的精确倍数,但如果不是真的那么它实际上会起作用(它只会给出比K字符都长的结果字符串,因为没有办法准确地得到K).

上一篇:如何从表示环肽的字符串生成子肽(特殊组合)?


下一篇:2个列表的Python组合(1个重复,1个非重复)