Skip to content

Instantly share code, notes, and snippets.

@Peng-YM
Last active April 28, 2020 10:26
Show Gist options
  • Select an option

  • Save Peng-YM/ca395d3597de4af0ce80dfa8245c53c7 to your computer and use it in GitHub Desktop.

Select an option

Save Peng-YM/ca395d3597de4af0ce80dfa8245c53c7 to your computer and use it in GitHub Desktop.
MOEAD-MM algorithm implemented in PlatEMO
function MOEADMM(Global)
% <algorithm> <A>
% Multi-modal Multi-objective Evolutionary Algorithm based on Decmoposition
% type --- 1 --- The type of aggregation function
% mu --- 4 --- The size of each sub-population
%% Parameter settings
[type, mu] = Global.ParameterSet(1, 4);
%% Generate the weight vectors
numW = ceil(Global.N / mu); % the number of weight vectors
[W, numW] = UniformPoint(numW, Global.M);
Global.N = numW * mu;
T = ceil(numW / 10);
%% Detect the closest T neighbors of each weight vector
B = pdist2(W, W);
[~, B] = sort(B, 2);
B = B(:, 1:T);
%% Generate random population
Population = Global.Initialization();
%% Calculate ideal point
z = min(Population.objs, [], 1);
%% Solution assignment
PopMap = cell(numW, 1); % PopMap{i} is the i-th sub-population
for i = 1:numW
PopMap{i} = Population((i-1)*mu+1:i*mu);
end
%% Optimization
while Global.NotTermination(Population)
%% estimate the niche radius
PopSize = size(Population, 2);
KD = zeros(1, PopSize);
% average population size
K = ceil(PopSize / 10);
for i = 1:PopSize
tmp = pdist2(Population.decs, Population(i).dec, "euclidean", "Smallest", K);
KD(i) = tmp(end);
end
nicheSize = mean(KD);
%% Update each weight vector
for i = 1:numW
% Generate Offspring
offspring = Mating(i);
% Update ideal and nadir points
z = min(z, min(offspring.obj, [], 1));
% Environmental selection
PopMap{i} = EnvironmentalSelection(i, offspring);
end
%% Convert PopMap to population
Population = [PopMap{:}];
%% Subset selection from the final population
if Global.evaluated >= Global.evaluation
Population = FinalSelection(Population);
end
end
%% Scalarizing function
function G = Fitness(Wi, Q)
szQ = size(Q, 2);
switch type
case 1
%% PBI
normW = repmat(norm(Wi), szQ, 1);
C = Q.objs-repmat(z, szQ, 1);
normC = sqrt(sum(C.^2, 2));
CosineC = sum(C .* repmat(Wi, szQ, 1), 2) ./ normW ./ normC;
SineC = sqrt(1 - CosineC .^ 2);
G = normC .* CosineC + 5 * normC .* SineC;
case 2
%% Tchebycheff
G = max(abs(Q.objs-repmat(z, szQ, 1)) .* repmat(Wi, szQ, 1), [], 2);
end
end
%% Mating
function Offspring = Mating(i)
Pi = PopMap{i};
C = [PopMap{B(i, :)}];
a = RandomPick(Pi, 1); % parent 1
b = RandomPick(C, 1); % parent 2
Offspring = GAhalf([a, b]);
end
%% Environmental Selection
function Q = EnvironmentalSelection(i, offspring)
Wi = W(i, :);
Pi = PopMap{i};
%% Combine parent and offspring
C = [Pi, offspring];
%% Calculate Fitness
G = Fitness(Wi, C);
%% Apply clearing method in the decision space
% locate the closest pair of points in the decision space
PD = pdist2(C.decs, C.decs);
minD = Inf; minI = 0; minJ = 0;
for ith = 1:size(C, 2)-1
for jth = ith+1:size(C, 2)
if PD(ith, jth) < minD
minD = PD(ith, jth);
minI = ith; minJ = jth;
end
end
end
% clearing
if minD < nicheSize
if G(minI) < G(minJ)
C(minJ) = [];
Q = C;
return
else
C(minI) = [];
Q = C;
return;
end
end
%% If clearing does not work, remove the one with worst fitness
[~, idx] = max(G);
C(idx) = [];
Q = C;
end
%% Simple selection strategy
function Q = FinalSelection(P)
FNO = NDSort(P.objs, 1);
Q = P(FNO == 1);
end
end
%% Helper functions
%% Random pick one from an list of elements, assume that list is 1*n array
function x = RandomPick(list, num)
n = size(list, 2);
perm = randperm(n);
x = list(perm(1:num));
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment