【问题标题】:Fibonacci mortal rabbits with variable fecundity具有可变繁殖力的斐波那契凡人兔
【发布时间】:2016-03-10 11:11:48
【问题描述】:

我正在尝试修改斐波那契凡人兔子的 Python 代码,以便根据兔子的年龄来改变它们的繁殖力。 举个例子吧。

我的兔子在 3 个月后成熟,在 6 个月后死亡。在它们 4 个月的繁殖力期间,它们会根据年龄产生不同数量的后代。 3个月大的时候生产2对兔子,4个月大的时候生产3对兔子,以此类推,直到第6个月。每对兔子由雌性和雄性组成。最后我会计算配对的数量而不是个人的数量。 从出生到死亡的繁殖力值:

fecundity = [0, 0, 2, 3, 3, 1]

我使用的 Python 代码 (https://github.com/jschendel/Rosalind/blob/master/011_FIBD.py) 是:

n = 12
m = 6
#n = months to run
#m = how many months the rabbits live

# Populate the initial rabbits.
Rabbits = [1]+[0]*(m-1)

# Calculate the new rabbits (bunnies), in a given month.
# Start at use range(1,n) since our initial population is 0 month old.
for month in range(1, n):
    Bunnies = 0
    # Get the number of Rabbits able to old enough to give birth.
    for j in range(1,m):
        Bunnies += Rabbits[(month-j-1)%m]
    # Bunnies replace the old rabbits who died.
    Rabbits[(month)%m] = Bunnies

# Total rabbits is the sum of the living rabbits.
Total_Rabbits = sum(Rabbits)

我不确定如何实现繁殖力的变化。任何帮助表示赞赏!

谢谢你, 瓦伦蒂娜

【问题讨论】:

  • [0, 0, 2, 3, 3, 1] 不应该是 只兔子(一只雄性,一只雌性)吗?
  • 是的,我没有指定!新生儿是成对的兔子(一个 F 一个 M)。但最后我会计算成对的数量而不是单个个体的数量。我编辑问题
  • for year in range(1, n): 应该是月份,而不是年份。 Rabbits[year-j-1%m] 是 j 个月前出生的兔子,在这条线上应用你的繁殖力因素。

标签: python fibonacci rosalind


【解决方案1】:

定义你的繁殖力数组以在兔子死亡时停止:

fecundity = [0, 0, 2, 3, 3, 1]

表示您的兔子在 7 个月大时死亡。 之后,您只需编写一个递归函数来计算特定步骤中新生儿的数量。我将步骤初始化为 1 对用于步骤 0,0 对用于步骤

def new_borns(step):
    if step < 0:
        return 0
    if step == 0:
        return 1
    nb_newborns = 0
    # We create a loop on living pairs
    for old_step in range(1, len(fecondity) +1):
        nb_newborns += (fecundity[old_step -1]) * new_borns(step - old_step)
    return nb_newborns

特定步骤的总人口是之前步骤的新生儿总数,仍然活着(即,对于您的生育力数组的长度)。

def FIBD(step):
    population = 0
    for i in range(len(fecundity)):
        population += new_borns(step - i)
    return population

要知道您在第 7 步有多少对,只需致电 FIBD(7) 兔子可以存活的月数就是繁殖力数组的长度。

当然,这个递归函数非常非常慢而且很糟糕。您需要一个缓存系统来避免多次计算同一步骤。这是要编写的完整文件。

#!/usr/bin/env python

fecundity = [0, 0, 2, 3, 3, 1]
new_borns_cache = [1]

def new_borns(step):
    if step < 0:
        return 0
    try :
        return new_borns_cache[step]
    except IndexError:
        if step == 0:
            return 1
        sum = 0
        for old_step in range(1, len(fecundity) +1):
            sum += (fecundity[old_step -1]) * new_borns(step - old_step)
        return sum

def fibd(step):
    population = 0
    for i in range(len(fecundity)):
        population += new_borns(step - i)
    return population

要使用它,只需导入,然后调用fibd(7)

【讨论】:

  • 一个可能非常有趣并且与这种算法相关联的术语是“卷积乘积”。只是为了您的兴趣。
【解决方案2】:

我自己来了一个答案,我真的修改了我之前发布的代码。我认为现在它更简单了

import numpy as np

m = 15
n = 18
fecundity = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 2, 1, 1, 1])
Bunnies = np.array([0]*m)
Rabbits = np.array([1]+[0]*(m-1))

for month in range(0, 18):
    # every month I shift the list of 1 since they're getting older
    Rabbits = np.roll(Rabbits, 1)
    # I set the newborns as 0
    Rabbits[0] = 0
    # I calculate the newborns
    Bunnies = Rabbits * fecundity
    # and then I assign them to the rabbits 0 month old
    Rabbits[0] = sum(Bunnies)

# the sum of Rabbits is the number of final pairs of Rabbits after n months
Total_Rabbits = sum(Rabbits)
# 26 Rabbits

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-29
    • 1970-01-01
    • 2015-06-05
    • 2014-05-23
    相关资源
    最近更新 更多