Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

196 lines (156 sloc) 6.176 kB
#!/usr/bin/env python
# This code is part of the Biopython distribution and governed by its
# license. Please see the LICENSE file that should have been included
# as part of this package.
"""Tests for Genetic Algorithm classes that provide selection capabilities.
"""
# standard library
import random
import unittest
# biopython
from Bio.Seq import MutableSeq
from Bio.Alphabet import SingleLetterAlphabet
# local stuff
from Bio.GA.Organism import Organism
from Bio.GA.Selection.Diversity import DiversitySelection
from Bio.GA.Selection.Tournament import TournamentSelection
from Bio.GA.Selection.RouletteWheel import RouletteWheelSelection
# --- helper classes and functions
class TestAlphabet(SingleLetterAlphabet):
"""Simple test alphabet.
"""
letters = ["0", "1", "2", "3"]
def test_fitness(genome):
"""Simple class for calculating fitnesses.
"""
genome_seq = genome.toseq()
return int(genome_seq.tostring())
class NoSelection:
"""A simple 'selection' class that just returns the generated population.
"""
def select(self, population):
return population
class NoMutation:
"""Simple 'mutation' class that doesn't do anything.
"""
def mutate(self, org):
return org.copy()
class NoCrossover:
"""Simple 'crossover' class that doesn't do anything.
"""
def do_crossover(self, org_1, org_2):
return org_1.copy(), org_2.copy()
class NoRepair:
"""Simple 'repair' class that doesn't do anything.
"""
def repair(self, org):
return org.copy()
def random_genome():
"""Return a random genome string.
"""
alphabet = TestAlphabet()
new_genome = ""
for letter in range(3):
new_genome += random.choice(alphabet.letters)
return MutableSeq(new_genome, alphabet)
def random_organism():
"""Generate a random organism.
"""
genome = random_genome()
return Organism(genome, test_fitness)
# --- the actual test classes
class DiversitySelectionTest(unittest.TestCase):
"""Test selection trying to maximize diversity.
"""
def setUp(self):
self.selector = DiversitySelection(NoSelection(), random_genome)
def test_get_new_organism(self):
"""Getting a new organism not in the new population.
"""
org = random_organism()
old_pop = [org]
new_pop = []
new_org = self.selector._get_new_organism(new_pop, old_pop)
self.assertEqual(new_org, org,
"Got an unexpected organism %s" % new_org)
def test_no_retrieve_organism(self):
"""Test not getting an organism already in the new population.
"""
org = random_organism()
old_pop = [org]
new_pop = [org]
new_org = self.selector._get_new_organism(new_pop, old_pop)
#assert new_org != org, "Got organism already in the new population."
#TODO - Why was the above commented out?
def test_selection(self):
"""Test basic selection on a small population.
"""
pop = [random_organism() for org_num in range(50)]
new_pop = self.selector.select(pop)
self.assertEqual(len(new_pop), len(pop),
"Did not maintain population size.")
class TournamentSelectionTest(unittest.TestCase):
"""Test selection based on a tournament style scheme.
"""
def setUp(self):
self.selector = TournamentSelection(NoMutation(), NoCrossover(),
NoRepair(), 2)
def test_select_best(self):
"""Ensure selection of the best organism in a population of 2.
"""
#Create any two non equal organisms
org_1 = random_organism()
while True:
org_2 = random_organism()
if org_2.fitness != org_1.fitness:
break
#Sort them so org_1 is most fit
if org_2.fitness > org_1.fitness:
org_1, org_2 = org_2, org_1
self.assertTrue(org_1.fitness > org_2.fitness)
pop = [org_1, org_2]
new_pop = self.selector.select(pop)
for org in new_pop:
self.assertEqual(org, org_1,
"Got a worse organism selected.")
#Just to make sure the selector isn't doing something
#silly with the order, try this with the input reserved:
pop = [org_2, org_1]
new_pop = self.selector.select(pop)
for org in new_pop:
self.assertEqual(org, org_1,
"Got a worse organism selected.")
def test_selection(self):
"""Test basic selection on a small population.
"""
pop = [random_organism() for org_num in range(50)]
new_pop = self.selector.select(pop)
self.assertEqual(len(new_pop), len(pop),
"Did not maintain population size.")
class RouletteWheelSelectionTest(unittest.TestCase):
"""Test selection using a roulette wheel selection scheme.
"""
def setUp(self):
self.selector = RouletteWheelSelection(NoMutation(), NoCrossover(),
NoRepair())
def test_select_best(self):
"""Ensure selection of a best organism in a population of 2.
"""
worst_genome = MutableSeq("0", TestAlphabet())
worst_org = Organism(worst_genome, test_fitness)
better_genome = MutableSeq("1", TestAlphabet())
better_org = Organism(better_genome, test_fitness)
new_pop = self.selector.select([worst_org, better_org])
for org in new_pop:
self.assertEqual(org, better_org,
"Worse organism unexpectly selected.")
def test_selection(self):
"""Test basic selection on a small population.
"""
pop = [random_organism() for org_num in range(50)]
new_pop = self.selector.select(pop)
self.assertEqual(len(new_pop), len(pop),
"Did not maintain population size.")
if __name__ == "__main__":
runner = unittest.TextTestRunner(verbosity = 2)
unittest.main(testRunner=runner)
Jump to Line
Something went wrong with that request. Please try again.