2016-03-10 4 views
2

J'essaye de modifier le code python des lapins mortels de Fibonacci afin de faire varier la fécondité des lapins en fonction de leur âge. Faisons un exemple.Lapins mortels de Fibonacci à fécondité variable

Mes lapins atteignent leur maturité après 3 mois et meurent après 6 mois. Au cours de leurs 4 mois de fécondité, ils produisent un nombre différent de progéniture en fonction de leur âge. Quand ils ont 3 mois, ils produisent 2 paires de lapins, à 4 mois produisent 3 paires de lapins et ainsi de suite jusqu'au sixième mois. Chaque paire de lapins est formée par une femelle et un mâle. À la fin je compterais le nombre de paires pas le nombre d'individus. valeurs Fécondité de la naissance à la mort:

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

Le code python que j'utilise (https://github.com/jschendel/Rosalind/blob/master/011_FIBD.py) est:

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) 

Je ne suis pas sûr de savoir comment mettre en œuvre la variation de la fécondité. Toute aide est appréciée!

Merci, Valentina

+0

Les paires '[0, 0, 2, 3, 3, 1]' ne devraient-elles pas être paires de lapins (un mâle, une femelle)? – fcalderan

+0

Oui, je ne l'ai pas précisé! Les nouveau-nés sont des paires de lapins (un F un M). Mais à la fin je compterais le nombre de paires pas le nombre d'individus simples. Je modifie la question – Valentina

+1

'pour l'année dans l'intervalle (1, n):' devrait être le mois, pas l'année. 'Les lapins [année-j-1% m]' sont les lapins nés il y a j mois, appliquez sur cette ligne votre facteur de fécondité. – xvan

Répondre

0

Je suis venu à une réponse moi-même et j'ai vraiment modifié le code que je tition. Je pense que maintenant c'est beaucoup plus simple

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 
2

Définir votre tableau de fécondité pour arrêter quand un lapin meurt:

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

signifie que vos lapins meurent à l'âge de 7 mois. Après cela, vous venez d'écrire une fonction récursive pour calculer le nombre de nouveau-nés dans une étape spécifique. J'initialise les étapes comme 1 paire pour l'étape 0, et 0 paire pour l'étape < 0. Vous pouvez bien sûr le modifier pour l'adapter à votre cas. (Ce que j'appelle une étape est une unité de temps, ici le mois). Voici la fonction:

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 

La population totale d'une étape spécifique est le total des new_borns pour les étapes précédentes, encore vivant (ie, pour la durée de votre tableau de fécondité).

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

Pour savoir combien de paires vous à l'étape 7, il suffit d'appeler FIBD(7) Le nombre de mois, le lapin peut vivre est la longueur du tableau de fécondité.

Bien sûr, cette fonction récursive est très très lente et mauvaise. Vous avez besoin d'un système de mise en cache pour éviter de calculer plusieurs fois la même étape. Voici le fichier complet à écrire.

#!/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 

Pour l'utiliser, il suffit d'importer et d'appeler fibd(7)

+1

Un terme qui pourrait être très intéressant, et qui est lié à ce genre d'algorithmes est "produit de convolution". Juste pour votre intérêt. – Dunatotatos