GAModel is an abstract class that implements the genetic algorithm. Developers only need to extend the class to implement init, and evaluateFitness methods.
| Name | Description |
|---|---|
population |
A cell containing all the individuals living in the population. |
constructor |
The constructor for individuals in the population. |
verbose |
The level of information that will show in the terminal. |
options |
Options used for optimizing the model. |
status |
A struct containing the current status of the model. |
statistics |
A struct containing the model's statistics. |
best |
The individual with the highest fitness score. |
A struct containing options about the model.
| Option | Description |
|---|---|
verbose |
The verbose level. |
populationSize |
The size of the population. |
generations |
The number of generations to run. |
selectionSchema |
The schema used for selecting individuals for reproduction. Popular methods include roulette, tournament, and rank. Learn more on the section for selection schema. |
tournamentSize |
The number of individuals that will be randomly chosen for each tournament. Only used in tournament selection. |
eliteSize |
The number of individuals that are guaranteed to survive to the next generation. |
crossoverFraction |
After excluding the elites, it specifies the fraction of individuals in the next generation created by performing crossover on two selected parents. |
mutateAfterCrossover |
Mutate on newly generated individuals. |
To set an option, use the register method.
% Register a single attribute
myModel.register('verbose', verbose);
% Register a struct, will not override existing parameters.
opt.populationSize = 25;
opt.maxHeight = 6;
opt.generations = 20;
myGPModel.register(opt);After excluding the elites, it specifies the fraction of individuals in the next generation created by performing crossover on two selected parents. For example, when the populationSize is 50, eliteSize is 8, then a crossoverFraction=0.70 will result in the generation consisting of:
- 10 elites directly copied from the previous generation.
- (50 - 8) * 0.8 = 29.4 = 29 (rounded) individuals are generated via crossover.
- The remaining 50 - 8 - 29 = 13 individuals are generated by mutating individuals from the previous generation.
These levels decide the amount of information you will get. Available verbose levels:
- 0: Mute
- 1: Only show results for each generation
- 2: Show information for each generation
- 3: Show results for individual
- 4: Show information for each individual (default)
The constructor for individuals in the population. Must be of type GAMember or any class that extends the GAMember class.
| Argument | Description |
|---|---|
constructor |
The constructor for individuals in the population. |
The constructor for individuals in the population. Must be of type GAMember or any class that extends the GAMember class.
When calling the run method, it invokes the following methods. First, beforeRun is called at the beginning. forEachGeneration is called for each generation. Within forEachGeneration, evaluateFitness is called get the fitness score for each individual. The evaluateFitness method must be specified by the programmers to fit the specific application. After reaching the maximum number of generations or a certain criteria are met, the loop ends and afterRun is invoked.
function stat = run(model, varargin)
model.beforeRun(varargin{:});
...
for gen=1:gens
model.forEachGeneration(gen, gens, varargin{:});
end
...
model.afterRun(varargin{:});
end| Signature | Description |
|---|---|
populate(model) |
Populate the GA model with individuals. Should specify populationSize using the register method first. |
stat = run(model, varargin) |
Start optimizing with genetic algorithm on the model. |
register(model, arg1, arg2) |
Register an option or a struct of options with the model. |
beforeRun(model, varargin) |
The method invoked at the beginning of the run method. Refer to the execution cycle. By default, the method does nothing. |
afterRun(model, varargin) |
The method invoked at the end of the run method. Refer to the execution cycle. By default, the method does nothing. |
Generate the initial population.
Optimize the model according to the execution cycle.
| Argument | Description |
|---|---|
varargin |
The list of arguments that will be provided to beforeRun, forEachGeneration, evaluateFitness, and afterRun. |
Register options one by one, or with the entire struct.
| Argument | Description |
|---|---|
arg1 |
Provide a struct of options or a key. |
arg2 |
Only when arg1 specified the key, specify the value. |
The method invoked at the beginning of the run method. Refer to the execution cycle.
| Argument | Description |
|---|---|
varargin |
A list of arguments that were provided to run. |
| By default, the function does nothing. |
The method invoked at the end of the run method. Refer to the execution cycle.
| Argument | Description |
|---|---|
varargin |
A list of arguments that were provided to run. |
| By default, the function does nothing. |
You must implement the following methods.
| Signature | Description |
|---|---|
init(model, varargin) |
Initialize every individual in the population. |
fitnesses = evaluateFitness(model, varargin) |
Evaulate the fitness and returns a vector of fitness values. |
The method should return a vector of size n, with the i-th entry being the fitness score of the i-th individual.
| Argument | Description |
|---|---|
vargin |
A cell of arguments corresponding to the arguments (in order) provided to the run method. |
Here is an example that you can fill in to meet your own needs.
When calling the run method:
myGAModel.run(myData, myOptions);In the method:
function fitnesses = evaluateFitness(model, varargin)
% Localize variables to avoid unnessary communication overhead.
% Skip this step if you do not use parallel computing toolbox.
n = model.options.populationSize;
% Retrieve the vairables initially provided when calling the
% run method.
myData = varargin{1};
myOptions = varargin{2};
% Spread out the variable to avoid communication overhead when
% using parallel computing toolbox
population = model.population;
fitnesses = zeros(n, 1);
% Get status information from the status struct
gen = model.status.generation;
% Execute using MATLAB's parallel computing toolbox. If you do
% not have the license for it, replace `parfor` with `for`.
parfor s=1:n
r = backtest(population{s}, myData);
fprintf("[Generation %d] Strategy %d return: %s\n", ...
gen, s, string(r));
fitnesses(s) = r;
end
endThis project, including the documentation, is licensed under the MIT license. Copyright (c) 2022 Bohui WU.