%_政治优化器
function [Leader_score,Leader_pos,Convergence_curve]=PO(SearchAgents_no,Max_iter,lb,ub,dim,fobj)
areas = 4;
parties = areas; %Number of political parties
lambda = 1.0; %Max limit of party switching rate
fEvals = 30000; %Number of function evaluations
% initialize position vector and score for the leader
Leader_pos=zeros(1,dim);
Leader_score=inf; %change this to -inf for maximization problems
%Initialize the positions of search agents
Positions=initialization(SearchAgents_no,dim,ub,lb);
auxPositions = Positions;
prevPositions = Positions;
Convergence_curve=zeros(1,Max_iter);
fitness=zeros(SearchAgents_no, 1);
%Running phases for initializations
for i=1:size(Positions,1)
% Return back the search agents that go beyond the boundaries of the search space
Flag4ub=Positions(i,:)>ub;
Flag4lb=Positions(i,:)<lb;
Positions(i,:)=(Positions(i,:).*(~(Flag4ub+Flag4lb)))+ub.*Flag4ub+lb.*Flag4lb;
%Calculate objective function for each search agent
fitness(i,1)=fobj(Positions(i,:));
%Update the leader
if fitness(i,1)<Leader_score % Change this to > for maximization problem
Leader_score=fitness(i,1);
Leader_pos=Positions(i,:);
end
end
% Election; %Run election phase
auxFitness = fitness;
prevFitness = fitness;
% GovernmentFormation;
%%%%%%%%%%%%%%%%%%%%% Govt. Formation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
aWinnerInd=zeros(areas,1); %Indices of area winners in x
aWinners = zeros(areas,dim); %Area winners are stored separately
for a = 1:areas
[aWinnerFitness,aWinnerParty]=min(fitness(a:areas:SearchAgents_no));
aWinnerInd(a,1) = (aWinnerParty-1) * areas + a;
aWinners(a,:) = Positions(aWinnerInd(a,1),:);
end
%Finding party leaders
pLeaderInd=zeros(parties,1); %Indices of party leaders in x
pLeaders = zeros(parties,dim); %Positions of party leaders in x
for p = 1:parties
pStIndex = (p-1) * areas + 1;
pEndIndex = pStIndex + areas - 1;
[partyLeaderFitness,leadIndex]=min(fitness(pStIndex:pEndIndex));
pLeaderInd(p,1) = (pStIndex - 1) + leadIndex; %Indexof party leader
pLeaders(p,:) = Positions(pLeaderInd(p,1),:);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
t=0;% Loop counter
while t<Max_iter
prevFitness = auxFitness;
prevPositions = auxPositions;
auxFitness = fitness;
auxPositions = Positions;
% ElectionCampaign;
%%%%%%%%%%%%%%%%%%%%% Election campaign %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for whichMethod = 1:2
for a = 1:areas
for p = 1:parties
i = (p-1)*areas + a; %index of member
for j=1:dim
if whichMethod == 1 %position-updating w.r.t party leader
center = pLeaders(p,j);
elseif whichMethod == 2 %position-updating w.r.t area winner
center = aWinners(a,j);
end
%Cases of Eq. 9 in paper
if prevFitness(i) >= fitness(i)
if (prevPositions(i,j) <= Positions(i,j) && Positions(i,j) <= center) ...
|| (prevPositions(i,j) >= Positions(i,j) && Positions(i,j) >= center)
radius = center - Positions(i,j);
Positions(i,j) = center + rand() * radius;
elseif (prevPositions(i,j) <= Positions(i,j) && Positions(i,j) >= center && center >= prevPositions(i,j)) ...
|| (prevPositions(i,j) >= Positions(i,j) && Positions(i,j) <= center && center <= prevPositions(i,j))
radius = abs(Positions(i,j) - center);
Positions(i,j) = center + (2*rand()-1) * radius;
elseif (prevPositions(i,j) <= Positions(i,j) && Positions(i,j) >= center && center <= prevPositions(i,j)) ...
|| (prevPositions(i,j) >= Positions(i,j) && Positions(i,j) <= center && center >= prevPositions(i,j))
radius = abs(prevPositions(i,j) - center);
Positions(i,j) = center + (2*rand()-1) * radius;
end
%Cases of Eq. 10 in paper
elseif prevFitness(i) < fitness(i)
if (prevPositions(i,j) <= Positions(i,j) && Positions(i,j) <= center) ...
|| (prevPositions(i,j) >= Positions(i,j) && Positions(i,j) >= center)
radius = abs(Positions(i,j) - center);
Positions(i,j) = center + (2*rand()-1) * radius;
elseif (prevPositions(i,j) <= Positions(i,j) && Positions(i,j) >= center && center >= prevPositions(i,j)) ...
|| (prevPositions(i,j) >= Positions(i,j) && Positions(i,j) <= center && center <= prevPositions(i,j))
radius = Positions(i,j) - prevPositions(i,j);
Positions(i,j) = prevPositions(i,j) + rand() * radius;
elseif (prevPositions(i,j) <= Positions(i,j) && Positions(i,j) >= center && center <= prevPositions(i,j)) ...
|| (prevPositions(i,j) >= Positions(i,j) && Positions(i,j) <= center && center >= prevPositions(i,j))
center2 = prevPositions(i,j);
radius = abs(center - center2);
Positions(i,j) = center + (2*rand()-1) * radius;
end
end
end
end
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% PartySwitching;
%%%%%%%%%%%%%%%%%%%%% Party switching Phase %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
psr = (1-t*((1)/Max_iter)) * lambda;
for p=1:parties
for a=1:areas
fromPInd = (p-1)*areas + a;
if rand() < psr
%Selecting a party other than current where want to send the
%member
toParty = randi(parties);
while(toParty == p)
toParty = randi(parties);
end
%Deciding member in TO party
toPStInd = (toParty-1) * areas + 1;
toPEndIndex = toPStInd + areas - 1;
[~,toPLeastFit] = max(fitness(toPStInd:toPEndIndex));
toPInd = toPStInd + toPLeastFit-1;
%Deciding what to do with member in FROM party and switching
fromPInd = (p-1)*areas + a;
temp = Positions(toPInd,:);
Positions(toPInd,:) = Positions(fromPInd);
Positions(fromPInd,:)=temp;
temp = fitness(toPInd);
fitness(toPInd) = fitness(fromPInd);
fitness(fromPInd) = temp;
end
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Election;
%%%%%%%%%%%%%%%%%%%%% Election Phase %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for i=1:size(Positions,1)
% Return back the search agents that go beyond the boundaries of the search space
Flag4ub=Positions(i,:)>ub;
Flag4lb=Positions(i,:)<lb;
Positions(i,:)=(Positions(i,:).*(~(Flag4ub+Flag4lb)))+ub.*Flag4ub+lb.*Flag4lb;
%Calculate objective function fo