diff --git a/PlatEMO/Algorithms/Multi-objective optimization/WASFGA/EnvironmentalSelectionW.m b/PlatEMO/Algorithms/Multi-objective optimization/WASFGA/EnvironmentalSelectionW.m new file mode 100644 index 000000000..ecdfea3a7 --- /dev/null +++ b/PlatEMO/Algorithms/Multi-objective optimization/WASFGA/EnvironmentalSelectionW.m @@ -0,0 +1,19 @@ +function [Population, FrontNo, CrowdDis] = EnvironmentalSelectionW(Vectores, Population, nsort, Point, ro) + %% Non-dominated sorting + [FrontNo, MaxFNo] = WASFGASort(Vectores, Population.objs, nsort, Point, ro); + 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/WASFGA/WASFGA.m b/PlatEMO/Algorithms/Multi-objective optimization/WASFGA/WASFGA.m new file mode 100644 index 000000000..8b6c064ca --- /dev/null +++ b/PlatEMO/Algorithms/Multi-objective optimization/WASFGA/WASFGA.m @@ -0,0 +1,52 @@ +classdef WASFGA < ALGORITHM + % + % WASFGA + % Point --- --- Preferred point + + %------------------------------- Reference -------------------------------- + % Ruiz, A. B., Saborido, R., & Luque, M. (2015). A preference-based + % evolutionary algorithm for multiobjective optimization: the weighting + % achievement scalarizing function genetic algorithm. Journal of Global + % Optimization, 62, 101-129. + %------------------------------- 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 + Point = Algorithm.ParameterSet(zeros(1,Problem.M)+0.5,0.00001); + ro = 0.0001; + %% Generate random population + Population = Problem.Initialization(); + %% Generate a sample of weight vectors + [n,~] = size(Population.objs); + if Problem.M == 2 + Vectors = generateWeightVectors2(n, 0.001); + else + [Vectors,Problem.N] = UniformPoint(Problem.N,Problem.M); + end + + FrontNo = WASFGASort(Vectors, Population.objs, inf, Point,ro); + CrowdDis = CrowdingDistance(Population.objs,FrontNo); + [v,~] = size(Vectors); + if v >= n + nsort = 2; + else + nsort = floor(n/v) + 1; + end + + %% Optimization + while Algorithm.NotTerminated(Population) + MatingPool = TournamentSelection(2,Problem.N,FrontNo,-CrowdDis); + Offspring = OperatorGA(Problem,Population(MatingPool)); + [Population,FrontNo,CrowdDis] = EnvironmentalSelectionW(Vectors, [Population,Offspring],nsort,Point,ro); + end + end + end +end \ No newline at end of file diff --git a/PlatEMO/Algorithms/Multi-objective optimization/WASFGA/WASFGASort.m b/PlatEMO/Algorithms/Multi-objective optimization/WASFGA/WASFGASort.m new file mode 100644 index 000000000..1eb974a0e --- /dev/null +++ b/PlatEMO/Algorithms/Multi-objective optimization/WASFGA/WASFGASort.m @@ -0,0 +1,74 @@ +function [FrontNo,MaxFNo] = WASFGASort(Vectors, PopObj, nsort, Point, ro) + + [nvectors, ~] = size(Vectors); + [Loc,MaxFNo] = frontsclass(Vectors, PopObj,inf, Point, ro); + [popsize, ~] = size(PopObj); + FrontNo = inf(1,size(PopObj,1)); + + for i = 1:popsize + Position = find(Loc == i); + iter = 0; + while nvectors*iter < Position + iter = iter + 1; + end + if iter == 0 || iter > nsort + FrontNo(i) = inf; + else + FrontNo(i) = iter; + end + end +end + +function [Loc, Max] = frontsclass(Vectors, PopObj, nsort, Point, ro) + [nvectors, ~] = size(Vectors); + %N is the population size + [N, ~] = size(PopObj); + FrontG = []; + %SolG will store the different solutions sorted by the achievement + %scalarizing function + SolG = []; + PopObj2 = PopObj; + Max = 0; + while length(FrontG) < N && 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; + for i = 1:min(nvectors, n) + + Front = []; + Values = zeros(n, 1); + + for j = 1:n + Values(j) = max((PopObj(j, :) - Point) .* Vectors(i, :)) + ro * sum(Vectors(i, :) .* (PopObj(j, :) - Point)); + end + + Vmin = min(Values); + Sol1 = find(Values == Vmin); + Front = [Front, Sol1(1)]; + FrontG = [FrontG, Front]; + valid_Loc = Front(Front <= size(PopObj, 1)); + SolG = [SolG; PopObj(valid_Loc, :)]; + PopObj(valid_Loc, :) = []; + [n, ~] = size(PopObj); + end + end + Loc = find_Loc(SolG, PopObj2); +end + +%This function will allow us to identify the position in the original +%matrix of the solutions in SolG +function index = find_Loc(rows, initial_matrix) + index = zeros(size(rows, 1), 1); + + for i = 1:size(rows, 1) + [equalrow, loc] = ismember(rows(i, :), initial_matrix, 'rows'); + + if equalrow + index(i) = loc; + end + end +end + diff --git a/PlatEMO/Algorithms/Multi-objective optimization/WASFGA/generateWeightVectors2.m b/PlatEMO/Algorithms/Multi-objective optimization/WASFGA/generateWeightVectors2.m new file mode 100644 index 000000000..31a88d49d --- /dev/null +++ b/PlatEMO/Algorithms/Multi-objective optimization/WASFGA/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