Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve the running speed of the test and application modules #120

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion PlatEMO/Algorithms/ALGORITHM.m
Original file line number Diff line number Diff line change
Expand Up @@ -198,4 +198,4 @@ function cb_menu(h)

set(get(get(h,'Parent'),'Children'),'Checked','off');
set(h,'Checked','on');
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
function [non_dominated, hd] = DominationCal_HEA(Objs, zmin, zmax, T)
[Objs_num, M] = size(Objs);
objs_dominated = zeros(1, Objs_num);
hd = zeros(1, Objs_num);
NormalizedObj = Objs ./ (zmax - zmin);
for i = 1: Objs_num
err = NormalizedObj(i, :) - NormalizedObj;
eq = zeros(Objs_num, 1);
max_err = max(err, [], 2);
min_err = min(err, [], 2);
H = -min_err ./ max_err;
for j = i + 1: Objs_num
for k = 1: M
if err(j, k) ~= 0
break
end
if k == M
eq(j) = 1;
end
end
end
objs_dominated(eq == 1) = 1;
H(eq == 1) = -inf;
H(max_err <= 0) = inf;
hd(i) = min(H);
end
objs_dominated(hd < T) = 1;
non_dominated = 1 - objs_dominated;
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
function [Population, Population_hd] = EnvironmentalSelection_HEA(Solutions, hd, zmin, zmax, N, W)
PopObj = Solutions.objs;
[P, ~] = size(PopObj);
zmin = min(zmin, min(PopObj,[],1));
nf = zmax - zmin; % normalization factor
nf(nf < 1e-6) = 1e-6; % Prevent dividing by zero
PopObj = (PopObj - zmin) ./ nf;
Fitness = pdist2(PopObj,W,'cosine');
[~, index] = min(Fitness, [], 1);
non_dominated = zeros(P, 1);
for i = 1: N
non_dominated(index(i)) = 1;
end
Population = Solutions(non_dominated == 1);
Population_hd = hd(non_dominated == 1);
K = N - sum(non_dominated);
for i = 1: K
[~, Maxhd_index] = max(hd);
Population = [Population, Solutions(Maxhd_index)];
Population_hd = [Population_hd, hd(Maxhd_index)];
hd(Maxhd_index) = -inf;
end
end
59 changes: 59 additions & 0 deletions PlatEMO/Algorithms/Multi-objective optimization/HEA/HEA.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
classdef HEA < ALGORITHM
% <multi/many> <real/binary/permutation>
% Hyper-dominance based evolutionary algorithm
% MaxT --- 0.05 --- The maximum value of tolerance

%------------------------------- Reference --------------------------------
% Z. Liu, F. Han, Q. Ling, H. Han, and J. Jiang, A many-objective
% optimization evolutionary algorithm based on hyper-dominande degree,
% Swarm and Evolutionary Computation, 2023, 83: 101411.
%------------------------------- 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".
%--------------------------------------------------------------------------

% This function is written by Zhe Liu

methods
function main(Algorithm,Problem)
%% Parameter setting
MaxT = Algorithm.ParameterSet(0.05);
[W, Problem.N] = UniformPoint(Problem.N,Problem.M);
T = 0;
step = MaxT/(Problem.maxFE / Problem.N);
%% Generate random population
Population = Problem.Initialization();
Solutions = Population;
zmin = min(Population.objs,[],1);
zmax = max(max(Population.objs, [], 1), zmin + 1e-6);
%% External archive initialization
while Algorithm.NotTerminated(Solutions)
%% Optimization
MatingPool = randperm(length(Population));
Offsprings = OperatorGA(Problem, Population(MatingPool));
Population = [Offsprings, Solutions];
zmin = min(zmin, min(Population.objs,[],1));
[non_dominated, hd] = DominationCal_HEA(Population.objs, zmin, zmax, T);
Population = Population(non_dominated == 1);
zmax = max(max(Population.objs, [], 1), zmin + 1e-6);
hd = hd(non_dominated == 1);
%% Environmental Selection
[Solutions, hd] = EnvironmentalSelection_HEA(Population, hd, zmin, zmax, Problem.N, W);
T = T + step;
%% Population regeneration
Population = Solutions;
r = unidrnd(Problem.N,[1,Problem.N]);
for i = 1: Problem.N
if hd(i) < hd(r(i))
Population(i) = Solutions(r(i));
end
end
end
end
end
end

42 changes: 29 additions & 13 deletions PlatEMO/GUI/Draw.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function currentAxes = Draw(Data,varargin)
function currentAxes = Draw(Data,PRO,varargin)
%Draw - Display data.
%
% Draw(P) displays all the points in P, where each row of P indicates one
Expand Down Expand Up @@ -32,21 +32,35 @@
persistent ax;
if length(Data) == 1 && isgraphics(Data)
ax = Data;
cla(ax);
k = length(ax.Children);
if PRO.fastdraw == 0 || k <= 1
cla(ax)
else
K = zeros(1, k);
for i = 1: k
if strcmp(ax.Children(i).Marker, 'o')
K(i) = 1;
end
end
delete(ax.Children(K==1))
end
elseif ~isempty(Data) && ismatrix(Data)
if isempty(ax) || ~isgraphics(ax)
ax = gca;
end
if size(Data,2) == 1
Data = [(1:size(Data,1))',Data];
end
set(ax,'FontName','Times New Roman','FontSize',13,'NextPlot','add','Box','on','View',[0 90],'GridLineStyle','none');
if islogical(Data)
[ax.XLabel.String,ax.YLabel.String,ax.ZLabel.String] = deal('Solution No.','Dimension No.',[]);
elseif size(Data,2) > 3
[ax.XLabel.String,ax.YLabel.String,ax.ZLabel.String] = deal('Dimension No.','Value',[]);
elseif ~isempty(varargin) && iscell(varargin{end})
[ax.XLabel.String,ax.YLabel.String,ax.ZLabel.String] = deal(varargin{end}{:});
if PRO.fastdraw == 0
cla(ax)
set(ax,'FontName','Times New Roman','FontSize',13,'NextPlot','add','Box','on','View',[0 90],'GridLineStyle','none');
if islogical(Data)
[ax.XLabel.String,ax.YLabel.String,ax.ZLabel.String] = deal('Solution No.','Dimension No.',[]);
elseif size(Data,2) > 3
[ax.XLabel.String,ax.YLabel.String,ax.ZLabel.String] = deal('Dimension No.','Value',[]);
elseif ~isempty(varargin) && iscell(varargin{end})
[ax.XLabel.String,ax.YLabel.String,ax.ZLabel.String] = deal(varargin{end}{:});
end
end
if ~isempty(varargin) && iscell(varargin{end})
varargin = varargin(1:end-1);
Expand Down Expand Up @@ -77,9 +91,11 @@
Label(2:2:end,:) = fliplr(Label(2:2:end,:));
plot(ax,reshape(Label',[],1),reshape(Data',[],1),varargin{:});
end
axis(ax,'tight');
set(ax.Toolbar,'Visible','off');
set(ax.Toolbar,'Visible','on');
if PRO.fastdraw == 0
axis(ax,'tight');
set(ax.Toolbar,'Visible','off');
set(ax.Toolbar,'Visible','on');
end
end
currentAxes = ax;
end
end
19 changes: 14 additions & 5 deletions PlatEMO/GUI/module_app.m
Original file line number Diff line number Diff line change
Expand Up @@ -726,31 +726,40 @@ function cb_slider(obj,~,~,ax)
obj.app.labelD.Text = sprintf('%d evaluations',ALG.result{index,1});
% Clear the default or specified axes
if nargin > 3
Draw(ax);
Draw(ax, PRO);
else
Draw(obj.app.axes);
Draw(obj.app.axes, PRO);
end
if PRO.M > 1
% Show the result of multi-objective optimization
if ~strcmp(PRO.display, obj.app.dropD(1).Value)
PRO.fastdraw = 0;
end
switch obj.app.dropD(1).Value
case 'Population (objectives)'
PRO.DrawObj(ALG.result{index,2});
case 'Population (variables)'
PRO.DrawDec(ALG.result{index,2});
otherwise
obj.app.waittip.Visible = 'on'; drawnow();
Draw(ALG.CalMetric(obj.app.dropD(1).Value),'-k.','LineWidth',1.5,'MarkerSize',10,{'Number of function evaluations',strrep(obj.app.dropD(1).Value,'_',' '),[]});
Draw(ALG.CalMetric(obj.app.dropD(1).Value), PRO,'-k.','LineWidth',1.5,'MarkerSize',10,{'Number of function evaluations',strrep(obj.app.dropD(1).Value,'_',' '),[]});
obj.app.waittip.Visible = 'off';
end
PRO.display = obj.app.dropD(1).Value;
else
% Show the result of single-objective optimization
if ~strcmp(PRO.display, obj.app.dropD(2).Value)
PRO.fastdraw = 0;
end
switch obj.app.dropD(2).Value
case 'Population (variables)'
PRO.DrawDec(ALG.result{index,2});
otherwise
Draw(ALG.CalMetric(obj.app.dropD(2).Value),'-k.','LineWidth',1.5,'MarkerSize',10,{'Number of function evaluations',strrep(obj.app.dropD(2).Value,'_',' '),[]});
Draw(ALG.CalMetric(obj.app.dropD(2).Value),PRO,'-k.','LineWidth',1.5,'MarkerSize',10,{'Number of function evaluations',strrep(obj.app.dropD(2).Value,'_',' '),[]});
end
PRO.display = obj.app.dropD(2).Value
end
PRO.fastdraw = 1;
end
end
%% Create the gif
Expand Down Expand Up @@ -869,4 +878,4 @@ function cb_toolbutton2(obj,~,~)
end
obj.cb_updateFilter();
end
end
end
8 changes: 4 additions & 4 deletions PlatEMO/GUI/module_exp.m
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ function cb_tableShow(obj,ui,~,type)
movegui(figure('NumberTitle','off','Name','','Position',[0 0 240*nCol 220*nRow]),'center');
for r = 1 : nRow
for c = 1 : nCol
ax = Draw(axes('Unit','pixels','Position',[(c-1)*240+35 (nRow-r)*220+35 200 170]));
ax = Draw(axes('Unit','pixels','Position',[(c-1)*240+35 (nRow-r)*220+35 200 170]),obj.data.PRO);
valid = find(reshape(~cellfun(@isempty,obj.data.result(r+loc(1)-1,c+loc(2)-1,:)),1,[]));
if ~isempty(valid)
[~,rank] = sort(obj.GetMetricValue(r+loc(1)-1,c+loc(2)-1,metric,false));
Expand All @@ -624,11 +624,11 @@ function cb_tableShow(obj,ui,~,type)
else
movegui(figure('NumberTitle','off','Name','','Position',[0 0 290*nRow 260]),'center');
for r = 1 : nRow
ax = Draw(axes('Unit','pixels','Position',[(r-1)*290+50 40 220 200]));
ax = Draw(axes('Unit','pixels','Position',[(r-1)*290+50 40 220 200]),obj.data.PRO);
s = {'o','+','s','*','^','x';'-k','--k','-b','--b','-g','--g'};
for c = 1 : nCol
value = obj.GetMetricValue(r+loc(1)-1,c+loc(2)-1,metric,true);
Draw(value,[s{1,mod(c-1,size(s,2))+1},s{2,mod(ceil(c/size(s,2))-1,size(s,2))+1}],'MarkerSize',5,'LineWidth',0.6);
Draw(value,obj.data.PRO,[s{1,mod(c-1,size(s,2))+1},s{2,mod(ceil(c/size(s,2))-1,size(s,2))+1}],'MarkerSize',5,'LineWidth',0.6);
end
legend(ax,arrayfun(@(s)class(s),obj.data.ALG(loc(2):loc(4)),'UniformOutput',false),'Location','best');
set(ax,'FontSize',10);
Expand Down Expand Up @@ -792,4 +792,4 @@ function table2mat(filename,Metric,metricName)
end
eval([metricName,'=Data;'])
save(filename,metricName);
end
end
21 changes: 15 additions & 6 deletions PlatEMO/GUI/module_test.m
Original file line number Diff line number Diff line change
Expand Up @@ -315,22 +315,25 @@ function cb_slider(obj,~,~,ax)
obj.app.labelC.Text = sprintf('%d evaluations',ALG.result{index,1});
% Clear the default or specified axes
if nargin > 3
Draw(ax);
Draw(ax, PRO);
else
Draw(obj.app.axes);
Draw(obj.app.axes, PRO);
end
isMetric = false;
if PRO.M > 1 % Multi-objective optimization
if ~strcmp(PRO.display,obj.app.dropC(1).Value)
PRO.fastdraw = 0;
end
switch obj.app.dropC(1).Value
case 'Population (objectives)'
PRO.DrawObj(ALG.result{index,2});
case 'Population (variables)'
PRO.DrawDec(ALG.result{index,2});
case 'True Pareto front'
Draw(PRO.optimum,{'\it f\rm_1','\it f\rm_2','\it f\rm_3'});
Draw(PRO.optimum,PRO,{'\it f\rm_1','\it f\rm_2','\it f\rm_3'});
otherwise
obj.app.waittip.Visible = 'on'; drawnow();
Draw(ALG.CalMetric(obj.app.dropC(1).Value),'-k.','LineWidth',1.5,'MarkerSize',10,{'Number of function evaluations',strrep(obj.app.dropC(1).Value,'_',' '),[]});
Draw(ALG.CalMetric(obj.app.dropC(1).Value),PRO,'-k.','LineWidth',1.5,'MarkerSize',10,{'Number of function evaluations',strrep(obj.app.dropC(1).Value,'_',' '),[]});
obj.app.waittip.Visible = 'off';
isMetric = true;
end
Expand All @@ -342,12 +345,16 @@ function cb_slider(obj,~,~,ax)
value = ALG.CalMetric(obj.app.dropD(2).Value);
obj.app.labelD.Text = sprintf('%.4e',value(end));
end
PRO.display = obj.app.dropC(1).Value;
else % Single-objective optimization
if ~strcmp(PRO.display,obj.app.dropC(2).Value)
PRO.fastdraw = 0;
end
switch obj.app.dropC(2).Value
case 'Population (variables)'
PRO.DrawDec(ALG.result{index,2});
otherwise
Draw(ALG.CalMetric(obj.app.dropC(2).Value),'-k.','LineWidth',1.5,'MarkerSize',10,{'Number of function evaluations',strrep(obj.app.dropC(2).Value,'_',' '),[]});
Draw(ALG.CalMetric(obj.app.dropC(2).Value),PRO,'-k.','LineWidth',1.5,'MarkerSize',10,{'Number of function evaluations',strrep(obj.app.dropC(2).Value,'_',' '),[]});
isMetric = true;
end
if ~isMetric
Expand All @@ -358,7 +365,9 @@ function cb_slider(obj,~,~,ax)
value = ALG.CalMetric(obj.app.dropD(3).Value);
obj.app.labelD.Text = sprintf('%.4e',value(end));
end
PRO.display = obj.app.dropC(2).Value;
end
PRO.fastdraw = 1;
end
end
%% Create the gif
Expand Down Expand Up @@ -445,4 +454,4 @@ function cb_dropdown2(obj,~,~)
end
end
end
end
end
14 changes: 8 additions & 6 deletions PlatEMO/Problems/PROBLEM.m
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
N = 100; % Population size
maxFE = 10000; % Maximum number of function evaluations
FE = 0; % Number of consumed function evaluations
fastdraw = 0; % Draw method (0.normal 1.fast)
display = '' % Item of displayed result
end
properties(SetAccess = protected)
M; % Number of objectives
Expand Down Expand Up @@ -304,9 +306,9 @@ function DrawDec(obj,Population)
% Problem.DrawDec(Population)

if all(obj.encoding==4)
Draw(logical(Population.decs));
Draw(logical(Population.decs),obj);
else
Draw(Population.decs,{'\it x\rm_1','\it x\rm_2','\it x\rm_3'});
Draw(Population.decs,obj,{'\it x\rm_1','\it x\rm_2','\it x\rm_3'});
end
end
function DrawObj(obj,Population)
Expand All @@ -319,8 +321,8 @@ function DrawObj(obj,Population)
% Example:
% Problem.DrawObj(Population)

ax = Draw(Population.objs,{'\it f\rm_1','\it f\rm_2','\it f\rm_3'});
if ~isempty(obj.PF)
ax = Draw(Population.objs,obj,{'\it f\rm_1','\it f\rm_2','\it f\rm_3'});
if ~isempty(obj.PF) && obj.fastdraw == 0
if ~iscell(obj.PF)
if obj.M == 2
plot(ax,obj.PF(:,1),obj.PF(:,2),'-k','LineWidth',1);
Expand All @@ -335,7 +337,7 @@ function DrawObj(obj,Population)
end
set(ax,'Children',ax.Children(flip(1:end)));
end
elseif size(obj.optimum,1) > 1 && obj.M < 4
elseif size(obj.optimum,1) > 1 && obj.M < 4 && obj.fastdraw == 0
if obj.M == 2
plot(ax,obj.optimum(:,1),obj.optimum(:,2),'.k');
elseif obj.M == 3
Expand Down Expand Up @@ -363,4 +365,4 @@ function DrawObj(obj,Population)
varargout(specified) = obj.parameter(specified);
end
end
end
end