Back to index

python-biopython  1.60
General.py
Go to the documentation of this file.
00001 """General functionality for crossover that doesn't apply.
00002 
00003 This collects Crossover stuff that doesn't deal with any specific
00004 type of crossover.
00005 """
00006 # standard library
00007 import random
00008 
00009 # local stuff
00010 from Bio.GA.Organism import Organism
00011 
00012 class SafeFitnessCrossover(object):
00013     """Perform crossovers, but do not allow decreases in organism fitness.
00014 
00015     This doesn't actually do any crossover work, but instead relies on
00016     another class to do the crossover and just checks that newly created
00017     organisms do not have less fitness. This is useful for cases where
00018     crossovers can 
00019     """
00020     def __init__(self, actual_crossover, accept_less = 0.0):
00021         """Initialize to do safe crossovers.
00022 
00023         Arguments:
00024 
00025         o actual_crossover - A Crossover class which actually implements
00026         crossover functionality.
00027 
00028         o accept_less - A probability to accept crossovers which
00029         generate less fitness. This allows you to accept some
00030         crossovers which reduce fitness, but not all of them.
00031         """
00032         self._crossover = actual_crossover
00033         self._accept_less_percent = accept_less
00034         self._accept_less_rand = random.Random()
00035 
00036     def do_crossover(self, org_1, org_2):
00037         """Perform a safe crossover between the two organism.
00038         """
00039         new_org_1, new_org_2 = self._crossover.do_crossover(org_1, org_2)
00040 
00041         return_orgs = []
00042 
00043         for start_org, new_org in ((org_1, new_org_1),
00044                                    (org_2, new_org_2)):
00045             new_org.recalculate_fitness()
00046 
00047             # if the starting organism has a better fitness,
00048             # keep it, minding the acceptance of less favorable change policy
00049             if start_org.fitness > new_org.fitness:
00050                 accept_change = self._accept_less_rand.random()
00051                 if accept_change <= self._accept_less_percent:
00052                     return_orgs.append(new_org)
00053                 else:
00054                     return_orgs.append(start_org)
00055             else:
00056                 return_orgs.append(new_org)
00057 
00058         assert len(return_orgs) == 2, "Should have two organisms to return."
00059 
00060         return return_orgs