主函数
clc;
clear;
close all;
CostFunction = @(x) MOP2(x);
nVar = 5;
VarSize = [1 nVar];
VarMin = -1;
VarMax = 1;
nObj = numel(CostFunction(unifrnd(VarMin, VarMax, VarSize)));
nDivision = 10;
Zr = GenerateReferencePoints(nObj, nDivision);
MaxIt = 50;
nPop = 80;
pCrossover = 0.5;
nCrossover = 2*round(pCrossover*nPop/2);
pMutation = 0.5;
nMutation = round(pMutation*nPop);
mu = 0.02;
sigma = 0.1*(VarMax-VarMin);
params.nPop = nPop;
params.Zr = Zr;
params.nZr = size(Zr, 2);
params.zmin = [];
params.zmax = [];
params.smin = [];
disp('Staring NSGA-III ...');
empty_individual.Position = [];
empty_individual.Cost = [];
empty_individual.Rank = [];
empty_individual.DominationSet = [];
empty_individual.DominatedCount = [];
empty_individual.NormalizedCost = [];
empty_individual.AssociatedRef = [];
empty_individual.DistanceToAssociatedRef = [];
pop = repmat(empty_individual, nPop, 1);
for i = 1:nPop
pop(i).Position = unifrnd(VarMin, VarMax, VarSize);
pop(i).Cost = CostFunction(pop(i).Position);
end
[pop, F, params] = SortAndSelectPopulation(pop, params);
for it = 1:MaxIt
popc = repmat(empty_individual, nCrossover/2, 2);
for k = 1:nCrossover/2
i1 = randi([1 nPop]);
p1 = pop(i1);
i2 = randi([1 nPop]);
p2 = pop(i2);
[popc(k, 1).Position, popc(k, 2).Position] = Crossover(p1.Position, p2.Position);
popc(k, 1).Cost = CostFunction(popc(k, 1).Position);
popc(k, 2).Cost = CostFunction(popc(k, 2).Position);
end
popc = popc(:);
popm = repmat(empty_individual, nMutation, 1);
for k = 1:nMutation
i = randi([1 nPop]);
p = pop(i);
popm(k).Position = Mutate(p.Position, mu, sigma);
popm(k).Cost = CostFunction(popm(k).Position);
end
pop = [pop
popc
popm];
[pop, F, params] = SortAndSelectPopulation(pop, params);
F1 = pop(F{1});
disp(['Iteration ' num2str(it) ': Number of F1 Members = ' num2str(numel(F1))]);
figure(1);
PlotCosts(F1);
pause(0.01);
end
disp(['Final Iteration: Number of F1 Members = ' num2str(numel(F1))]);
disp('Optimization Terminated.');
function [pop, d, rho] = AssociateToReferencePoint(pop, params)
Zr = params.Zr;
nZr = params.nZr;
rho = zeros(1, nZr);
d = zeros(numel(pop), nZr);
for i = 1:numel(pop)
for j = 1:nZr
w = Zr(:, j)/norm(Zr(:, j));
z = pop(i).NormalizedCost;
d(i, j) = norm(z - w'*z*w);
end
[dmin, jmin] = min(d(i, :));
pop(i).AssociatedRef = jmin;
pop(i).DistanceToAssociatedRef = dmin;
rho(jmin) = rho(jmin) + 1;
end
end
function [y1 y2] = Crossover(x1, x2)
alpha = rand(size(x1));
y1 = alpha.*x1+(1-alpha).*x2;
y2 = alpha.*x2+(1-alpha).*x1;
end
function b = Dominates(x, y)
if isstruct(x)
x = x.Cost;
end
if isstruct(y)
y = y.Cost;
end
b = all(x <= y) && any(x<y);
end
function Zr = GenerateReferencePoints(M, p)
Zr = GetFixedRowSumIntegerMatrix(M, p)' / p;
end
function A = GetFixedRowSumIntegerMatrix(M, RowSum)
if M < 1
error('M cannot be less than 1.');
end
if floor(M) ~= M
error('M must be an integer.');
end
if M == 1
A = RowSum;
return;
end
A = [];
for i = 0:RowSum
B = GetFixedRowSumIntegerMatrix(M - 1, RowSum - i);
A = [A; i*ones(size(B, 1), 1) B];
end
end
function z = MOP2(x)
n = numel(x);
z1 = 1-exp(-sum((x-1/sqrt(n)).^2));
z2 = 1-exp(-sum((x+1/sqrt(n)).^2));
z = [z1 z2]';
end
function y = Mutate(x, mu, sigma)
nVar = numel(x);
nMu = ceil(mu*nVar);
j = randsample(nVar, nMu);
y = x;
y(j) = x(j)+sigma*randn(size(j));
end
function [pop, F] = NonDominatedSorting(pop)
nPop = numel(pop);
for i = 1:nPop
pop(i).DominationSet = [];
pop(i).DominatedCount = 0;
end
F{1} = [];
for i = 1:nPop
for j = i+1:nPop
p = pop(i);
q = pop(j);
if Dominates(p, q)
p.DominationSet = [p.DominationSet j];
q.DominatedCount = q.DominatedCount+1;
end
if Dominates(q.Cost, p.Cost)
q.DominationSet = [q.DominationSet i];
p.DominatedCount = p.DominatedCount+1;
end
pop(i) = p;
pop(j) = q;
end
if pop(i).DominatedCount == 0
F{1} = [F{1} i];
pop(i).Rank = 1;
end
end
k = 1;
while true
Q = [];
for i = F{k}
p = pop(i);
for j = p.DominationSet
q = pop(j);
q.DominatedCount = q.DominatedCount-1;
if q.DominatedCount == 0
Q = [Q j];
q.Rank = k+1;
end
pop(j) = q;
end
end
if isempty(Q)
break;
end
F{k+1} = Q;
k = k+1;
end
end
function [pop, params] = NormalizePopulation(pop, params)
params.zmin = UpdateIdealPoint(pop, params.zmin);
fp = [pop.Cost] - repmat(params.zmin, 1, numel(pop));
params = PerformScalarizing(fp, params);
a = FindHyperplaneIntercepts(params.zmax);
for i = 1:numel(pop)
pop(i).NormalizedCost = fp(:, i)./a;
end
end
function a = FindHyperplaneIntercepts(zmax)
w = ones(1, size(zmax, 2))/zmax;
a = (1./w)';
end
function params = PerformScalarizing(z, params)
nObj = size(z, 1);
nPop = size(z, 2);
if ~isempty(params.smin)
zmax = params.zmax;
smin = params.smin;
else
zmax = zeros(nObj, nObj);
smin = inf(1, nObj);
end
for j = 1:nObj
w = GetScalarizingVector(nObj, j);
s = zeros(1, nPop);
for i = 1:nPop
s(i) = max(z(:, i)./w);
end
[sminj, ind] = min(s);
if sminj < smin(j)
zmax(:, j) = z(:, ind);
smin(j) = sminj;
end
end
params.zmax = zmax;
params.smin = smin;
end
function w = GetScalarizingVector(nObj, j)
epsilon = 1e-10;
w = epsilon*ones(nObj, 1);
w(j) = 1;
end
function PlotCosts(pop)
Costs = [pop.Cost];
plot(Costs(1, :), Costs(2, :), 'r*', 'MarkerSize', 8);
xlabel('1st Objective');
ylabel('2nd Objective');
grid on;
end
function [pop, F, params] = SortAndSelectPopulation(pop, params)
[pop, params] = NormalizePopulation(pop, params);
[pop, F] = NonDominatedSorting(pop);
nPop = params.nPop;
if numel(pop) == nPop
return;
end
[pop, d, rho] = AssociateToReferencePoint(pop, params);
newpop = [];
for l = 1:numel(F)
if numel(newpop) + numel(F{l}) > nPop
LastFront = F{l};
break;
end
newpop = [newpop; pop(F{l})];
end
while true
[~, j] = min(rho);
AssocitedFromLastFront = [];
for i = LastFront
if pop(i).AssociatedRef == j
AssocitedFromLastFront = [AssocitedFromLastFront i];
end
end
if isempty(AssocitedFromLastFront)
rho(j) = inf;
continue;
end
if rho(j) == 0
ddj = d(AssocitedFromLastFront, j);
[~, new_member_ind] = min(ddj);
else
new_member_ind = randi(numel(AssocitedFromLastFront));
end
MemberToAdd = AssocitedFromLastFront(new_member_ind);
LastFront(LastFront == MemberToAdd) = [];
newpop = [newpop; pop(MemberToAdd)];
rho(j) = rho(j) + 1;
if numel(newpop) >= nPop
break;
end
end
[pop, F] = NonDominatedSorting(newpop);
end
function zmin = UpdateIdealPoint(pop, prev_zmin)
if ~exist('prev_zmin', 'var') || isempty(prev_zmin)
prev_zmin = inf(size(pop(1).Cost));
end
zmin = prev_zmin;
for i = 1:numel(pop)
zmin = min(zmin, pop(i).Cost);
end
end