From 38829f5bc028ab9a6c9d5dc18385bb6a67e81181 Mon Sep 17 00:00:00 2001 From: Antonio Date: Wed, 20 Mar 2024 13:22:50 +0100 Subject: [PATCH] Adding EMO algorithm GWASF-GA --- .../GWASFGA/EnvironmentalSelectionGW.m | 19 ++++ .../GWASFGA/GWASFGA.m | 79 +++++++++++++++++ .../GWASFGA/GWASFGASort.m | 87 +++++++++++++++++++ .../GWASFGA/generateWeightVectors2.m | 15 ++++ 4 files changed, 200 insertions(+) create mode 100644 PlatEMO/Algorithms/Multi-objective optimization/GWASFGA/EnvironmentalSelectionGW.m create mode 100644 PlatEMO/Algorithms/Multi-objective optimization/GWASFGA/GWASFGA.m create mode 100644 PlatEMO/Algorithms/Multi-objective optimization/GWASFGA/GWASFGASort.m create mode 100644 PlatEMO/Algorithms/Multi-objective optimization/GWASFGA/generateWeightVectors2.m diff --git a/PlatEMO/Algorithms/Multi-objective optimization/GWASFGA/EnvironmentalSelectionGW.m b/PlatEMO/Algorithms/Multi-objective optimization/GWASFGA/EnvironmentalSelectionGW.m new file mode 100644 index 00000000..b8070968 --- /dev/null +++ b/PlatEMO/Algorithms/Multi-objective optimization/GWASFGA/EnvironmentalSelectionGW.m @@ -0,0 +1,19 @@ +function [Population, FrontNo, CrowdDis] = EnvironmentalSelectionGW(Vectors, Population,Utop, Nadir, nsort, ro, eps) + %% Non-dominated sorting + [FrontNo, MaxFNo] = GWASFGASort(Vectors, Population.objs,Utop, Nadir, nsort, ro, eps); + Next = FrontNo < MaxFNo; + + %% Calculate the crowding distance of each solution + CrowdDis = CrowdingDistance(Population.objs, FrontNo); + + %% Select the solutions in the last front by their crowding distances + Last = find(FrontNo == MaxFNo); + [~, Rank] = sort(CrowdDis(Last), 'descend'); + numSelected = min(nsort - sum(Next), numel(Last)); % Avoid selecting more than available + Next(Last(Rank(1:numSelected))) = true; + + %% Population for next generation + Population = Population(Next); + FrontNo = FrontNo(Next); + CrowdDis = CrowdDis(Next); +end diff --git a/PlatEMO/Algorithms/Multi-objective optimization/GWASFGA/GWASFGA.m b/PlatEMO/Algorithms/Multi-objective optimization/GWASFGA/GWASFGA.m new file mode 100644 index 00000000..7725272a --- /dev/null +++ b/PlatEMO/Algorithms/Multi-objective optimization/GWASFGA/GWASFGA.m @@ -0,0 +1,79 @@ +classdef GWASFGA < ALGORITHM + % + % GWASFGA + + + %------------------------------- Reference -------------------------------- + % Saborido, R., Ruiz, A. B., & Luque, M. (2017). Global WASF-GA: An + % evolutionary algorithm in multiobjective optimization to approximate + % the whole Pareto optimal front. Evolutionary computation, 25(2), 309-349. + %------------------------------- Copyright -------------------------------- + % Copyright (c) 2023 BIMK Group. You are free to use the PlatEMO for + % research purposes. All publications which use this platform or any code + % in the platform should acknowledge the use of "PlatEMO" and reference "Ye + % Tian, Ran Cheng, Xingyi Zhang, and Yaochu Jin, PlatEMO: A MATLAB platform + % for evolutionary multi-objective optimization [educational forum], IEEE + % Computational Intelligence Magazine, 2017, 12(4): 73-87". + %-------------------------------------------------------------------------- + methods + function main(Algorithm,Problem) + %% Parameter setting + ro = 0.0001; + eps = 0.01; + %% Generate random population + Population = Problem.Initialization(); + %% Generate a sample of weight vectors + + [n,col] = size(Population.objs); + disp(col) + if Problem.M == 2 + + %ConfiguraciĆ³n de antes + Vectors = generateWeightVectors2(n, 0.001); + else + [Vectors,Problem.N] = UniformPoint(Problem.N,Problem.M ); + end + [v,~] = size(Vectors); + if v >= n + nsort = 2; + else + nsort = floor(n/v) + 1; + end + nadir = zeros(1, col); + Utop = zeros(1, col); + disp(Population.objs); + disp(size(Population.objs)) + A = Population.objs; + %% Initialize Nadir and Utopian points. + for i = 1:col + Maxs = max(A(:, i)) + eps; + Mins = min(A(:, i)) - eps; + nadir(i) = Maxs; + Utop(i) = Mins; + end + FrontNo = GWASFGASort(Vectors, Population.objs,Utop,nadir, nsort,ro, eps); + CrowdDis = CrowdingDistance(Population.objs,FrontNo); + + %% Optimization + while Algorithm.NotTerminated(Population) + MatingPool = TournamentSelection(2,Problem.N,FrontNo,-CrowdDis); + Offspring = OperatorGA(Problem,Population(MatingPool)); + [Population,FrontNo,CrowdDis] = EnvironmentalSelectionGW(Vectors, [Population,Offspring], Utop,nadir, nsort,ro, eps); + P = Population.objs; + %Check if nadir and Utopian points have changed after each + %generation of the algorithm + for i = 1:col + Maxs = max(P(:, i)) + eps; + Mins = min(P(:, i)) - eps; + + if Utop(i) > Mins + Utop(i) = Mins; + end + if nadir(i) < Maxs + nadir(i) = Maxs; + end + end + end + end + end +end \ No newline at end of file diff --git a/PlatEMO/Algorithms/Multi-objective optimization/GWASFGA/GWASFGASort.m b/PlatEMO/Algorithms/Multi-objective optimization/GWASFGA/GWASFGASort.m new file mode 100644 index 00000000..0d1b10c8 --- /dev/null +++ b/PlatEMO/Algorithms/Multi-objective optimization/GWASFGA/GWASFGASort.m @@ -0,0 +1,87 @@ +function [FrontNo,MaxFNo] = GWASFGASort(Vectors, PopObj, Utop,Nadir, nsort, ro, eps) + [nvectors, ~] = size(Vectors); + [Loc,MaxFNo] = frontloc(Vectors, PopObj,Utop, Nadir, inf, ro, eps); + [popsize, ~] = size(PopObj); + FrontNo = inf(1,size(PopObj,1)); + for i = 1:popsize + position = find(Loc == i); + count = 0; + while nvectors*count < position + count = count + 1; + end + if count == 0 || count > nsort + FrontNo(i) = inf; + else + FrontNo(i) = count; + + end + end +end + +function [Loc, Max] = frontloc(Vectors, PopObj,Utop,nadir, nsort, ro, eps) + [lengthVectors, ~] = size(Vectors); + %bound is the population size + [bound, ~] = size(PopObj); + %SolG will store the different solutions sorted by the achievement + %scalarizing function + SolutionsG = []; + PopObj2 = PopObj; + Max = 0; + while size(SolutionsG,1) < bound && Max < nsort + % n will be the size of the population that will be compared in + % each iteration, it will change in every iteration. + [n, ~] = size(PopObj); + + Max = Max + 1; + + %In each iteration, we alternate between the nadir and utopian points to sort the population into frontiers + for i = 1:(lengthVectors/2) + + ValuesU = zeros(n, 1); + + for j = 1:n + ValuesU(j) = max((PopObj(j, :) - Utop) .* Vectors((2*i -1), :)) + ro * sum(Vectors((2*i -1 ), :) .* (PopObj(j, :) - Utop)); + end + [~, indexU] = sort(ValuesU); + Sol1 = indexU(1); + SolutionsG = [SolutionsG; PopObj(Sol1, :)]; + + if size(SolutionsG,1) == bound + break + end + + PopObj(Sol1, :) = []; + [n, ~] = size(PopObj); + ValuesN = zeros(n,1); + for j = 1:n + ValuesN(j) = max((PopObj(j, :) - nadir) .* Vectors((2*i ), :)) + ro * sum(Vectors((2*i ), :) .* (PopObj(j, :) - nadir)); + end + [~, indexN] = sort(ValuesN); + Sol2 = indexN(1); + + SolutionsG = [SolutionsG; PopObj(Sol2, :)]; + if size(SolutionsG,1) == bound + break + end + PopObj(Sol2, :) = []; + [n, ~] = size(PopObj); + end + end + Loc = find_Loc(SolutionsG, PopObj2); +end + +%This function will allow us to identify the position in the original +%matrix of the solutions in SolG +function location = find_Loc(moved_rows, initial_matrix) + location = zeros(size(moved_rows, 1), 1); + + for i = 1:size(moved_rows, 1) + % Find the position of the moved row in the initial matrix + [equal_row, index] = ismember(moved_rows(i, :), initial_matrix, 'rows'); + + % Verify if there is any similarity + if equal_row + location(i) = index; + end + end +end \ No newline at end of file diff --git a/PlatEMO/Algorithms/Multi-objective optimization/GWASFGA/generateWeightVectors2.m b/PlatEMO/Algorithms/Multi-objective optimization/GWASFGA/generateWeightVectors2.m new file mode 100644 index 00000000..31a88d49 --- /dev/null +++ b/PlatEMO/Algorithms/Multi-objective optimization/GWASFGA/generateWeightVectors2.m @@ -0,0 +1,15 @@ +function weightVectors = generateWeightVectors2(Nmu, epsilon) + % Input: + % - Nmu: Number of weight vectors + % - epsilon: Small positive value (e.g., 0.01) + + % Initialize weight vectors matrix + weightVectors = zeros(Nmu, 2); + + % Generate weight vectors + for j = 1:Nmu + uj1 = epsilon + (j - 1) * (1 - 2 * epsilon) / (Nmu - 1); + uj2 = 1 - uj1; + weightVectors(j, :) = [uj1, uj2]; + end +end