├── PSO_VNS.m └── README.md /PSO_VNS.m: -------------------------------------------------------------------------------- 1 | %% I. clear environment 2 | clc; 3 | clear; 4 | close all; 5 | d2r = pi/180; 6 | 7 | %% II. model building 8 | % 3 pursuers position, velocity vector and 9 | % Effective detection distance and maximum detection distance 10 | p1 = [0 0; 0 0.01; 30 40]; 11 | p2 = [0 0.1; 0 0.01; 30 50]; 12 | p3 = [0.1 0; -0.01 0.01; 25 30]; 13 | p4 = [0.1 0.1; 0.01 0.1; 30 40]; 14 | p5 = [-0.2 0; 0.01 0.1; 30 40]; 15 | p6 = [0 0.05; 0 0.01; 20 40]; 16 | p7 = [0 0.1; -0.1 0.01; 30 50]; 17 | p8 = [-0.1 0; 0.08 0.01; 25 30]; 18 | p9 = [0.1 0.1; 0.01 0.16; 20 40]; 19 | p10 = [0.2 0; -0.6 0.1; 30 40]; 20 | P(1, :, :) = p1; 21 | P(2, :, :) = p2; 22 | P(3, :, :) = p3; 23 | P(4, :, :) = p4; 24 | P(5, :, :) = p5; 25 | P(6, :, :) = p6; 26 | P(7, :, :) = p7; 27 | P(8, :, :) = p8; 28 | P(9, :, :) = p9; 29 | P(10, :, :) = p10; 30 | % 3 evaders position, velocity vector and points of importance 31 | e1 = [15 15; -1 -1; 0.5 0]; 32 | e2 = [-20 0.1; 1 0; 0.7 0]; 33 | e3 = [0.1 14; 0 -1; 0.5 0]; 34 | e4 = [5 10; -0.5 -2; 0.8 0]; 35 | e5 = [-15 10; 1 -1; 0.3 0]; 36 | e6 = [20 2; -1 -1.4; 0.9 0]; 37 | e7 = [-10 14; 0.7 -1; 0.5 0]; 38 | e8 = [-19 10; 1.5 -2; 0.5 0]; 39 | E(1, :, :) = e1; 40 | E(2, :, :) = e2; 41 | E(3, :, :) = e3; 42 | E(4, :, :) = e4; 43 | E(5, :, :) = e5; 44 | E(6, :, :) = e6; 45 | E(7, :, :) = e7; 46 | E(8, :, :) = e8; 47 | %% III. Main function 48 | 49 | tic; 50 | fbest = vnspso(P, E); 51 | toc; 52 | 53 | % aaa = [0 0 1 0; 0 1 0 0; 0 0 0 1; 0 1 0 0; 1 0 0 0]; 54 | % fitnessf(aaa, P, E) 55 | 56 | %% IV. Fitness functions 57 | function Fr1 = threatrangeFit(e) 58 | % threat distance fitness function 59 | obj = [0 0]; %attacking object's position 60 | temp = e(1, :); 61 | R = obj - temp; %range vector 62 | V = e(2, :); %velocity vector of attacking missile 63 | Rt = 10*sign(dot(R,V))*norm(R)*norm(cross([R 0],[V 0]))/norm(R)/norm(V); % threat distance 64 | temp2 = (1-sign(Rt))*norm(R); 65 | if Rt == 0 66 | if R(1)*V(1) > 0 67 | temp2 = 0; 68 | else 69 | temp2 = 2*norm(R); 70 | end 71 | end 72 | 73 | Fr1 = exp(-(temp2*10+Rt)*0.1); %threat distance fitness function 74 | end 75 | 76 | function Fr2 = velE(e) 77 | % flying velocity fitness function 78 | V = e(2, :); 79 | Fr2 = 1-exp(-5*norm(V)); 80 | end 81 | 82 | function Fr3 = impotanceE(e) 83 | % threatening level fitness function 84 | Fr3 = e(3, 1); 85 | end 86 | 87 | function Frj = threatBonus(e) 88 | % threatening fitness of evader 89 | % p, e refer to pursuer and evader respectively 90 | % tau refers to Weighted coefficients, 91 | tau = [13 13 13]; 92 | Frj = tau(1)*threatrangeFit(e)+tau(2)*velE(e)+tau(3)*impotanceE(e); 93 | end 94 | 95 | function Sij = probabilityIJ(p, e) 96 | % predicted interception probability of persuer i to evader j 97 | lmd1 = 1; 98 | lmd2 = 1; 99 | omg1 = 0.5; 100 | omg2 = 0.5; 101 | 102 | Rap = p(3, 1); % effective detective distance 103 | Trp = p(3, 2); % maximum detective distance 104 | temp = p - e; 105 | R = temp(1, :); % range vector 106 | dij = norm(R); 107 | temp2 = e - p; 108 | temp3 = p - e; 109 | rij = temp2(1, :); 110 | rji = temp3(1, :); 111 | vi = p(2, :); % vector of pursuer 112 | vj = e(2, :); % vector of evader 113 | eij = acos(dot(rij, vi)/norm(vi)/norm(rij)); % pre-angle of velocity 114 | eji = acos(dot(rji, vj)/norm(vj)/norm(rji)); % pre-angle of velocity 115 | % coefficient of range threatening 116 | if dij <= Rap 117 | Sdij = 1; 118 | elseif dij < Trp 119 | Sdij = 1-(dij-Rap)/(Trp-Rap); 120 | else 121 | Sdij = 0; 122 | end 123 | % coefficient of angle threatening 124 | Seij = exp(-lmd1*(eij+eji)^lmd2); 125 | % coefficient of velocity threatening 126 | if norm(vj) < 0.2 127 | Svpi = 1; 128 | elseif norm(vj) <= 3 129 | Svpi = -0.4*norm(vj)+1.2; 130 | else 131 | Svpi = 0; 132 | end 133 | 134 | Sij = omg1*Sdij*Seij+omg2*Svpi; % interception probability 135 | end 136 | 137 | function F = fitnessf(Dori, P, E) 138 | % fitness function 139 | % input: D, distribute matrix 140 | % output: fitness value 141 | [m, n] = size(Dori); % m refer to row, n refer to column 142 | Fsr = 0; 143 | for j = 1:n 144 | TTsij = 1; 145 | for i = 1:m 146 | Sij = probabilityIJ(squeeze(P(i, :, :)), squeeze(E(j, :, :))) * Dori(i, j); % core inovation 147 | TTsij = TTsij * (1 - Sij); 148 | end 149 | Ssj = 1 - TTsij; 150 | if Ssj == 0 151 | Ssj = -3; 152 | end 153 | Fsr = Fsr + threatBonus(squeeze(E(j, :, :)))*Ssj; 154 | end 155 | F = Fsr; 156 | end 157 | 158 | function D = decode(Dori) 159 | % decoding function: get standard distribute matrix by decoding original distribute matrix 160 | % original distribute matrix 161 | % standard distribute matrix 162 | D = Dori; 163 | [row, col] = size(D); 164 | for i=1:row 165 | maxr = max(D(i, :)); 166 | for j=1:col 167 | if D(i, j) < maxr 168 | D(i, j) = 0; 169 | else 170 | D(i, j) = 1; 171 | end 172 | end 173 | end 174 | end 175 | 176 | %% V. VNS functions 177 | function K = neighborhoodchange(Kori, nth, P, E) 178 | % neighborhoodchange function 179 | % input: Kori refers to initial particle, nth refers to n-th neighborhood structrue 180 | % output: better particle 181 | [row, col] = size(Kori); 182 | N = 3; % max iterations 183 | % first neighborhood structrue: exchange 184 | if nth == 1 185 | for i = 1:N 186 | Kn = Kori; 187 | fori = fitnessf(Kori, P, E); 188 | rd1 = randi([1 row]); % obtain random integer between 1 and row 189 | rd2 = randi([1 row]); 190 | rd3 = randi([1 col]); 191 | rd4 = randi([1 col]); 192 | while rd2 == rd1 193 | rd1 = randi([1 row]); 194 | rd2 = randi([1 row]); 195 | end 196 | while rd4 == rd3 197 | rd3 = randi([1 col]); 198 | rd4 = randi([1 col]); 199 | end 200 | % exchange 2 rows 201 | temp = Kn(rd1, :); 202 | Kn(rd1, :) = Kn(rd2, :); 203 | Kn(rd2, :) = temp; 204 | % exchange 2 columns 205 | temp = Kn(:, rd3); 206 | Kn(:, rd3) = Kn(:, rd4); 207 | Kn(:, rd4) = temp; 208 | fnow = fitnessf(Kn, P, E); 209 | % whether to update the particle 210 | if fnow > fori 211 | K = Kn; 212 | Kori = Kn; 213 | else 214 | K = Kori; 215 | end 216 | end 217 | end 218 | % seceond neighborhood structrue: reverse 219 | if nth == 2 220 | for i = 1:N 221 | Kn = Kori; 222 | fori = fitnessf(Kori, P, E); 223 | rd1 = randi([1 row]); % obtain random integer between 1 and row; 224 | temp = zeros(1, col); 225 | for c = 1:col 226 | temp(c) = Kn(rd1, 1+col-c); 227 | end 228 | Kn(rd1, :) = temp; 229 | fnow = fitnessf(Kn, P, E); 230 | if fnow > fori 231 | K = Kn; 232 | Kori = Kn; 233 | else 234 | K = Kori; 235 | end 236 | end 237 | end 238 | % third neighborhood structrue: insert 239 | if nth == 3 240 | for i = 1:N 241 | Kn = Kori; 242 | fori = fitnessf(Kori, P, E); 243 | rd1 = randi([1 row]); % obtain random integer between 1 and row; 244 | rd2 = randi([1 col]); % obtain random integer between 1 and column; 245 | temp = zeros(1, col); 246 | temp(rd2) = 1; 247 | Kn(rd1, :) = temp; % insert a new vector in it 248 | fnow = fitnessf(Kn, P, E); 249 | if fnow > fori 250 | K = Kn; 251 | Kori = Kn; 252 | else 253 | K = Kori; 254 | end 255 | end 256 | end 257 | 258 | end 259 | 260 | function [D, isupdate] = vns(Dori, P, E) 261 | % vns algorithm 262 | % input: distribute function 263 | % output: upgraded distribute function, whether to update the matrix 264 | Nmax = 3; 265 | Klmax = 3; 266 | isupdate = false; 267 | n = 1; 268 | while n <= Nmax 269 | k = 1; 270 | while k <= Klmax 271 | fori = fitnessf(Dori, P, E); 272 | Dn = neighborhoodchange(Dori, k, P, E); % proccede k-th neighborhood structrue 273 | fnow = fitnessf(Dn, P, E); 274 | if fnow > fori 275 | Du = Dn; 276 | Dori = Dn; 277 | k = 0; 278 | isupdate = true; 279 | else 280 | Du = Dori; 281 | end 282 | k = k+1; 283 | end 284 | n = n+1; 285 | 286 | end 287 | D = Du; 288 | end 289 | 290 | %% VI.VNS-PSO algorithm 291 | function Result = vnspso(P, E) 292 | % mixed PSO algorithm 293 | % input: information of pursuer and evader 294 | % ouput: distribute matrix 295 | 296 | % obtain number of P and E 297 | [numP,temp,temp] = size(P); 298 | [numE,temp,temp] = size(E); 299 | % coefficients 300 | c1 = 1.1931; 301 | c2 = 1.1931; 302 | omg = 0.87; 303 | maxgen = 100; % number of iterations 304 | sizepop = 50; % Population size 305 | Vmax = 1; % limits of velocity 306 | Vmin = -1; 307 | popmax = 1; % limits of position 308 | popmin = 0; 309 | 310 | % original population 311 | for i = 1:sizepop 312 | % obtain a particle swarm randomly 313 | popi = popmin + (popmax - popmin)*rand(numP, numE); 314 | for k = 1:numP 315 | popi(k,:) = popi(k,:)/sum(popi(k,:)); 316 | end 317 | pop(i,:,:) = popi; % original postion 318 | V(i,:,:) = Vmin + (Vmax - Vmin)*rand(numP, numE); % original velocity 319 | % caculate fitness value 320 | fitness(i) = fitnessf(squeeze(pop(i,:,:)), P, E); 321 | end 322 | 323 | % Individual and global extremums of the initial population 324 | [bestfitness bestindex] = max(fitness); 325 | zbest = pop(bestindex,:,:); % global extremums 326 | gbest = pop; % Individual extremums 327 | fitnessgbest = fitness; % Individual extremums fitness value 328 | fitnesszbest = bestfitness; % global extremums fitness value 329 | 330 | 331 | 332 | % iterations 333 | for i = 1:maxgen 334 | for j = 1:sizepop 335 | % velocity update 336 | V(j,:,:) = omg*V(j,:,:) + c1*rand*(gbest(j,:,:) - pop(j,:,:)) + c2*rand*(zbest - pop(j,:,:)); 337 | 338 | % position update 339 | pop(j,:,:) = pop(j,:,:) + V(j,:,:); 340 | pop(j,find(pop(j,:,:)<0)) = 0; 341 | popj = squeeze(pop(j,:,:)); 342 | for k = 1:numP 343 | popj(k,:) = popj(k,:)/sum(popj(k,:)); 344 | end 345 | pop(j,:,:) = popj; 346 | 347 | % caculate fitness value 348 | fitness(j) = fitnessf(squeeze(pop(j,:,:)), P, E); 349 | 350 | Fhistory(i, j) = fitness(j); 351 | 352 | 353 | end 354 | for j = 1:sizepop 355 | % individual extremum update 356 | if fitness(j) > fitnessgbest(j) 357 | gbest(j,:,:) = pop(j,:,:); 358 | fitnessgbest(j) = fitness(j); 359 | end 360 | 361 | % global extremum update 362 | if fitness(j) > fitnesszbest 363 | zbest = pop(j,:,:); 364 | fitnesszbest = fitness(j); 365 | end 366 | end 367 | % vns strategy 368 | for j = 1:sizepop 369 | popj = squeeze(pop(j,:,:)); 370 | if i > 3 371 | if (Fhistory(i, j) - Fhistory(i-1, j)) < 1e-4 372 | if (Fhistory(i, j) - Fhistory(i-2, j)) < 1e-4 373 | if mod(i, 15) == 0 374 | if j == 1 375 | disp('vns going'); 376 | end 377 | omg = 0.4; 378 | % vns strategy 379 | [popjn, isupdate] = vns(popj, P, E); 380 | pop(j,:,:) = popjn; 381 | tmptfitness = fitnessf(popjn, P, E); 382 | % individual extremum update 383 | if isupdate 384 | gbest(j,:,:) = popjn; 385 | fitnessgbest(j) = tmptfitness; 386 | end 387 | % global extremum update 388 | if tmptfitness > fitnesszbest 389 | zbest = pop(j,:,:); 390 | fitnesszbest = tmptfitness; 391 | end 392 | end 393 | end 394 | end 395 | end 396 | 397 | end 398 | 399 | yy(i) = fitnesszbest; % fitness value each iteration 400 | disp(i); 401 | disp(squeeze(pop(1, :, :))); 402 | end 403 | 404 | %save('bestfitness.mat','yy'); 405 | % figure; 406 | % plot(yy); 407 | % figure; 408 | % plot(Fhistory(:,1)); 409 | % xlabel('iterations'); 410 | % ylabel('fitness of one single particle'); 411 | % disp(Fhistory(:,1)'); 412 | Result = yy(maxgen); 413 | disp('ultimate distribute matrix:'); 414 | disp(squeeze(zbest)); 415 | disp('ultimate fitness value:'); 416 | disp(Result); 417 | 418 | end 419 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hybrid-Particle-Swarm-Optimization-Algorithm 2 | 一种混合VNS(变邻域搜索算法)的PSO(粒子群优化算法)用以解决拦截对抗中的任务分配问题,新的算法能够有效地避免粒子群陷入局部收敛,并且解决离散优化问题 3 | --------------------------------------------------------------------------------