foreword
When evaluating the effect of multi-objective optimization algorithms, we usually use five main indicators: GD (Generational Distance), IGD (Inverted Generational Distance), Hypervolume, Spacing and Spread.
GD and IGD are indicators used to measure the distance between the solution set generated by the algorithm and the real frontier solution. Specifically, GD measures the average Euclidean distance between all generated solutions and the true frontier solution, while IGD measures the average Euclidean distance between all true frontier solutions and the generated solution. The goal of these two indicators is that the smaller the better, that is, the generated solution set of the algorithm should be as close as possible to the real frontier solution.
Hypervolume is an indicator used to measure the volume of the real frontier solution that the solution set generated by the algorithm can cover. The goal is that the bigger the better, that is, the solution set generated by the algorithm should cover as many real frontier solutions as possible.
Spacing and Spread are indicators used to measure the distribution of the solution set generated by the algorithm. Spacing measures the minimum Euclidean distance between all solutions, while Spread measures the maximum Euclidean distance between all solutions.
Through comprehensive evaluation of these indicators, we can better understand the performance of the algorithm and optimize it.
Code
MATLAB
Spread.m
%% PopObj:算法求得的pareto解集
%% PF:真实的解集
function Score = Spread(PopObj,PF)
Dis1 = pdist2(PopObj,PopObj);
Dis1(logical(eye(size(Dis1,1)))) = inf;
[~,E] = max(PF,[],1);PF(E,:)
Dis2 = pdist2(PF(E,:),PopObj);
d1 = sum(min(Dis2,[],2));
d2 = mean(min(Dis1,[],2));
Score = (d1+sum(abs(min(Dis1,[],2)-d2))) / (d1+(size(PopObj,1)-size(PopObj,2))*d2);
end
Spacing.m
%% PopObj:算法求得的pareto解集
%% PF:真实的解集
function Score = Spacing(PopObj,PF)
Distance = pdist2(PopObj,PopObj,'cityblock');
Distance(logical(eye(size(Distance,1)))) = inf;
Score = std(min(Distance,[],2));
end
IGD.m
%% PopObj:算法求得的pareto解集
%% PF:真实的解集
function Score = IGD(PopObj,PF)
Distance = min(pdist2(PF,PopObj),[],2);
Score = mean(Distance);
end
HV.m
%% PopObj:算法求得的pareto解集
%% PF:真实的解集
function [Score,PopObj] = HV(PopObj,PF)
% Hypervolume
[N,M] = size(PopObj);
fmin = min(min(PopObj,[],1),zeros(1,M));
fmax = max(PF,[],1);
PopObj = (PopObj-repmat(fmin,N,1))./repmat((fmax-fmin)*1.1,N,1);
PopObj(any(PopObj>1,2),:) = [];
% The reference point is set to (1,1,...)
RefPoint = ones(1,M);
if isempty(PopObj)
Score = 0;
elseif M < 4
% Calculate the exact HV value
pl = sortrows(PopObj);
S = {1,pl};
for k = 1 : M-1
S_ = {};
for i = 1 : size(S,1)
Stemp = Slice(cell2mat(S(i,2)),k,RefPoint);
for j = 1 : size(Stemp,1)
temp(1) = {cell2mat(Stemp(j,1))*cell2mat(S(i,1))};
temp(2) = Stemp(j,2);
S_ = Add(temp,S_);
end
end
S = S_;
end
Score = 0;
for i = 1 : size(S,1)
p = Head(cell2mat(S(i,2)));
Score = Score + cell2mat(S(i,1))*abs(p(M)-RefPoint(M));
end
else
% Estimate the HV value by Monte Carlo estimation
SampleNum = 1000000;
MaxValue = RefPoint;
MinValue = min(PopObj,[],1);
Samples = unifrnd(repmat(MinValue,SampleNum,1),repmat(MaxValue,SampleNum,1));
if gpuDeviceCount > 0
% GPU acceleration
Samples = gpuArray(single(Samples));
PopObj = gpuArray(single(PopObj));
end
for i = 1 : size(PopObj,1)
drawnow();
domi = true(size(Samples,1),1);
m = 1;
while m <= M && any(domi)
domi = domi & PopObj(i,m) <= Samples(:,m);
m = m + 1;
end
Samples(domi,:) = [];
end
Score = prod(MaxValue-MinValue)*(1-size(Samples,1)/SampleNum);
end
end
function S = Slice(pl,k,RefPoint)
p = Head(pl);
pl = Tail(pl);
ql = [];
S = {};
while ~isempty(pl)
ql = Insert(p,k+1,ql);
p_ = Head(pl);
cell_(1,1) = {abs(p(k)-p_(k))};
cell_(1,2) = {ql};
S = Add(cell_,S);
p = p_;
pl = Tail(pl);
end
ql = Insert(p,k+1,ql);
cell_(1,1) = {abs(p(k)-RefPoint(k))};
cell_(1,2) = {ql};
S = Add(cell_,S);
end
function ql = Insert(p,k,pl)
flag1 = 0;
flag2 = 0;
ql = [];
hp = Head(pl);
while ~isempty(pl) && hp(k) < p(k)
ql = [ql;hp];
pl = Tail(pl);
hp = Head(pl);
end
ql = [ql;p];
m = length(p);
while ~isempty(pl)
q = Head(pl);
for i = k : m
if p(i) < q(i)
flag1 = 1;
else
if p(i) > q(i)
flag2 = 1;
end
end
end
if ~(flag1 == 1 && flag2 == 0)
ql = [ql;Head(pl)];
end
pl = Tail(pl);
end
end
function p = Head(pl)
if isempty(pl)
p = [];
else
p = pl(1,:);
end
end
function ql = Tail(pl)
if size(pl,1) < 2
ql = [];
else
ql = pl(2:end,:);
end
end
function S_ = Add(cell_,S)
n = size(S,1);
m = 0;
for k = 1 : n
if isequal(cell_(1,2),S(k,2))
S(k,1) = {cell2mat(S(k,1))+cell2mat(cell_(1,1))};
m = 1;
break;
end
end
if m == 0
S(n+1,:) = cell_(1,:);
end
S_ = S;
end
GD.m
%% PopObj:算法求得的pareto解集
%% PF:真实的解集
function Score = GD(PopObj,PF)
% Generational distance
Distance = min(pdist2(PopObj,PF),[],2);
Score = norm(Distance) / length(Distance);
end