2

作为即将到来的生物信息学课程的准备,我正在做一些来自 rosalind.info 的作业。我目前被困在“孟德尔第一定律”的作业中。

我想我可以通过这个蛮力强迫自己,但不知何故,我的想法一定太复杂了。我的方法是这样的:

建立一个具有三个级别的概率树。有两种生物交配,生物 A 和生物 B。第一级是,选择生物 A 纯合显性 (k)、杂合 (m) 或纯合隐性 (n) 的概率是多少。似乎以纯合显性为例,因为总共有 (k+m+n) 个生物,其中 k 个是纯合显性的,所以概率是 k/(k+m+n)。

然后在这棵树中,假设我们知道 A 被选为什么生物,那么在每一个下面都会出现生物 B 为 k / m / n 的概率。例如,如果生物 A 被选为杂合子 (m),那么生物 B 也是杂合子的概率为 (m-1)/(k+m+n-1),因为现在剩下的杂合子少了一个。

这将给出两个级别的概率,并且会涉及大量代码以达到这一点,因为我实际上是在构建一个树形结构,并且每个分支都为该部分手动编写了代码。

在此处输入图像描述

现在选择生物 A 和 B 后,他们每个人都有两条染色体。这些染色体之一可以随机挑选。所以对于 A 染色体 1 或 2 可以被挑选出来,对于 B 来说也是一样的。所以有 4 种不同的选择:挑选 A 的 1,挑选 B 的 1。挑选 A 的 2,挑选 B 的 1。挑选 A 的 1,挑选 B 的 2。挑选A 中的 2 个,B 中的 2 个。这些中的每一个的概率都是 1/4。所以最后这棵树会有这些叶子概率。

然后从那里以某种方式通过魔术我将所有这些概率加起来,看看两种生物产生具有显性等位基因的生物的概率是多少。

我怀疑这项任务是否旨在花费数小时来解决。我在想什么?

更新:

以最荒谬的蛮力方式解决了这个问题。只需运行数千次模拟交配并找出最终具有显性等位基因的部分,直到有足够的精度来通过分配。

import random
k = 26
m = 18
n = 25

trials = 0
dominants = 0

while True:
    s = ['AA'] * k + ['Aa'] * m + ['aa'] * n
    first = random.choice(s)
    s.remove(first)
    second = random.choice(s)
    has_dominant_allele = 'A' in [random.choice(first), random.choice(second)]
    trials += 1
    if has_dominant_allele:
        dominants += 1
    print "%.5f" % (dominants / float(trials))
4

6 回答 6

5

具有显性等位基因的物种要么是AA要么Aa

您的总种群(k + n + mk( hom) 具有 的纯合显性生物AAm( het) 具有 的杂合显性生物Aan( rec) 具有 的纯合隐性生物aa组成。这些生物中的每一个都可以与任何其他生物交配。

具有显性等位基因的生物的概率为:

P_dom = n_dominant/n_total or 1 - n_recessive/n_total

对这些组合中的每一个进行 Punnett 方阵并不是一个坏主意:

  hom + het

  |  A | a
-----------
A | AA | Aa
a | Aa | aa


  het + rec

  |  a | a
-----------
A | Aa | Aa
a | aa | aa

显然,两种生物的交配会产生四个可能的孩子。hom+het产生 4 个具有隐性等位基因的生物体中的 1 个,het+rec产生 4 个具有隐性等位基因的生物体中的 2 个。

您可能也想对其他组合执行此操作。

由于我们不仅仅是将生物体一对一地交配,而是将k + m + n一大堆放在一起,因此很高兴知道后代的总数和具有特定等位基因的“孩子”的数量。

如果你不介意一点 Python,combfromscipy.misc在这里可能会有所帮助。在计算中,不要忘记(a)您4从每个组合中得到孩子,以及(b)您需要一个因子(来自 Punnett 方格)来确定组合中的隐性(或显性)后代。

更新

    # total population
    pop_total = 4 * comb(hom + het + rec, 2)

    # use PUNNETT squares!

    # dominant organisms         
    dom_total = 4*comb(hom,2) + 4*hom*het + 4*hom*rec + 3*comb(het,2) + 2*het*rec

    # probability for dominant organisms
    phom = dom_total/pop_total
    print phom

    # probability for dominant organisms + 
    # probability for recessive organisms should be 1
    # let's check that:
    rec_total = 4 * comb(rec, 2) + 2*rec*het + comb(het, 2)
    prec = totalrec/totalpop
    print 1 - prec
于 2014-08-04T16:45:07.787 回答
1

您不需要在 while 循环中运行数千次模拟。您可以运行一个模拟,并根据其结果计算概率。

from itertools import product

k = 2  # AA  homozygous dominant
m = 2  # Aa  heterozygous
n = 2  # aa  homozygous recessive

population = (['AA'] * k) + (['Aa'] * m) + (['aa'] * n)

all_children = []
for parent1 in population:
    # remove selected parent from population.
    chosen = population[:]
    chosen.remove(parent1)
    for parent2 in chosen:
        # get all possible children from 2 parents. Punnet square
        children = product(parent1, parent2)
        all_children.extend([''.join(c) for c in children])

dominants = filter(lambda c: 'A' in c, all_children)
# float for python2
print float(len(list(dominants))) / len(all_children)
# 0.7833333
于 2017-09-12T08:08:28.627 回答
1

克劳斯的解决方案大部分是正确的。但是,在计算具有至少一个显性等位基因的组合数量时会出现错误。这部分是不正确的,因为虽然组合 2 个等位基因形成后代时有 4 种可能性,但实际上只执行了一种可能性。因此,克劳斯的解决方案计算出的百分比明显高于应有的百分比。

计算具有至少一个显性等位基因的生物体组合数的正确方法如下:

# k  = number of homozygous dominant organisms
# n = number of heterozygous organisms
# m  = number of homozygous recessive organisms

dom_total = comb(k, 2) + k*m + k*n + .5*m*n + .75*comb(m, 2)

# Instead of:
# 4*comb(k,2) + 4*k*n + 4*k*m + 3*comb(n,2) + 2*n*m

上面的代码段用于计算主导组合的总数,因为它将每个部分乘以它将产生主导后代的百分比(100% 为 1)。您可以将每个部分视为每种类型组合(k&k、k&m、k&n、m&n、m&m)的小方块数。

所以整个正确的代码段应该是这样的:

# Import comb (combination operation) from the scipy library 
from scipy.special import comb

def calculateProbability(k, m, n):
    # Calculate total number of organisms in the population:
    totalPop = k + m + n 
    # Calculate the number of combos that could be made (valid or not):
    totalCombos = comb(totalPop, 2)
    # Calculate the number of combos that have a dominant allele therefore are valid:
    validCombos = comb(k, 2) + k*m + k*n + .5*m*n + .75*comb(m, 2)
    probability = validCombos/totalCombos
    return probability

# Example Call: 
calculateProbability(2, 2, 2)
# Example Output: 0.783333333333
于 2017-07-27T18:44:53.187 回答
1

这更像是一个概率/计数问题而不是编码。首先计算后代只有隐性特征的概率更容易。如果您在理解任何内容时遇到任何困难,请告诉我。我运行了以下代码,我的输出通过了 rosalind 分级机。

def mendel(x, y, z):
    #calculate the probability of recessive traits only
    total = x+y+z
    twoRecess = (z/total)*((z-1)/(total-1))
    twoHetero = (y/total)*((y-1)/(total-1))
    heteroRecess = (z/total)*(y/(total-1)) + (y/total)*(z/(total-1))

    recessProb = twoRecess + twoHetero*1/4 + heteroRecess*1/2
    print(1-recessProb) # take the complement

#mendel(2, 2, 2)

with open ("rosalind_iprb.txt", "r") as file:
    line =file.readline().split()
    x, y, z= [int(n) for n in line]
    print(x, y, z)
file.close()
print(mendel(x, y, z))

于 2017-07-19T03:32:15.647 回答
0

我怀疑这项任务是否旨在花费数小时来解决。我在想什么?

我也有同样的问题。在阅读了整个线程之后,我想出了代码。

我希望代码本身能够解释概率计算:

def get_prob_of_dominant(k, m, n):
    # A - dominant factor
    # a - recessive factor
    # k - amount of organisms with AA factors (homozygous dominant)
    # m - amount of organisms with Aa factors (heterozygous)
    # n - amount of organisms with aa factors (homozygous recessive)
    events = ['AA+Aa', 'AA+aa', 'Aa+aa', 'AA+AA', 'Aa+Aa', 'aa+aa']

    # get the probability of dominant traits (set up Punnett square)
    punnett_probabilities = {
        'AA+Aa': 1,
        'AA+aa': 1,
        'Aa+aa': 1 / 2,
        'AA+AA': 1,
        'Aa+Aa': 3 / 4,
        'aa+aa': 0,
    }
    event_probabilities = {}
    totals = k + m + n

    # Event: AA+Aa -> P(X=k, Y=m) + P(X=m, Y=k):
    P_km = k / totals * m / (totals - 1)
    P_mk = m / totals * k / (totals - 1)
    event_probabilities['AA+Aa'] = P_km + P_mk

    # Event: AA+aa -> P(X=k, Y=n) + P(X=n, Y=k):
    P_kn = k / totals * n / (totals - 1)
    P_nk = n / totals * k / (totals - 1)
    event_probabilities['AA+aa'] = P_kn + P_nk

    # Event: Aa+aa -> P(X=m, Y=n) +P(X=n, Y=m):
    P_mn = m / totals * n / (totals - 1)
    P_nm = n / totals * m / (totals - 1)
    event_probabilities['Aa+aa'] = P_mn + P_nm

    # Event: AA+AA -> P(X=k, Y=k):
    P_kk = k / totals * (k - 1) / (totals - 1)
    event_probabilities['AA+AA'] = P_kk

    # Event: Aa+Aa -> P(X=m, Y=m):
    P_mm = m / totals * (m - 1) / (totals - 1)
    event_probabilities['Aa+Aa'] = P_mm

    # Event: aa+aa -> P(X=n, Y=n) + P(X=n, Y=n) = 0 (will be * 0, so just don't use it)
    event_probabilities['aa+aa'] = 0

    # Total probability is the sum of (prob of dominant factor * prob of the event)
    total_probability = 0
    for event in events:
        total_probability += punnett_probabilities[event] * event_probabilities[event]
    return round(total_probability, 5)

于 2019-01-20T13:21:41.517 回答
0

我刚刚找到了答案的公式。您有 8 种可能的交配相互作用,可以产生显性后代:

DDxDD, DDxDd, DdxDD, DdxDd, DDxdd, ddxDD, Ddxdd, ddxDd

分别产生以下优势后代的概率:

1.0, 1.0, 1.0, 0.75, 1.0, 1.0, 0.5, 0.5

起初我觉得这很奇怪,DDxdd而且ddxDD是两个独立的交配事件,但如果你仔细想想,它们在概念上略有不同。is的概率和DDxddisk/(k+m+n) * n/((k-1)+m+n)的概率。从数学上讲,这些是相同的,但从概率的角度来看,这是两个独立的事件。所以你的总概率是这些不同交配事件的概率之和乘以该交配事件产生显性后代的概率。我不会在这里一步一步地简化它,但它会给你代码:ddxDDn/(k+m+n) * k/(k+m+(n-1))

total_probability = ((k ** 2 - k) + (2 * k * m) + (3 / 4 * (m ** 2 - m)) + (2* k * n) + (m * n)) / (total_pop ** 2 - total_pop)

您需要做的就是插入您的 、 和 的值,k然后您就会得到他们要求的概率。mn

于 2018-11-18T21:20:09.410 回答