我在研究中经常使用遗传算法,并且遇到了一个有趣的问题,即如何最好地在基因组上执行遗传操作。假设您有一个由 f(x,y) = a x^n + b x^n-1 + ... + c y^m + d y^m-1 ... 等定义的函数。它只是一个多变量计算起来有些昂贵的函数,因此您正在尝试尽可能高效地进行遗传操作。
如果您使用的是基因组的二进制表示,我发现有两种合理的方法可以执行遗传操作。让我们只看交叉阶段。
这是 Matlab 中矢量化锦标赛选择的代码(用于变量名称的上下文)
%% Tournament Selection
T = round(rand(2*popSize,S)*(popSize-1)+1); % Tournaments
[~,idx] = max(F(T),[],2); % Index of Winners
W = T(sub2ind(size(T),(1:2*popSize)',idx)); % Winners
因此,您有 2 个不同的变量正在优化,我的问题是您是否要拆分遗传操作,以便将交叉分别应用于每个变量,然后将数组重新连接在一起,这对于 2 点来说看起来像这样交叉:
%% 2 Point Crossover
Pop2 = Pop(W(1:2:end),:); % Set Pop2 = Pop Winners 1
P2A = Pop(W(2:2:end),:); % Assemble Pop2 Winners 2
% Split Pop2 for x and y genomes
xPop2 = Pop2(:,1:genome/2);
yPop2 = Pop2(:,genome/2 + 1:end);
% Split P2A for x and y genomes
xP2A = P2A(:,1:genome/2);
yP2A = P2A(:,genome/2+2:end);
% For x genome
Ref = ones(popSize,1)*(1:genome/2); % Reference Matrix
CP = sort(round(rand(popSize,2)*(genome/2-1)+1),2); % Crossover Points
xidx = CP(:,1)*ones(1,genome/2)<Ref & CP(:,2)*ones(1,genome/2)>Ref; % Logical Index
xPop2(xidx) = xP2A(xidx); % Recombine Winners
% For y genome
Ref = ones(popSize,1)*(1:genome/2); % Reference Matrix
CP = sort(round(rand(popSize,2)*(genome/2-1)+1),2); % Crossover Points
yidx = CP(:,1)*ones(1,genome/2)<Ref & CP(:,2)*ones(1,genome/2)>Ref; % Logical Index
yPop2(yidx) = yP2A(yidx); % Recombine Winners
Pop2 = horzcat(xPop2,yPop2);
P2A = horzcat(xP2A,yP2A);
或者您是否将基因组视为单个交叉操作,并且只执行 2 点交叉,就好像它只是一个像这样的单个变量基因组:
Pop2 = Pop(W(1:2:end),:); % New Pop is Winners of old Pop
P2A = Pop(W(2:2:end),:); % Assemble Pop2 Winners 2
Ref = ones(popSize,1)*(1:genome); % Ones Matrix
CP = sort(round(rand(popSize,2)*(genome-1)+1),2); % Crossover Points
idx = CP(:,1)*ones(1,genome)<Ref&CP(:,2)*ones(1,genome)>Ref; % Index
Pop2(idx)=P2A(idx); % Recombine Winners
有谁知道已经进行的任何研究表明两种不同的基因组表示方式的差异?我还没有找到任何关于它的发布,但这可能只是因为我不知道如何在谷歌中智能地表达我的问题。
谢谢