Contracts¶
Contracts are used to check the pre and post conditions of functions to make sure that the evolutionary algorithm remains constrained within the solution space.
All contracts used by all functions are listed here. It is highly recommended that similar functions that are implemented in the future implement similar contracts. This will be explained further as each contract is explaioned.
GA.py¶
The main GA driver has the following contracts. It is highly recommended that any GA implemented to maximize the fitness score should implement these contracts.
The main GA runner¶
Preconditions¶
kwargsshould be suppliedkwargsis a dict mapping argument names (strings) to argument values- The maximum number of generations allowed is greater than 0
Postconditions¶
kwargsshould not be changed- At least one of the following two conditions must hold
- the fitness of the fittest individual (being returned) is at least
targetscore - the current generation count is equal to the maximum number of generations allowed
- the fitness of the fittest individual (being returned) is at least
the maximum number of generations allowed is greater than 0
Individual.py¶
The following contracts must be followed for any implementation of the Individual class
Individual.__hash__(self, other)¶
Preconditions¶
None
Postconditions¶
- an
intshould be returned selfshould not be changed
In addition to these, the current implementation has the following methods implemented:
Individual.__eq__(self, other)¶
Preconditions¶
othershould be an instance ofIndividual
Postconditions¶
othershould not be changedselfshould not be changed
Individual.__setitem__(self, index, obj)¶
Preconditions¶
- Exactly one of the following two conditions must be satisfied:
- 0 <=
index<= len(self.chromosomes) - len(self.chromosomes)*-1 >= index >= -1
- 0 <=
Postconditions¶
- The object at
self.chromosomes[index]should beobj
Individual.__contains__(self, chromosome)¶
Preconditions¶
None
Postconditions¶
selfshould not be changedchromosomeshould not be changed
population.py¶
The following contracts are applied to the functions in population.py
genPop(N, chromGenfuncs, chromGenParams)¶
Preconditions¶
- N >= 0
chromGenfuncsis a list- Every entry in
chromGenfuncsis a function chromGenParamssis a list- The lengths of
chromGenfuncsandchromGenParamsare equal
Postconditions¶
- The inputs are unchanged
- Function returns a list
- The length of the returned list is
N - The returned list contains exactly 1 of each item i.e. no two items in the returned list are equal
genCharsChrom(l, chars)¶
Preconditions¶
lis an integercharsis an instance of some class that implements__getitem__charsis an instance of some class that implements__len__len(chars)is greater than 0
Postconditions¶
- The inputs are unchanged
- Function returns a list
- The length of the returned list is
l - Every element in the returned list exists in
chars
score.py¶
score(p, scorefuncs, scorefuncparams, SCORES)¶
Preconditions¶
pis an instance ofIndividualscorefuncsis a list of functionsscorefuncparamsis a list of tuples- The lengths of
scorefuncsandscorefuncparamsare equal SCORESis a dictionary
Postconditions¶
The inputs are unchanged
pis inSCORES- Exactly one of the following two conditions are met:
pwas inSCORESbefore this function was called and the number of entries inSCOREShas not changedpwas not inSCORESbefore this function was called and the number of entries inSCOREShas increased by exactly 1
scoreOnes(p)¶
Preconditions¶
pis list- All elements in
pare strings of length exactly 1 - All elements in
pare either ‘0’ or ‘1’
Postconditions¶
pis unchaged- An integer is returned
- The value returned is at least 0
scoreTSP(tour, DIST)¶
- post:
- isinstance(__return__, float)
- post[tour, DIST]:
- __old__.tour == tour __old__.DIST == DIST
Preconditions¶
touris a listDISTis a dictionary- All elements in
tourare integers - All keys in
DISTare integers - All values in
DISTare dictionaries - Every key in every value of
DISTis an integer - Every value in every value of
DISTis a float
Loop Invariant¶
answer(the value to be returned is at most 0 and monotonously decreases
Postconditions¶
- The inputs are unchanged
- The function returns a float
getRouletteWheel(pop, SCORES)¶
Preconditions¶
popis a list of instances ofIndividualSCORESis a dictionary- Every element in
popis a key inSCORES
Postconditions¶
- The inputs are unchanged
- A list of 3-tuples of type (Individual, float, float) is returned
- The length of the returned list is equal to the length of
pop - The first element of every tuple in the returned list exists in
pop - The second float is smaller than the third float in every tuple in the returned list
rouletteWheelSelect(wheel, s=None)¶
Preconditions¶
wheelis a list of 3-tuples which satisfy all the following conditions- The first element is an instance of
Individual - The last two elements are floats
- The first float is smaller than the second
- The first element is an instance of
- Exactly one of the following two conditions are met:
sis a floatsis None
Postconditions:¶
- The inputs are unchanged
- An instance of
Individualis returned
tournamentSelect(pop, T, w, n, scorefunc, scoreparams)¶
Preconditions¶
popis a list of instances ofIndividualTis an integerwis an integernis an integerwis at mostnn%wis exactly 0nis at mostTscoreparamsis a tuple
Postconditions¶
- The inputs are unchanged
- A list of
ninstances ofIndividualis returned
crossover.py¶
The following contracts are implemented for the crossover functions.
crossOnes(p1, p2, chrom)¶
injectionco(p1, p2, chrom)¶
twoChildCrossover(p1,p2, crossfuncs, crossparams)¶
Preconditions¶
p1andp2are instances ofIndividualp1andp2are of exactly equal length- The number of elements in
crossfuncsis exactly equal to the length ofp1(and therefore ofp2) - The number of elements in
crossfuncsis exactly equal to the number of elements incrossparams - Every element in
crossparamsis a tuple
Postconditions¶
- The inputs are unchanged
- A tuple of two elements of type
Individualis returned - Each of the returned children has the same number of chromosomes as the parents
- Each chromosome in each of the children has the same length as the corresponding chromosome of both parents
oneChildCrossover(p1,p2, crossfuncs, crossparams)¶
Preconditions¶
p1andp2are instances ofIndividualp1andp2are of exactly equal length- The number of elements in
crossfuncsis exactly equal to the length ofp1(and therefore ofp2) - The number of elements in
crossfuncsis exactly equal to the number of elements incrossparams - Every element in
crossparamsis a tuple
Postconditions¶
- The inputs are unchanged
- A tuple of one element of type
Individualis returned - The returned child has the same number of chromosomes as the parents
- Each chromosome in the child has the same length as the corresponding chromosome of both parents
muatation.py¶
mutateSingleAllele(p, chrom, chars)¶
Preconditions¶
pis an instance ofIndividualchromis an integerThe value of each gene in the
chromth chromosome ofpexists inchars- Exactly one of the following two conditions must be satisfied:
- 0 <=
index<= len(self.chromosomes) - len(self.chromosomes)*-1 >= index >= -1
- 0 <=
Postconditions¶
- The inputs are unchanged
- A new instance of
Individualis returned - The
chromth chromosome of the returned individual is not equal to thechromth chromosome ofp - All other chromosomes of the returned individual are exactly the same as the corresponding chromosome of
p
swapmut(p, chrom)¶
Preconditions¶
pis an instance ofIndividualchromis an integer- Exactly one of the following two conditions are satisfied:
- 0 <=
chrom<=len(p.chromosomes) len(self.chromosomes)*-1>=index>= -1
- 0 <=
Postconditions¶
- The inputs are unchaged
- An instance of
Individualis returned - All values in the
chromth chromosome ofpare present in thechromth chromosome of the output individual - The
chromth chromosomes of the output individual andpare not equal - There are exactly two genes in the
chromth chromome ofpand the returned individual, whose values differ
revmut(p, chrom)¶
Preconditions¶
pis an instance ofIndividualchromis an integer- Exactly one of the following two conditions are satisfied:
- 0 <=
chrom<=len(p.chromosomes) len(self.chromosomes)*-1>=index>= -1
- 0 <=
Postconditions¶
- The inputs are unchaged
- An instance of
Individualis returned - All values in the
chromth chromosome ofpare present in the`chromth chromosome of the output individual - The
chromth chromosomes of the output individual andpare not equal
shufflemut(p, chrom)¶
- post[p, chrom]:
- __old__.p == p __old__.chrom == chrom isinstance(__return__, Individual) __return__.chromosomes[chrom] != p.chromosomes[chrom] forall(p.chromosomes[chrom], lambda e: e in __return__.chromosomes[chrom]) forall(__return__.chromosomes[chrom], lambda e: e in p.chromosomes[chrom])
Preconditions¶
pis an instance ofIndividualchromis an integer- Exactly one of the following two conditions are satisfied:
- 0 <=
chrom<=len(p.chromosomes) len(self.chromosomes)*-1>=index>= -1
- 0 <=
Postconditions¶
- The inputs are unchaged
- An instance of
Individualis returned - All values in the
chromth chromosome ofpare present in the`chromth chromosome of the output individual - The
chromth chromosomes of the output individual andpare not equal - The length of the
chromth chromosome of the returned individual is exactly equal to the length of thechromth chromosome ofp