这个问题结合了分子生物学中的限制性酶(restriction enzymes)的概念和概率统计学的应用。
生物背景:
- 限制性酶:细菌使用这些酶来切割病毒DNA的双链,从而使病毒失去功能。这些酶在病毒DNA上切割的位置被称为限制位点。
- 识别序列:每种限制性酶都预设了一个反向回文的DNA间隔作为其结合并切割的识别序列。这些间隔通常是偶数长度,一般是4或6个碱基对长,尽管也存在更长的识别序列。
计算问题:
- 问题提出了一个简单的问题:细菌如何“知道”它在病毒DNA中找到限制位点的可能性很高?答案是识别序列的短长度保证了大量的随机匹配发生。
- 例如,一个长度为6的识别序列平均每4096个碱基对出现一次,但这并不意味着相关的限制性酶每4096个碱基对就切割一次病毒DNA;它可能在相邻的地方找到两个限制位点,然后在许多千个核苷酸中都不找到限制位点。
-
计算单个碱基出现的概率: 根据GC含量,我们可以计算每种碱基的出现概率。例如,如果GC含量为0.5,则G和C的出现概率各为0.25(因为GC含量是G和C的总和),而A和T的出现概率也各为0.25。
-
计算子串出现的概率: 对于特定的DNA子串,其出现的概率是其所有碱基出现概率的乘积。例如,对于子串"AG",如果A和G的出现概率分别为0.25和0.25,则"AG"出现的概率是0.25 × 0.25 = 0.0625。
-
计算整个序列中子串出现的预期次数: 在长度为n的DNA序列中,有n−∣s∣+1个可能的起始位置来放置长度为∣s∣的子串s(其中∣s∣是子串的长度)。因此,子串s出现的预期次数是每个位置出现子串的概率之和,即(n−∣s∣+1)×子串出现的概率。
-
应用于数组A中的每个GC含量: 对于数组A中的每个GC含量值,重复上述步骤来计算子串在相应GC含量下出现的预期次数,并将结果存储在数组B中。
举个例子,对于样本数据集:
- DNA字符串长度 n=10。
- DNA字符串 s="AG"。
- GC含量数组 A=[0.25,0.5,0.75]。
我们需要分别对每个GC含量值计算"AG"出现的预期次数。假设在GC含量为0.25时,A和T的概率为0.375,G和C的概率为0.125,那么"AG"出现的概率为0.375 × 0.125 = 0.046875。因此,在长度为10的序列中,"AG"出现的预期次数为(10−2+1)×0.046875=9×0.046875=0.422(10−2+1)×0.046875=9×0.046875=0.422。同样的方法应用于其他GC含量值。
代码:
data = []
with open('', 'r') as f:for line in f:data.append(line.strip('\n'))
n = int(data[0])
s = data[1]
A = [float(x) for x in data[2].split()]AT, GC = 0, 0
for nt in s:if nt == 'A' or nt == 'T':AT += 1elif nt == 'G' or nt == 'C':GC += 1B = [0]*len(A)
for i, j in enumerate(A):P = (((1 - j)/2)**AT)*((j/2)**GC)*(n - len(s)+1)B[i] = '%0.3f' % P
print(*B, sep=' ')