From cc837b423f3d6e013869086e6aa4b92228c1a02d Mon Sep 17 00:00:00 2001 From: Vladimir Date: Sat, 12 Dec 2015 00:32:52 +0300 Subject: [PATCH 1/3] Made visualization for proccess. Added: graph, speed of iterations adjusting, buttons for reset and iteration++ --- .classpath | 6 + .gitignore | 1 + .project | 17 ++ .../org.eclipse.ltk.core.refactoring.prefs | 2 + src/org/gandhim/pso/Main.java | 15 ++ src/org/gandhim/pso/MainFrame.java | 155 ++++++++++++++++++ src/org/gandhim/pso/PSOConstants.java | 6 +- src/org/gandhim/pso/PSODriver.java | 11 -- src/org/gandhim/pso/PSOProcess.java | 75 ++++++--- src/org/gandhim/pso/PaintPanel.java | 132 +++++++++++++++ src/org/gandhim/pso/ProblemSet.java | 12 +- 11 files changed, 392 insertions(+), 40 deletions(-) create mode 100644 .classpath create mode 100644 .gitignore create mode 100644 .project create mode 100644 .settings/org.eclipse.ltk.core.refactoring.prefs create mode 100644 src/org/gandhim/pso/Main.java create mode 100644 src/org/gandhim/pso/MainFrame.java delete mode 100644 src/org/gandhim/pso/PSODriver.java create mode 100644 src/org/gandhim/pso/PaintPanel.java diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..fb50116 --- /dev/null +++ b/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ae3c172 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/.project b/.project new file mode 100644 index 0000000..77e2734 --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + pso-example-java + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/.settings/org.eclipse.ltk.core.refactoring.prefs b/.settings/org.eclipse.ltk.core.refactoring.prefs new file mode 100644 index 0000000..b196c64 --- /dev/null +++ b/.settings/org.eclipse.ltk.core.refactoring.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false diff --git a/src/org/gandhim/pso/Main.java b/src/org/gandhim/pso/Main.java new file mode 100644 index 0000000..d73e5e1 --- /dev/null +++ b/src/org/gandhim/pso/Main.java @@ -0,0 +1,15 @@ +package org.gandhim.pso; + +import javax.swing.JFrame; + +public class Main { + + public static void main(String[] args) + { + MainFrame frame1 = new MainFrame(); + frame1.setSize(600, 400); + frame1.setVisible(true); + frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + } + +} diff --git a/src/org/gandhim/pso/MainFrame.java b/src/org/gandhim/pso/MainFrame.java new file mode 100644 index 0000000..0fc91f3 --- /dev/null +++ b/src/org/gandhim/pso/MainFrame.java @@ -0,0 +1,155 @@ +package org.gandhim.pso; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.GridBagLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.util.Hashtable; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.plaf.basic.BasicArrowButton; + +public class MainFrame extends JFrame implements PSOConstants +{ + private PaintPanel panel1; + private JPanel panel2; + private Hashtable labelTable1; + private JPanel container1; + private JButton button1, button2; + private JCheckBox checkbox1; + private JSlider slider1; + private static JTextArea textarea1; + private JScrollPane scroll1; + + public MainFrame() + { + super("Particle Swarm Optimization"); + + container1 = new JPanel(new GridBagLayout()); + add(container1, BorderLayout.CENTER); + + panel2 = new JPanel(); + add(panel2, BorderLayout.SOUTH); + + button1 = new JButton("Back to the begin"); + panel2.add(button1, BorderLayout.WEST); + + + button2 = new JButton("Forward"); + panel2.add(button2, BorderLayout.WEST); + + checkbox1 = new JCheckBox("Iterate automatically"); + panel2.add(checkbox1, BorderLayout.CENTER); + + labelTable1 = new Hashtable(); + labelTable1.put(new Integer(MIN_DELAY), new JLabel(MIN_DELAY/1000f + "it/sec")); + labelTable1.put(new Integer((MIN_DELAY + MAX_DELAY)/2), new JLabel((MIN_DELAY + MAX_DELAY)/2000f + "it/sec")); + labelTable1.put(new Integer(MAX_DELAY), new JLabel(MAX_DELAY/1000f + "it/sec")); + + slider1 = new JSlider(JSlider.VERTICAL, MIN_DELAY, MAX_DELAY, MIN_DELAY); + slider1.setLabelTable(labelTable1); + slider1.setPaintLabels(true); + add(slider1, BorderLayout.WEST); + + textarea1 = new JTextArea(20, 22); + textarea1.setEditable(false); + textarea1.setLineWrap(true); + scroll1 = new JScrollPane(textarea1); + scroll1.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); + + add(scroll1, BorderLayout.EAST); + + panel1 = new PaintPanel(); + container1.add(panel1); + + container1.addComponentListener(new ComponentListenerOne()); + button1.addActionListener(new ActionListenerOne(false)); + button2.addActionListener(new ActionListenerOne(true)); + checkbox1.addItemListener(new ItemListenerOne()); + slider1.addChangeListener(new ChangeListenerOne()); + } + + public static void appendText(String text) + { + textarea1.append(text + "\n"); + textarea1.setCaretPosition(textarea1.getDocument().getLength()); + } + + class ComponentListenerOne implements ComponentListener + { + + @Override + public void componentResized(ComponentEvent e) { + + int w = container1.getWidth(); + int h = container1.getHeight(); + int size = Math.min(w, h); + panel1.setPreferredSize(new Dimension(size, size)); + container1.revalidate(); + } + + @Override + public void componentMoved(ComponentEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void componentShown(ComponentEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void componentHidden(ComponentEvent e) { + // TODO Auto-generated method stub + + } + } + + class ActionListenerOne implements ActionListener + { + private boolean forward; + + public ActionListenerOne(boolean forward) + { + super(); + this.forward = forward; + } + + public void actionPerformed(ActionEvent e) + { + panel1.executeProcess(this.forward); + } + + } + + class ItemListenerOne implements ItemListener + { + public void itemStateChanged(ItemEvent e) + { + panel1.setAutoIterate(checkbox1.isSelected()); + } + } + + class ChangeListenerOne implements ChangeListener + { + public void stateChanged(ChangeEvent e) + { + JSlider source = (JSlider)e.getSource(); + if(!source.getValueIsAdjusting()) + { + int delay = (int)source.getValue(); + panel1.setIterateTimerDelay(delay); + } + } + } +} diff --git a/src/org/gandhim/pso/PSOConstants.java b/src/org/gandhim/pso/PSOConstants.java index 4b9c60d..f3949aa 100644 --- a/src/org/gandhim/pso/PSOConstants.java +++ b/src/org/gandhim/pso/PSOConstants.java @@ -9,8 +9,10 @@ public interface PSOConstants { int SWARM_SIZE = 30; int MAX_ITERATION = 100; int PROBLEM_DIMENSION = 2; - double C1 = 2.0; - double C2 = 2.0; + double C1 = 1; + double C2 = 1; double W_UPPERBOUND = 1.0; double W_LOWERBOUND = 0.0; + int MIN_DELAY = 100; + int MAX_DELAY = 1000; } diff --git a/src/org/gandhim/pso/PSODriver.java b/src/org/gandhim/pso/PSODriver.java deleted file mode 100644 index 6889d4a..0000000 --- a/src/org/gandhim/pso/PSODriver.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.gandhim.pso; - -/* author: gandhi - gandhi.mtm [at] gmail [dot] com - Depok, Indonesia */ - -// this is a driver class to execute the PSO process - -public class PSODriver { - public static void main(String args[]) { - new PSOProcess().execute(); - } -} diff --git a/src/org/gandhim/pso/PSOProcess.java b/src/org/gandhim/pso/PSOProcess.java index 2bccb53..e556319 100644 --- a/src/org/gandhim/pso/PSOProcess.java +++ b/src/org/gandhim/pso/PSOProcess.java @@ -16,23 +16,43 @@ public class PSOProcess implements PSOConstants { private double gBest; private Location gBestLocation; private double[] fitnessValueList = new double[SWARM_SIZE]; + private int t = 0; + private double w; + private double err = 9999; + public int getT() { + return t; + } + Random generator = new Random(); - public void execute() { - initializeSwarm(); - updateFitnessList(); + public void execute(boolean forward) { - for(int i=0; i 0) + { + t = 0; } - int t = 0; - double w; - double err = 9999; - while(t < MAX_ITERATION && err > ProblemSet.ERR_TOLERANCE) { + if(t == 0) + { + initializeSwarm(); + System.out.println("LAL"); + updateFitnessList(); + + for(int i=0; i ProblemSet.ERR_TOLERANCE) + { // step 1 - update pBest for(int i=0; i getSwarm() { + return swarm; + } + + public Vector getpBestLocation() { + return pBestLocation; + } + + public Location getgBestLocation() { + return gBestLocation; + } } diff --git a/src/org/gandhim/pso/PaintPanel.java b/src/org/gandhim/pso/PaintPanel.java new file mode 100644 index 0000000..e6762b7 --- /dev/null +++ b/src/org/gandhim/pso/PaintPanel.java @@ -0,0 +1,132 @@ +package org.gandhim.pso; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.event.*; + +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.Timer; + +public class PaintPanel extends JPanel +{ + private PSOProcess process; + private double minX, maxX, minY, maxY; + private Font font; + private boolean autoIterate; + private Timer IterateTimer; + + public PaintPanel() + { + super(); + setBackground(Color.LIGHT_GRAY); + process = new PSOProcess(); + executeProcess(false); + autoIterate = false; + + IterateTimer = new Timer(100, new ActionListener() + { + public void actionPerformed(ActionEvent e) + { + if(autoIterate) + executeProcess(true); + } + } + ); + IterateTimer.start(); + + minX = ProblemSet.LOC_X_LOW; + maxX = ProblemSet.LOC_X_HIGH; + minY = ProblemSet.LOC_Y_LOW; + maxY = ProblemSet.LOC_Y_HIGH; + + font = new Font("Serif", Font.PLAIN, 10); + } + + public void setAutoIterate(boolean autoIterate) { + this.autoIterate = autoIterate; + } + public void setIterateTimerDelay(int delay) + { + IterateTimer.setDelay(delay); + } + + private Point formattedPoint(double x, double y) + { + + double normX = (x - (minX + maxX)/2)/((maxX - minX)/2); + double normY = (y - (minY + maxY)/2)/((maxY - minY)/2); + + return new Point(getWidth()/2 + (int)(getWidth()/2*normX), getHeight()/2 - ((int)(getHeight()/2*normY))); + } + + public void executeProcess(boolean forward) + { + process.execute(forward); + repaint(); + } + + public int getT() + { + return process.getT(); + } + + private void drawGrid(Graphics g) + { + Point point1, point2; + + for(int i = (int) minX; i <= maxX; i++) + { + point1 = formattedPoint(i, minY); + point2 = formattedPoint(i, maxY); + g.drawLine(point1.x, point1.y, point2.x, point2.y); + g.drawString(String.valueOf(i), point1.x, (point1.y + point2.y)/2); + } + + for(int i = (int) minY; i <= maxY; i++) + { + point1 = formattedPoint(minX, i); + point2 = formattedPoint(maxX, i); + g.drawLine(point1.x, point1.y, point2.x, point2.y); + g.drawString(String.valueOf(i), (point1.x + point2.x)/2, point1.y); + } + } + + public void drawCircle(Graphics g, int x, int y, int size) + { + g.drawOval(x - size/2, y - size/2, size, size); + } + + public void fillCircle(Graphics g, int x, int y, int size) + { + g.fillOval(x - size/2, y - size/2, size, size); + } + + public void paintComponent(Graphics g) + { + super.paintComponent(g); + + Point point; + + g.setColor(Color.GRAY); + g.setFont(font); + + drawGrid(g); + + g.setColor(Color.BLUE); + + for(Particle particle: process.getSwarm()) + { + point = formattedPoint(particle.getLocation().getLoc()[0], particle.getLocation().getLoc()[1]); + fillCircle(g, point.x, point.y, 4); + } + + g.setColor(Color.RED); + + point = formattedPoint(process.getgBestLocation().getLoc()[0], process.getgBestLocation().getLoc()[1]); + drawCircle(g, point.x, point.y, 8); + + } +} diff --git a/src/org/gandhim/pso/ProblemSet.java b/src/org/gandhim/pso/ProblemSet.java index 663aa68..e27daf6 100644 --- a/src/org/gandhim/pso/ProblemSet.java +++ b/src/org/gandhim/pso/ProblemSet.java @@ -12,10 +12,10 @@ // you need to introduce a new variable (other than x and y) public class ProblemSet { - public static final double LOC_X_LOW = 1; - public static final double LOC_X_HIGH = 4; - public static final double LOC_Y_LOW = -1; - public static final double LOC_Y_HIGH = 1; + public static final double LOC_X_LOW = -3; + public static final double LOC_X_HIGH = 3; + public static final double LOC_Y_LOW = -3; + public static final double LOC_Y_HIGH = 3; public static final double VEL_LOW = -1; public static final double VEL_HIGH = 1; @@ -27,9 +27,7 @@ public static double evaluate(Location location) { double x = location.getLoc()[0]; // the "x" part of the location double y = location.getLoc()[1]; // the "y" part of the location - result = 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); + result = Math.pow(1 - x, 2) + 100 * Math.pow(y - x * x, 2); return result; } From 8f87d039b75f4bed9b57cee31a6bb6f9c95191bd Mon Sep 17 00:00:00 2001 From: Vladimir Date: Tue, 15 Dec 2015 02:17:36 +0300 Subject: [PATCH 2/3] Minor fixes W is now changing from 0.9 to 0.4 If solution found, then do not execute proccess --- src/org/gandhim/pso/PSOConstants.java | 4 ++-- src/org/gandhim/pso/PSOProcess.java | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/org/gandhim/pso/PSOConstants.java b/src/org/gandhim/pso/PSOConstants.java index f3949aa..294ae4e 100644 --- a/src/org/gandhim/pso/PSOConstants.java +++ b/src/org/gandhim/pso/PSOConstants.java @@ -11,8 +11,8 @@ public interface PSOConstants { int PROBLEM_DIMENSION = 2; double C1 = 1; double C2 = 1; - double W_UPPERBOUND = 1.0; - double W_LOWERBOUND = 0.0; + double W_UPPERBOUND = 0.9; + double W_LOWERBOUND = 0.4; int MIN_DELAY = 100; int MAX_DELAY = 1000; } diff --git a/src/org/gandhim/pso/PSOProcess.java b/src/org/gandhim/pso/PSOProcess.java index e556319..a7dfe40 100644 --- a/src/org/gandhim/pso/PSOProcess.java +++ b/src/org/gandhim/pso/PSOProcess.java @@ -36,7 +36,8 @@ else if(!forward && t > 0) { t = 0; } - + else if(t >= MAX_ITERATION) + return; if(t == 0) { From 4f72e63439aced88f3920e78275dedfa0539af43 Mon Sep 17 00:00:00 2001 From: Vladimir Date: Sat, 13 May 2017 01:04:00 +0300 Subject: [PATCH 3/3] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ad813cb..2e240d7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -pso-example-java +Particle Swarm Optimization with UI ================ -Particle Swarm Optimization (PSO) Sample Code using Java +Swing library is used here for UI programming. -This project is a complete version of Particle Swarm Optimization with Java sample code described in http://gandhim.wordpress.com/2010/04/04/particle-swarm-optimization-pso-sample-code-using-java. +Thanks to https://github.com/therealmanalu for PSO implementation on Java.