Bereksperimen dengan Particle Swarm Optimization

Salah satu pepatah hidup yang pernah disampaikan ke saya adalah dalam hidup ini tidak ada yang ideal. kita hanya bisa melakukan yang terbaik hari ini dengan segala keterbatasan. Hal yang abstrak namun dapat diterjemahkan menjadi persoalan yang selalu dihadapi manusia adalah optimasi dengan harapan hari ini lebih baik dari hari kemarin dan hari esok lebih baik dari hari ini.

Suatu persoalan optimasi pada dasarnya dapat dideskripsikan sebagai pengaturan atau pengisian nilai sekumpulan variabel pada suatu fungsi sedemikian rupa sehingga keluaran fungsi tersebut mendekati nilai yang diharapkan (minimum atau maksimum). Fungsi tersebut dinamakan dengan fungsi objektif atau kriteria dan jika fungsi objektif dapat didekomposisi menjadi beberapa fungsi objektif yang lebih spesifik dan maka persoalan optimasi diberi label sebagai persoalan optimasi multiobjektif atau persoalan optimasi multikriteria.

Dari perkuliahan semester yang lalu ada salah satu mata kuliah yaitu intelejensia kolektif yang mengkaji tentang swarm intelligence untuk melakukan penyelesaian persoalan secara tersebar. Topik pembahasan kuliah ini secara umum membahas teknik optimasi yang berbasis pada populasi objek atau agen dan interaksinya dalam menyelesaikan persoalan bersama. beberapa teknik yang diceritakan mulai dari algoritma evolusioner seperti algoritma genetik dan pemrograman genetik, memetic algorithm, hingga ACO (Ant Colony Optimization) dan PSO (Particle Swarm Optimization). Kedua topik terakhir merupakan topik yang dibahas secara lebih mendalam lewat review (dan atau implementasi) makalah tentang topik tersebut yang kemudian dipresentasikan di depan kelas oleh masing-masing peserta. Topik tentang ACO sebelumnya sempat saya ceritakan secara umum sehingga sekarang saya akan bercerita tentang PSO.


Particle Swarm Optimization

PSO terinspirasi dari perilaku gerakan kawanan hewan seperti ikan (school of fish), hewan herbivor (herd), dan burung (flock) yang kemudian tiap objek hewan disederhanakan menjadi sebuah partikel. Suatu partikel dalam ruang memiliki posisi yang dikodekan sebagai vektor koordinat. Vektor posisi ini dianggap sebagai keadaan yang sedang ditempati oleh suatu partikel di ruang pencarian. Setiap posisi dalam ruang pencarian merupakan alternatif solusi yang dapat dievaluasi menggunakan fungsi objektif. Setiap partikel bergerak dengan kecepatan v.

Ciri khas dari PSO adalah pengaturan kecepatan partikel secara heuristik dan probabilistik. Jika suatu partikel memiliki kecepatan yang konstan maka jika jejak posisi suatu partikel divisualisasikan akan membentuk garis lurus. Dengan adanya faktor eksternal yang membelokkan garis tersebut yang kemudian menggerakkan partikel dalam ruang pencarian maka diharapkan partikel dapat mengarah, mendekati, dan pada akhirnya mencapai titik optimal. faktor eksternal yang dimaksud antara lain posisi terbaik yang pernah dikunjungi suatu partikel, posisi terbaik seluruh partikel (diasumsikan setiap partikel mengetahui posisi terbaik setiap partikel lainnya), serta faktor kreativitas untuk melakukan eksplorasi. Secara matematis deskripsi di atas ditampilkan sebagai berikut :

vi(t) = u1.k1.vi(t-1) + u2.k2.(xbestixi) + u3.k3.(xbestgxi) + u4.vacak

xbest di atas merupakan catatan khusus mengenai posisi terbaik yang pernah dikunjungi tiap partikel. Indeks g menyatakan partikel yang posisi terbaiknya merupakan posisi terbaik dibandingkan posisi partikel lainnya. vacak merupakan vektor arah acak yang diinterpretasi sebagai faktor kreativitas untuk melakukan eksplorasi. nilai skalar u1 hingga u4 merupakan variabel acak (random variate) yang terdistribusi merata (uniform distribution) sedangkan a1 hingga a4 merupakan koefisien pengaruh masing-masing suku.

Implementasi

Agar dapat bereksperimen dengan algoritma ini maka kita perlu membuat implementasinya ke dalam program. Saya telah membuat implementasi sederhana dalam delphi seperti berikut :

{bagian interface}
type
  TVector = array of real;
  TParticle = record
    Position: TVector;
    Velocity: TVector; //velocity vector
    MyBest: TVector; //personal best position
    BestCost: Real;
  end;
  TCostFunction = function( v: TVector ): real of object;

  TPSO = class
  protected
    FNumParticle: integer;
    FVectorDimension: integer;
    FBest: integer;
    FCost: TCostFunction;
  public
    FParticles: array of TParticle;
    constructor Create( NumParticle, VectorLen: integer );
    destructor Free;
    procedure Step;
    property CostFn: TCostFunction read FCost write FCost;
    property Count: integer read FNumParticle;
    property Dimension: integer read FVectorDimension;
    property BestParticle: integer read FBest;
  end;
{...}
{ bagian implementasi }
{ TPSO }

constructor TPSO.Create( NumParticle, VectorLen: integer );
var
  i                 : integer;
begin
  FNumParticle := NumParticle;
  FVectorDimension := VectorLen;
  SetLength( FParticles, NumParticle );
  for i := 0 to High( FParticles ) do begin
    SetLength( FParticles[i].Position, VectorLen );
    SetLength( FParticles[i].Velocity, VectorLen );
    SetLength( FParticles[i].MyBest, VectorLen );
  end;
  FBest := 0;
end;

destructor TPSO.Free;
var
  i                 : integer;
begin
  for i := 0 to high( FParticles ) do begin
    setlength( FParticles[i].Position, 0 );
    setlength( FParticles[i].Velocity, 0 );
    setlength( FParticles[i].MyBest, 0 );
  end;
  setlength( Fparticles, 0 );
end;

procedure TPSO.Step;
var
  i, j              : integer;
  a, b, c, d        : real;
  u1, u2, u3, u4    : real;
  cost              : real;
  rvec              : TVector;
begin
  a := 1;
  b := 1;
  c := 1;
  d := 1;
  setlength( rvec, FVectorDimension );

  for i := 0 to High( FParticles ) do begin
    u1 := random;
    u2 := random;
    u3 := random;

    u4 := random;
    for j := 0 to FVectorDimension - 1 do
      rvec[j] := random;

    //update velocity
    for j := 0 to FVectorDimension - 1 do begin
      FParticles[i].Velocity[j] :=
        u1 * a * FParticles[i].Velocity[j] //velocity inertia
        + u2 * b * ( FParticles[i].MyBest[j] - FParticles[i].Position[j] ) //personal history best
        + u3 * c * ( FParticles[FBest].MyBest[j] - FParticles[i].Position[j] ) //global best
        + u4 * d * rvec[j] //random vector for exploration
        ;
    end;
  end;

  //update position
  for i := 0 to High( FParticles ) do begin
    for j := 0 to FVectorDimension - 1 do
      FParticles[i].Position[j] := FParticles[i].Position[j] + FParticles[i].Velocity[j];

    //calculate new cost
    cost := FCost( FParticles[i].Position );

    //update mybest if necessary
    if cost < FParticles[i].BestCost then begin
      FParticles[i].BestCost := cost;
      for j := 0 to high( FParticles[i].Position ) do
        FParticles[i].MyBest[j] := FParticles[i].Position[j];
    end;
  end;

  //select global best
  for i := 0 to High( FParticles ) do
    if FParticles[i].BestCost < FParticles[FBest].BestCost then
      FBest := i;
end;

Seiring dengan kode tersebut saya juga membuat program sederhana untuk bereksperimen dengan parameter PSO. Program tersebut memiliki fungsi objektif sederhana yaitu mencari satu titik di ruang berdimensi N sehingga fungsi evaluasinya pun cukup berupa fungsi jarak euclidean antara posisi tiap partikel dengan posisi titik tujuan.

tampilan program eksperimen PSO

program eksperimen PSO

potongan kode untuk aplikasi di atas adalah sbb:

{ di bagian definisi form }
    target: TVector;
    function dist( v: TVector ): real;
{ bagian implementasi }
procedure TForm1.FormCreate( Sender: TObject );
begin
  randomize;
end;

function TForm1.dist( v: TVector ): real;
var
  i                 : integer;
  tmp               : real;
begin
  result := 0;
  for i := 0 to high( v ) do begin
    tmp := ( target[i] - v[i] );
    tmp := tmp * tmp;
    result := result + tmp;
  end;
  result := sqrt( result );
end;

procedure TForm1.Button1Click( Sender: TObject );
var
  pso               : TPSO;
  i, j              : integer;
  Dim               : integer;
  thr               : real;

  procedure display;
  const
    w               = 4;
  var
    ptgt            : TPOint;
    i               : integer;
  begin
    with Image1.Canvas do begin
      FillRect( Image1.ClientRect );
      ptgt.X := round( target[0] );
      ptgt.Y := round( target[1] );
      Pen.Color := clRed;
      Rectangle( Rect( ptgt.X - w, ptgt.Y - w, ptgt.X + w, ptgt.Y + w ) );
      Pen.Color := clBlue;
      for i := 0 to pso.Count - 1 do begin
        ptgt.X := round( pso.FParticles[i].Position[0] );
        ptgt.Y := round( pso.FParticles[i].Position[1] );
        Rectangle( Rect( ptgt.X - w, ptgt.Y - w, ptgt.X + w, ptgt.Y + w ) );
      end;
    end;
  end;

begin
  thr := strtofloat( maskedit1.Text ); //MaskEdit1 : Error Threshold
  dim := spinedit2.Value; //SpinEdit2 : Vector Dimension

  setlength( target, dim );
  target[0] := random( image1.Width );
  target[1] := random( image1.Height );
  for j := 2 to high( target ) do
    target[j] := random( image1.Width );

  pso := TPSO.Create( spinedit1.Value, dim ); //SpinEdit1 : Number of Particle
  pso.CostFn := dist;
  for i := 0 to pso.Count - 1 do begin
    for j := 0 to pso.Dimension - 1 do begin
      pso.FParticles[i].Position[j] := random( image1.Width );
      pso.FParticles[i].Velocity[j] := 0;
      pso.FParticles[i].MyBest[j] := pso.FParticles[i].Position[j];
      pso.FParticles[i].BestCost := MAXINT;
    end;
  end;
  display;

  for i := 0 to SpinEdit3.Value do begin //SpinEdit3 : Max Iteration
    pso.Step;
    if pso.FParticles[pso.BestParticle].BestCost < thr then break;
    display;
    Image1.Canvas.TextOut( 0, 0, format( 'iteration : %d', [i] ) );
    Application.ProcessMessages;
  end;

  memo1.Lines.Add( format( 'best cost : %.8f', [pso.FParticles[pso.BestParticle].BestCost] ) );
  pso.Free;
end;

Program di atas akan membangkitkan posisi acak pada titik tujuan dan posisi partikel sebagai vektor berdimensi N dan menampilkan proyeksi dua sumbu pertama dari partikel (untuk alasan ini, jangan membuat vektor berdimensi satu ya!).

Pembahasan

Pada dasarnya rumus perubahan kecepatan di atas bisa bervariasi, namun dari eksperimen saya menggunakan program di atas saya menyimpulkan bahwa kombinasi keempat elemen di atas menghasilkan waktu konvergensi yang paling cepat dibandingkan jika salah satu suku dihilangkan untuk persoalan berdimensi > 3 (saya mencoba di 8 dimensi). Bagaimana menurut anda?

10 comments

  1. kholis · Februari 22, 2010

    program PSOnya kok g bisa di donlot ya?
    mohon di duplikat di hosting lain. thanks

  2. ata · September 24, 2010

    wahh.. seandainya saya udah baca ini 1 bulan sebelumnya.. saya ga akan terlalu repot untuk buat program PSO ini. hahha.. tp gpp deh.. makasih buat info program PSOnya yah..

  3. Fitri · November 12, 2010

    Materi-materi lainnya ada ga? Thanks ya 😀

  4. saprol · Maret 9, 2011

    waw..gud info..
    kbanyakan nyari info kok rsx ad yg lebih..
    blh tw g referensinya d buku ap?
    but so far..i like this, thx y…

  5. kLepto · Maret 29, 2011

    nie nyang ane cari,, makase sobbb…

  6. newbee · Desember 6, 2011

    saya bingun akan fungsi dari PSO, kalau kita sudah tau solusi optimal, kanapa harus pakai PSO ?

  7. fitri · Desember 14, 2011

    ada gak yang lebih detailnya?
    saya masih bingung mengenai kecepatan yang dimaksudkan dalam pso

  8. Dank_Zhie · Januari 2, 2012

    Makasih banget gan!! Ijin copas dikit buat tugas kuliah ^^

    priawadi.blogspot.com

  9. Ping-balik: Particle Swarm Optimization - ahmadta09's blog
  10. indr4brr · Maret 1, 2012

    pembahasan yang menarik,
    lagi nyari2 informasi tentang pso soalnya.

Tinggalkan komentar

Situs ini menggunakan Akismet untuk mengurangi spam. Pelajari bagaimana data komentar Anda diproses.