-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCChromosome.py
74 lines (66 loc) · 2.97 KB
/
CChromosome.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import random
class CBaseChromosome():
"""
The following methods need to be implemented, in order to assure compatibility with the population class.
"""
def mutate(self):
"""
Random change in stored data
:return:
"""
pass
def __add__(self, other_chromosome):
"""
This method should define a + operator for chromosomes. The operator should realize a random
recombination of two chromosomes.
:param other_chromosome:
:return:result of recombination
"""
pass
# -------------------------------Class CChromosome-------------------------------------
class CChromosome(CBaseChromosome):
"""
Saves the inheritable information of individuals. This information is saved in an array "loci", which has the form
[..., (locus,locus_evolves), ...]
"""
def __init__(self, mutation_range, mutation_rate, loci=None):
if loci is None:
loci = []
self.loci = list(loci) # make a copy, has the form [(locus, locus_evolves), ...], locus is a value in [0,1]
self.mutation_range = mutation_range # mutation range: for details go to the method mutate
self.mutation_rate = mutation_rate # mutation rate: for details go to the method mutate
def mutate(self):
"""
Changes all genes randomly whose evolve parameter is set to true
:return:
"""
for i, (locus, locus_evolves) in enumerate(self.loci):
if locus_evolves and (random.random() < self.mutation_rate):
locus = locus + random.uniform(-1, 1) * self.mutation_range
self.loci[i] = (locus, locus_evolves)
# Creates a new chromosome by randomly assigning either a locus from "self" or from "other_chromosome"
def __add__(self, other_chromosome):
"""
Defines a + operator for chromosomes.The operator is not deterministic! The operator realizes a random
recombination of two chromosomes.
:param other_chromosome:
:return:result of recombination
"""
novi_loci = []
for i, (locus_a, locus_a_evolves) in enumerate(self.loci):
(locus_b, locus_b_evolves) = other_chromosome.loci[i]
if random.random() < 0.5:
novi_loci.append((
# *1 ensures that a copy of the value is made and not just a reference
# ToDo: Necessary? If yes, there is for sure a better way!
locus_a * 1, locus_a_evolves))
else:
novi_loci.append((locus_b * 1, locus_b_evolves))
new_chromosome = CChromosome(self.mutation_range, self.mutation_rate, novi_loci)
return new_chromosome
def __str__(self):
n_str = ""
for (locus, locus_evolves) in self.loci:
n_str += str(locus) + " locus evolves? " + str(locus_evolves) + "\n"
return n_str
# -------------------------------End of class CChromosome-------------------------------------