1 """General functionality for crossover that doesn't apply.
2
3 This collects Crossover stuff that doesn't deal with any specific
4 type of crossover.
5 """
6
7 import random
8
9
10 from Bio.GA.Organism import Organism
11
12
14 """Perform crossovers, but do not allow decreases in organism fitness.
15
16 This doesn't actually do any crossover work, but instead relies on
17 another class to do the crossover and just checks that newly created
18 organisms do not have less fitness. This is useful for cases where
19 crossovers can
20 """
21 - def __init__(self, actual_crossover, accept_less = 0.0):
22 """Initialize to do safe crossovers.
23
24 Arguments:
25
26 o actual_crossover - A Crossover class which actually implements
27 crossover functionality.
28
29 o accept_less - A probability to accept crossovers which
30 generate less fitness. This allows you to accept some
31 crossovers which reduce fitness, but not all of them.
32 """
33 self._crossover = actual_crossover
34 self._accept_less_percent = accept_less
35 self._accept_less_rand = random.Random()
36
38 """Perform a safe crossover between the two organism.
39 """
40 new_org_1, new_org_2 = self._crossover.do_crossover(org_1, org_2)
41
42 return_orgs = []
43
44 for start_org, new_org in ((org_1, new_org_1),
45 (org_2, new_org_2)):
46 new_org.recalculate_fitness()
47
48
49
50 if start_org.fitness > new_org.fitness:
51 accept_change = self._accept_less_rand.random()
52 if accept_change <= self._accept_less_percent:
53 return_orgs.append(new_org)
54 else:
55 return_orgs.append(start_org)
56 else:
57 return_orgs.append(new_org)
58
59 assert len(return_orgs) == 2, "Should have two organisms to return."
60
61 return return_orgs
62