2""" @brief Genomes in EVOLIFE are defined
as a binary strings.
4 The way the genome string
is implemented (e.g. list of binary numbers
5 or bits compacted into integers) should remain private to this module
"""
7#============================================================================#
8# EVOLIFE http://evolife.telecom-paris.fr Jean-Louis Dessalles
23if __name__ ==
'__main__':
24 sys.path.append(
'../..')
25 from Evolife.Scenarii.MyScenario
import InstantiateScenario
26 InstantiateScenario(
'Cooperation',
'../Evolife')
36 """ class DNA: individuals
' 'DNA
' defined as a string of bits
39 def __init__(self, Scenario, Nb_nucleotides):
43 Fill = self.Scenario.Parameter('DNAFill', Default=-1)
45 if (Fill==1): self.
__dna.append(1)
46 elif (Fill==0): self.
__dna.append(0)
47 else: self.
__dna.append(random.randint(0,1))
51 """ fills the DNA with given Nucleotides
53 self.__dna = Nucleotides[:]
54 if len(Nucleotides) > 0
and len(Nucleotides) != self.
nb_nucleotides:
55 Tools.error(
'DNA: initialization',
'Provided genome length does not match gene map')
56 if len(Nucleotides) > 0
and not set(Nucleotides) <= set([0,1]):
57 Tools.error(
'DNA: initialization',
'Provided genome is not binary')
59 def hybrid(self, mother, father, number_crossover = -1):
60 """ builds the child's DNA from the parents' DNA
63 if number_crossover < 0: number_crossover = self.
Scenario.Parameter(
'NbCrossover')
65 Loci_crossover = random.sample(range(1,self.
nb_nucleotides), number_crossover)
66 Loci_crossover = [0] + sorted(Loci_crossover)
72 parent1 = mother.__dna
73 parent2 = father.__dna
74 if random.randint(0,1):
75 parent1, parent2 = parent2, parent1
77 for cut_point
in range(len(Loci_crossover)-1):
78 self.
__dna += list(parent1[Loci_crossover[cut_point]:Loci_crossover[cut_point+1]])
79 parent1, parent2 = parent2, parent1
82 def mutate(self, mutation_rate = -1):
83 """ computing the expected number of mutations
85 if mutation_rate < 0: mutation_rate = self.
Scenario.Parameter(
'MutationRate')
86 mutation_number = Tools.chances(mutation_rate/1000.0, self.
nb_nucleotides)
91 for mutation
in range(mutation_number):
92 pos = random.randint(0, self.nb_nucleotides - 1)
93 self.__dna[pos] = 1 - self.__dna[pos]
94 return mutation_number
97 """ reads a chunk of DNA
99 if coding ==
None: coding = self.Scenario.Parameter(
'GeneCoding')
100 if coding
in range(-1,3):
102 coding = [
'Nocoding',
'Weighted',
'Unweighted',
'Gray'][coding+1]
104 coding = coding.lower()
105 if coding ==
'nocoding':
107 if coding
not in [
'weighted',
'unweighted',
'gray']:
108 Tools.error(
"DNA",
'unknown binary coding mode')
110 for pos
in range(start,end):
111 if coding ==
'unweighted':
112 value += self.__dna[pos]
115 value += (self.__dna[pos] << (end - 1 - pos))
117 value = Tools.GrayTable.Gray2Int(value)
120 Tools.error(
"DNA",
"reading outside the DNA")
123 """ computes the Hamming distance between two DNA strings
126 for pos
in range(self.nb_nucleotides):
127 distance += (self.__dna[pos] != alter.__dna[pos])
131 """ returns DNA as a tuple
133 return tuple(self.__dna)
135 def __str__(self, compact=0):
137 return str(sum(self.__dna))
139 return "-".join([
"%s" %pos
for pos
in self.__dna])
148if __name__ ==
"__main__":
150 print(DNA.__doc__ +
'\n')
151 mother =
DNA(9, Blank=
False)
154 father =
DNA(9, Blank=
False)
158 child.hybrid(mother,father,2)
165 print(
'child\'s value (weighted) :')
166 print(child.read_DNA(0,4, coding = MyScenario.Parameter(
'Weighted')))
167 print(
'child\'s value (unweighted):')
168 print(child.read_DNA(0,4, coding = MyScenario.Parameter(
'Unweighted')))
169 print(
'distance with mother:')
170 print(child.hamming(mother))
171 print(
'distance with father:')
172 print(child.hamming(father))
173 raw_input(
'\n[Return]')
177__author__ =
'Dessalles'
class DNA: individuals' 'DNA' defined as a string of bits
def DNAfill(self, Nucleotides)
fills the DNA with given Nucleotides
def hybrid(self, mother, father, number_crossover=-1)
builds the child's DNA from the parents' DNA
def mutate(self, mutation_rate=-1)
computing the expected number of mutations
def hamming(self, alter)
computes the Hamming distance between two DNA strings
def read_DNA(self, start, end, coding=None)
reads a chunk of DNA
def get_DNA(self)
returns DNA as a tuple