-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgMOEADAGR.m
156 lines (143 loc) · 5.2 KB
/
gMOEADAGR.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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
classdef gMOEADAGR < ALGORITHM
% <multi/many> <real/binary/permutation>
% Adaptive Replacement Strategies for MOEA/D (generational version)
% delta --- 0.8 --- The probability of selecting candidates from neighborhood
% type --- 2 --- The type of aggregation function
% Tm --- 0.1 --- The mating neighborhood size
% Trm --- 0.4 --- The maximum replacement neighborhood size
% AS --- 1 --- The adaptive scheme
%
% Author: Ruihao Zheng
% Last modified: 19/03/2024
% Ref: "Adaptive Replacement Strategies for MOEA/D"
methods
function main(Algorithm,Problem)
%% Parameter setting
[delta, type, Tm, Trm, AS] = Algorithm.ParameterSet(0.8, 2, 0.1, 0.4, 1);
%% initialization
% Generate the weight vectors
[W, Problem.N] = UniformPoint(Problem.N, Problem.M);
Tm = ceil(Problem.N * Tm);
Trm = ceil(Problem.N * Trm);
% Detect the neighbours of each solution
B = pdist2(W, W);
[~,B] = sort(B, 2);
% Detect the mating neighbours of each solution
Bm = B(:, 1:Tm);
% Generate random population
Population = Problem.Initialization();
% Initialize the reference point
z = min(Population.objs, [], 1);
% Dertermine the scalar function
switch type
case 1
type = 1.1;
case 2
type = 2.1;
otherwise
error('Unavailable value of p.')
end
% Precalculation
normW = vecnorm(W,2,2);
%% Optimization
while Algorithm.NotTerminated(Population)
% Update the size of neighborhood for replacement
Tr = updateTr(Trm, AS, Problem.FE, Problem.maxFE);
% Get the mating pool
MatingPool = zeros(1, 2 * Problem.N);
for i = 1 : Problem.N
% Choose the parents
if rand < delta
P = Bm(i, randperm(Tm));
else
P = randperm(Problem.N);
end
MatingPool(i) = P(1);
MatingPool(Problem.N + i) = P(2);
end
% Generate N offspring
Offspring = OperatorGAhalf(Population(MatingPool));
% Update the reference point
z = min([z; Offspring.objs]);
% Replacement
Pt = [Population Offspring];
objs = Pt.objs;
index_Pt = zeros(Problem.N, 1);
for i = 1 : Problem.N
% find the most suitable offspring for the problem form Tr closest solutions
% [~, closest] = mink(1-((objs - z)*W(i, :)' ./ (vecnorm(objs-z,2,2).*normW(i))), Tr);
[~, closest] = mink(1-((objs - z)*W(i, :)' ./ ((sum((objs-z).^2,2)).^(1/2).*normW(i))), Tr);
g_Tr = calSubpFitness(type, objs(closest, :), z, W(i, :));
[~, Ri] = min(g_Tr);
index_Pt(i) = closest(Ri);
end
Population = Pt(index_Pt);
end
end
end
end
%%
function Tr = updateTr(Trm, AS, k, K, varargin)
% Update the parameter 'Tr' in AGRs
keys = {'gamma', 'slope'};
if ~isempty(varargin)
isStr = find(cellfun(@ischar,varargin(1:end-1))&~cellfun(@isempty,varargin(2:end)));
index = isStr(ismember(varargin(isStr),keys)) + 1;
for i = 1 : length(isStr)
str = varargin{isStr(i)};
switch str
case 'gamma'
gamma = varargin{index(i)};
case 'slope'
slope = varargin{index(i)};
end
end
end
switch AS
case 1
% Sigmoid
if ~exist('gamma', 'var')
gamma = 0.25; % center
end
if ~exist('slope', 'var')
slope = 20;
end
Tr = ceil(Trm / (1 + exp(-slope * (k/K - gamma))));
case 2
% Linear
Tr = ceil(k / K * Trm);
case 3
% Exponential
if ~exist('slope', 'var')
slope = 5;
end
Tr = ceil( ((exp(slope*k/K)-1) * Trm) / (exp(slope) - 1) );
case 4
% GR
Tr = Trm;
end
end
function g = calSubpFitness(type, objs, z, W)
% Calculate the function values of the scalarization method
type2 = floor(type);
switch type2
case 1
% weight sum approach
switch round((type - type2) * 10)
case 1
g = sum(objs ./ W, 2);
case 2
g = sum((objs-z) .* W, 2);
otherwise
g = sum(objs .* W, 2);
end
case 2
% Tchebycheff approach
switch round((type - type2) * 10)
case 1
g = max(abs(objs-z) ./ W, [], 2);
otherwise
g = max(abs(objs-z) .* W, [], 2);
end
end
end