From febc80c641d63407b64d7f648b6661b91c3a74ed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Chlo=C3=A9=20Muller?= <chloe.muller@student-cs.fr>
Date: Wed, 29 Jan 2020 14:33:50 +0100
Subject: [PATCH] Ajout de la fonction de comparaison selon la selection
 utilisee

---
 algogenetique.py |  58 ++++++++++++++++++++++-----
 individu.py      |   8 ++--
 population.py    | 102 ++++++++++++++++++++---------------------------
 3 files changed, 96 insertions(+), 72 deletions(-)

diff --git a/algogenetique.py b/algogenetique.py
index 138d8a1..3122ce1 100644
--- a/algogenetique.py
+++ b/algogenetique.py
@@ -4,11 +4,12 @@ import numpy
 import RotTable
 from individu import Individu
 from population import Population, afficher
-import croisement
+from croisement import * 
 from Traj3D import *
 from random import random
 import matplotlib.pyplot as plt
 import time
+from copy import deepcopy
 
 # def main(N,tmax,pmutation, proportion,brin="plasmid_8k.fasta"):
 #     '''lineList = [line.rstrip('\n') for line in open(brin)]
@@ -29,22 +30,22 @@ import time
 #     plt.plot([i for i in range(tmax)], L, label = str(pmutation))
 #     return(best)
 
-def main(N,tmax,pmutation, proportion):
+def main(N,tmax,pmutation, proportion, indice_selection, population_initiale, enfant = croisement_un_point):
 
     L=[]
     lineList = [line.rstrip('\n') for line in open("plasmid_8k.fasta")]
     brin = ''.join(lineList[1:])
-    People=Population(N)
+    People=deepcopy(population_initiale)
     # S1=[]
     for individu in People.indiv:
-        individu.evaluate(brin)
+        individu.evaluate()
         # S1.append(int(individu.score))
     # maximum=int(max(S1))
     for i in range(tmax):
-        #print(i)
+        print(i)
         mini=People.indiv[0].score
         best=People.indiv[0]
-        People.reproduction(p = proportion, proba_mutation= pmutation)
+        People.reproduction(p = proportion, proba_mutation= pmutation, selection = indice_selection, enfant = enfant)
         for individu in People.indiv:
             if individu.score<mini:
                 best=individu
@@ -52,7 +53,8 @@ def main(N,tmax,pmutation, proportion):
         L.append(mini)
 
     # plt.subplot(221)
-    plt.plot([i for i in range(tmax)], L, label = str(pmutation))
+    liste_selections = ["selection_p_best", "selection_duel_pondere", "selection_duel", "selection_par_rang", "selection_proportionnelle"]
+    plt.plot([j for j in range(tmax)], L, label = liste_selections[indice_selection])
     
 
     # plt.subplot(223)
@@ -79,6 +81,7 @@ def main(N,tmax,pmutation, proportion):
 
 
 def test_mutation():
+    start_time = time.time()
     plt.figure()
     for i in range(1,5):
         print("\n \n", i)
@@ -91,5 +94,42 @@ def test_mutation():
     plt.show()   
 
 
-start_time = time.time()
-test_mutation()
+def comparaison_selections():
+    liste_selections = ["selection_p_best", "selection_duel_pondere", "selection_duel", "selection_par_rang", "selection_proportionnelle"]
+    liste_time = []
+    plt.figure()
+    People = Population(100)
+    for individu in People.indiv:
+        individu.evaluate()
+    S2=[individu.score for individu in People.indiv]
+    plt.hist(S2, range = (0,int(max(S2)+10)), bins = 20, color = 'blue')
+    plt.show()
+    plt.figure()
+    for i in range(5):
+        print("\n", liste_selections[i], "\n")
+        start_time = time.time()
+        best = main(100, 35, 0.001, 50, i, deepcopy(People))[0]
+        liste_time.append((liste_selections[i], time.time() - start_time, best.score))
+    plt.legend()
+    plt.xlabel("Nombre de générations")
+    plt.ylabel("Score du meilleur individu")
+    plt.title("Comparaison en fonction de la méthode de sélection")
+    print(numpy.array(liste_time))
+    plt.show()   
+
+# def comparaisons_croisements():
+#     liste_croisements = ["croisement_un_point", "croisement_deux_points"]
+
+
+
+
+# test_mutation()
+
+comparaison_selections()
+
+
+# [['selection_p_best' '85.1275908946991']
+#  ['selection_duel_pondere' '85.47507500648499']
+#  ['selection_duel' '88.86001086235046']
+#  ['selection_par_rang' '87.76551222801208']
+#  ['selection_proportionnelle' '87.30216789245605']]
\ No newline at end of file
diff --git a/individu.py b/individu.py
index 08744e8..2047877 100644
--- a/individu.py
+++ b/individu.py
@@ -84,10 +84,10 @@ class Individu():
 # print(individu1.table.rot_table)
 # individu1.mutation()
 
-table = RotTable()
-test = Individu(table)
-test.evaluate("AAAGGATCTTCTTGAGATCCTTTTTTTCTGCGCGTAATCTGCTGCCAGTAAACGAAAAAACCGCCTGGGGAGGCGGTTTAGTCGAA")
-print(test.score)
+# table = RotTable()
+# test = Individu(table)
+# test.evaluate("AAAGGATCTTCTTGAGATCCTTTTTTTCTGCGCGTAATCTGCTGCCAGTAAACGAAAAAACCGCCTGGGGAGGCGGTTTAGTCGAA")
+# print(test.score)
 
 
 # qqun=Individu(RotTable())
diff --git a/population.py b/population.py
index 7d25073..43e3762 100644
--- a/population.py
+++ b/population.py
@@ -22,18 +22,8 @@ class Population:
     def selection_p_best(self,p=None):
         if p==None:
             p=(self.n)//2
-            
-        def tri_rapide_aux(tableau,debut,fin):
-            if debut < fin-1:
-                positionPivot=partitionner(tableau,debut,fin)
-                tri_rapide_aux(tableau,debut,positionPivot)
-                tri_rapide_aux(tableau,positionPivot+1,fin)
-            
-        def tri_rapide(tableau):
-            tri_rapide_aux(tableau,0,len(tableau))
-        
         liste_individus=self.indiv
-        tri_rapide(liste_individus)
+        liste_individus.sort(key = lambda individu : individu.score)
         individus_selectionnes = [element for element in liste_individus[:p]]
         self = self.modifier_population(individus_selectionnes)
 
@@ -41,21 +31,23 @@ class Population:
     def selection_duel_pondere(self,p=None): 
         if p == None :
             p = (self.n)//2
-        newself=[] 
-        vu=set()
+        meilleur = self.indiv[0]
+        for individu in self.indiv :
+            if meilleur.score > individu.score:
+                meilleur = individu
+        newself=[meilleur] 
         m=randrange(0,self.n)
         t=randrange(0,self.n)                   #méthode des duels pondérée: si x=10 et y=1, y a une chance sur 11 de passer
+        non_vu = [i for i in range(0, self.n)]          
         while len(newself)<p:
-            while m in vu:
-                m=randrange(0,self.n)
-            while t in vu:
-                t=randrange(0,self.n)
+            m = choice(non_vu)
+            non_vu.remove(m)
+            t = choice(non_vu)
+            non_vu.remove(t)
             x=self.indiv[m]
             y=self.indiv[t]
-            vu.add(t)
-            vu.add(m)
-            p=random()
-            if p>x.score/(x.score+y.score):
+            proba=random()
+            if proba<x.score/(x.score+y.score):
                 newself.append(y)
             else:
                 newself.append(x)
@@ -68,10 +60,8 @@ class Population:
         meilleur = self.indiv[0]
         for individu in self.indiv :
             if meilleur.score > individu.score:
-                #print("meilleur, individu: ", meilleur.score, individu.score)
                 meilleur = individu
-        newself = [meilleur]
-        vu=set()                        
+        newself = [meilleur]                      
         t=randrange(0,self.n)
         m=randrange(0,self.n)
         non_vu = [i for i in range(0, self.n)]          
@@ -95,35 +85,11 @@ class Population:
         if p == None :
             p = (self.n)//2
         liste_individus = self.indiv
-        n = self.n
-        
-        def echanger(tableau, i, j):
-            tableau[i], tableau[j] = tableau[j], tableau[i]
-            
-        def partitionner(tableau,debut,fin):
-            echanger(tableau,debut,randint(debut,fin-1)) 
-            partition=debut
-            for i in range(debut+1,fin):
-                # if tableau[i] < tableau[debut]:
-                if tableau[i].score<tableau[debut].score: 
-                    partition+=1 
-                    echanger(tableau,i,partition) 
-            echanger(tableau,debut,partition) 
-            return partition
-            
-        def tri_rapide_aux(tableau,debut,fin):
-            if debut < fin-1:
-                positionPivot=partitionner(tableau,debut,fin)
-                tri_rapide_aux(tableau,debut,positionPivot)
-                tri_rapide_aux(tableau,positionPivot+1,fin)
-            
-        def tri_rapide(tableau):
-            tri_rapide_aux(tableau,0,len(tableau))
-            
-        tri_rapide(liste_individus)
-        individus_selectionnes = []
+        n = self.n        
+        liste_individus.sort(key = lambda individu : individu.score, reverse = True)
+        individus_selectionnes = [liste_individus[-1]]
     
-        for _ in range(p):
+        for _ in range(p-1):
             curseur = random()*n*(n+1)/2
             # print("curseur", curseur)
             j = 1
@@ -135,26 +101,33 @@ class Population:
         
         self = self.modifier_population(individus_selectionnes)
         
-    def selection_proportionelle(self,p= None):
+    def selection_proportionnelle(self,p= None):
         if p == None :
             p = (self.n)//2
-        newself=[]
+        meilleur = self.indiv[0]
+        for individu in self.indiv :
+            if meilleur.score > individu.score:
+                meilleur = individu
+        newself = [meilleur]      
         somme=0
         for indiv in self.indiv:
-            somme=somme+indiv.score
+            somme+=1/indiv.score
         while len(newself)<p:
             m=m=randrange(0, self.n)
             x=self.indiv[m]
-            p=random()
-            if p<=x.score/somme:
+            proba=random()
+            if proba<=x.score/somme:
                 newself.append(x)
         self = self.modifier_population(newself)
 
     def reproduction(self,proba_mutation = None, selection=None,enfant=croisement_un_point, p = None):
+        liste_selections = [self.selection_p_best, self.selection_duel_pondere, self.selection_duel, self.selection_par_rang, self.selection_proportionnelle]
         if proba_mutation == None :
             proba_mutation = 0.001
         if selection == None :
             selection = self.selection_duel
+        else :
+            selection = liste_selections[selection]
         if p == None :
             p = (self.n)//2
         vieille_taille = self.n
@@ -179,7 +152,7 @@ class Population:
 def afficher(popu):
     for individu in popu.indiv :
         print("\n individu \n")
-        print(individu.table.rot_table)
+        # print(individu.table.rot_table)
         print ("score", individu.score)
     
 def test():
@@ -194,10 +167,21 @@ def test():
 
 #test()
 
+def test2():
+    popu = Population(10)
+    for individu in popu.indiv :
+        lineList = [line.rstrip('\n') for line in open("plasmid_8k.fasta")]
+        brin = ''.join(lineList[1:])
+        individu.evaluate()
+    print("\n \n POPULATION INITIALE \n \n")
+    afficher(popu)
+    popu.selection_proportionnelle()
+    print("\n\nAPRES SELECTION \n\n")
+    afficher(popu)
     
 
 
-
+# test2()
 
 
 
-- 
GitLab