罗莎琳德"孟德尔的第一定律" IPRB

时间:2014-08-04 12:50:32

标签: python bioinformatics rosalind

作为即将开始的生物信息学课程的准备,我正在从rosalind.info做一些任务。我目前陷入了作业#34; Mendel's First Law"。

我认为我可以通过这种方式来蛮力,但不知怎的,我的想法必须过于复杂。我的方法是:

构建一个包含三个级别的概率树。有两种交配的生物,生物A和生物B.第一级是,作为生物挑选的概率是什么?纯合显性(k),杂合(m)或纯合隐性(n)。例如,对于纯合显性,似乎共有(k + m + n)个生物,其中k是纯合显性,概率为k /(k + m + n)。

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

这将提供两个级别的概率,并且将涉及到很多代码只是为了实现这一点,因为我真的要构建一个树结构,并且每个分支都为该部分手动编写代码。

enter image description here

现在,在选择生物A和B之后,每个生物都有两条染色体。其中一条染色体可以随机挑选。因此对于A染色体1或2可以被选择并且对于B来说相同。因此有4种不同的选择:选择A中的A,来自B中的1个。选择A中的A,来自B中的1个。选择A中的1个,B中的2个。 B中的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))

6 个答案:

答案 0 :(得分:4)

具有显性等位基因的物种可以是AAAa

您的总人口(k + n + mkhom)纯合优势生物组成,AAmhet)杂合优势具有Aanrec)纯合隐性生物的生物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,那么来自comb的{​​{1}}可能会有所帮助。在计算中,不要忘记(a)你从每个组合中得到scipy.misc个孩子,并且(b)你需要一个因子(来自Punnett方格)来确定组合中的隐性(或显性)后代

<强>更新

4

答案 1 :(得分:1)

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

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

# 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&amp; k,k&amp; m,k&amp; n,m&amp; n,m&amp; 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

答案 2 :(得分: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

答案 3 :(得分:0)

这比编码更像是一个概率/计数问题。更容易计算后代仅具有隐性特征的概率。如果您对任何事情有任何疑问,请告诉我。我运行了以下代码,我的输出通过了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))

答案 4 :(得分: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

最初,DDxddddxDD是两个单独的交配事件,对我来说似乎很奇怪,但是如果您考虑一下,它们在概念上会略有不同。 DDxdd的概率为k/(k+m+n) * n/((k-1)+m+n)ddxDD的概率为n/(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)

您所需要做的就是插入kmn的值,您将获得他们要求的概率。

答案 5 :(得分: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)