In this assignment, you will implement main parts of genetic algorithms.
There are lots of algorithms that researchers use in each part and your are going to implement the famous ones. And of course there are some rare ideas to implement here(the harder you work the better grade you get)!
- First of all, you should implement everything only using numpy or built-in libraries.
- You should only implement functions to do the task for each module. This means that you have to assume some predefined code and implement your own code,using that.
- You can define sub functions for simplifying your task.
- We've provided a sample class of chromosomes with some attributes. You can assume that this class will be parsed as the chromosome in your functions.
- In some of the modules, you need to change the class to add some new attributes. To do so, you should extend the class and add new attributes to your new implemented class.
- Modules have weighted grades so the more work you put in the more points you get.
- Some modules are optional for some groups.
- Groups are categorized based on theirs skills. So the more skilled you are the more tasks and different points for each task you get.
- (optional) Unit testing has bonus points. If you use online CI tools like Travis CI or Azure DevOps for testing, you'll get more bonus points!!!
Note: If you want to use unit testing in your codes, please provide high quality tests. writing low quality test is just a waste time (Go play GTA instead!)
- For god's sake write something! maybe someday you have to use your own project(hopefully).
- You have to provide documentation for all of the function arguments and return values and of course a simple explanation about your function and a numerical example of how would your function work. 3.Don't know how to write docs in python? OK, google it!
This tutorial may help you to write better docs.
- we've provided some modules for each section.
- Each module will be a function as described in implementation section.
- There is a little description on what each module is and some links as reference. You must read those links and implement modules based on algorithms provided in the references. In some modules, we've provided a paper,related to the module. It is your task to study the papers and find out how to implement the modules.
This assignment includes these parts:
- Initialization (Population and Chromosome)
- Selection Methods
- Crossover Methods
- Mutation Methods
We will describe each section later on
In this step we talk about initializing chromosomes and population. So here are the contents:
- Chromosome
- Population
Here we assume that every problem can be encoded to chromosomes with 1 dimensional vector genes.
But the structure of this genes depends on the problem. We describe most famous ones here so we have 3 types of gene vectors:
- A binary vector in which 1 represents the existence of the genes and 0 represents non-existence.
Numeric example:
genes = [0, 1, 0, 0, 0, 1, ... , 0]
print(chromosome.genes)
output: [0, 1, 0, 0, 0, 1, ... , 0]
- An integer vector of vectors which each element represents a vector of the batch of the genes with the same size. something like a flatten 2 dimensional matrix.
genes = [
[1,2,3],
[2,1,3],
[3,2,1],
[3,1,2]
]
chromosome.genes = genes.flatten()
print(chromosome.genes)
output: [1,2,3,2,1,3,3,2,1,3,1,2]
3.An integer vector of vectors like state 2, but each element has different size. So this is your duty to think about the best encoding way for it.
genes = [
[1,2,3,4,5],
[3,2,1],
[2,3,1,4],
[1]
]
chromosome.genes = genes.flatten()
print(chromosome.genes)
output: [1,2,3,4,5,3,2,1,2,3,1,4,1]
lengths
is important. So we add another attribute to the chromosome
class.
chromosome.lengths = [5,3,4,1]
So every time you want to apply any operation on these features, you have to do it with respect to lengths
.
Note: These numbers are just for demonstration purposes and in real world example, they are data points (features).
We've provided a class representing a simple chromosome. You need to complete all the functions with respect to this class.
import numpy as np
class chromosome():
def __init__(self, genes, id=None, fitness=-1, flatten= False, lengths=None):
self.id = id
self.genes = genes
self.fitness = fitness
# if you need more parameters for specific problem, extend this class
def flatten_feaures():
# in this function you should implement your logic to flatten features
pass
def describe(self):
print('ID=#{}, fitenss={}, \ngenes=\n{}'.format(self.id, self.fitness, self.genes))
c = chromosome(genes=np.array([1,2,3]),id=1,fitness = 125.2)
c.describe()
c2 = chromosome(genes = np.array([[1,2],[2,1]]).flatten(), id=2,
fitness=140, flatten=True)
c2.describe()
ID=#1, fitenss=125.2,
genes=
[1 2 3]
ID=#2, fitenss=140,
genes=
[1 2 2 1]
In the population,chromosomes are like friends and enemies. So all operators in mutation and crossover will be applied on these chromosomes based on nature selection ideas and survival of the fittest.
Initialization can help you to find global optima faster but can even get you stuck in the local optima on the other hand. Hence, it is an important part.
There are some methods to initialize population and they are hyperparameters.
Hyperparameters are:
- Population Size
- Chromosome Genes
The most famous one is random initialization.
Population initialization:
- Pseudo Random
- Quasi Random Sequence
- Centroid Voronoi Tessellation
This is the simplest method. Actually the random
class in every programming language is a pseudo random number. And of course you can make a uniform random using this pseudo randoms.
So in your implementation, you must use numpy.random
to initialize population and chromosomes.
Just do everything random! If you need more information, check more reading section below.
the initial population is often selected randomly using pseudo random numbers.It’s usually more important that the points are as evenly distributed as possible than that they imitate random points. In this paper, we study the use of quasi-random sequences in the initial population of a genetic algorithm. Sample points in a quasi-random sequence are designed to have good distribution properties.
Use this link as reference.
In this method, we consider data points as clusters and will separate them based on some criteria. And then initialize random points with respect to these regions.
Use this paper as reference.
If you need to know more about random numbers, this and this about different methods.
The main purpose of selection phase is to select the fittest individuals and let them pass their genes to the next generation.
These are your tasks:
- Truncation Selection
- Tournament Selection
- stochastic Universal Sampling
- Roulette Wheel Selection
- Roulette Wheel Selection with stochastic Acceptance
- Linear Ranking Selection
- Exponential Ranking Selection
- Self-Adaptive Tournament Selection
Use This as reference.
More reading:
Muhlenbein's Breeder Genetic Algorithm.
Use this as reference.
Use this as reference.
Use this as reference.
Use this as reference.
Use this and this as reference.
Use this and this as reference.
Use this as reference.
The idea is to have better individuals at the next generations. So we have to do something. Here we try to use top individuals offspring for next generations as parents. This help us to exploit.
Here is some of crossover operators:
- Single-point Crossover
- Multi-point Crossover (N-point)
- Uniform Crossover
- Flat Crossover
- Order Crossover (OX)
- Partially Mapped Crossover(PMX)
- Edge Recombination Crossover (ERX)
- Cycle Crossover (CX)
- Alternating Edges Crossover (AEX)
Note: You must implement each operator for 3 types of chromosome classes. (See Initialization section).
Reference:
The main goal of mutation phase is to change the values of genes in a chromosome randomly and introduce new genetic material into the population,to increase genetic diversity.
These are your tasks:
- Uniform/Random Mutation
- Inorder Mutation
- Twors Mutation
- Centre inverse mutation (CIM)
- Reverse Sequence Mutation (RSM)
- Throas Mutation
- Thrors Mutation
- Partial Shuffle Mutation (PSM)
- Scrabmle Mutation
- Distance-Based Mutation Operator (DMO)
The reference for 9/10 of these operators here.
Use this link.
You can get paper here.
MIT License
Copyright (c) 2018 Computational Intelligence - University of Guilan
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Get in touch with Authors: Mohammad Doosti Lakhani, Hamed Faraji