-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmyga.m
116 lines (92 loc) · 3.46 KB
/
myga.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
% for now constraint only between min and max
% myga find the MAXIMUM
function [ p_opt, fit_opt, res ] = myga(f, constraints, var_type, options)
% options:
% options.population_number
% options.selection_quantity % from 0 to 1
% options.mutation_min
% options.mutation_max
% options.mutation_threshold
% options.max_iterations
% options.crossover_first_threshold
pop = init_population(options.population_number, constraints, var_type);
fitness = fitness_population(options.population_number, pop, f);
[fitness, pop] = sort_population(pop, fitness);
disp('random population generated')
kk = 1;
res(kk).pop = pop;
res(kk).fitness = fitness;
convergence = false;
while ~convergence
disp('apply selection')
[fitness, pop] = apply_selection(options.population_number, pop, fitness, options);
disp('complete population')
[fitness, pop] = complete_population(f, options.population_number, pop, fitness, options);
disp('sort population')
[fitness, pop] = sort_population(pop, fitness);
disp(['iteration ' , num2str(kk), 'done.'])
kk = kk + 1;
res(kk).pop = pop;
res(kk).fitness = fitness;
if kk >= options.max_iterations
convergence = true;
end
end
p_opt = pop(1, :);
fit_opt = fitness(1);
end
function [fit, pop] = complete_population(f, n, pop, fit, options)
%myga_const.CROSSOVER_STATEGY_ALWAYS_BEST = 11;
first_nan_index = find(isinf(fit) == 1, 1); % only the first nan elements
if options.crossover_strategy == myga_const.CROSSOVER_STATEGY_ALWAYS_BEST
for ii = first_nan_index:n
index = mod(ii - first_nan_index + 1, n - first_nan_index) + 1;
pop(ii, :) = crossover(pop(1, :), pop(ii, :), options.crossover_first_threshold);
fit(ii) = f(pop(ii, :));
end
end
end
function p = crossover(p1, p2, threshold)
rands = rand(size(p1));
mask = rands < threshold;
%antimask = 1 - mask;
p = p2;
p(mask) = p1(mask);
%p(antimask) = p2(antimask);
end
function [fit, pop] = apply_selection(n, pop, fit, options)
rands = rand(n, 1);
comparison = linspace(1, options.selection_quantity / 2, n)';
fit(rands >= comparison) = -inf; % part of the population
[fit, pop] = sort_population(pop, fit);
end
function pop = apply_mutation(n, pop, options)
% TODO now is linear but can be more complex or also user defined
mutation_probability = linspace(options.mutation_min, options.mutation_max, n);
rands = rand(n, 1);
end
function fit = fitness_population(n, pop, f)
fit = zeros(n, 1);
for ii = 1:n
fit(ii) = f(pop(ii, :));
end
end
function [fit, pop] = sort_population(pop, fit)
[fit, index] = sort(fit, 1, 'descend');
pop = pop(index, :);
end
function pop = init_population(n, constraints, var_type)
%VAR_TYPE_INT = 11;
%VAR_TYPE_DOUBLE = 9;
% var_type = 11 INT
% var_type = 9 DOUBLE
var_num = size(constraints, 1);
pop = zeros(n, var_num);
rands = rand(size(pop));
for ii = 1:var_num
pop(:, ii) = constraints(ii, 1) + rands(:, 1) .* (constraints(ii, 2) - constraints(ii, 1));
if var_type(ii) == myga_const.VAR_TYPE_INT
pop(:, ii) = round(pop(:, ii));
end
end
end