#################################
########### AGRO 2024 ###########
#################################

## Importations

import matplotlib.pyplot as plt
import numpy as np
import numpy.random as rd

## Problème A

S = 30
v0 = 5
L = [v0]
v = v0
for k in range(19) :
    v = v + v*(S-v)/(2*S)
    L.append(v)
plt.plot(L,'.')
plt.xlabel("n")
plt.ylabel("v_n")
plt.show()

## Problème B

def galton_watson(lambda_,n) :
    population = np.zeros(n+1)
    population[0] = 1
    Z = 1
    for i in range(1,n+1) :
        descendants = 0
        for j in range(Z) :
            descendants += rd.poisson(lambda_)
        population[i] = descendants
        Z = descendants
        if descendants == 0 :
            return population
    return population

## B1
# lambda_ est le paramètre de la loi de Poisson
# modélisant la descendance d'un individu.
# n est le nombre de générations qu'on simule.

## B2
# les lignes 11 et 12 arrêtent le script de
# la fonction 'population' lorsqu'il y a extinction.

# La ligne 2 initialise une liste de taille n+1
# emplie de zéros : c'est par défaut les populations
# de la génération 0 à la génération n.

# Les lignes 6 à 8 simulent pour chaque individu
# de la génération (i-1) un nombre aléatoire de
# descendants suivant la loi de Poisson de paramètre
# lambda, la variable locale 'descendants' indique
# la somme de tous les descendants donc la population
# à la génération (i).

## B3

# Une somme de Z variables aléatoires indépendantes
# et suivant toutes une loi de Poisson de paramètre
# lambda suit une loi de Poisson de paramètre Z*lambda
# par stabilité de la loi de Poisson ;
# donc on peut simuler en une seule ligne le nombre
# de descendants à la génération suivante en utilisant
# rd.poisson(Z*lambda_).

## B4

lambda_ = 0.7
for k in range(10) :
    plt.plot(galton_watson(lambda_,20))
plt.show()

# On peut faire la conjecture que la probabilité
# d'extinction est grande quand lambda < 1
# et plus faible, voire nulle, quand lambda > 1.

## B5

def galton_watson_2(lambda_,n) :
    population = np.zeros(n+1)
    population[0] = 1
    Z = 1
    for i in range(1,n+1) :
        descendants = 0
        for j in range(Z) :
            descendants += rd.poisson(lambda_)
        population[i] = descendants
        Z = descendants
        if descendants == 0 :
            return 1
    return 0

def extinction(lambda_) :
    N = 500 # 5000 paraît beaucoup ?
    n = 30 # 60 générations c'est beaucoup ?
    proba = 0
    for _ in range(N) :
        proba += galton_watson_2(lambda_,n)
    return proba / N

## B6

# on conjecture que la probabilité d'extinction est
# proche de 1 quand lambda < 1, et décroît rapidement
# quand lambda > 1 augmente.














