1.前置知识:
1.1基础概念
详细见这篇文章:CMOPs 约束多目标问题基础知识-CSDN博客
1.2约束支配准则CDP
定义: y ≺CDP x,满足下列任意一种情况,我们就说解y支配解x。
- y 是可行解,x 为不可行解
- y 和 x 都为不可行解,但是 y 的 CV 值小于 x 的 CV 值
- y 和 x 都为可行解且 y ≺x(解y在所有目标值上都小于等于解x且解y至少有一个目标值上小于解x)
1.3角度支配准则ACDP
角度值的计算公式:
- 解之间夹角越大,其目标空间中的分布越分散,有助于多样性。
- 在相同可行性或约束违反程度下,夹角大的解优于夹角小的解。
- 夹角信息用于衡量解在目标空间中的分布情况
1.4DE/rand/1 和 DE/current-to-best/1
- 差分进化公式DE/rand/1:这是差分进化中一种基础的变异策略,完全基于随机选择父代个体生成变异向量。
- 差分进化公式DE/current-to-best/1:这是改进的局部搜索策略,通过利用当前解 xi 和一个优先解 xbest(从最优个体中选择)生成变异向量。
- vi:第 i 个个体的变异向量。
- xi:当前个体。
- xb:从种群中按概率从最优 p% 个体中选取的个体,通常称为“优先解”。
- xr1, xr2:从种群中随机选择的两个不同个体,且 xr1≠xr2≠xi。
- F:缩放因子。
1.5 OCMOPs和DCMOPs
- OCMOPs:带有目标空间约束的基准问题被称为静态约束多目标优化问题,约束条件和目标函数在整个优化过程中不变。
- DCMOPs:带有决策空间约束的基准问题被称为动态约束多目标优化问题,目标函数或约束可能在不同时间段具有不同的定义或形式,导致 Pareto 前沿会动态变化。
目标空间中三个OCMOPs的约束程度与目标之间的关系
2.SDC基准问题介绍
本文主要介绍该篇文献提出的算法,文献中提出的基准问题仅做简要介绍,详细了解请参考文章末尾所给的文献链接。
2.1SDC被提出的动机
- 现存的基准问题存在的一些问题:1.围绕CPF来构建可行域,换句话,很多约束函数和目标值直接相关而不是和决策变量。用目标值离可行域的距离来表示约束违背度CV。2.约束地形不是多模态的。3.决策变量的数量是固定的。基于以上问题使得现有的很多基准问题很难完全代表现实中问题的特点。
- 现实中问题的特点:特点1:约束函数常常是直接和决策变量相关而不是目标值。特点2:仅仅一些但不是全部决策变量和约束相关。特点3:等式和不等式约束都存在。特点4:决策变量的数量也直接和约束相关并且总决策变量数量也是可扩展的。
- SDC基准问题的特点:SDC中的约束变量数量是可扩展的,因此约束函数具有可调整的难度。此外,为了帮助用户轻松验证算法在变体函数上的泛化性能,提供了几个不同的参数接口来构建变体函数。总共提出了15个基准测试问题从SDC1-SDC15。
2.2SDC与目标值的关系
- SDC1-SDC15的构建
- SDC1,SDC5,SDC7约束违反程度与目标值的关系
- SDC1:有两个区域分别分布在第一象限和第三象限。值得注意的是, CPF位于第一象限。因此,如果算法更多地关注目标,种群将落入分布在第三象限的不可行区域。在第一象限,随着目标值的降低,约束违反程度并不会降低,因此目标和约束之间存在非线性关系。
- SDC7:随着目标值的降低,约束违反程度也随之降低,因此目标和约束之间存在线性关系。这与上面三个OCMOPs问题具有相似性。
- SDC5:SDC5展示了一个非常复杂的景地形,在这个地形中,整个区域充满了众多局部区域。因此,算法应该能够探索整个决策空间并找到更有希望的区域。否则,算法很容易陷入局部区域。
3.IMTCMO算法提出的背景与动机
- 在约束单目标优化工作中,各种各样的约束处理机制CHTs利用不可行解的信息以及维持种群的多样性,其次,他们提出了各种进化操作符以提高种群的搜索能力。在众多进化操作符中,差分进化(DE)变异策略已被证明是成功的,因为它们能够处理复杂的变量关联,并具有自适应的搜索能力。并且结合它们能够改善算法的表现。
- SDC功能由于约束和目标之间的复杂关系而更加复杂。特别是当问题有许多离散的可行区域或具有更好目标的局部不可行区域时,算法应该充分探索不可行区域,并利用不可行解来识别有前景的可行区域。为此提出IMTCMO算法并用SDC来测试性能。算法的主种群使用CDP方法来保持可行性,辅助种群使用改进的epsilon方法来保持不可行区域的多样性,并利用不同的差分进化(DE)公式来生成新的个体。
4.IMTCMO算法
算法总体流程伪代码
4.1 IMTCMO算法流程图
- 主种群MainPOP通过局部搜索策略和全局搜索策略各生成N/2个子代。然后结合两个种群的子代。再依据CDP准则+欧式距离来进行环境选择更新MainPOP。继续循环迭代直到满足终止条件。
- 辅助种群AuxiliaryPOP与主种群MainPOP在环境选择前的流程是相同的。在环境选择的时候则是利用ε方法来更新AuxiliaryPOP。继续循环迭代直到满足终止条件。
- ε方法:ε方法主要是将个体的约束违背度CV作为额外的一个目标值来进行优化,并基于多目标的CHT来对种群排序。
4.2局部和全局搜索策略
策略伪代码
- 局部搜索策略:先计算种群个体之间的角度值,将离当前个体角度值最小的Nr个个体作为当前个体的邻居,利用DE/rand/1来生成子代,其中xr1(对应nei,1)和xr2(对应nei,2)是从当前个体的邻居中随机选择的两个个体。
- 全局搜索策略:计算种群个体的适应度值,选择适应度最小的pa*N个个体(这里pa=0.1)放到Pbest中。利用DE/current-to-pbest/1来生成子代,其中的xpbest是从Pbest中随机挑选的,xr1(对应DPi,1)xr2(对应DPi,2)是随机选择的两个个体。
- 策略分析:局部搜索主要目的是维持种群的多样性,主要种群MainPOP可以使用局部搜索来定位多个离散的可行区域。辅助种群AuiliaryPOP可以使用局部搜索来充分探索局部不可行区域。所以选用DE/rand/1来生成子代,该方法随机性很高。全局搜索主要目的是增加种群的可行率,加速收敛。MainPOP可以使用全局搜索使个体靠近优秀个体,从而改善种群分布。AuiliaryPOP可以使用全局搜索加快信息流动,以便找到更有前景的区域。
5.IMTCMO在SDC上的实验结果
“+”,“−”,和“≈”分别表示结果显著优于、显著劣于和统计上与IMTCMO获得的结果相似
该表给出了平均IGD结果,其中每个问题的最佳解用灰色标记。此外,如果一个算法在一个函数上找不到任何可行解,结果用“NaN”表示。结果显示由于SDC约束和目标之间更复杂的关系,用于解决OCMOPs的算法不能很好地解决SDC基准问题。与用CHTs来平衡约束和目标值的算法(CMOEA-MS, MSCMO, ICMA, cDPEA, DCNSGA-III)相比,IMTCMO获得了最小的排名,展示了其优越性。
6.部分源码展现
【声明】:以下代码是博主本人实现,CalFitness和EnvirmoentSelect借鉴了Platemo平台代码,具体实现在Platemo平台。IMTCMO算法源码原作者已上传到Platemo平台。
算法总体流程伪代码,将局部搜索和全局搜索策略也包含在内
classdef I_IMTCMO < ALGORITHM
% <multi> <real/integer/label/binary/permutation> <constrained>
methods
function main(Algorithm,Problem)
% 初始化种群
Population1 = Problem.Initialization();
Population2 = Problem.Initialization();
CV = sum(max(0,[Population1.cons;Population2.cons]),2);
%参数设置
epsilon0 = max(CV,[],1);
if epsilon0 == 0
epsilon0 = 1;
end
%邻居个数
Nr = 10;
%Pbest最优解个数参数
pa = 0.1;
%种群大小
N = Problem.N;
%循环次数
T = 1;
%最大循环次数
MaxT = Problem.maxFE/Problem.N;
%目标值理想值
Zmin1 = [];
Zmin2 = [];
%% Optimization
while Algorithm.NotTerminated(Population1)
%放松约束值计算
loga = (-log(epsilon0) - 6) / log(1 - 0.5);
epsilon = epsilon0*(1-(T/MaxT)).^loga;
%% 局部搜索生成一半的子代
%随机打乱种群顺序
LPopulation1 = Population1(randperm(N));
LPopulation2 = Population2(randperm(N));
%目标值归一化
Zmin1 = min([LPopulation1.objs;Zmin1],[],1);
Zmin2 = min([LPopulation2.objs;Zmin2],[],1);
Obj1 = LPopulation1.objs - Zmin1;
Obj2 = LPopulation2.objs - Zmin2;
%计算每个解之间的角度值
angle1 = acos(1 - pdist2(Obj1,Obj1,'cosine'));
angle2 = acos(1 - pdist2(Obj2,Obj2,'cosine'));
%将到自身的角度值设为无穷大
angle1(angle1<1e-6) = inf;
angle2(angle2<1e-6) = inf;
%找到前一半解的最近Nr个邻居
[~,Neighbor1] = sort(angle1,2);
Neighbor1 = Neighbor1(1:N/2,1:Nr);
[~,Neighbor2] = sort(angle2,2);
Neighbor2 = Neighbor2(1:N/2,1:Nr);
%对每行邻居随机生成两个索引值
rows = (1:N/2)';
random_cols1 = randi(size(Neighbor1,2),N/2,2);
random_cols2 = randi(size(Neighbor2,2),N/2,2);
%转换成线性索引
linear_indices1 = sub2ind(size(Neighbor1), repmat(rows, 1, size(random_cols1, 2)), random_cols1);
linear_indices2 = sub2ind(size(Neighbor2), repmat(rows, 1, size(random_cols2, 2)), random_cols2);
% 根据线性索引提取每行的邻居索引
ne1 = Neighbor1(linear_indices1);
ne2 = Neighbor2(linear_indices2);
%用DE/rand/1生成一半子代
Offspring1(1:N/2) = DE_rand_1(Problem,LPopulation1(1:N/2),LPopulation1(ne1(:,1)),LPopulation1(ne1(:,2)));
Offspring2(1:N/2) = DE_rand_1(Problem,LPopulation2(1:N/2),LPopulation2(ne2(:,1)),LPopulation2(ne2(:,2)));
%% 全局搜索生成另一半子代
Gpbest1 = Population1(1:ceil(pa*N));
Gpbest2 = Population2(1:ceil(pa*N));
%随机从打乱顺序的种群中选择N个解(可能会重复)
DP1 = LPopulation1(randi(N,1,N));
DP2 = LPopulation2(randi(N,1,N));
%随机从Gpbest中选择解(含重复)
best1 = Gpbest1(randi(length(Gpbest1),1,N/2));
best2 = Gpbest2(randi(length(Gpbest2),1,N/2));
%用DE/pbest/1生成另一半子代
Offspring1(1+N/2:N) = DE_pbest_1(Problem,LPopulation1(1+N/2:end),best1,DP1(1:N/2),DP1(1+N/2:end));
Offspring2(1+N/2:N) = DE_pbest_1(Problem,LPopulation2(1+N/2:end),best2,DP2(1:N/2),DP2(1+N/2:end));
%共享子代个体
P1 = [Population1,Offspring1,Offspring2];
P2 = [Population2,Offspring1,Offspring2];
%主种群用CDP的方法,辅助种群依靠改进的ε方法选择最好的N个个体
[Population1,~] = EnviromentSelect1(P1,N);
[Population2,~] = EnviromentSelect2(P2,N,epsilon);
%种群迭代次数+1
T = T+1;
end
end
end
end
AuiliaryPOP种群的环境选择,依据改进ε方法
function [Population,Fitness] = EnviromentSelect2(Population,N,epslion)
%计算所有解的约束违背值
allCV = sum(max(0,Population.cons),2);
%将小于epslion的个体记为FeaPop处理,其余个体记为InfeaPop
index1 = allCV<=epslion;
index2 = allCV>epslion;
FeaPop = Population(index1);
InfeaPop = Population(index2);
%% Fitness值计算
if sum(index1) == 0
%如果全是InfeaPop个体,则用CDP准则(约束优先)计算适应度值
Infeafit = CalFitness(InfeaPop.objs,InfeaPop.cons);
[Population,Fitness] = Enviroment(InfeaPop,Infeafit,N);
elseif sum(index1) <= N
%如果FeaPop个体小于N个,将FeaPop个体的CV值作为额外的目标值再计算适应度值
FeaCV = sum(max(Population(index1).cons,0),2);
Feafit = CalFitness([FeaPop.objs,FeaCV]);
%将适应度值按从小到大排序,再将FeaPop依据适应度值排名从优到劣排序
[~,rank] = sort(Feafit);
FeaFit = Feafit(rank);
FeaPop = FeaPop(rank);
%计算InfeaPop个体的适应度值并依据补充缺少的个体
InfeaFit = CalFitness(InfeaPop.objs,InfeaPop.cons);
[InfeaPop,InfeaFit] = Enviroment(InfeaPop,InfeaFit,N-length(FeaPop));
%将InfeaPop个体适应度加上FeaPop的最大适应度值,使其被选择的概率小于FeaPop个体
InfeaFit = InfeaFit + max(FeaFit);
%合并两个种群和适应度值
Population = [FeaPop,InfeaPop];
Fitness = [FeaFit,InfeaFit];
else
%如果FeaPop个体多余N个,将FeaPop个体的CV值作为额外的目标值再计算适应度值
FeaCV = sum(max(Population(index1).cons,0),2);
Feafit = CalFitness([FeaPop.objs,FeaCV]);
[Population,Fitness] = Enviroment(FeaPop,Feafit,N);
end
end
function [Population,Fitness] = Enviroment(Population,Fitness,N)
%环境选择前N个最好的解
Next = Fitness < 1;
if sum(Next) < N
[~,Rank] = sort(Fitness);
Next(Rank(1:N)) = true;
elseif sum(Next) > N
Del = Truncation(Population(Next).objs,sum(Next)-N);
Temp = find(Next);
Next(Temp(Del)) = false;
end
% 选取的下一代种群
Population = Population(Next);
Fitness = Fitness(Next);
% 种群选取顺序从优到劣,适应度同理,对应上每个个体。
[Fitness,rank] = sort(Fitness);
Population = Population(rank);
end
function Del = Truncation(PopObj,K)
%多余个体依据拥挤距离来删除,优先删除拥挤距离小的个体
Distance = pdist2(PopObj,PopObj);
Distance(logical(eye(length(Distance)))) = inf;
Del = false(1,size(PopObj,1));
while sum(Del) < K
Remain = find(~Del);
Temp = sort(Distance(Remain,Remain),2);
[~,Rank] = sortrows(Temp);
Del(Remain(Rank(1))) = true;
end
end
MainPOP种群环境选择,依据CDP
function [Population,Fitness] = EnviromentSelect1(Population,N)
%% 计算每个解的适应度值
Fitness = CalFitness(Population.objs,Population.cons);
%% 环境选择前N个解
Next = Fitness < 1;
if sum(Next) < N
[~,Rank] = sort(Fitness);
Next(Rank(1:N)) = true;
elseif sum(Next) > N
Del = Truncation(Population(Next).objs,sum(Next)-N);
Temp = find(Next);
Next(Temp(Del)) = false;
end
% 选取的下一代种群
Population = Population(Next);
Fitness = Fitness(Next);
% 种群选取顺序从优到劣,适应度同理,对应上每个个体。
[Fitness,rank] = sort(Fitness);
Population = Population(rank);
end
function Del = Truncation(PopObj,K)
%多余个体依据拥挤距离来删除,优先删除拥挤距离小的个体
Distance = pdist2(PopObj,PopObj);
Distance(logical(eye(length(Distance)))) = inf;
Del = false(1,size(PopObj,1));
while sum(Del) < K
Remain = find(~Del);
Temp = sort(Distance(Remain,Remain),2);
[~,Rank] = sortrows(Temp);
Del(Remain(Rank(1))) = true;
end
end
CalFitness适应度值的计算,CDP准则。
function Fitness = CalFitness(PopObj,PopCon)
% Calculate the fitness of each solution
%计算约束违背度
N = size(PopObj,1);
if nargin == 1
CV = zeros(N,1);
else
CV = sum(max(0,PopCon),2);
end
%% Detect the dominance relation between each two solutions
Dominate = false(N);
for i = 1 : N-1
for j = i+1 : N
if CV(i) < CV(j)
Dominate(i,j) = true;
elseif CV(i) > CV(j)
Dominate(j,i) = true;
else
k = any(PopObj(i,:)<PopObj(j,:)) - any(PopObj(i,:)>PopObj(j,:));
if k == 1
Dominate(i,j) = true;
elseif k == -1
Dominate(j,i) = true;
end
end
end
end
%% Calculate S(i)每个个体支配的个数
S = sum(Dominate,2);
%% Calculate R(i)支配第i个体的所有个体支配其他个体的个数
R = zeros(1,N);
for i = 1 : N
R(i) = sum(S(Dominate(:,i)));
end
%% 计算拥挤距离
Distance = pdist2(PopObj,PopObj);
Distance(logical(eye(length(Distance)))) = inf;
Distance = sort(Distance,2);
%每个个体的拥挤距离取第√N+2大的距离
D = 1./(Distance(:,floor(sqrt(N)))+2);
%% 计算适应度
Fitness = R + D';
end
7.参考文献
K. Qiao et al., "Evolutionary Constrained Multiobjective Optimization: Scalable High-Dimensional Constraint Benchmarks and Algorithm," in IEEE Transactions on Evolutionary Computation, vol. 28, no. 4, pp. 965-979, Aug. 2024, doi: 10.1109/TEVC.2023.3281666