#Question 0 :
#Je commence par remarquer que le fait que les yeux aient tendance à avoir une couleur marron, n'a aucune influence sur la conservation des allèles bleu ou marron au cours des générations. Ce qu'on va observer ici est donc la manière dont vont se disperser les allèles au cours du temps (ou à se regrouper)

#1 20 générations sur une population de 20 personnes semble très aléatoire, nos résultats seront difficiles à exploiter (chaque tirage a un impact sur 5% de la population suivante. On peut s'attendre à des résultats très différents quand on sait qu'il y a 20 générations)
#Malgré tout, on peut supposer que :
#P0=(4,12) aura tendance à faire diminuer le nombre de BB et augmenter le nombre de MM (puisqu'on commence avec au total 12 allèles B et 28 allèles M)
#P0=(12,4) aura l'effet inverse
#P0=(5,5) aura tendance à faire lentement pencher la population vers les BB ou les MM

#2 Pour 2000 individus (et 100 générations, ce qui est finalement peu comparé à l'exemple précédent puisqu'il faudrait 2000 générations pour respecter les proportions). On peut s'attendre à des résultats plus réguliers, donc qui respecteront mieux ce que j'ai énoncé pour la question précédente

#3 pour 20 individus, avec 2000 générations. L'ajout de la règle des 2 individus prédéterminés implique qu'on ne pourra jamais atteindre le cas où 100% de la population est un BB (ou MM). De plus, avoir au minimum 1 individu dans la couleur minoritaire à une influence non négligeable sur la population (5%). Ainsi, on peu s'attendre à des retournements de situation multiples au cours des 2000 générations (il devrait suffire de quelques dizaines de générations pour qu'une couleur minoritaire devienne majoritaire, en raison de la faible taille de population)


#Question 1 : petite population. Pendant tout ce dm, nous utiliseront la notation : 0-> allèle maron et 1->allèle bleu


#Pour chaque nouvel individu, on va choisir aléatoirement 2 parents, puis on va choisir aléatoirement le couple d'allèles résultant de ces parents.

##On considèrera que les deux allèles d'un enfant peut provenir du même allèle d'un de ses parents

BB=0;
MM=1;
MB=2;

set.seed(1337);

resultat_individu = c(BB , MM , MB); #Celle variable contient les résultats que l'on peut déduire d'un tirage aléatoire grâce à la fonction de répartition



#create_rep_parent va retourner une fonction de répartition permettant de déterminer l'identité d'un parent. Elle est calculée à partir de la taille de la population et les proportions de la génération actuelle
create_rep_parent = function (POP,P0)
{
  bb = P0[1]/POP;
  mm = P0[2]/POP;
  rep<-c(bb, bb+mm);
  return(rep);
}


#create_rep_alleles va retourner la fonction de répartition permettant de déterminer le couple d'allèles du nouvel individu. Elle est calculée à partir des 2 parents.
create_rep_alleles = function (p1,p2) #p1=0 -> bb ; p1=1 -> mm ; p1 = 2 -> bm
{
  rep<-c(0,0)
  if(p1+p2==0) #bb bb
  {
    rep[1] = 1;
  }
  else if(p1+p2==1)  #bb mm ou mm bb
  {
    rep[1]= 1/3;
    rep[2]= 2/3;
  }
  else if(p1==BB && p2==MB || p1==MB && p2==BB)  #bb mb ou mb bb
  {
    rep[1] = 9/16;
    rep[2] = rep[1] + 1/16;
  }
  else if(p1==MM && p2==MM)  #mm mm
  {
    rep[1]= 0;
    rep[2]= 1;
  }
  else if(p1+p2==4) #mb mb
  {
    rep[1]= 1/3;
    rep[2]= 2/3;
  }
  else if((p1==MB && p2==MM) || (p1==MM && p2==MB))
  {
    rep[1] = 1/16;
    rep[2] = rep[1] + 9/16;
  }
  
  return(rep);
}


#get_resultat retourne le resultat obtenu en fonction du tirage effectué et de la fonction de répartition
get_resultat = function (rep,res,x)
{
  n = length(rep);
  for(i in 1:n)
  {
    x;
    rep[i];
    x<rep[i];
    if(x<rep[i]) { return(res[i]);}
  }
  return(res[i+1]);
  
}



#calcule la fonction de répartition du choix du deuxième parent
get_new_rep = function(POP,P0,p1)
{
  if(p1==BB)
  {
    new_P0 = c(P0[1] - 1 , P0[2])
    rep = create_rep_parent(POP-1 , new_P0);
  }
  else if(p1==MM)
  {
    new_P0 = c(P0[1] , P0[2] - 1)
    rep = create_rep_parent(POP-1 , new_P0);
  }
  else 
  {
    rep = create_rep_parent(POP-1, P0);
  }
  return(rep);
}



##next_gene calcule la génération suivante en fonction de la génération actuelle
next_gene = function(POP,P0)
{

  X = runif(POP*3);  #On effectue 3 tirages par individu
  rep_parent1<-create_rep_parent(POP,P0);

  res<-c(0,0);
  
  i=1;
  while(i <= POP*3)
  {
    p1=get_resultat(rep_parent1,resultat_individu,X[i]);
    
    rep_parent2 = get_new_rep(POP,P0,p1);
    p2=get_resultat(rep_parent2,resultat_individu,X[i+1]);

    rep_alleles = create_rep_alleles(p1,p2);
    new_individu = get_resultat(rep_alleles,resultat_individu,X[i+2]);
    
    res[new_individu+1] = res[new_individu+1] + 1;

    i = i+3;
  }
  return(res);
}

#horizon renvoie une liste de 2 vecteurs contenant chacun pour chaque génération le nombre de BB (resp MM)
horizon = function(I_max,POP,P0)
{
  res = list();
  v1=c();
  v2=c();
  for(i in 1:I_max)
  {
    v1[i]=P0[1]
    v2[i]=P0[2]
    P0 = next_gene(POP,P0);
  }
  res[[1]] = v1;
  res[[2]] = v2;
  return(res);
}

# trace va afficher une courbe représentant la part de BB et une pour la part de MM dans la population
trace=function(liste,POP)
{
  v_courbe1 = liste[[1]]/POP*100;
  v_courbe2 = liste[[2]]/POP*100;  
  xrange = seq(1,length(v_courbe1),1);
  N = length(v_courbe1);
  lines(xrange,v_courbe1, type="l", lwd=1.5, col="blue");
  lines(xrange,v_courbe2, type="l", lwd=1.5, col="brown");
}

#trace_x_courbes créé le repère et trace X courbes grâce à la fonction trace
trace_x_courbes = function(I, POP, P0, X=1)
{
  generations=seq(1,I,1);
  part_population = seq(1,I,1);
  plot(generations,part_population, type="l",lwd=1.5, col="white",ylim = c(0,100));
  for(i in 1:X)
  {
    Pi = horizon(I,POP,P0);
    trace(Pi,POP);
  }
}

P=20;
Imax=20;
P0 = c(12,4);

trace_x_courbes(Imax,P,P0,10);

P0 = c(4,12);

trace_x_courbes(Imax,P,P0,10);

P0 = c(5,5);

trace_x_courbes(Imax,P,P0,10);

#On constate que les résultats sont très variables et donc difficiles à exploiter. On en déduit qu'en 20 générations, le système a le temps de beaucoup varier. Ceci est dû à la petite taille de la population.

#Question 2 

P=2000;
Imax=100;
P0 = c(1200,400);

trace_x_courbes(Imax,P,P0,10);

P0 = c(400,1200);

trace_x_courbes(Imax,P,P0,10);

P0 = c(500,500);

trace_x_courbes(Imax,P,P0,10);

#Observations : On observe des résultats assez proches de la situation d'origine au bout de 100 générations. On peut l'expliquer par la grande taille de la population, qui a donc plus tendance à s'approcher du résultat attendu en moyenne. On peut aussi en déduire que pour une population aussi grande, 100 générations ne sont pas suffisantes pour observer beaucoup de fluctuation (peut être que 2000 générations donneraient des résultats semblables à la question précédente.)
#On ajoutera qu'en termes de proportions, 100 générations pour 2000 individus sont équivalentes à la première génération dans la question précédente.


#Question 3

next_gene_bis = function (POP,P0)
{
  
  X = runif((POP-2)*3);  #On effectue 3 tirages par individu
  rep_parent1<-create_rep_parent(POP,P0);

  res<-c(0,0);
  
  i=1;
  while(i <= (POP-2)*3)
  {
    p1=get_resultat(rep_parent1,resultat_individu,X[i]);
    
    rep_parent2 = get_new_rep(POP,P0,p1);
    p2=get_resultat(rep_parent2,resultat_individu,X[i+1]);

    rep_alleles = create_rep_alleles(p1,p2);
    new_individu = get_resultat(rep_alleles,resultat_individu,X[i+2]);
    
    res[new_individu+1] = res[new_individu+1] + 1;

    i = i+3;
  }
  res[1] = res[1]+1;
  res[2] = res[2]+1;
  return(res);
}

horizon_bis = function(I_max,POP,P0)
{
  res = list();
  v1=c();
  v2=c();
  for(i in 1:I_max)
  {
    v1[i]=P0[1]
    v2[i]=P0[2]
    P0 = next_gene_bis(POP,P0);
  }
  res[[1]] = v1;
  res[[2]] = v2;
  return(res);
}

trace_x_courbes_bis = function(I, POP, P0, X=1)
{
  generation=seq(1,I,1);
  part_pop = seq(1,I,1);
  plot(generation,part_pop, type="l",lwd=1.5, col="white",ylim = c(0,100));
  for(i in 1:X)
  {
    Pi = horizon_bis(I,POP,P0);
    trace(Pi,POP);
  }
}


P=20;
I=2000;
P0 = c(12,4);

trace_x_courbes_bis(I,P,P0,10);

P0 = c(4,12);

trace_x_courbes_bis(I,P,P0,10);

P0 = c(5,5);

trace_x_courbes_bis(I,P,P0,10)

#Observations : Cette nouvelle configuration modifie la question 1 car elle empêche d'arriver dans la situation où 100% de la population est BB ou MM. Ainsi, aucune situation n'est définitive.
#Le système ne semble pas du tout stable. Je ne vois pas de zone qui semble plus attirante que d'autres


#Quesiton 4 : 
#Les résultats obtenus sont conformes à mes attentes. Je m'attendais tout de même à moins de variations dans la question 3.
#Je suppose qu'un modèle intéressant à étudier serait le cas où chaque individu est le parent d'un enfant.
#Il pourrait aussi être intéressant d'observer une grande population évoluant sur une très longue période temporelle.