Sunteți pe pagina 1din 21

Particle Swarm Optimization

1.1 Notiuni generale

În domeniul informaticii, optimizarea roboților de particule (PSO) este o metodă


computațională care optimizează o problemă încercând în mod iterativ să îmbunătățească
o soluție candidată cu privire la o anumită măsură de calitate. Rezolvă o problemă prin
faptul că are o populație de soluții candidate, numite particule de aici, și care le mută pe
acestea în spațiul de căutare, conform formulelor matematice simple, asupra poziției și
vitezei particulelor. Fiecare mișcare a particulelor este influențată de poziția sa cea mai
cunoscută locală, dar este, de asemenea, îndrumată spre cele mai cunoscute poziții din
spațiul de căutare, care sunt actualizate deoarece pozițiile mai bune sunt găsite de alte
particule. Acest lucru este de așteptat pentru a muta roi către cele mai bune soluții.

PSO este atribuită inițial lui Kennedy, Eberhart și Shi și a fost inițial destinată simulării
comportamentului social, ca o reprezentare stilizată a mișcării organismelor într-o turmă
de păsări sau pe o școală de pești. Algoritmul a fost simplificat și sa observat o
performanță optimizată. Cartea lui Kennedy și Eberhart descrie multe aspecte filosofice
ale PSO și inteligența roiurilor. Un sondaj amplu al aplicațiilor PSO este realizat de Poli
o revizuire cuprinzătoare a lucrărilor teoretice și experimentale privind PSO a fost
publicată de Bonyadi și Michalewicz.

Taxonomie

Particle Swarm Optimization aparține domeniului Inteligenței Swarm și a Inteligenței Colective


și este un sub-câmp al Inteligenței Computaționale. Particle Swarm Optimization este legată de
alți algoritmi Swarm Intelligence, cum ar fi Ant Colony Optimization și este un algoritm de bază
pentru numeroase variații, prea numeroase pentru a fi enumerate.

Inspirație

Particle Swarm Optimization este inspirată de comportamentul social de hrănire a unor animale,
cum ar fi comportamentul flocking al păsărilor și comportamentul școlar al peștilor.

Metaforă
Particulele din roiuri zburau printr-un mediu urmând membrii instalatori ai roiului și, în general,
influențează mișcarea lor spre zone istorice bune din mediul lor.
Strategie

Scopul algoritmului este de a avea localizate toate particulele optime într-un hiper-volum
multidimensional. Acest lucru se realizează prin atribuirea unor poziții aleatorii inițial tuturor
particulelor din spațiu și a vitezelor inițiale mici aleatorii. Algoritmul este executat ca o simulare,
avansând poziția fiecărei particule în funcție de viteza sa, poziția globală cea mai cunoscută în
spațiul problemei și cea mai bună poziție cunoscută unei particule. Funcția obiectiv este
prelevată după fiecare actualizare a poziției. De-a lungul timpului, printr-o combinație de
explorare și exploatare a unor poziții bune cunoscute în spațiul de căutare, particulele se ciocnesc
sau converg în jurul unei optime sau mai multe optime.

Particle Swarm Optimization ar putea părea complicat, dar este într-adevăr un algoritm foarte
simplu. Pe o serie de iterații, un grup de variabile are valorile lor ajustate mai aproape de
membrul a cărui valoare este mai apropiată de țintă la un moment dat. Imaginați-vă o turmă de
păsări care circulă într-o zonă în care pot mirosi o sursă ascunsă de hrană. Cel care este cel mai
apropiat de mâncare îi șuieră pe cel mai tare și pe celelalte păsări care se plimba în direcția lui.

Dacă oricare dintre celelalte păsări înconjurătoare se apropie mai mult de țintă decât de prima, se
zgâlțâie și ceilalți se îndreaptă spre el. Acest model de strângere continuă până când una dintre
păsări se va întâmpla asupra mâncării. Este un algoritm simplu și ușor de implementat.

Algoritmul ține evidența a trei variabile globale:

 Valoarea sau condiția țintă;


 Valoarea globală cea mai bună (gBest) indicând datele particulelor care sunt în prezent
cele mai apropiate de țintă;
 Oprirea valorii care indică momentul în care algoritmul ar trebui să se oprească dacă nu
se găsește obiectivul.

Fiecare particulă constă din:

 Datele reprezintă o soluție posibilă;


 valoare a vitezei care indică cât de mult pot fi modificate datele;
 valoare personală cea mai bună (pBest) indicând cea mai apropiată;
 Datele particulelor au apărut vreodată la Tinta.

1.2 Pseudocod-algoritm

O variantă de bază a algoritmului PSO funcționează prin faptul că are o populație (numită
roi) de soluții candidate (numite particule). Aceste particule sunt deplasate în spațiul de
căutare conform câtorva formule simple. Mișcările particulelor sunt ghidate de poziția lor
cea mai cunoscută în spațiul de căutare, precum și de poziția cea mai cunoscută a
întregului roi. Atunci când sunt descoperite poziții îmbunătățite, acestea vor veni apoi
pentru a ghida mișcările roiului. Procesul este repetat și, în acest fel, se speră, dar nu este
garantat, că în cele din urmă va fi găsită o soluție satisfăcătoare. În mod formal, permiteți
f: ℝn → ℝ să fie funcția de cost care trebuie minimizată. Funcția ia o soluție candidată ca
argument în forma unui vector de numere reale și produce un număr real ca ieșire care
indică valoarea funcției obiective a soluției candidat date. Gradientul f nu este cunoscut.
Scopul este de a găsi o soluție a pentru care f (a) ≤ f (b) pentru toate b în spațiul de
căutare, ceea ce ar însemna a este minimul global. Maximizarea poate fi efectuată luând
în considerare funcția h = -f. Fie S numărul de particule din roi, fiecare având o poziție xi
∈ ℝn în spațiul de căutare și o viteză vi ∈ ℝn. Fie Pi cea mai cunoscuta pozitie a
particulei i si g este cea mai cunoscuta pozitie a intregului roi.

Este, de asemenea, obișnuit să se vadă algoritmi PSO care utilizează topologii


populaționale sau "cartiere", care pot fi submulțimi mai mici, localizate la cea mai bună valoare
globală. Aceste cartiere pot implica două sau mai multe particule care sunt predeterminate să
acționeze împreună sau submulțimi ale spațiului de căutare pe care particulele se întâmplă în
timpul testării. Folosirea cartierelor ajuta adesea algoritmul sa evite blocarea in minimele locale

Figura 1. Câteva topologii populaționale obișnuite (cartiere). (A) Persoane cu o singură vedere,
în care persoanele se compară numai cu cele mai bune rezultate. (B) Topologia inelului, în care
fiecare persoană se compară numai cu cele din stânga și din dreapta. (C) Topologie complet
conectată, unde toată lumea este comparată. (D) Izolate, în cazul în care indivizii se compară
numai cu cei din grupurile specificate.

Definirea vecinătății și modul în care sunt utilizate au efecte diferite asupra comportamentului
algoritmului.
The Algorithm

Figura 2. Diagrama de flux care ilustrează algoritmul de optimizare a globului de


particule.

Pseudo Code
For each particle
{
Initialize particle
}

Do until maximum iterations or minimum error criteria


{
For each particle
{
Calculate Data fitness value
If the fitness value is better than pBest
{
Set pBest = current fitness value
}
If pBest is better than gBest
{
Set gBest = pBest
}
}

For each particle


{
Calculate particle Velocity
Use gBest and Velocity to update particle Data
}

Acesta este un exemplu simplu în care algoritmul găsește trei numere care ajung până la o valoare țintă.
Se utilizează un cartier complet conectat, astfel încât toate particulele pot fi comparate unele cu altele.

TARGET - răspunsul pe care îl caută algoritmul.


MAX_INPUTS - acest număr de operanzi în expresie.
MAX_PARTICLES - numărul de particule utilizate în test.
V_MAX - permisă modificarea vitezei maxime.
MAX_EPOCHS - număr de iterații pentru algoritm.
START_RANGE_MIN - cel mai mic număr aleator pentru a porni operanții la.
START_RANGE_MAX - cel mai mare număr aleator pentru a porni operanții la.

Destul de usor. Găsiți trei operanzi care adaugă până la 50. Zece particule folosite. V_MAX = 10
Exemplu rezultat 1:

47 + -3 + 8 = 52
27 + 3 + 10 = 40
41 + 6 + 31 = 78
47 + 40 + -4 = 83
41 + -3 + 30 = 68
6 + 14 + 35 = 55
3 + 11 + 36 = 50
47 + 2 + 9 = 58
40 + -3 + 29 = 66
1 + 8 + 11 = 20
epoch number: 21
Particle 6 has achieved target.
3 + 11 + 36 = 50

Zece operanzi și 20 de particule. V_MAX = 10. De obicei, algoritmul funcționează puțin mai greu pentru a găsi
soluția.

Exemplu rezultat 2:
5 + -3 + 18 + 12 + 9 + 15 + 16 + 27 + -17 + -1 = 81
11 + 29 + -5 + 15 + -11 + 15 + -9 + 12 + -1 + 6 = 62
-10 + -2 + 5 + 12 + 14 + 21 + -23 + 10 + 5 + -5 = 27
23 + -10 + -3 + 12 + -9 + 1 + 7 + 8 + -42 + -15 = -28
23 + 1 + -9 + 12 + -12 + 23 + -9 + 12 + -1 + 10 = 50
22 + 19 + 36 + 8 + -18 + 3 + 36 + -17 + -1 + 0 = 88
-10 + -3 + 7 + 12 + 15 + 11 + 24 + -7 + 15 + -18 = 46
0 + -16 + -9 + -3 + 9 + 15 + 15 + 22 + 5 + 10 = 48
-10 + 25 + 30 + 12 + -18 + -3 + -9 + -7 + -1 + 10 = 29
0 + 2 + -9 + 12 + -1 + 6 + 26 + 7 + -36 + -17 = -10
-9 + -11 + -4 + 12 + -10 + 15 + -30 + 17 + 14 + -20 = -26
18 + -5 + 21 + -22 + -1 + 5 + 26 + 17 + 23 + -21 = 61
-20 + -17 + -10 + -8 + -1 + 6 + 13 + 14 + 21 + -8 = -10
23 + 1 + -1 + -18 + 7 + 13 + 9 + 18 + 25 + -6 = 71
23 + 25 + -9 + 12 + 26 + -19 + -9 + -7 + -1 + 10 = 51
-13 + 25 + 1 + 7 + 26 + -19 + -9 + 7 + -35 + -16 = -26
-11 + -4 + 21 + 3 + 9 + 20 + 36 + 9 + -15 + -5 = 63
20 + 2 + -14 + 3 + 18 + 21 + -9 + 25 + -1 + 10 = 75
0 + -12 + -9 + 12 + -7 + 4 + 7 + 14 + -1 + 10 = 18
4 + 6 + 34 + -20 + 8 + 23 + -9 + -25 + -18 + 10 = 13
epoch number: 103
Particle 4 has achieved target.
23 + 1 + -9 + 12 + -12 + 23 + -9 + 12 + -1 + 10 = 50

Java Code:

import java.util.ArrayList;
import java.util.Random;

public class Swarm_Ex1


{
private static final int TARGET = 50;
private static final int MAX_INPUTS = 3;
private static final int MAX_PARTICLES = 20;
private static final int V_MAX = 10; // Maximum velocity change
allowed.

private static final int MAX_EPOCHS = 200;


// The particles will be initialized with data randomly chosen within the range
// of these starting min and max values:
private static final int START_RANGE_MIN = 140;
private static final int START_RANGE_MAX = 190;

private static ArrayList<Particle> particles = new ArrayList<Particle>();

private static void initialize()


{
for(int i = 0; i < MAX_PARTICLES; i++)
{
Particle newParticle = new Particle();
int total = 0;
for(int j = 0; j < MAX_INPUTS; j++)
{
newParticle.data(j, getRandomNumber(START_RANGE_MIN,
START_RANGE_MAX));
total += newParticle.data(j);
} // j
newParticle.pBest(total);
particles.add(newParticle);
} // i
return;
}

private static void PSOAlgorithm()


{
int gBest = 0;
int gBestTest = 0;
Particle aParticle = null;
int epoch = 0;
boolean done = false;

initialize();

while(!done)
{
// Two conditions can end this loop:
// if the maximum number of epochs allowed has been reached, or,
// if the Target value has been found.
if(epoch < MAX_EPOCHS){

for(int i = 0; i < MAX_PARTICLES; i++)


{
aParticle = particles.get(i);
for(int j = 0; j < MAX_INPUTS; j++)
{
if(j < MAX_INPUTS - 1){
System.out.print(aParticle.data(j) + " + ");
}else{
System.out.print(aParticle.data(j) + " = ");
}
} // j

System.out.print(testProblem(i)+ "\n");
if(testProblem(i) == TARGET){
done = true;
}
} // i

gBestTest = minimum();
aParticle = particles.get(gBest);
// if(any particle's pBest value is better than the gBest value, make
it the new gBest value.
if(Math.abs(TARGET - testProblem(gBestTest)) < Math.abs(TARGET -
testProblem(gBest))){
gBest = gBestTest;
}

getVelocity(gBest);

updateparticles(gBest);

System.out.println("epoch number: " + epoch);

epoch += 1;

}else{
done = true;
}
}
return;
}
private static void getVelocity(int gBestindex)
{
// from Kennedy & Eberhart(1995).
// vx[][] = vx[][] + 2 * rand() * (pbestx[][] - presentx[][]) +
// 2 * rand() * (pbestx[][gbest] - presentx[][])

int testResults = 0;
int bestResults = 0;
double vValue = 0.0;
Particle aParticle = null;

bestResults = testProblem(gBestindex);

for(int i = 0; i < MAX_PARTICLES; i++)


{
testResults = testProblem(i);
aParticle = particles.get(i);
vValue = aParticle.velocity() + 2 * new Random().nextDouble() *
(aParticle.pBest() - testResults) + 2 * new Random().nextDouble() * (bestResults -
testResults);

if(vValue > V_MAX){


aParticle.velocity(V_MAX);
}else if(vValue < -V_MAX){
aParticle.velocity(-V_MAX);
}else{
aParticle.velocity(vValue);
}
}
return;
}

private static void updateparticles(int gBestindex)


{
Particle gBParticle = particles.get(gBestindex);

for(int i = 0; i < MAX_PARTICLES; i++)


{
for(int j = 0; j < MAX_INPUTS; j++)
{
if(particles.get(i).data(j) != gBParticle.data(j)){
particles.get(i).data(j, particles.get(i).data(j) +
(int)Math.round(particles.get(i).velocity()));
}
} // j

// Check pBest value.


int total = testProblem(i);
if(Math.abs(TARGET - total) < particles.get(i).pBest()){
particles.get(i).pBest(total);
}

} // i
return;
}

private static int testProblem(int index)


{
int total = 0;
Particle aParticle = null;

aParticle = particles.get(index);
for(int i = 0; i < MAX_INPUTS; i++)
{
total += aParticle.data(i);
}
return total;
}

private static void printSolution()


{
// Find solution particle.
int i = 0;
for(; i < particles.size(); i++)
{
if(testProblem(i) == TARGET){
break;
}
}
// Print it.
System.out.println("Particle " + i + " has achieved target.");
for(int j = 0; j < MAX_INPUTS; j++)
{
if(j < MAX_INPUTS - 1){
System.out.print(particles.get(i).data(j) + " + ");
}else{
System.out.print(particles.get(i).data(j) + " = " + TARGET);
}
} // j
System.out.print("\n");
return;
}

private static int getRandomNumber(int low, int high)


{
return (int)((high - low) * new Random().nextDouble() + low);
}

private static int minimum()


{
// Returns an array index.
int winner = 0;
boolean foundNewWinner = false;
boolean done = false;

while(!done)
{
foundNewWinner = false;
for(int i = 0; i < MAX_PARTICLES; i++)
{
if(i != winner){ // Avoid self-comparison.
// The minimum has to be in relation to the Target.
if(Math.abs(TARGET - testProblem(i)) < Math.abs(TARGET -
testProblem(winner))){
winner = i;
foundNewWinner = true;
}
}
}

if(foundNewWinner == false){
done = true;
}
}
return winner;
}

private static class Particle


{
private int mData[] = new int[MAX_INPUTS];
private int mpBest = 0;
private double mVelocity = 0.0;

public Particle()
{
this.mpBest = 0;
this.mVelocity = 0.0;
}

public int data(int index)


{
return this.mData[index];
}

public void data(int index, int value)


{
this.mData[index] = value;
return;
}

public int pBest()


{
return this.mpBest;
}

public void pBest(int value)


{
this.mpBest = value;
return;
}

public double velocity()


{
return this.mVelocity;
}

public void velocity(double velocityScore)


{
this.mVelocity = velocityScore;
return;
}
} // Particle

public static void main(String[] args)


{
PSOAlgorithm();
printSolution();
return;
}

}
Result:

Aceasta este o interpretare a problemei clasice a comis voiajorului, unde cel mai scurt tur trebuie
să fie găsit în rândul tuturor oraselor, fără să-l viziteze de două ori. Algoritmul execută distanța
minimă carteziană prin opt orașe numite 0, 1, 2, 3, 4, 5, 6 și 7. Există 88 (sau 16.777.216)
combinații posibile, dar acest algoritm le poate găsi în mai puțin de 83, și uneori mai puțin de 82!
Locațiile orașelor sunt (30, 5), (40, 10), (40, 20), (29, 25), (19, 25), (9, 19) 5). Acesta este
aproximativ un cerc; ceva ușor de văzut pe un grafic și verificați soluțiile algoritmului cu. Sunt
explorate toate modurile de combinare folosind șiruri de opt cifre de la 0 la 7 pentru a găsi cea
care reprezintă distanța cea mai scurtă (adică, 01234567). Cu mâna, am găsit soluția de
aproximativ 86.6299, care este valoarea țintă a algoritmului. Pentru a simplifica acest exemplu,
nu există nici un punct de pornire sau final, și nu contează în ce direcție merge turul (adică
înainte sau înapoi).
De exemplu, o soluție care arată ca 34567012 este validă deoarece se deplasează înainte de la 3
și în jurul valorii de 2. Soluția 76543210 este la fel de valabilă, merge doar înapoi de la 7 la 0.
M-am decis să iau cu ușurință un algoritm PSO ușor diferit. Am adăugat cel mai grav la nivel
global variabilelor globale. Scorul de viteză se calculează folosind viteza globală cea mai
defavorabilă, definind viteza ca măsură a cât de rău se face fiecare particulă (spre deosebire de
cât de bun). Modificarea datelor se face prin schimbarea cifrelor din cadrul fiecărui set de date
particulare. Valoarea schimbării depinde de cât de rău se face (adică, viteza). Particulele sunt
împinse încet către cel mai bun la nivel mondial, prin copierea unor fragmente din cele mai bune
date ale particulelor (topologie cu o singură perspectivă). Schimbarea și copierea se fac pentru
toate particulele, cu excepția celor mai bune la nivel mondial. În acest exemplu, pot fi
experimentate doar trei variabile: PARTICLE_COUNT - numărul de particule utilizate în test.
V_MAX - permisă modificarea vitezei maxime. MAX_EPOCHS - număr de iterații pentru
algoritm.

Exemplu rezultat 1
PARTICLE_COUNT = 10, V_MAX = 4, MAX_EPOCHS = 10000.
Route: 2, 3, 4, 6, 5, 7, 0, 1, Distance: 99.93584193997158
Route: 2, 7, 3, 4, 6, 5, 0, 1, Distance: 132.21887327932137
Route: 6, 4, 7, 3, 5, 0, 1, 2, Distance: 161.01823909844032
Route: 4, 7, 0, 5, 2, 6, 1, 3, Distance: 178.79093664436735
Route: 3, 6, 1, 5, 0, 4, 7, 2, Distance: 194.08096028878091
Route: 4, 6, 0, 7, 2, 1, 5, 3, Distance: 148.4061583915042
Route: 7, 0, 1, 2, 3, 4, 5, 6, Distance: 86.62998956150375
Route: 5, 2, 3, 6, 7, 0, 1, 4, Distance: 139.06558715090466
Route: 7, 2, 3, 6, 0, 4, 5, 1, Distance: 171.45598237170142
Route: 2, 3, 0, 4, 6, 1, 5, 7, Distance: 179.90206048967966
Changes for particle 1: 2
Changes for particle 2: 2
Changes for particle 3: 2
Changes for particle 4: 3
Changes for particle 5: 3
Changes for particle 6: 3
Changes for particle 7: 3
Changes for particle 8: 3
Changes for particle 9: 4
epoch number: 85
Target reached.
Shortest Route: 7, 0, 1, 2, 3, 4, 5, 6, Distance: 86.62998956150375

Exemplu rezultat 2
PARTICLE_COUNT = 4, V_MAX = 4, MAX_EPOCHS = 10000. Fewer workers usually means longer to
finish.
Route: 2, 0, 7, 6, 5, 4, 3, 1, Distance: 99.99543531546844
Route: 6, 0, 7, 1, 2, 3, 4, 5, Distance: 105.73803621780542
Route: 0, 1, 2, 3, 4, 5, 6, 7, Distance: 86.62998956150375
Route: 7, 0, 3, 4, 5, 6, 1, 2, Distance: 127.70301302273303
Changes for particle 1: 3
Changes for particle 2: 3
Changes for particle 3: 4
epoch number: 801
Target reached.
Shortest Route: 0, 1, 2, 3, 4, 5, 6, 7, Distance: 86.62998956150375

Exemplu rezultat 3
PARTICLE_COUNT = 10, V_MAX = 8, MAX_EPOCHS = 10000. Increasing the velocity using the
implementation in this code has little effect.
Route: 0, 7, 5, 6, 4, 3, 2, 1, Distance: 99.93584193997157
Route: 1, 0, 7, 6, 5, 4, 3, 2, Distance: 86.62998956150375
Route: 6, 4, 1, 5, 2, 3, 0, 7, Distance: 161.78381796573566
Route: 5, 2, 3, 0, 4, 1, 6, 7, Distance: 172.28187399281768
Route: 1, 6, 4, 0, 2, 3, 5, 7, Distance: 162.1209488352703
Route: 0, 1, 3, 2, 7, 5, 6, 4, Distance: 136.36234159873652
Route: 0, 3, 6, 5, 1, 2, 7, 4, Distance: 165.76791494289756
Route: 6, 5, 4, 7, 0, 3, 1, 2, Distance: 133.2067162232275
Route: 7, 3, 1, 2, 4, 6, 5, 0, Distance: 136.2266417744836
Route: 6, 5, 7, 3, 1, 4, 2, 0, Distance: 155.1366049017671
Changes for particle 1: 4
Changes for particle 2: 6
Changes for particle 3: 6
Changes for particle 4: 6
Changes for particle 5: 7
Changes for particle 6: 7
Changes for particle 7: 7
Changes for particle 8: 7
Changes for particle 9: 8
epoch number: 221
Target reached.
Shortest Route: 1, 0, 7, 6, 5, 4, 3, 2, Distance: 86.62998956150375

import java.util.ArrayList;
import java.util.Random;

public class Swarm_Ex2b


{
private static final int PARTICLE_COUNT = 10;
private static final int V_MAX = 4; // Maximum velocity change allowed.
// Range: 0 >= V_MAX < CITY_COUNT

private static final int MAX_EPOCHS = 10000;

private static ArrayList<Particle> particles = new ArrayList<Particle>();

private static ArrayList<cCity> map = new ArrayList<cCity>();


private static final int CITY_COUNT = 8;
private static final double TARGET = 86.63;
// Number for algorithm to find.
private static int XLocs[] = new int[] {30, 40, 40, 29, 19, 9, 9, 20};
private static int YLocs[] = new int[] {5, 10, 20, 25, 25, 19, 9, 5};

private static void initializeMap()


{
for(int i = 0; i < CITY_COUNT; i++)
{
cCity city = new cCity();
city.x(XLocs[i]);
city.y(YLocs[i]);
map.add(city);
}
return;
}

private static void PSOAlgorithm()


{
Particle aParticle = null;
int epoch = 0;
boolean done = false;

initialize();

while(!done)
{
// Two conditions can end this loop:
// if the maximum number of epochs allowed has been reached, or,
// if the Target value has been found.
if(epoch < MAX_EPOCHS){

for(int i = 0; i < PARTICLE_COUNT; i++)


{
aParticle = particles.get(i);
System.out.print("Route: ");
for(int j = 0; j < CITY_COUNT; j++)
{
System.out.print(aParticle.data(j) + ", ");
} // j

getTotalDistance(i);
System.out.print("Distance: " + aParticle.pBest() + "\n");
if(aParticle.pBest() <= TARGET){
done = true;
}
} // i

bubbleSort(); // sort particles by their pBest scores, best to


worst.

getVelocity();

updateparticles();
System.out.println("epoch number: " + epoch);

epoch++;

}else{
done = true;
}
}
return;
}

private static void initialize()


{
for(int i = 0; i < PARTICLE_COUNT; i++)
{
Particle newParticle = new Particle();
for(int j = 0; j < CITY_COUNT; j++)
{
newParticle.data(j, j);
} // j
particles.add(newParticle);
for(int j = 0; j < 10; j++)
{
randomlyArrange(particles.indexOf(newParticle));
}
getTotalDistance(particles.indexOf(newParticle));
} // i
return;
}

private static void randomlyArrange(final int index)


{
int cityA = new Random().nextInt(CITY_COUNT);
int cityB = 0;
boolean done = false;
while(!done)
{
cityB = new Random().nextInt(CITY_COUNT);
if(cityB != cityA){
done = true;
}
}

int temp = particles.get(index).data(cityA);


particles.get(index).data(cityA, particles.get(index).data(cityB));
particles.get(index).data(cityB, temp);
return;
}

private static void getVelocity()


{
double worstResults = 0;
double vValue = 0.0;

// after sorting, worst will be last in list.


worstResults = particles.get(PARTICLE_COUNT - 1).pBest();

for(int i = 0; i < PARTICLE_COUNT; i++)


{
vValue = (V_MAX * particles.get(i).pBest()) / worstResults;

if(vValue > V_MAX){


particles.get(i).velocity(V_MAX);
}else if(vValue < 0.0){
particles.get(i).velocity(0.0);
}else{
particles.get(i).velocity(vValue);
}
}
return;
}

private static void updateparticles()


{
// Best is at index 0, so start from the second best.
for(int i = 1; i < PARTICLE_COUNT; i++)
{
// The higher the velocity score, the more changes it will need.
int changes = (int)Math.floor(Math.abs(particles.get(i).velocity()));
System.out.println("Changes for particle " + i + ": " + changes);
for(int j = 0; j < changes; j++){
if(new Random().nextBoolean()){
randomlyArrange(i);
}
// Push it closer to it's best neighbor.
copyFromParticle(i - 1, i);
} // j

// Update pBest value.


getTotalDistance(i);
} // i

return;
}

private static void printBestSolution()


{
if(particles.get(0).pBest() <= TARGET){
// Print it.
System.out.println("Target reached.");
}else{
System.out.println("Target not reached");
}
System.out.print("Shortest Route: ");
for(int j = 0; j < CITY_COUNT; j++)
{
System.out.print(particles.get(0).data(j) + ", ");
} // j
System.out.print("Distance: " + particles.get(0).pBest() + "\n");
return;
}

private static void copyFromParticle(final int source, final int destination)


{
// push destination's data points closer to source's data points.
Particle best = particles.get(source);
int targetA = new Random().nextInt(CITY_COUNT); // source's city to
target.
int targetB = 0;
int indexA = 0;
int indexB = 0;
int tempIndex = 0;

// targetB will be source's neighbor immediately succeeding targetA


(circular).
int i = 0;
for(; i < CITY_COUNT; i++)
{
if(best.data(i) == targetA){
if(i == CITY_COUNT - 1){
targetB = best.data(0); // if end of array,
take from beginning.
}else{
targetB = best.data(i + 1);
}
break;
}
}

// Move targetB next to targetA by switching values.


for(int j = 0; j < CITY_COUNT; j++)
{
if(particles.get(destination).data(j) == targetA){
indexA = j;
}
if(particles.get(destination).data(j) == targetB){
indexB = j;
}
}
// get temp index succeeding indexA.
if(indexA == CITY_COUNT - 1){
tempIndex = 0;
}else{
tempIndex = indexA + 1;
}

// Switch indexB value with tempIndex value.


int temp = particles.get(destination).data(tempIndex);
particles.get(destination).data(tempIndex,
particles.get(destination).data(indexB));
particles.get(destination).data(indexB, temp);

return;
}

private static void getTotalDistance(final int index)


{
Particle thisParticle = null;
thisParticle = particles.get(index);
thisParticle.pBest(0.0);

for(int i = 0; i < CITY_COUNT; i++)


{
if(i == CITY_COUNT - 1){
thisParticle.pBest(thisParticle.pBest() +
getDistance(thisParticle.data(CITY_COUNT - 1), thisParticle.data(0))); // Complete
trip.
}else{
thisParticle.pBest(thisParticle.pBest() +
getDistance(thisParticle.data(i), thisParticle.data(i + 1)));
}
}
return;
}

private static double getDistance(final int firstCity, final int secondCity)


{
cCity cityA = null;
cCity cityB = null;
double a2 = 0;
double b2 = 0;
cityA = map.get(firstCity);
cityB = map.get(secondCity);
a2 = Math.pow(Math.abs(cityA.x() - cityB.x()), 2);
b2 = Math.pow(Math.abs(cityA.y() - cityB.y()), 2);

return Math.sqrt(a2 + b2);


}

private static void bubbleSort()


{
boolean done = false;
while(!done)
{
int changes = 0;
int listSize = particles.size();
for(int i = 0; i < listSize - 1; i++)
{
if(particles.get(i).compareTo(particles.get(i + 1))
== 1){
Particle temp = particles.get(i);
particles.set(i, particles.get(i + 1));
particles.set(i + 1, temp);
changes++;
}
}
if(changes == 0){
done = true;
}
}
return;
}

private static class Particle implements Comparable<Particle>


{
private int mData[] = new int[CITY_COUNT];
private double mpBest = 0;
private double mVelocity = 0.0;

public Particle()
{
this.mpBest = 0;
this.mVelocity = 0.0;
}

public int compareTo(Particle that)


{
if(this.pBest() < that.pBest()){
return -1;
}else if(this.pBest() > that.pBest()){
return 1;
}else{
return 0;
}
}

public int data(final int index)


{
return this.mData[index];
}
public void data(final int index, final int value)
{
this.mData[index] = value;
return;
}

public double pBest()


{
return this.mpBest;
}

public void pBest(final double value)


{
this.mpBest = value;
return;
}

public double velocity()


{
return this.mVelocity;
}

public void velocity(final double velocityScore)


{
this.mVelocity = velocityScore;
return;
}
} // Particle

private static class cCity


{
private int mX = 0;
private int mY = 0;

public int x()


{
return mX;
}

public void x(final int xCoordinate)


{
mX = xCoordinate;
return;
}

public int y()


{
return mY;
}

public void y(final int yCoordinate)


{
mY = yCoordinate;
return;
}
} // cCity

public static void main(String[] args)


{
initializeMap();
PSOAlgorithm();
printBestSolution();
return;
}

Concluzii

PSO este o metaheuristică deoarece face puține presupuneri sau nu despre problema
optimizată și poate căuta spații foarte mari ale soluțiilor candidate. Cu toate acestea,
metaheuristica, cum ar fi PSO, nu garantează găsirea unei soluții optime. De asemenea,
PSO nu folosește gradientul problemei care este optimizat, ceea ce înseamnă că PSO nu
necesită ca problema optimizării să fie diferențiată așa cum este cerută de metodele
clasice de optimizare cum ar fi coborârea gradientului și metodele cvasi-newton.
De asemenea aceasta metoda poate fi folosita in domeniul energiei si a producerii de
piese de conectivitate pentru ca se folosesc semiautomate care pot fi rulate prin Java si se
poate face o optimizare mai usoara a pieselor de conectivitate produse.

Bibliografie:

http://mnemstudio.org/particle-swarm-example-1.htm
https://www.mathworks.com/help/gads/particle-swarm-optimization-
algorithm.html?requestedDomain=true
http://ieeexplore.ieee.org/document/488968/

[Eberhart1995] R. C. Eberhart and J. Kennedy, "A new optimizer using particle


swarm theory", in Proceedings of the sixth international symposium
on micro machine and human science, 1995.

[Kennedy1995] J. Kennedy and R. C. Eberhart, "Particle swarm optimization", in


Proceedings of the IEEE International Conference on Neural
Networks, 1995.

[Kennedy1999] J. Kennedy, "Small Worlds and Mega-Minds: Effects of


Neighborhood Topology on Particle Swarm Performance", in
Proceedings of the 1999 Congress on Evolutionary Computation,
1999.
[Kennedy2001] J. Kennedy and R. C. Eberhart and Y. Shi, "Swarm Intelligence",
Morgan Kaufmann, 2001.

[Poli2007] R. Poli and J. Kennedy and T. Blackwell, "Particle swarm optimization


An overview", Swarm Intelligence, 2007.

[Poli2008a] R. Poli, "Analysis of the publications on the applications of particle


swarm optimisation", Journal of Artificial Evolution and Applications,
2008.
Balan Larisa Bianca
Anul II – MCTI
Profesor universitar: Pintea Camelia

S-ar putea să vă placă și