MATLAB算法实战应用案例精讲-【智能优化算法】多目标算法性能评价指标

前言

在评估多目标优化算法的效果时,我们通常使用五个主要指标:GD(Generational Distance)、IGD(Inverted Generational Distance)、Hypervolume、Spacing和Spread。

GDIGD是用于测量算法生成的解集合与真实前沿解之间的距离的指标。具体而言,GD测量了所有生成解与真实前沿解之间的平均欧几里得距离,而IGD测量了所有真实前沿解与生成解之间的平均欧几里得距离。这两个指标的目标是越小越好,即算法的生成解集合应该尽可能接近真实前沿解。

Hypervolume则是用于测量算法生成的解集合能够覆盖的真实前沿解的体积大小的指标。目标是越大越好,即算法生成的解集合应该尽可能覆盖更多的真实前沿解。

SpacingSpread是用于测量算法生成的解集合的分布情况的指标。Spacing测量了所有解之间的最小欧几里得距离,而Spread测量了所有解之间的最大欧几里得距离。

通过对这些指标的全面评估,我们可以更好地了解算法的表现并进行优化。

代码实现

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

猜你喜欢

转载自blog.csdn.net/qq_36130719/article/details/130145093