Question 0

Décrire votre intuition

Les tirages pour déterminer les parents seront uniformes (1 parmi la taille de P0, avec remise à chaque tirage), et de même pour le choix de l’allèle. On aura donc (environ) la même chance de tomber sur un allèle bleu qu’un allèle marron à chaque génération. Ainsi, il y a de fortes chances pour que la population aux yeux bleus conserve sa proportion au cours du temps, qu’elle soit élevée ou faible. On remarquera certainement de légères variations, mais d’assez faible importance.

Question 1 : Cas d’une petite population

set.seed(42)

#Génère un nombre aléatoire entre 1 et N
Alea = function(N) {
  sample(1:N,1);  
}

#génère une population P0 de longueur P, avec BB individus à deux allèles bleus et MM individus avec deux allèles marrons.
genP0 = function(P ,BB, MM) {
    p0 = c();
    p0[1:P] = 1;
    p0[1:BB] = 2;
    p0[BB+1:MM] = 0;
    p0;
}

# Renvoie une population de P individus à partir d'un autre population dont les proportions d'alleles sont BB, BM et MM. Cette population s'exprime en nombre d'alleles bleues
genPi = function(P_current) {
  N = length(P_current);
  
  P_next = c(); #La génération suivante qui va être générée
  for(i in 1:N) {
    #Je ne prends pas en compte de si le père = la mère. Dans une grande population, c'est peu représentatif. On sélectionne ici les deux parents qui vont donner un de leurs allèles
    Pere = P_current[Alea(N)];
    Mere = P_current[Alea(N)];
    
    # On choisit une allele du parent au hasard (1 si l'allele est bleue, 0 sinon)
    #Récupération des allèles des parents
    A1 = selectAllele(Pere);
    A2 = selectAllele(Mere);
    
    #formation de l'enfant et ajout dans la future génération
    Enfant = A1+A2;
    P_next[i] = Enfant;
  }
  
  P_next;
}

#Fonction de simulation de l'évolution d'une population P0 au cours des Imax générations qui vont suivre
sim = function(P0, Imax){ 
  N = length(P0);
  
  P_evol = matrix(ncol=N, nrow=Imax); #Matrice de dimension N, Imax, représentant toutes les générations de la population, entre 0 et Imax
  P_evol[1,] = P0; #Placement de la première génération

  for(i in 2:Imax) {
    P_evol[i,] = genPi(P_evol[i-1,]); #Calcul de la génération suivante en fonction de l'actuelle
  }
  
  P_evol;
}

#simule une sélection d'allèle sur les deux possédés par un individu
selectAllele = function(nbA) {
  ifelse(nbA == 2,1, ifelse(nbA == 0,0,if(runif(1)>=0.5) 1 else 0))
}

#Fonction de récupération de l'évolution du gène nbAllele (Bleu) de la population Pn au cours de toutes ses générations.
getVariation = function(Pn, nbAllele = 2) {
  Imax = length(Pn[,1]);
  pct = c();
  
  for(i in 1:Imax) {
    #Calcul effectué sur les lignes (une ligne = une génération)
    pct[i] = sum(Pn[i,]==nbAllele)/length(Pn[i,]);
  }
  
  pct;
}

#Affichage graphique de l'évolution des allèles (différence entre BB et MM) d'une population P0 au cours de ses Imax futures générations, sur N itérations
render = function(P0, Imax, N, title="Evolution des allèles d'une population") {
  plot(NULL,ylim=c(0,1.5),xlim=c(1,Imax),main=title, sub="BB en bleu, MM en marron", ylab="Taux d'alléles", xlab="Génération")
  for(i in 1:N){
    Pi = sim(P0, Imax);
    
    txM = getVariation(Pi,0); #Calcul du taux de d'apparition du gène MM sur les générations pour la population Pi.
    txB = getVariation(Pi,2); #idem avec le gène BB
      
    # Affichage des courbes
    lines(txM, col='brown',type='l')
    lines(txB, col='blue',type='l')
  }
  legend(0,1.6,c("Allèles MM", "Allèles BB"),lty=c(1,1), lwd=c(2.5,2.5), col=c("brown","blue"));
}

Afin d’analyser la situation, on utilise diverses simulations :

render(genP0(20,4,12), 20, 10, "Evolution d'une petite population P0 = (4, 12) sur 20 générations")

render(genP0(20,12,4), 20, 10, "Evolution d'une petite population P0 = (12, 4) sur 20 générations")

render(genP0(20,5,5), 20, 10, "Evolution d'une petite population P0 = (5, 5) sur 20 générations")

render(genP0(20,10,0), 20, 10, "Evolution d'une petite population P0 = (10, 0) sur 20 générations")

render(genP0(20,0,10), 20, 10, "Evolution d'une petite population P0 = (0, 10) sur 20 générations")

render(genP0(20,0,19), 20, 10, "Evolution d'une petite population P0 = (0, 19) sur 20 générations")

render(genP0(20,0,0), 20, 10, "Evolution d'une petite population P0 = (0, 0) sur 20 générations")

Etudier les données sur de si petites populations, avec si peu de générations semble très peu concluant : en fonction de la population de départ, on ne peut pas tirer de conclusion car les génération finales peuvent diverger de façon importante :

Ainsi, du fait de la trop faible population et du peu de générations simulées, on ne peut pas conclure correctement. Il faut réaliser des tests sur de plus grands ensembles.

Question 2 : Cas d’une grande population

render(genP0(2000,400,1200), 100, 10, "Evolution d'une grande population P0 = (400, 1200) sur 100 générations")

render(genP0(2000,1200,400), 100, 10, "Evolution d'une grand population P0 = (1200, 400) sur 100 générations")

Dans un premier temps, on peut confirmer qu’un plus grand échantillon permet une meilleure interprétation des résultats. De plus, le fait d’avoir plus de générations permet de mieux percevoir l’évolution des populations dans le temps.

Pour les deux premières courbes, on remarque d’abord une chute des deux proportions, puis stabilisation continue, qui tend entre la proportion initiale, et la valeur minimale à la chute de la courbe.

render(genP0(2000,500,500), 100, 10, "Evolution d'une grande population P0 = (500, 500) sur 100 générations")

Dans le cadre de valeurs initiales équivalentes, on constate également une conservation globale des valeurs, avec cependant un étalement légèrement positif en faveur des allèles MM et donc en défaveur des allèles BB. Cependant, la tendance générale reste conservatrice.

render(genP0(2000,1000,1000), 100, 10, "Evolution d'une grande population P0 = (500, 500) sur 100 générations")

Avec un équilibre total au début, on remarque à nouveau une chute brutale (ce qui est logiques, on obtient forcément une grosse partition d’allèles BM après la première sélection parentale). La tendance générale reste ensuite plutôt stable.

render(genP0(2000,0,1990), 100, 10, "Evolution d'une grande population P0 = (500, 500) sur 100 générations")

Avec une population totalement déséquilibrée, on observe encore une conservation des moyennes initiales. Cela semble plutôt logique : il y a peu de chance pour que deux parents avec au moins un allèle bleu chacun se rencontre, et donc encore moins de chance pour que ces deux parents cèdent un allèle bleu chacun à leur enfant.

On peut donc admettre l’hypothèse initiale d’après ces résultats, mais faire varier quelques paramètres peut s’avérer utile pour confirmer de façon plus probante cette proposition.

Question 3 : Cas d’une petite population avec préservation

# Renvoie une population de P individus à partir d'un autre population dont les proportions d'alleles sont BB, BM et MM. Cette population s'exprime en nombre d'alleles bleues
genPiPres = function(P_current) {
  N = length(P_current);
  
  P_next = c();
  for(i in 1:N-2) {
    #Je ne prends pas en compte de si le père = la mère. Dans une grande population, c'est peu représentatif. On sélectionne ici les deux parents qui vont donner un de leurs allèles
    Pere = P_current[Alea(N)];
    Mere = P_current[Alea(N)];
    
    # On choisit une allele du parent au hasard (1 si l'allele est bleue, 0 sinon)
    #Récupération des allèles des parents
    A1 = selectAllele(Pere);
    A2 = selectAllele(Mere);
    
    #formation de l'enfant et ajout dans la future génération
    Enfant = A1+A2;
    P_next[i] = Enfant;
  }
  P_next[N] = 0;
  P_next[N-1] = 2;
  
  P_next;
}

simPres = function(P0, Imax){ 
  N = length(P0);
  
  P_evol = matrix(ncol=N, nrow=Imax);
  P_evol[1,] = P0;

  for(i in 2:Imax) {
    P_evol[i,] = genPiPres(P_evol[i-1,]);
  }
  
  P_evol;
}

renderPres = function(P0, Imax, N, title="Evolution des allèles d'une population") {
  plot(NULL,ylim=c(0,1.5),xlim=c(1,Imax),main=title, sub="BB en bleu, MM en marron", ylab="Taux d'alléles", xlab="Génération")
  for(i in 1:N){
    Pi = simPres(P0, Imax);
    
    txM = getVariation(Pi,0);
    txB = getVariation(Pi,2);
      
    # On affiche les courbes
    lines(txM, col='brown',type='l')
    lines(txB, col='blue',type='l')
  }
  legend(0,1.6,c("Allèles MM", "Allèles BB"),lty=c(1,1), lwd=c(2.5,2.5), col=c("brown","blue"));
}
renderPres(genP0(20,4,12), 2000, 10, "Evolution d'une petite population P0(4,12) sur 2000 générations")

renderPres(genP0(20,12,4), 2000, 10, "Evolution d'une petite population P0(12,4) sur 2000 générations")

renderPres(genP0(20,5,5), 2000, 10,  "Evolution d'une petite population P0(5,5) sur 2000 générations")

Ici, on génère sur une petite population, et sur une très longue période, avec une contrainte sur la population. Cette contrainte montre ici une variation très forte de la répartition de la population tout au cours de l’évolution de celle-ci. Il est difficile d’analyser de telles courbes, car elles ont tendance à toutes se chevaucher.

La modification volontaire de deux individus empêche la stagnation d’un allèle en particulier, et répète donc les premières étapes de stabilisation, ce qui explique la forte variation tout au long des simulations. Si on prenait des exemples avec de plus grandes populations, on pourrait certainement avoir plus d’information à ressortir des graphes…

renderPres(genP0(200,50,50), 200, 10,  "Evolution d'une petite population P0(50,50) sur 200 générations")

Avec une population plus grande, et moins de génération (la tendance générale est tout de même conservée, étant donné la répétition constatée), on constate à nouveau la forte oscillation des résultats. On en déduit donc que l’insertion de seulement deux éléments, même dans une grande population peut avoir des répercutions très importantes !

renderPres(genP0(200,0,190), 200, 10,  "Evolution d'une petite population P0(0,190) sur 200 générations")

J’avais également envie de voir l’évolution de la population avec une population initiale totalement déséquilibrée. On remarque une totalement inversion de la tendance dans certains cas, ce qui est assez surprenant.

renderPres(genP0(200,0,190), 2000, 5,  "Evolution d'une petite population P0(0,190) sur 2000 générations")

Un dernier test sera de vérifier la tendance avec beaucoup plus de générations, ce qui amène une autre hypothèse : la contrainte des deux individus à double-allèle force une uniformisation de la population :

On pourrait en déduire que l’apparition forcée d’un seul individu permet la régulation d’une population sur le long terme.

Question 4

L’hypothèse initiale semble vérifiée, en plus du fait qu’en règle générale, il y a une légère période d’aplanissement avant de conserver une tendance finale dans la population. En revanche, je ne m’attendais pas à ce que forcer la conservation minimale pour quelques individus ait de telles répercusions sur l’évolution de la population. Une chose intéressante à tester serait de réaliser la contrainte sur peu d’individus, dans une grande population pour voir si l’hypothèse émise sur l’oscillation de la courbe se confirme. Enfin, la modification de mon modèle se ferait certainement au niveau de la sélection des parents, qui n’est pas du tout réaliste. Bien qu’aléatoire, elle ne tient pas compte du sexe de la personne (par exemple, il se pourrait que 60% des femmes aient les yeux bleus, et seulement 20% des hommes également), cela changerait certainement les résultats. De plus, dans une situation réelle, le hasard n’est pas seul moteur de la mixité génétique, ce qui fait que le taux de personnes aux yeux clairs varie en fonction de nombreux autres critères.