Sunday, April 4, 2010

Particle Swarm Optimization (PSO) Sample Code using Java

Yes, I'm still coding and I'm proud of it :)

This post assume that the reader has already known about Particle Swarm Optimization (PSO) method, and hence I wouldn't spare a space to explain about it. But if you'd like to ask the method's component on the code I provide below then I'll be gladly explain it in greater length. [This post is written by Gandhi Manalu - gandhim.wordpress.com]

In this post, I'll describe and provide a sample code of PSO method for solving a very simple function optimization. Let say that the function to be minimized is as follow:

$latex f(x,y) = (2.8125-x+xy^4)^2+(2.25-x+xy^2)^2+(1.5-x+xy)^2$

With the following constraints: $latex 1<=x<=4; -1<=y<=1$

In order to solve this problem using PSO, we'll need these classes:

  • Position: to represent Position part of the particle
  • Velocity: to represent Velocity part of the particle
  • Particle: the particle itself [This post is written by Gandhi Manalu - gandhim.wordpress.com]
  • SimplePSO: the main control of the program
  • PSOConstants: an interface to define parameters used in the PSO
Since we're going to solve two-variable function optimization, we'll need to provide two-dimensional position and velocity. For the Position we have:

package org.gandhim.pso;

/**
*
* @author gandhim
*/
public class Position {
private double x;
private double y;

public Position(double x, double y) {
this.x = x;
this.y = y;
}

public double getX() {
return x;
}

public void setX(double x) {
this.x = x;
}

public double getY() {
return y;
}

public void setY(double y) {
this.y = y;
}
}

For the Velocity we have:

package org.gandhim.pso;

/**
*
* @author gandhim
*/
public class Velocity {
private double x;
private double y;

public Velocity(double x, double y) {
this.x = x;
this.y = y;
}

public double getX() {
return x;
}

public void setX(double x) {
this.x = x;
}

public double getY() {
return y;
}

public void setY(double y) {
this.y = y;
}
}
And the Particle is as follow:[This post is written by Gandhi Manalu - gandhim.wordpress.com]

package org.gandhim.pso;

/**
*
* @author gandhim
*/
public class Particle {
private Position location;
private Velocity velocity;
private double fitness;

public double getFitness() {
calculateFitness();
return fitness;
}

public void calculateFitness() {
double x = this.location.getX();
double y = this.location.getY();

fitness = Math.pow((2.8125 - x + x * Math.pow(y, 4)), 2) +
Math.pow((2.25 - x + x * Math.pow(y, 2)), 2) +
Math.pow((1.5 - x + x * y), 2);
}

public Position getLocation() {
return location;
}

public void setLocation(Position location) {
this.location = location;
}

public Velocity getVelocity() {
return velocity;
}

public void setVelocity(Velocity velocity) {
this.velocity = velocity;
}
}

Pay attention to the calculateFitness() method, it is where we put the function evaluation. Now, we're ready for the main process of the PSO. In this class, we'll need several methods:
  • initializeSwarm() - to initialize the swarm used in the method
  • execute() - the main part of the process[This post is written by Gandhi Manalu - gandhim.wordpress.com]
Here's the code (partial code):

private void initializeSwarm() {
Particle p;
Random generator = new Random();

for (int i = 0; i < SWARM_SIZE; i++) {
p = new Particle();
double posX = generator.nextDouble() * 3.0 + 1.0;
double posY = generator.nextDouble() * 2.0 - 1.0;
p.setLocation(new Position(posX, posY));

double velX = generator.nextDouble() * 2.0 - 1.0;
double velY = generator.nextDouble() * 2.0 - 1.0;
p.setVelocity(new Velocity(velX, velY));

swarm.add(p);
}
}

public void execute() {
Random generator = new Random();
initializeSwarm();

evolutionaryStateEstimation();

int t = 0;
double w;

while (t < MAX_ITERATION) {
// calculate corresponding f(i,t) corresponding to location x(i,t)
calculateAllFitness();

// update pBest
if (t == 0) {
for (int i = 0; i < SWARM_SIZE; i++) {
pBest[i] = fitnessList[i];
pBestLoc.add(swarm.get(i).getLocation());
}
} else {
for (int i = 0; i < SWARM_SIZE; i++) {
if (fitnessList[i] < pBest[i]) {
pBest[i] = fitnessList[i];
pBestLoc.set(i, swarm.get(i).getLocation());
}
}
}

int bestIndex = getBestParticle();
// update gBest
if (t == 0 || fitnessList[bestIndex] < gBest) {
gBest = fitnessList[bestIndex];
gBestLoc = swarm.get(bestIndex).getLocation();
}

w = W_UP - (((double) t) / MAX_ITERATION) * (W_UP - W_LO);

for (int i = 0; i < SWARM_SIZE; i++) {
// update particle Velocity
double r1 = generator.nextDouble();
double r2 = generator.nextDouble();
double lx = swarm.get(i).getLocation().getX();
double ly = swarm.get(i).getLocation().getY();
double vx = swarm.get(i).getVelocity().getX();
double vy = swarm.get(i).getVelocity().getY();
double pBestX = pBestLoc.get(i).getX();
double pBestY = pBestLoc.get(i).getY();
double gBestX = gBestLoc.getX();
double gBestY = gBestLoc.getY();

double newVelX = (w * vx) + (r1 * C1) * (pBestX - lx) + (r2 * C2) * (gBestX - lx);
double newVelY = (w * vy) + (r1 * C1) * (pBestY - ly) + (r2 * C2) * (gBestY - ly);
swarm.get(i).setVelocity(new Velocity(newVelX, newVelY));

// update particle Location
double newPosX = lx + newVelX;
double newPosY = ly + newVelY;
swarm.get(i).setLocation(new Position(newPosX, newPosY));
}

t++;
}
}

And the last is the interface for storing the constants:

package org.gandhim.pso;

/**
*
* @author gandhim
*/
public interface PSOConstants {
int SWARM_SIZE = 30;
int DIMENSION = 2;
int MAX_ITERATION = 300;
double C1 = 2.0;
double C2 = 2.0;
double W_UP = 1.0;
double W_LO = 0.0;
}

I made the interface just for the sake of flexibility. A sample of running the program is as follow: PSO Result

As we can see from the result, the program found the solution of the problem for (x=3.0 and y=0.5). You might have noticed that the program is not optimized yet, for example it could have been stopped when it already found the solution.[This post is written by Gandhi Manalu - gandhim.wordpress.com]

Actually, there are other PSO's components that have not been implemented in this program, for example constraints handling. But since the problem we solved here is a very simple one it doesn't really need the constraint handling.

I hope that this post is useful for you.

New Year's Resolution: Current State

I don't know why, but it just came into my mind about nine (yes, it's nine!) new year's resolutions that I made on the very first day of this 2010 year.

I'm trying to count how many of them have been realized or at least being attempted. Well, though the progress is not aggressive I'm happy to say that all of them are being proceed. Some is 50% done, the other is still 30% done, but at least they're all started to improve day by day (well at least week by week). I don't want to make a speculation, or even planning an "alternative" resolution in case of some of my resolution are not able to be achieved (on time). All of them are important, so they're all have to be achieved. Though I still have 8 more months to go, I realize I couldn't waste my time again.

So I have to focus to speed up the progress. Stop at doing unproductive activities. Eliminate procrastination spirit. And just do it!

Prof. Kaoru Hirota's Visit

Prof. Kaoru Hirota

Several weeks ago, Prof. Kaoru Hirota from the HIROTA LAB, Titech, visit our lab. His lab's research topics are interesting. I hope to go there sometimes in the future. Hopefully :)

Free Pop Yahoo Mail

Actually this trick is a very old one, but it still works until now, and I've been using it for quite some time now. It just came to my mind to share it with those who haven't known about this yet.

Yes, it's true. You can easily pop your yahoo mails into your desktop based email client like Thunderbird or Windows Live Mail. You just need to change your time zone setting. Don't worry, your email address will be stay the same (endings with @yahoo.com, it won't change into @yahoo.co.id whatsoever). I didn't have much time to provide the visual steps, but I guarantee that the textual steps is comprehensive enough for you to follow.

Here are the steps: [These steps provided by Gandhi Manalu - gandhim.wordpress.com]

  1. Open your web based Yahoo Mail (I use the All-New version).
  2. At the right hand side of the window there is an Options menu, click on it and choose "More options...".
  3. At the left hand pane you can see several menus, chose Accounts.
  4. At the right hand pane click "Add or edit an account". A new window will be opened to add or edit an account.
  5. Just choose the default one (the one titled Yahoo! Mail) and click Edit button.[These steps provided by Gandhi Manalu - gandhim.wordpress.com]
  6. Now you have several options at the left side, choose "Account Information".
  7. You'll be asked to enter your account information (password) again. Just enter it and press "Sign In".
  8. Scroll down to "Account Settings" box, you'll find "Set language, site, and time zone" menu, just click it.
  9. In the new setting, just choose Yahoo! Asia.
  10. Press finished. Now, your time zone will be Yahoo! Asia. Don't worry, it won't change your time zone, you can adjust it under the time zone drop box. [These steps provided by Gandhi Manalu]
  11. Now go back to window opened at step 3. You'll find "POP & Forwarding" menu there. Click it.
  12. At the right side pane choose "Set up or edit POP & Forwarding". A new window will be opened.
  13. Choose "Web & POP Access" to enable POP Access and don't forget to press the "Save" button at the left bottom side of the window.
  14. Now, you can pop your Yahoo email freely into your desktop based email client application.

Depends on your email client application, you can setup a new Yahoo email account. Use this setting while configuring your email client: [These steps provided by Gandhi Manalu - gandhim.wordpress.com]

  • Incoming mail (POP 3): pop.mail.yahoo.com. Port number: 995.
  • Outgoing mail (SMTP): smtp.mail.yahoo.com. Port number: 465.

And you're ready popping your Yahoo email, freely! Have fun.

Monday, December 28, 2009

Choice

This post is about Sunday morning service I attended at the Grace Baptist Church at Taipei on December 27, 2009. The sermon was taken from Galatians 6:7-10 and preached by pastor Jim West.

7Do not be deceived: God cannot be mocked. A man reaps what he sows. 8The one who sows to please his sinful nature, from that nature will reap destruction; the one who sows to please the Spirit, from the Spirit will reap eternal life. 9Let us not become weary in doing good, for at the proper time we will reap a harvest if we do not give up. 10Therefore, as we have opportunity, let us do good to all people, especially to those who belong to the family of believers.

Here's what I got:

  1. You can kid yourself about your choice of seed.
    1. Gal 6:7a, Do not deceive yourselves.
    2. Matt 18:12-13, The process of wandering from truth is one move at a time, so you'll never aware of it. Be careful!
    3. Matt 22:29, You are in error because you do not know the scriptures or the power of God.
  2. You can't kid God about your choice of seed.
    1. No one makes fool of God.
    2. God can't be mocked.
    3. We must not even try to ridicule God.
  3. You be careful about your choice of seed.
    1. The harvest we gather is a direct result of the seeds we sow.
  4. You never have a choice about what you harvest.

The law of harvest: If we sow good seed, we will reap good harvest.

The law of the ratio of harvest: if we sow a little we harvest a little, if we sow many we harvest many.

Summed up in a sentence: Every person harvests a crop, in due time, that corresponds to the seed he or she planted.

Probing question: What will be the crop that I will harvest?

Download full audio recording here.

Wednesday, December 2, 2009

Blogging again...

Finally, I decided to start blogging again.. No special reason for this decision, actually I've been thinking about this for several months, but I just wanted to wait for the right moment. And this is it, the beginning of the end. This is the beginning of December, the last month, the end of 2009.

I can't guarantee (as always) that I'll write regularly, since there are lots of things to do in my daily activities. But I'll try for at least one post per week.

So, welcome back, and enjoy this blog again :)

Cold Town, 1st December 2009