diff --git a/RotTable.py b/RotTable.py index efdebce4cf42480c3be6c111f39fcce5c4cfa90e..a2f779a499910677002066fb2fc015a4f738fc6a 100644 --- a/RotTable.py +++ b/RotTable.py @@ -21,7 +21,26 @@ class RotTable: "TA": [36, 0.9, 0, 1.1, 2, 0],\ "TC": [36.9, 5.3, -120, 0.9, 6, 0],\ "TG": [34.5, 3.5, 64, 0.9, 34, 0],\ - "TT": [35.62, 7.2, -154, 0.06, 0.6, 0]\ + "TT": [35.62, 7.2, 154, 0.06, 0.6, 0]\ + } + + __CORRESPONDANCE = {\ + "AA": "TT",\ + "AC": "TG",\ + "AG": "TC",\ + "AT": "TA",\ + "CA": "GT",\ + "CC": "GG",\ + "CG": "GC",\ + "CT": "GA",\ + "GA": "CT",\ + "GC": "CG",\ + "GG": "CC",\ + "GT": "CA",\ + "TA": "AT",\ + "TC": "AG",\ + "TG": "AC",\ + "TT": "AA",\ } # get the angles in each axis (x, y, z), considering the deviation @@ -41,6 +60,9 @@ class RotTable: # return __ORIGINAL_ROT_TABLE def orta(self): return self.__ORIGINAL_ROT_TABLE + + def corr(self): + return self.__CORRESPONDANCE ################### # WRITING METHODS # diff --git a/__pycache__/Traj3D.cpython-37.pyc b/__pycache__/Traj3D.cpython-37.pyc index 9089d353fd2661eb0e1c444fe75a6b707a6ecd10..865cc612f429be0814ee850289aa455b69755f50 100644 Binary files a/__pycache__/Traj3D.cpython-37.pyc and b/__pycache__/Traj3D.cpython-37.pyc differ diff --git a/__pycache__/croisement.cpython-37.pyc b/__pycache__/croisement.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..98b13d554544eea09ac20c1e882b98c4ee553e0c Binary files /dev/null and b/__pycache__/croisement.cpython-37.pyc differ diff --git a/__pycache__/individu.cpython-37.pyc b/__pycache__/individu.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1c9eaac8adf3f0912697d410ab3a2309c5c10947 Binary files /dev/null and b/__pycache__/individu.cpython-37.pyc differ diff --git a/__pycache__/population.cpython-37.pyc b/__pycache__/population.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..14e980ef62041555b1d3d28efc6dd1b0cc4e3b90 Binary files /dev/null and b/__pycache__/population.cpython-37.pyc differ diff --git a/algogenetique.py b/algogenetique.py new file mode 100644 index 0000000000000000000000000000000000000000..9b91cb95af25a08044e3ecc9e682ca1e82153211 --- /dev/null +++ b/algogenetique.py @@ -0,0 +1,39 @@ +import mathutils +import math +import numpy +import RotTable +from individu import Individu +from population import Population +import croisement +from Traj3D import * +from random import random +import matplotlib.pyplot as plt + + +def main(N,tmax,pmutation, proportion,brin="plasmid_8k.fasta"): + '''lineList = [line.rstrip('\n') for line in open(brin)] + brin = ''.join(lineList[1:])''' + L=[] + People=Population(N) + for i in range(tmax): + max=0 + best=None + for individu in People.indiv: + individu.evaluate("AAAGGATCTTCTTGAGATCCTTTTTTTCTGCGCGTAATCTGCTGCCAGTAAACGAAAAAACCGCCTGGGGAGGCGGTTTAGTCGAA") + People.reproduction(p = proportion) + for individu in People.indiv: + individu.mutation(pmutation) + for individu in People.indiv: + individu.evaluate("AAAGGATCTTCTTGAGATCCTTTTTTTCTGCGCGTAATCTGCTGCCAGTAAACGAAAAAACCGCCTGGGGAGGCGGTTTAGTCGAA") + if individu.score>max: + best=individu + max=individu.score + L.append(max) + print(L) + plt.plot([i for i in range(tmax)], L) + plt.show() + return(individu) + + +main(100,50,0.015,2) + diff --git a/croisement.py b/croisement.py index a59546f35101170f94063bcc93992754ca4c402a..48a399f3e03e49d46867b53a1695e99657f13c67 100644 --- a/croisement.py +++ b/croisement.py @@ -1,5 +1,6 @@ import numpy from RotTable import RotTable +from individu import Individu ROT_TABLE = {\ "AA": [35.62, 7.2, -154, 0.06, 0.6, 0],\ @@ -22,17 +23,17 @@ ROT_TABLE = {\ def croisement_un_point(parent1, parent2): - enfant1 = RotTable() - enfant2 = RotTable() + enfant1 = Individu(RotTable()) + enfant2 = Individu(RotTable()) comp = 0 point_crois= numpy.random.random_integers(0,16) for doublet in ROT_TABLE: if comp < point_crois: - enfant1.rot_table[doublet] = parent1.rot_table[doublet] - enfant2.rot_table[doublet] = parent2.rot_table[doublet] + enfant1.table.rot_table[doublet] = parent1.table.rot_table[doublet] + enfant2.table.rot_table[doublet] = parent2.table.rot_table[doublet] else : - enfant1.rot_table[doublet] = parent2.rot_table[doublet] - enfant2.rot_table[doublet] = parent1.rot_table[doublet] + enfant1.table.rot_table[doublet] = parent2.table.rot_table[doublet] + enfant2.table.rot_table[doublet] = parent1.table.rot_table[doublet] comp += 1 return enfant1, enfant2 diff --git a/individu.py b/individu.py index 326fde786f81513c9d11145656719c35a5736c5a..9c3dbdb5b43982a03832d64cb7584d7257c1c843 100644 --- a/individu.py +++ b/individu.py @@ -1,5 +1,5 @@ from RotTable import RotTable -from Traj3D import * +from Traj3D import Traj3D import numpy as np from math import sqrt from random import random @@ -8,6 +8,8 @@ P1 = 0.015 class Individu(): + + def __init__(self, table): self.table = table self.score = None @@ -24,7 +26,7 @@ class Individu(): first_name = brin[0] last_name = brin[-1] - rot_computed = self.table.Rot_Table[last_name+first_name] + rot_computed = self.table.rot_table[last_name+first_name] rot_traj = first_nucleotide - last_nucleotide # print(rot_traj) # print(rot_computed) @@ -39,10 +41,14 @@ class Individu(): for coord in range(3): tir = random() if tir < proba : - # print("mutation", doublet, coord) - # print("table", table_rotations[doublet][coord]) table_rotations[doublet][coord] =np.random.uniform(low = self.table.orta()[doublet][coord] - self.table.orta()[doublet][coord + 3], high = self.table.orta()[doublet][coord] + self.table.orta()[doublet][coord + 3]) - # print("table", table_rotations[doublet][coord]) + doublet2 = self.table.corr()[doublet] + if coord == 0 or coord == 1 : + table_rotations[doublet2][coord] = table_rotations[doublet][coord] + else : + #sur l'axe z il y a un moins + table_rotations[doublet2][coord] = - table_rotations[doublet][coord] + # individu1 = Individu(RotTable()) # print(individu1.table.rot_table) diff --git a/population.py b/population.py index c1a1a413240574732ee27affacd13bb894d49c11..1af8dc965318864929e1462d992a0bd7bc746fa5 100644 --- a/population.py +++ b/population.py @@ -1,53 +1,69 @@ import random +from random import random, randint, randrange +from individu import Individu +from RotTable import RotTable +from croisement import croisement_un_point, croisement_deux_points class Population: def __init__(self,n): - self.indiv=[Individu(rot_table.alea) for k in range (n)] + self.indiv=[Individu(RotTable()) for k in range (n)] self.n = n - - def selection_duel_pondere(self,p=(self.n)//2): + + def modifier_population(self, liste_individus): + """Fonction qui renvoie une nouvelle instance de population a partir d'une liste d'individus""" + self.n = len(liste_individus) + self.indiv = liste_individus + return self + + def selection_duel_pondere(self,p=None): + if p == None : + p = (self.n)//2 newself=[] - vu={} - m=None - t=None #méthode des duels pondérée: si x=10 et y=1, y a une chance sur 11 de passer + vu=set() + 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 while len(newself)<p: while m in vu: - m=random.randrange(0,len(self)) + m=randrange(0,self.n) while t in vu: - t=random.randrange(0,len(self)) - x=self[m] - y=self[t] + t=randrange(0,self.n) + x=self.indiv[m] + y=self.indiv[t] vu.add(t) vu.add(m) - p=uniform(0,1) + p=random() if p>x.score/(x.score+y.score): newself.append(y) else: newself.append(x) - return(newself) + self = self.modifier_population(newself) - def selection_duel(self,p=(self.n)//2): + def selection_duel(self,p=None): + if p == None : + p = (self.n)//2 newself=[] - vu={} - t=None - m=None + vu=set() + t=randrange(0,self.n) + m=randrange(0,self.n) while len(newself)<p: while m in vu: - m=random.randrange(0,len(self)) + m=randrange(0,self.n) while t in vu: - t=random.randrange(0,len(self)) - x=self[m] - y=self[t] + t=randrange(0,self.n) + x=self.indiv[m] + y=self.indiv[t] vu.add(t) vu.add(m) if x.score<=y.score: newself.append(x) else: newself.append(y) - return(newself) + self = self.modifier_population(newself) - def selection_par_rang(self, p=(self.n)//2): + def selection_par_rang(self,p = None): + if p == None : + p = (self.n)//2 liste_individus = self.indiv n = self.n @@ -58,7 +74,7 @@ class Population: echanger(tableau,debut,randint(debut,fin-1)) partition=debut for i in range(debut+1,fin): - if tableau[i] < tableau[debut]: + # if tableau[i] < tableau[debut]: if tableau[i].score<tableau[debut].score: partition+=1 echanger(tableau,i,partition) @@ -85,39 +101,59 @@ class Population: j+=1 #on doit prendre l'individu avec le jème score # print("individus selectionés", individus_selectionnes) - individus_selectionnes.append(liste[j-1]) - - def modifier_population(self, liste_individus): - self.n = len(liste_individus) - self.indiv = liste_individus - return self + individus_selectionnes.append(liste_individus[j-1]) - self = modifier_population(self, individus_selectionnes) + self = self.modifier_population(individus_selectionnes) - def selection_proportionelle(self,p=(self.n)//2): + def selection_proportionelle(self,p= None): + if p == None : + p = (self.n)//2 newself=[] somme=0 - for indiv in self: + for indiv in self.indiv: somme=somme+indiv.score while len(newself)<p: - m=m=random.randrange(0,len(self)) - x=self[m] - p=uniform(0,1) + m=m=randrange(0, self.n) + x=self.indiv[m] + p=random() if p<=x.score/somme: newself.append(x) - return(newself) - - def reproduction(self,selection=selection_duel,enfant=mixage,p=n//2): - newself=selection(self,p) - while len(newself)<self.n: - m=random.randrange(0,len(newself)) - t=random.randrange(0,len(newself)) + self = self.modifier_population(newself) + + def reproduction(self,selection=None,enfant=croisement_un_point, p = None): + if selection == None : + selection = self.selection_duel + if p == None : + p = (self.n)//2 + vieille_taille = self.n + selection(p) + newself = list(self.indiv) + while len(newself)<vieille_taille: + m=randrange(0,self.n) + t=randrange(0,self.n) x=newself[m] y=newself[t] - newself.append(enfant(x,y)) - return(newself) - - + couple_enfant = enfant(x,y) + newself.append(couple_enfant[0]) + newself.append(couple_enfant[1]) + self = self.modifier_population(newself) + +def afficher(popu): + for individu in popu.indiv : + print("\n individu \n") + print(individu.table.rot_table) + +def test(): + popu = Population(4) + print("\n POPULATION INITIALE \n") + for individu in popu.indiv : + individu.evaluate("AAAGGATCTTCTTGAGATCCTTTTTTTCTGCGCGTAATCTGCTGCCAGTAAACGAAAAAACCGCCTGGGGAGGCGGTTTAGTCGAA") + afficher(popu) + popu.reproduction(selection = popu.selection_duel) + print("\n REPRODUCTION \n") + afficher(popu) + +#test() diff --git a/selection_par_rang.py b/selection_par_rang.py deleted file mode 100644 index ded5567fe7094249e4e3f1e0222031f0010a0164..0000000000000000000000000000000000000000 --- a/selection_par_rang.py +++ /dev/null @@ -1,45 +0,0 @@ -from random import random - -def creer_population(self, liste_individus): - self.n = len(liste_individus) - self.indiv = set(liste_individus) - return self - -def selection_par_rang(self, p = n//2): - set_individus = self.indiv - n = self.n - - def partitionner(tableau,debut,fin): - echanger(tableau,debut,random.randint(debut,fin-1)) - partition=debut - for i in range(debut+1,fin): - 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)) - - liste = list(set_individus) - tri_rapide(liste) - individus_selectionnes = [] - - for _ in range(p): - curseur = random()*n*(n+1)/2 - j = 1 - while j*(j+1)/2 < curseur : - j+=1 - #on doit prendre l'individu avec le jème score - individus_selectionnes.append(liste[j]) - self = creer_population(self, liste_individus) - - - \ No newline at end of file