Skip to content

Commit 8565d14

Browse files
authored
Documenting the new fitness_func parameter
Adding more description of the new parameter named fitness_func that accepts a function representing the fitness function that returns a fitness value for a single solution.
1 parent 004a066 commit 8565d14

File tree

1 file changed

+45
-18
lines changed

1 file changed

+45
-18
lines changed

README.md

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
# GeneticAlgorithmPython
2-
32
This project implements the genetic algorithm (GA) in Python mainly using NumPy.
43

54
The project has 2 main files which are:
65

7-
1. `ga.py`: Holds all necessary methods for implementing the GA.
6+
1. `ga.py`: Holds all necessary methods for implementing the genetic algorithm inside a class named `GA`.
87

98
2. `example.py`: Just gives an example of how to use the project by calling the methods in the `ga.py` file.
109

@@ -27,15 +26,15 @@ To use the project, here is the summary of the minimum required steps:
2726

2827
Let's discuss how to do each of these steps.
2928

30-
### Preparing the Parameters
29+
### The Supported Parameters
3130

3231
The project has many parameters to allow customizing the genetic algorithm for your purpose. Before running the GA, the parameters must be prepared. The list of all supported parameters is as follows:
3332

3433
- `num_generations` : Number of generations.
3534
- `sol_per_pop` : Number of solutions (i.e. chromosomes) within the population.
3635
- `num_parents_mating ` : Number of solutions to be selected as parents.
37-
- `function_inputs ` : Inputs of the function to be optimized.
38-
- `function_output` : The output of the function to be optimized.
36+
- `num_genes`: Number of genes in the solution/chromosome.
37+
- `fitness_func` : A function for calculating the fitness value for each solution.
3938
- `parent_selection_type="sss"` : The parent selection type. Supported types are `sss` (for steady state selection), `rws` (for roulette wheel selection), `sus` (for stochastic universal selection), `rank` (for rank selection), `random` (for random selection), and `tournament` (for tournament selection).
4039
- `keep_parents=-1` : Number of parents to keep in the current population. `-1` (default) means keep all parents in the next population. `0` means keep no parents in the next population. A value `greater than 0` means keep the specified number of parents in the next population. Note that the value assigned to `keep_parents` cannot be `< - 1` or greater than the number of solutions within the population `sol_per_pop`.
4140
- `K_tournament=3` : In case that the parent selection type is `tournament`, the `K_tournament` specifies the number of parents participating in the tournament selection. It defaults to `3`.
@@ -46,12 +45,40 @@ The project has many parameters to allow customizing the genetic algorithm for y
4645
- `random_mutation_min_val=-1.0` : For `random` mutation, the `random_mutation_min_val` parameter specifies the start value of the range from which a random value is selected to be added to the gene. It defaults to `-1`.
4746
- `random_mutation_max_val=1.0` : For `random` mutation, the `random_mutation_max_val` parameter specifies the end value of the range from which a random value is selected to be added to the gene. It defaults to `+1`.
4847

49-
The user doesn't have to specify all of such parameters while creating an instance of the GA class. Here is an example for preparing such parameters:
48+
The user doesn't have to specify all of such parameters while creating an instance of the GA class. A very important parameter you must care about is `fitness_func`.
49+
50+
### Preparing the `fitness_func` Parameter
51+
52+
Even there are a number of steps in the genetic algorithm pipeline that can work the same regardless of the problem being solved, one critical step is the calculation of the fitness value. There is no unique way of calculating the fitness value and it changes from one problem to another.
53+
54+
On **`15 April 2020`**, a new argument named `fitness_func` is added that allows the user to specify a custom function to be used as a fitness function. This function must be a **maximization function** so that a solution with a high fitness value returned is selected compared to a solution with a low value. Doing that allows the user to freely use the project to solve any problem by passing the appropriate fitness function.
55+
56+
Let's discuss an example:
57+
58+
> Given the following function:
59+
> y = f(w1:w6) = w1x1 + w2x2 + w3x3 + w4x4 + w5x5 + 6wx6
60+
> where (x1,x2,x3,x4,x5,x6)=(4,-2,3.5,5,-11,-4.7) and y=44
61+
> What are the best values for the 6 weights (w1 to w6)? We are going to use the genetic algorithm to optimize this function.
62+
63+
So, the task is about using the genetic algorithm to find the best values for the 6 weight `W1` to `W6`. Thinking of the problem, it is clear that the best solution is that returning an output that is close to the desired output `y=44`. So, the fitness function should return a value that gets higher when the solution's output is closer to `y=44`. Here is a function that does that. The function must accept a single parameter which is a 1D vector representing a single solution.
5064

5165
```python
52-
function_inputs = [4,-2,3.5,5,-11,-4.7]
53-
function_output = 44
66+
function_inputs = [4,-2,3.5,5,-11,-4.7] # Function inputs.
67+
desired_output = 44 # Function output.
68+
69+
def fitness_func(solution):
70+
output = numpy.sum(solution*function_inputs)
71+
fitness = 1.0 / numpy.abs(output - desired_output)
72+
return fitness
73+
```
5474

75+
By creating this function, you are ready to use the project.
76+
77+
### Parameters Example
78+
79+
Here is an example for preparing the parameters:
80+
81+
```python
5582
num_generations = 50
5683
sol_per_pop = 8
5784
num_parents_mating = 4
@@ -65,8 +92,12 @@ crossover_type = "single_point"
6592
mutation_type = "random"
6693

6794
keep_parents = 1
95+
96+
num_genes = len(function_inputs)
6897
```
6998

99+
After the parameters are prepared, we can import the `ga` module and build an instance of the GA class.
100+
70101
### Import the `ga.py` Module
71102

72103
The next step is to import the `ga` module as follows:
@@ -85,8 +116,8 @@ The `GA` class is instantiated where the previously prepared parameters are fed
85116
ga_instance = ga.GA(num_generations=num_generations,
86117
sol_per_pop=sol_per_pop,
87118
num_parents_mating=num_parents_mating,
88-
function_inputs=function_inputs,
89-
function_output=function_output,
119+
num_genes=num_genes,
120+
fitness_func=fitness_func,
90121
mutation_percent_genes=mutation_percent_genes,
91122
mutation_num_genes=mutation_num_genes,
92123
parent_selection_type=parent_selection_type,
@@ -113,17 +144,12 @@ Inside this method, the genetic algorithm evolves over a number of generations b
113144

114145
### Plotting Results
115146

116-
There is a method named `plot_result()` which creates 2 figures summarizing the results.
147+
There is a method named `plot_result()` which creates a figure summarizing how the fitness values of the solutions change with the generations .
117148

118149
```python
119150
ga_instance.plot_result()
120151
```
121152

122-
The first figure shows how the solutions' outputs change with the generations.
123-
![Fig01](https://user-images.githubusercontent.com/16560492/78829951-8391d400-79e7-11ea-8edf-e46932dc76da.png)
124-
125-
The second figure shows how the fitness values of the solutions change with the generations.
126-
127153
![Fig02](https://user-images.githubusercontent.com/16560492/78830005-93111d00-79e7-11ea-9d8e-a8d8325a6101.png)
128154

129155
### Saving & Loading the Results
@@ -150,6 +176,7 @@ print(loaded_ga_instance.best_solution())
150176
```
151177

152178
## Crossover, Mutation, and Parent Selection
179+
153180
The project supports different types for selecting the parents and applying the crossover & mutation operators.
154181

155182
The supported crossover operations at this time are:
@@ -196,9 +223,9 @@ You can also check my book cited as [**Ahmed Fawzy Gad 'Practical Computer Visio
196223

197224
**Important Note**
198225

199-
It is important to note that this project does not implement everything in GA and there are a wide number of variations to be applied. For example, this project uses decimal representation for the chromosome and the binary representations might be preferred for other problems.
226+
It is important to note that this project does not implement everything in GA and there are a wide number of variations to be applied. For example, this project just uses decimal representation for the chromosome and the binary representations might be preferred for other problems.
200227

201-
## Get in Touch
228+
## Get it Touch
202229
* E-mail: ahmed.f.gad@gmail.com
203230
* [LinkedIn](https://www.linkedin.com/in/ahmedfgad)
204231
* [Amazon Author Page](https://amazon.com/author/ahmedgad)

0 commit comments

Comments
 (0)