Last active
April 28, 2020 10:26
-
-
Save Peng-YM/ca395d3597de4af0ce80dfa8245c53c7 to your computer and use it in GitHub Desktop.
MOEAD-MM algorithm implemented in PlatEMO
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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