diff --git a/pom.xml b/pom.xml index 16be193afda55540c62c09123d6920438207fb91..bcb85bff126b50614916d2b9f223a12ccb1f4286 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,5 @@ -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> diff --git a/src/main/java/com/syncleus/dann/examples/Main.java b/src/main/java/com/syncleus/dann/examples/Main.java index 64fcdbbf7c93fd0246b7c181d2b775f1f4f21447..76d108b4db05335a716a3c02fed1d56a8c716526 100644 --- a/src/main/java/com/syncleus/dann/examples/Main.java +++ b/src/main/java/com/syncleus/dann/examples/Main.java @@ -18,169 +18,148 @@ ******************************************************************************/ package com.syncleus.dann.examples; -import java.io.BufferedReader; -import java.io.File; -import java.io.InputStreamReader; -import java.net.URL; - import org.apache.log4j.Logger; import org.apache.log4j.xml.DOMConfigurator; +import java.io.*; +import java.net.URL; + /** * Runs dANN demos from a console menu. + * * @author Jeffrey Phillips Freeman */ -public final class Main -{ - private static final Logger LOGGER = Logger.getLogger(Main.class); - /** How long to sleep in milli-seconds, until checking for input again. */ - private static final long INPUT_SLEEP = 100; +public final class Main { + private static final Logger LOGGER = Logger.getLogger(Main.class); + /** + * How long to sleep in milli-seconds, until checking for input again. + */ + private static final long INPUT_SLEEP = 100; - private Main() - { - } + private Main() { + } - public static void main(final String[] args) - { - try - { - if(new File("log4j.xml").exists()) - DOMConfigurator.configure("log4j.xml"); - else - { - final URL logConfig = ClassLoader.getSystemResource("log4j.xml"); - assert logConfig != null; - DOMConfigurator.configure(logConfig); - } + public static void main(final String[] args) { + try { + if (new File("log4j.xml").exists()) + DOMConfigurator.configure("log4j.xml"); + else { + final URL logConfig = ClassLoader.getSystemResource("log4j.xml"); + assert logConfig != null; + DOMConfigurator.configure(logConfig); + } - LOGGER.info("program started..."); + LOGGER.info("program started..."); - final BufferedReader inReader = new BufferedReader(new InputStreamReader(System.in)); + final BufferedReader inReader = new BufferedReader(new InputStreamReader(System.in)); - final String[] newArgs = new String[Math.max(0, args.length - 1)]; - if (args.length > 1) - { - System.arraycopy(args, 1, newArgs, 0, args.length - 1); - } + final String[] newArgs = new String[Math.max(0, args.length - 1)]; + if (args.length > 1) { + System.arraycopy(args, 1, newArgs, 0, args.length - 1); + } - String selectorArg = null; - if (args.length > 0) - { - selectorArg = args[0]; - } + String selectorArg = null; + if (args.length > 0) { + selectorArg = args[0]; + } - if (selectorArg != null) - { - if (selectorArg.compareTo("--xor") == 0) - { - com.syncleus.dann.examples.xor.XorDemo.main(newArgs); - } - else if (selectorArg.compareTo("--nci") == 0) - { - com.syncleus.dann.examples.nci.ui.NciDemo.main(newArgs); - } - else if (selectorArg.compareTo("--colormap") == 0) - { - com.syncleus.dann.examples.colormap.ColorMapDemo.main(newArgs); - } - else if (selectorArg.compareTo("--hyperassociativemap") == 0) - { - com.syncleus.dann.examples.hyperassociativemap.visualization.ViewMap.main(newArgs); - } - else if (selectorArg.compareTo("--tsp") == 0) - { - com.syncleus.dann.examples.tsp.TravellingSalesmanDemo.main(newArgs); - } - else if (selectorArg.compareTo("--fft") == 0) - { - com.syncleus.dann.examples.fft.FftDemo.main(newArgs); - } - } + if (selectorArg != null) { + if (selectorArg.compareTo("--xor") == 0) { + com.syncleus.dann.examples.xor.XorDemo.main(newArgs); + } + else if (selectorArg.compareTo("--nci") == 0) { + com.syncleus.dann.examples.nci.ui.NciDemo.main(newArgs); + } + else if (selectorArg.compareTo("--colormap") == 0) { + com.syncleus.dann.examples.colormap.ColorMapDemo.main(newArgs); + } + else if (selectorArg.compareTo("--hyperassociativemap") == 0) { + com.syncleus.dann.examples.hyperassociativemap.visualization.ViewMap.main(newArgs); + } + else if (selectorArg.compareTo("--tsp") == 0) { + com.syncleus.dann.examples.tsp.TravellingSalesmanDemo.main(newArgs); + } + else if (selectorArg.compareTo("--fft") == 0) { + com.syncleus.dann.examples.fft.FftDemo.main(newArgs); + } + } - System.out.println("dANN Example Sets"); + System.out.println("dANN Example Sets"); - int currentCommand = 'q'; - do - { - boolean received = false; - while (!received) - { - System.out.println(); - System.out.println("X) XOR Example"); - System.out.println("I) Image Compression Example w/GUI"); - System.out.println("V) Hyperassociative Map Visualizations"); - System.out.println("C) SOM Color Map"); - System.out.println("T) Travelling Salesman"); - System.out.println("F) Fast Fourier Transform Demo"); - System.out.println("P) Path Finding Demo"); - System.out.println("H) Command Line Help"); - System.out.println("Q) quit"); - System.out.println("\tEnter command: "); + int currentCommand = 'q'; + do { + boolean received = false; + while (!received) { + System.out.println(); + System.out.println("X) XOR Example"); + System.out.println("I) Image Compression Example w/GUI"); + System.out.println("V) Hyperassociative Map Visualizations"); + System.out.println("C) SOM Color Map"); + System.out.println("T) Travelling Salesman"); + System.out.println("F) Fast Fourier Transform Demo"); + System.out.println("P) Path Finding Demo"); + System.out.println("H) Command Line Help"); + System.out.println("Q) quit"); + System.out.println("\tEnter command: "); - received = true; - try - { - while (!inReader.ready()) - { - Thread.sleep(INPUT_SLEEP); - } - currentCommand = inReader.readLine().toLowerCase().toCharArray()[0]; - } - catch (ArrayIndexOutOfBoundsException caughtException) - { - received = false; - } - } + received = true; + try { + while (!inReader.ready()) { + Thread.sleep(INPUT_SLEEP); + } + currentCommand = inReader.readLine().toLowerCase().toCharArray()[0]; + } + catch (ArrayIndexOutOfBoundsException caughtException) { + received = false; + } + } - System.out.println(); + System.out.println(); - switch (currentCommand) - { - case 'c': - com.syncleus.dann.examples.colormap.ColorMapDemo.main(newArgs); - break; - case 'x': - com.syncleus.dann.examples.xor.XorDemo.main(newArgs); - break; - case 'i': - com.syncleus.dann.examples.nci.ui.NciDemo.main(newArgs); - break; - case 'h': - System.out.println("The command line differs for each of the example files."); - System.out.println(); - System.out.println("XOR Exmaple:"); - System.out.println("java -jar bin dANN-examples.jar --xor [save-location]"); - break; - case 'v': - com.syncleus.dann.examples.hyperassociativemap.visualization.ViewMap.main(newArgs); - break; - case 't': - com.syncleus.dann.examples.tsp.TravellingSalesmanDemo.main(newArgs); - break; - case 'f': - com.syncleus.dann.examples.fft.FftDemo.main(newArgs); - break; - case 'p': - com.syncleus.dann.examples.pathfind.PathFindDemoPanel.main(newArgs); - break; - case 'q': - System.out.print("Quiting..."); - break; - default: - System.out.println("Invalid command"); - } - } while ((currentCommand != 'q') && (currentCommand >= 0)); - System.out.println("Quit"); - } - catch (Exception caught) - { - LOGGER.error("A throwable was caught in the main execution thread", caught); - throw new RuntimeException("An exception was caught", caught); - } - catch (Error caught) - { - LOGGER.error("A throwable was caught in the main execution thread", caught); - throw new Error("Error caught", caught); - } - } + switch (currentCommand) { + case 'c': + com.syncleus.dann.examples.colormap.ColorMapDemo.main(newArgs); + break; + case 'x': + com.syncleus.dann.examples.xor.XorDemo.main(newArgs); + break; + case 'i': + com.syncleus.dann.examples.nci.ui.NciDemo.main(newArgs); + break; + case 'h': + System.out.println("The command line differs for each of the example files."); + System.out.println(); + System.out.println("XOR Exmaple:"); + System.out.println("java -jar bin dANN-examples.jar --xor [save-location]"); + break; + case 'v': + com.syncleus.dann.examples.hyperassociativemap.visualization.ViewMap.main(newArgs); + break; + case 't': + com.syncleus.dann.examples.tsp.TravellingSalesmanDemo.main(newArgs); + break; + case 'f': + com.syncleus.dann.examples.fft.FftDemo.main(newArgs); + break; + case 'p': + com.syncleus.dann.examples.pathfind.PathFindDemoPanel.main(newArgs); + break; + case 'q': + System.out.print("Quiting..."); + break; + default: + System.out.println("Invalid command"); + } + } while ((currentCommand != 'q') && (currentCommand >= 0)); + System.out.println("Quit"); + } + catch (Exception caught) { + LOGGER.error("A throwable was caught in the main execution thread", caught); + throw new RuntimeException("An exception was caught", caught); + } + catch (Error caught) { + LOGGER.error("A throwable was caught in the main execution thread", caught); + throw new Error("Error caught", caught); + } + } } diff --git a/src/main/java/com/syncleus/dann/examples/colormap/AboutDialog.java b/src/main/java/com/syncleus/dann/examples/colormap/AboutDialog.java index fae6b92c104a98c492fa9994e48ee8976da780c1..439d12299f4a7b6d50b426ff35928f1138a74a56 100644 --- a/src/main/java/com/syncleus/dann/examples/colormap/AboutDialog.java +++ b/src/main/java/com/syncleus/dann/examples/colormap/AboutDialog.java @@ -18,18 +18,22 @@ ******************************************************************************/ package com.syncleus.dann.examples.colormap; -import java.awt.Frame; -import javax.swing.JDialog; +import javax.swing.*; +import java.awt.*; -public class AboutDialog extends JDialog -{ - public AboutDialog(final Frame parent, final boolean modal) - { - super(parent, modal); - initComponents(); - } +public class AboutDialog extends JDialog { + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton1; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JTextArea jTextArea1; + public AboutDialog(final Frame parent, final boolean modal) { + super(parent, modal); + initComponents(); + } - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { @@ -67,48 +71,42 @@ public class AboutDialog extends JDialog javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 434, Short.MAX_VALUE)) - .addGroup(layout.createSequentialGroup() - .addGap(170, 170, 170) - .addComponent(jLabel2)) - .addGroup(layout.createSequentialGroup() - .addGap(203, 203, 203) - .addComponent(jButton1)) - .addGroup(layout.createSequentialGroup() - .addGap(190, 190, 190) - .addComponent(jLabel1))) - .addContainerGap()) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 434, Short.MAX_VALUE)) + .addGroup(layout.createSequentialGroup() + .addGap(170, 170, 170) + .addComponent(jLabel2)) + .addGroup(layout.createSequentialGroup() + .addGap(203, 203, 203) + .addComponent(jButton1)) + .addGroup(layout.createSequentialGroup() + .addGap(190, 190, 190) + .addComponent(jLabel1))) + .addContainerGap()) ); layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(jLabel1) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel2) - .addGap(11, 11, 11) - .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 170, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jButton1) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel2) + .addGap(11, 11, 11) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 170, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButton1) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); pack(); }// </editor-fold>//GEN-END:initComponents -private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed - this.setVisible(false); -}//GEN-LAST:event_jButton1ActionPerformed - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JButton jButton1; - private javax.swing.JLabel jLabel1; - private javax.swing.JLabel jLabel2; - private javax.swing.JScrollPane jScrollPane1; - private javax.swing.JTextArea jTextArea1; + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + this.setVisible(false); + }//GEN-LAST:event_jButton1ActionPerformed // End of variables declaration//GEN-END:variables } diff --git a/src/main/java/com/syncleus/dann/examples/colormap/ColorMap1dCallable.java b/src/main/java/com/syncleus/dann/examples/colormap/ColorMap1dCallable.java index 256b57a0622dd06a25ae0074511d6e27be0abf3e..1755ec2cd3c2d1ba5ce5360d5a5e25da2a98c601 100644 --- a/src/main/java/com/syncleus/dann/examples/colormap/ColorMap1dCallable.java +++ b/src/main/java/com/syncleus/dann/examples/colormap/ColorMap1dCallable.java @@ -18,121 +18,107 @@ ******************************************************************************/ package com.syncleus.dann.examples.colormap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Random; -import java.util.concurrent.Callable; import com.syncleus.dann.math.Vector; import com.syncleus.dann.neural.Synapse; -import com.syncleus.dann.neural.som.SomInputNeuron; -import com.syncleus.dann.neural.som.SomNeuron; -import com.syncleus.dann.neural.som.SomOutputNeuron; +import com.syncleus.dann.neural.som.*; import com.syncleus.dann.neural.som.brain.ExponentialDecaySomBrain; -import java.awt.Color; import org.apache.log4j.Logger; -public final class ColorMap1dCallable implements Callable<Color[]> -{ - private volatile int iterations; - private volatile double learningRate; - private volatile int width; - private static final Random RANDOM = new Random(); - private volatile int progress; - private static final Logger LOGGER = Logger.getLogger(ColorMap1dCallable.class); - static final int COLOR_CHANNELS = 3; - - public ColorMap1dCallable(final int iterations, final double learningRate, final int width) - { - this.iterations = iterations; - this.learningRate = learningRate; - this.width = width; - } - - @Override - public Color[] call() - { - try - { - //initialize brain - final ExponentialDecaySomBrain<SomInputNeuron, SomOutputNeuron, SomNeuron, Synapse<SomNeuron>> brain - = new ExponentialDecaySomBrain<SomInputNeuron, SomOutputNeuron, SomNeuron, Synapse<SomNeuron>>(COLOR_CHANNELS, 1, getIterations(), getLearningRate()); - - //create the output latice - for(double x = 0; x < getWidth(); x++) - brain.createOutput(new Vector(new double[] {x})); - - //run through random training data for all iterations - for(int iteration = 0; iteration < getIterations(); iteration++) - { - this.progress++; - - for (int ci = 0; ci < COLOR_CHANNELS; ci++) - brain.setInput(ci, RANDOM.nextDouble()); - - brain.getBestMatchingUnit(true); - } - - //pull the output weight vectors - final Map<Vector, double[]> outputWeightVectors = brain.getOutputWeightVectors(); - - //construct the color array - Color[] colorPositions = new Color[getWidth()]; - for(Entry<Vector, double[]> weightVector : outputWeightVectors.entrySet()) - { - final Vector currentPoint = weightVector.getKey(); - final double[] currentVector = weightVector.getValue(); - - //convert the current Vector to a color. - final Color currentColor = new Color((float)currentVector[0], (float)currentVector[1], (float)currentVector[2]); - - //add the current color to the colorPositions - colorPositions[(int)Math.floor(currentPoint.getCoordinate(1))] = currentColor; - } - - //return the color positions - return colorPositions; - } - catch(Exception caught) - { - LOGGER.error("Exception was caught", caught); - throw new RuntimeException("Throwable was caught", caught); - } - catch(Error caught) - { - LOGGER.error("Error was caught", caught); - throw new Error("Throwable was caught", caught); - } - } - - /** - * @return the iterations - */ - public int getIterations() - { - return iterations; - } - - /** - * @return the learningRate - */ - public double getLearningRate() - { - return learningRate; - } - - /** - * @return the width - */ - public int getWidth() - { - return width; - } - - /** - * @return the progress - */ - public int getProgress() - { - return progress; - } +import java.awt.*; +import java.util.*; +import java.util.Map.Entry; +import java.util.concurrent.Callable; + +public final class ColorMap1dCallable implements Callable<Color[]> { + static final int COLOR_CHANNELS = 3; + private static final Random RANDOM = new Random(); + private static final Logger LOGGER = Logger.getLogger(ColorMap1dCallable.class); + private volatile int iterations; + private volatile double learningRate; + private volatile int width; + private volatile int progress; + + public ColorMap1dCallable(final int iterations, final double learningRate, final int width) { + this.iterations = iterations; + this.learningRate = learningRate; + this.width = width; + } + + @Override + public Color[] call() { + try { + //initialize brain + final ExponentialDecaySomBrain<SomInputNeuron, SomOutputNeuron, SomNeuron, Synapse<SomNeuron>> brain + = new ExponentialDecaySomBrain<SomInputNeuron, SomOutputNeuron, SomNeuron, Synapse<SomNeuron>>(COLOR_CHANNELS, 1, getIterations(), getLearningRate()); + + //create the output latice + for (double x = 0; x < getWidth(); x++) + brain.createOutput(new Vector(new double[]{x})); + + //run through random training data for all iterations + for (int iteration = 0; iteration < getIterations(); iteration++) { + this.progress++; + + for (int ci = 0; ci < COLOR_CHANNELS; ci++) + brain.setInput(ci, RANDOM.nextDouble()); + + brain.getBestMatchingUnit(true); + } + + //pull the output weight vectors + final Map<Vector, double[]> outputWeightVectors = brain.getOutputWeightVectors(); + + //construct the color array + Color[] colorPositions = new Color[getWidth()]; + for (Entry<Vector, double[]> weightVector : outputWeightVectors.entrySet()) { + final Vector currentPoint = weightVector.getKey(); + final double[] currentVector = weightVector.getValue(); + + //convert the current Vector to a color. + final Color currentColor = new Color((float) currentVector[0], (float) currentVector[1], (float) currentVector[2]); + + //add the current color to the colorPositions + colorPositions[(int) Math.floor(currentPoint.getCoordinate(1))] = currentColor; + } + + //return the color positions + return colorPositions; + } + catch (Exception caught) { + LOGGER.error("Exception was caught", caught); + throw new RuntimeException("Throwable was caught", caught); + } + catch (Error caught) { + LOGGER.error("Error was caught", caught); + throw new Error("Throwable was caught", caught); + } + } + + /** + * @return the iterations + */ + public int getIterations() { + return iterations; + } + + /** + * @return the learningRate + */ + public double getLearningRate() { + return learningRate; + } + + /** + * @return the width + */ + public int getWidth() { + return width; + } + + /** + * @return the progress + */ + public int getProgress() { + return progress; + } } diff --git a/src/main/java/com/syncleus/dann/examples/colormap/ColorMap2dCallable.java b/src/main/java/com/syncleus/dann/examples/colormap/ColorMap2dCallable.java index bce91b098ddebd4761c034f9db49219febdb2429..9b4d99984e6b006cdd96685bfb027db8bb9e7de8 100644 --- a/src/main/java/com/syncleus/dann/examples/colormap/ColorMap2dCallable.java +++ b/src/main/java/com/syncleus/dann/examples/colormap/ColorMap2dCallable.java @@ -18,156 +18,134 @@ ******************************************************************************/ package com.syncleus.dann.examples.colormap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Random; -import java.util.concurrent.Callable; import com.syncleus.dann.math.Vector; import com.syncleus.dann.neural.Synapse; -import com.syncleus.dann.neural.som.SomInputNeuron; -import com.syncleus.dann.neural.som.SomNeuron; -import com.syncleus.dann.neural.som.SomOutputNeuron; +import com.syncleus.dann.neural.som.*; import com.syncleus.dann.neural.som.brain.ExponentialDecaySomBrain; -import java.awt.Color; import org.apache.log4j.Logger; -public class ColorMap2dCallable implements Callable<Color[][]> -{ - private volatile int iterations; - private volatile double learningRate; - private volatile int width; - private volatile int height; - - private static final Random RANDOM = new Random(); - - private volatile int progress; - - private static final Logger LOGGER = Logger.getLogger(ColorMap2dCallable.class); - - public ColorMap2dCallable(final int iterations, final double learningRate, final int width, final int height) - { - this.iterations = iterations; - this.learningRate = learningRate; - this.width = width; - this.height = height; - } - - @Override - public Color[][] call() - { - try - { - //initialize brain - final ExponentialDecaySomBrain<SomInputNeuron, SomOutputNeuron, SomNeuron, Synapse<SomNeuron>> brain - = new ExponentialDecaySomBrain<SomInputNeuron, SomOutputNeuron, SomNeuron, Synapse<SomNeuron>>(ColorMap1dCallable.COLOR_CHANNELS, 2, getIterations(), getLearningRate()); - - //create the output latice - for(double x = 0; x < getWidth(); x++) - for(double y = 0; y < getHeight(); y++) - brain.createOutput(new Vector(new double[] {x, y})); - - //makes sure all the weights are randomly distributed within the - //output bounds. - for(Synapse synapse : brain.getEdges()) - synapse.setWeight(RANDOM.nextDouble()); - - //run through random training data - for(int iteration = 0; iteration < getIterations(); iteration++) - { - this.progress++; - - for (int ci = 0; ci < ColorMap1dCallable.COLOR_CHANNELS; ci++) - brain.setInput(ci, RANDOM.nextDouble()); - - brain.getBestMatchingUnit(true); - } - - //pull the output weight vectors - final Map<Vector, double[]> outputWeightVectors = brain.getOutputWeightVectors(); - - //construct the color array - Color[][] colorPositions = new Color[getWidth()][getHeight()]; - for(Entry<Vector, double[]> weightVector : outputWeightVectors.entrySet()) - { - final Vector currentPoint = weightVector.getKey(); - final double[] currentVector = weightVector.getValue(); - - //convert the current Vector to a color. - if( (float)currentVector[0] < 0f ) - { - LOGGER.warn("Incorrect red component: " + currentVector[0]); - currentVector[0] *= -1f; - } - if( (float)currentVector[1] < 0f ) - { - LOGGER.warn("Incorrect green compoent: " + currentVector[1]); - currentVector[1] *= -1f; - } - if( (float)currentVector[2] < 0f ) - { - LOGGER.warn("Incorrect blue compoent: " + currentVector[1]); - currentVector[2] *= -1f; - } - final Color currentColor = new Color((float)currentVector[0], (float)currentVector[1], (float)currentVector[2]); - - //add the current color to the colorPositions - colorPositions[(int)Math.floor(currentPoint.getCoordinate(1))][(int)Math.floor(currentPoint.getCoordinate(2))] = currentColor; - } - - //return the color positions - return colorPositions; - } - catch(Exception caught) - { - LOGGER.error("Exception was caught", caught); - throw new RuntimeException("Throwable was caught", caught); - } - catch(Error caught) - { - LOGGER.error("Error was caught", caught); - throw new Error("Throwable was caught", caught); - } - } - - - - /** - * @return the iterations - */ - public int getIterations() - { - return iterations; - } - - /** - * @return the learningRate - */ - public double getLearningRate() - { - return learningRate; - } - - /** - * @return the width - */ - public int getWidth() - { - return width; - } - - /** - * @return the height - */ - public int getHeight() - { - return height; - } - - /** - * @return the progress - */ - public int getProgress() - { - return progress; - } +import java.awt.*; +import java.util.*; +import java.util.Map.Entry; +import java.util.concurrent.Callable; + +public class ColorMap2dCallable implements Callable<Color[][]> { + private static final Random RANDOM = new Random(); + private static final Logger LOGGER = Logger.getLogger(ColorMap2dCallable.class); + private volatile int iterations; + private volatile double learningRate; + private volatile int width; + private volatile int height; + private volatile int progress; + + public ColorMap2dCallable(final int iterations, final double learningRate, final int width, final int height) { + this.iterations = iterations; + this.learningRate = learningRate; + this.width = width; + this.height = height; + } + + @Override + public Color[][] call() { + try { + //initialize brain + final ExponentialDecaySomBrain<SomInputNeuron, SomOutputNeuron, SomNeuron, Synapse<SomNeuron>> brain + = new ExponentialDecaySomBrain<SomInputNeuron, SomOutputNeuron, SomNeuron, Synapse<SomNeuron>>(ColorMap1dCallable.COLOR_CHANNELS, 2, getIterations(), getLearningRate()); + + //create the output latice + for (double x = 0; x < getWidth(); x++) + for (double y = 0; y < getHeight(); y++) + brain.createOutput(new Vector(new double[]{x, y})); + + //makes sure all the weights are randomly distributed within the + //output bounds. + for (Synapse synapse : brain.getEdges()) + synapse.setWeight(RANDOM.nextDouble()); + + //run through random training data + for (int iteration = 0; iteration < getIterations(); iteration++) { + this.progress++; + + for (int ci = 0; ci < ColorMap1dCallable.COLOR_CHANNELS; ci++) + brain.setInput(ci, RANDOM.nextDouble()); + + brain.getBestMatchingUnit(true); + } + + //pull the output weight vectors + final Map<Vector, double[]> outputWeightVectors = brain.getOutputWeightVectors(); + + //construct the color array + Color[][] colorPositions = new Color[getWidth()][getHeight()]; + for (Entry<Vector, double[]> weightVector : outputWeightVectors.entrySet()) { + final Vector currentPoint = weightVector.getKey(); + final double[] currentVector = weightVector.getValue(); + + //convert the current Vector to a color. + if ((float) currentVector[0] < 0f) { + LOGGER.warn("Incorrect red component: " + currentVector[0]); + currentVector[0] *= -1f; + } + if ((float) currentVector[1] < 0f) { + LOGGER.warn("Incorrect green compoent: " + currentVector[1]); + currentVector[1] *= -1f; + } + if ((float) currentVector[2] < 0f) { + LOGGER.warn("Incorrect blue compoent: " + currentVector[1]); + currentVector[2] *= -1f; + } + final Color currentColor = new Color((float) currentVector[0], (float) currentVector[1], (float) currentVector[2]); + + //add the current color to the colorPositions + colorPositions[(int) Math.floor(currentPoint.getCoordinate(1))][(int) Math.floor(currentPoint.getCoordinate(2))] = currentColor; + } + + //return the color positions + return colorPositions; + } + catch (Exception caught) { + LOGGER.error("Exception was caught", caught); + throw new RuntimeException("Throwable was caught", caught); + } + catch (Error caught) { + LOGGER.error("Error was caught", caught); + throw new Error("Throwable was caught", caught); + } + } + + + /** + * @return the iterations + */ + public int getIterations() { + return iterations; + } + + /** + * @return the learningRate + */ + public double getLearningRate() { + return learningRate; + } + + /** + * @return the width + */ + public int getWidth() { + return width; + } + + /** + * @return the height + */ + public int getHeight() { + return height; + } + + /** + * @return the progress + */ + public int getProgress() { + return progress; + } } diff --git a/src/main/java/com/syncleus/dann/examples/colormap/ColorMapDemo.java b/src/main/java/com/syncleus/dann/examples/colormap/ColorMapDemo.java index 462eb3cb9bb71b37940d127f2c291848f39baa77..48b521ee3eb92d77a5d9815ba1d57bf1d116d6d4 100644 --- a/src/main/java/com/syncleus/dann/examples/colormap/ColorMapDemo.java +++ b/src/main/java/com/syncleus/dann/examples/colormap/ColorMapDemo.java @@ -18,188 +18,189 @@ ******************************************************************************/ package com.syncleus.dann.examples.colormap; -import java.awt.Color; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import javax.swing.JFrame; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import javax.swing.SpinnerNumberModel; -import javax.swing.Timer; -import javax.swing.UIManager; import org.apache.log4j.Logger; -public class ColorMapDemo extends JFrame implements ActionListener -{ - private static final Logger LOGGER = Logger.getLogger(ColorMapDemo.class); - - private final SpinnerNumberModel iterationsModel = new SpinnerNumberModel(INITIAL_ITERATIONS, 1, 10000, 100); - private final SpinnerNumberModel learningRateModel = new SpinnerNumberModel(INITIAL_LEARNING_RATE, Double.MIN_VALUE, 1.0, 0.01); +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.util.concurrent.*; + +public class ColorMapDemo extends JFrame implements ActionListener { + private static final Logger LOGGER = Logger.getLogger(ColorMapDemo.class); + private static final int INITIAL_ITERATIONS = 200; + private final SpinnerNumberModel iterationsModel = new SpinnerNumberModel(INITIAL_ITERATIONS, 1, 10000, 100); + private static final double INITIAL_LEARNING_RATE = 0.5; + private final SpinnerNumberModel learningRateModel = new SpinnerNumberModel(INITIAL_LEARNING_RATE, Double.MIN_VALUE, 1.0, 0.01); + private final ExecutorService executor; + private final Timer progressTimer = new Timer(100, this); + private Color[] color1d; + private Color[][] color2d; + private Future<Color[]> future1d; + private Future<Color[][]> future2d; + private ColorMap1dCallable callable1d; + private ColorMap2dCallable callable2d; + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JMenuItem aboutMenuItem; + private javax.swing.JComboBox dimentionalityComboBox; + private javax.swing.JMenuItem exitMenuItem; + private javax.swing.JSpinner iterationsSpinner; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JMenu jMenu1; + private javax.swing.JMenu jMenu2; + private javax.swing.JMenuBar jMenuBar1; + private javax.swing.JSpinner learningRateSpinner; + private javax.swing.JProgressBar progressBar; + private javax.swing.JButton trainDisplayButton; + public ColorMapDemo() { + this.executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } + catch (Exception caught) { + LOGGER.warn("Could not set the UI to native look and feel", caught); + } - private Color[] color1d; - private Color[][] color2d; + initComponents(); - private Future<Color[]> future1d; - private Future<Color[][]> future2d; + this.iterationsSpinner.setValue(INITIAL_ITERATIONS); + this.iterationsSpinner.setModel(this.iterationsModel); + this.learningRateSpinner.setValue(INITIAL_LEARNING_RATE); + this.learningRateSpinner.setModel(this.learningRateModel); + this.setResizable(false); + this.setSize(550, 175); + this.color1d = (new ColorMap1dCallable(INITIAL_ITERATIONS, INITIAL_LEARNING_RATE, 500)).call(); + + this.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent event) { + executor.shutdown(); + } + }); + } - private ColorMap1dCallable callable1d; - private ColorMap2dCallable callable2d; + public static void main(final String[] args) { + try { + java.awt.EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + try { + new ColorMapDemo().setVisible(true); + } + catch (Exception caught) { + LOGGER.error("Exception was caught", caught); + throw new RuntimeException("Exception was caught", caught); + } + catch (Error caught) { + LOGGER.error("Error was caught", caught); + throw new RuntimeException("Error was caught", caught); + } + } + }); + } + catch (Exception caught) { + LOGGER.error("Exception was caught", caught); + throw new RuntimeException("Exception was caught", caught); + } + catch (Error caught) { + LOGGER.error("Error was caught", caught); + throw new Error("Error was caught", caught); + } + } - private static final int INITIAL_ITERATIONS = 200; - private static final double INITIAL_LEARNING_RATE = 0.5; + @Override + public void actionPerformed(final ActionEvent evt) { + if (this.callable1d != null) { + this.progressBar.setMaximum(this.callable1d.getIterations()); + this.progressBar.setMinimum(0); + this.progressBar.setValue(this.callable1d.getProgress()); + } + else if (this.callable2d != null) { + this.progressBar.setMaximum(this.callable2d.getIterations()); + this.progressBar.setMinimum(0); + this.progressBar.setValue(this.callable2d.getProgress()); + } - private final ExecutorService executor; + if (this.future1d != null) { + if (!this.future1d.isDone()) + return; + try { + this.color2d = null; + this.color1d = this.future1d.get(); + this.setSize(550, 175); + this.repaint(); - private final Timer progressTimer = new Timer(100, this); + this.future1d = null; + this.future2d = null; + this.progressTimer.stop(); + this.trainDisplayButton.setEnabled(true); - public ColorMapDemo() - { - this.executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); - try - { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } + catch (InterruptedException caught) { + LOGGER.error("ColorMap was unexpectidy interupted", caught); + throw new Error("Unexpected interuption. Get should block indefinately", caught); + } + catch (ExecutionException caught) { + LOGGER.error("ColorMap had an unexcepted problem executing.", caught); + throw new Error("Unexpected execution exception. Get should block indefinately", caught); + } } - catch(Exception caught) - { - LOGGER.warn("Could not set the UI to native look and feel", caught); + else if (this.future2d != null) { + if (!this.future2d.isDone()) + return; + try { + this.color1d = null; + this.color2d = this.future2d.get(); + this.setSize(550, 650); + this.repaint(); + + this.future1d = null; + this.future2d = null; + this.progressTimer.stop(); + this.trainDisplayButton.setEnabled(true); + } + catch (InterruptedException caught) { + LOGGER.error("ColorMap was unexpectidy interupted", caught); + throw new Error("Unexpected interuption. Get should block indefinately", caught); + } + catch (ExecutionException caught) { + LOGGER.error("ColorMap had an unexcepted problem executing.", caught); + throw new Error("Unexpected execution exception. Get should block indefinately", caught); + } + } + else { + this.progressTimer.stop(); + this.trainDisplayButton.setEnabled(true); } + } - initComponents(); + @Override + public void paint(final Graphics graphics) { + super.paint(graphics); - this.iterationsSpinner.setValue(INITIAL_ITERATIONS); - this.iterationsSpinner.setModel(this.iterationsModel); - this.learningRateSpinner.setValue(INITIAL_LEARNING_RATE); - this.learningRateSpinner.setModel(this.learningRateModel); - this.setResizable(false); - this.setSize(550, 175); - this.color1d = (new ColorMap1dCallable(INITIAL_ITERATIONS, INITIAL_LEARNING_RATE, 500)).call(); - - this.addWindowListener(new WindowAdapter() - { - @Override - public void windowClosing(WindowEvent event) - { - executor.shutdown(); - } - }); + if (this.color1d != null) { + for (int colorIndex = 0; colorIndex < this.color1d.length; colorIndex++) { + final Color color = this.color1d[colorIndex]; + graphics.setColor(color); + graphics.drawLine(25 + colorIndex, 125, 25 + colorIndex, 150); + } + } + else if (this.color2d != null) { + final Graphics2D graphics2d = (Graphics2D) graphics; + + for (int colorXIndex = 0; colorXIndex < this.color2d.length; colorXIndex++) { + for (int colorYIndex = 0; colorYIndex < this.color2d[colorXIndex].length; colorYIndex++) { + final Color color = this.color2d[colorXIndex][colorYIndex]; + graphics2d.setColor(color); + final int xPos = colorXIndex * 10; + final int yPos = colorYIndex * 10; + graphics2d.fillRect(25 + xPos, 125 + yPos, 10, 10); + } + } + } } - @Override - public void actionPerformed(final ActionEvent evt) - { - if(this.callable1d != null) - { - this.progressBar.setMaximum(this.callable1d.getIterations()); - this.progressBar.setMinimum(0); - this.progressBar.setValue(this.callable1d.getProgress()); - } - else if(this.callable2d != null) - { - this.progressBar.setMaximum(this.callable2d.getIterations()); - this.progressBar.setMinimum(0); - this.progressBar.setValue(this.callable2d.getProgress()); - } - - if(this.future1d != null) - { - if(!this.future1d.isDone()) - return; - try - { - this.color2d = null; - this.color1d = this.future1d.get(); - this.setSize(550, 175); - this.repaint(); - - this.future1d = null; - this.future2d = null; - this.progressTimer.stop(); - this.trainDisplayButton.setEnabled(true); - - } - catch(InterruptedException caught) - { - LOGGER.error("ColorMap was unexpectidy interupted", caught); - throw new Error("Unexpected interuption. Get should block indefinately", caught); - } - catch(ExecutionException caught) - { - LOGGER.error("ColorMap had an unexcepted problem executing.", caught); - throw new Error("Unexpected execution exception. Get should block indefinately", caught); - } - } - else if(this.future2d != null) - { - if(!this.future2d.isDone()) - return; - try - { - this.color1d = null; - this.color2d = this.future2d.get(); - this.setSize(550, 650); - this.repaint(); - - this.future1d = null; - this.future2d = null; - this.progressTimer.stop(); - this.trainDisplayButton.setEnabled(true); - } - catch(InterruptedException caught) - { - LOGGER.error("ColorMap was unexpectidy interupted", caught); - throw new Error("Unexpected interuption. Get should block indefinately", caught); - } - catch(ExecutionException caught) - { - LOGGER.error("ColorMap had an unexcepted problem executing.", caught); - throw new Error("Unexpected execution exception. Get should block indefinately", caught); - } - } - else - { - this.progressTimer.stop(); - this.trainDisplayButton.setEnabled(true); - } - } - - @Override - public void paint(final Graphics graphics) - { - super.paint(graphics); - - if(this.color1d != null) - { - for(int colorIndex = 0; colorIndex < this.color1d.length; colorIndex++) - { - final Color color = this.color1d[colorIndex]; - graphics.setColor(color); - graphics.drawLine(25+colorIndex, 125, 25+colorIndex, 150); - } - } - else if(this.color2d != null) - { - final Graphics2D graphics2d = (Graphics2D) graphics; - - for(int colorXIndex = 0; colorXIndex < this.color2d.length; colorXIndex++) - { - for(int colorYIndex = 0; colorYIndex < this.color2d[colorXIndex].length; colorYIndex++) - { - final Color color = this.color2d[colorXIndex][colorYIndex]; - graphics2d.setColor(color); - final int xPos = colorXIndex * 10; - final int yPos = colorYIndex * 10; - graphics2d.fillRect(25 + xPos, 125 + yPos, 10, 10); - } - } - } - } - @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { @@ -231,7 +232,7 @@ public class ColorMapDemo extends JFrame implements ActionListener jLabel3.setText("Dimentionality:"); - dimentionalityComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "1D", "2D" })); + dimentionalityComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[]{"1D", "2D"})); dimentionalityComboBox.setName("dimentionalityComboBox"); // NOI18N trainDisplayButton.setText("Train & Display"); @@ -273,148 +274,93 @@ public class ColorMapDemo extends JFrame implements ActionListener javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(jLabel1) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(iterationsSpinner, javax.swing.GroupLayout.DEFAULT_SIZE, 106, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel2) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(learningRateSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 43, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel3) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(dimentionalityComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, 332, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(trainDisplayButton))) - .addContainerGap()) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(iterationsSpinner, javax.swing.GroupLayout.DEFAULT_SIZE, 106, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel2) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(learningRateSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 43, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel3) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(dimentionalityComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, 332, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(trainDisplayButton))) + .addContainerGap()) ); layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel3) - .addComponent(dimentionalityComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel1) - .addComponent(iterationsSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(learningRateSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel2)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) - .addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(trainDisplayButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap(219, Short.MAX_VALUE)) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3) + .addComponent(dimentionalityComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1) + .addComponent(iterationsSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(learningRateSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(trainDisplayButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(219, Short.MAX_VALUE)) ); pack(); }// </editor-fold>//GEN-END:initComponents - private void exitMenuItemMouseReleased(java.awt.event.MouseEvent evt)//GEN-FIRST:event_exitMenuItemMouseReleased - {//GEN-HEADEREND:event_exitMenuItemMouseReleased - System.exit(0); - }//GEN-LAST:event_exitMenuItemMouseReleased - - private void trainDisplayButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_trainDisplayButtonActionPerformed - {//GEN-HEADEREND:event_trainDisplayButtonActionPerformed - final int iterations = this.iterationsModel.getNumber().intValue(); - final double learningRate = this.learningRateModel.getNumber().doubleValue(); - - if( this.dimentionalityComboBox.getSelectedIndex() == 0 ) - { - if(this.future1d != null) - this.future1d.cancel(true); - if(this.future2d != null) - this.future2d.cancel(true); - - this.callable2d = null; - this.future2d = null; - - this.callable1d = new ColorMap1dCallable(iterations, learningRate, 500); - this.future1d = executor.submit(this.callable1d); - } - else - { - if (this.future1d != null) - this.future1d.cancel(true); - if (this.future2d != null) - this.future2d.cancel(true); - - this.callable1d = null; - this.future1d = null; - - this.callable2d = new ColorMap2dCallable(iterations, learningRate, 50, 50); - this.future2d = executor.submit(this.callable2d); - } - - this.progressTimer.start(); - this.trainDisplayButton.setEnabled(false); - }//GEN-LAST:event_trainDisplayButtonActionPerformed - - private void aboutMenuItemMouseReleased(java.awt.event.MouseEvent evt)//GEN-FIRST:event_aboutMenuItemMouseReleased - {//GEN-HEADEREND:event_aboutMenuItemMouseReleased + private void exitMenuItemMouseReleased(java.awt.event.MouseEvent evt)//GEN-FIRST:event_exitMenuItemMouseReleased + {//GEN-HEADEREND:event_exitMenuItemMouseReleased + System.exit(0); + }//GEN-LAST:event_exitMenuItemMouseReleased + + private void trainDisplayButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_trainDisplayButtonActionPerformed + {//GEN-HEADEREND:event_trainDisplayButtonActionPerformed + final int iterations = this.iterationsModel.getNumber().intValue(); + final double learningRate = this.learningRateModel.getNumber().doubleValue(); + + if (this.dimentionalityComboBox.getSelectedIndex() == 0) { + if (this.future1d != null) + this.future1d.cancel(true); + if (this.future2d != null) + this.future2d.cancel(true); + + this.callable2d = null; + this.future2d = null; + + this.callable1d = new ColorMap1dCallable(iterations, learningRate, 500); + this.future1d = executor.submit(this.callable1d); + } + else { + if (this.future1d != null) + this.future1d.cancel(true); + if (this.future2d != null) + this.future2d.cancel(true); + + this.callable1d = null; + this.future1d = null; + + this.callable2d = new ColorMap2dCallable(iterations, learningRate, 50, 50); + this.future2d = executor.submit(this.callable2d); + } + + this.progressTimer.start(); + this.trainDisplayButton.setEnabled(false); + }//GEN-LAST:event_trainDisplayButtonActionPerformed + + private void aboutMenuItemMouseReleased(java.awt.event.MouseEvent evt)//GEN-FIRST:event_aboutMenuItemMouseReleased + {//GEN-HEADEREND:event_aboutMenuItemMouseReleased final AboutDialog about = new AboutDialog(this, true); about.setVisible(true); - }//GEN-LAST:event_aboutMenuItemMouseReleased - - public static void main(final String[] args) - { - try - { - java.awt.EventQueue.invokeLater(new Runnable() - { - @Override - public void run() - { - try - { - new ColorMapDemo().setVisible(true); - } - catch(Exception caught) - { - LOGGER.error("Exception was caught", caught); - throw new RuntimeException("Exception was caught", caught); - } - catch(Error caught) - { - LOGGER.error("Error was caught", caught); - throw new RuntimeException("Error was caught", caught); - } - } - }); - } - catch(Exception caught) - { - LOGGER.error("Exception was caught", caught); - throw new RuntimeException("Exception was caught", caught); - } - catch(Error caught) - { - LOGGER.error("Error was caught", caught); - throw new Error("Error was caught", caught); - } - } - - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JMenuItem aboutMenuItem; - private javax.swing.JComboBox dimentionalityComboBox; - private javax.swing.JMenuItem exitMenuItem; - private javax.swing.JSpinner iterationsSpinner; - private javax.swing.JLabel jLabel1; - private javax.swing.JLabel jLabel2; - private javax.swing.JLabel jLabel3; - private javax.swing.JMenu jMenu1; - private javax.swing.JMenu jMenu2; - private javax.swing.JMenuBar jMenuBar1; - private javax.swing.JSpinner learningRateSpinner; - private javax.swing.JProgressBar progressBar; - private javax.swing.JButton trainDisplayButton; + }//GEN-LAST:event_aboutMenuItemMouseReleased // End of variables declaration//GEN-END:variables } diff --git a/src/main/java/com/syncleus/dann/examples/fft/FftDemo.java b/src/main/java/com/syncleus/dann/examples/fft/FftDemo.java index 0553c971e6e352a339175510f03a6484aa89692a..5aec1dd53d29c3138598fd1466f85e80600542f1 100644 --- a/src/main/java/com/syncleus/dann/examples/fft/FftDemo.java +++ b/src/main/java/com/syncleus/dann/examples/fft/FftDemo.java @@ -18,82 +18,115 @@ ******************************************************************************/ package com.syncleus.dann.examples.fft; -import com.syncleus.dann.dataprocessing.signal.transform.CooleyTukeyFastFourierTransformer; -import com.syncleus.dann.dataprocessing.signal.transform.DiscreteFourierTransform; -import com.syncleus.dann.dataprocessing.signal.transform.FastFourierTransformer; -import java.awt.Color; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import javax.sound.sampled.AudioFormat; -import javax.sound.sampled.AudioSystem; -import javax.sound.sampled.DataLine; -import javax.sound.sampled.LineUnavailableException; -import javax.sound.sampled.TargetDataLine; -import javax.swing.JFrame; -import javax.swing.JProgressBar; -import javax.swing.Timer; - -public class FftDemo extends JFrame implements ActionListener -{ - /** - * The sample rate in Hz. - * Common values: 8000, 11025, 16000, 22050, 44100 - */ - private static final float AUDIO_SAMPLE_RATE = 8000.0F; - /** The sample size in bits. */ - private static final int AUDIO_SAMPLE_SIZE = 16; - private static final int AUDIO_CHANNELS = 1; - private static final boolean AUDIO_SIGNED = true; - private static final boolean AUDIO_BIG_ENDIAN = false; - - private final AudioFormat audioFormat; - private final TargetDataLine targetDataLine; - private final FastFourierTransformer transformer; - private final JProgressBar[] frequencyBars; - private final Timer sampleTimer = new Timer(100, this); - - public FftDemo() - { +import com.syncleus.dann.dataprocessing.signal.transform.*; + +import javax.sound.sampled.*; +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; + +public class FftDemo extends JFrame implements ActionListener { + /** + * The sample rate in Hz. + * Common values: 8000, 11025, 16000, 22050, 44100 + */ + private static final float AUDIO_SAMPLE_RATE = 8000.0F; + /** + * The sample size in bits. + */ + private static final int AUDIO_SAMPLE_SIZE = 16; + private static final int AUDIO_CHANNELS = 1; + private static final boolean AUDIO_SIGNED = true; + private static final boolean AUDIO_BIG_ENDIAN = false; + + private final AudioFormat audioFormat; + private final TargetDataLine targetDataLine; + private final FastFourierTransformer transformer; + private final JProgressBar[] frequencyBars; + private final Timer sampleTimer = new Timer(100, this); + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JMenuItem aboutMenuItem; + private javax.swing.JMenuItem exitMenuItem; + private javax.swing.JMenu fileMenuItem; + private javax.swing.JProgressBar frequencyBar1; + private javax.swing.JProgressBar frequencyBar10; + private javax.swing.JProgressBar frequencyBar11; + private javax.swing.JProgressBar frequencyBar12; + private javax.swing.JProgressBar frequencyBar13; + private javax.swing.JProgressBar frequencyBar14; + private javax.swing.JProgressBar frequencyBar15; + private javax.swing.JProgressBar frequencyBar16; + private javax.swing.JProgressBar frequencyBar17; + private javax.swing.JProgressBar frequencyBar18; + private javax.swing.JProgressBar frequencyBar19; + private javax.swing.JProgressBar frequencyBar2; + private javax.swing.JProgressBar frequencyBar20; + private javax.swing.JProgressBar frequencyBar21; + private javax.swing.JProgressBar frequencyBar22; + private javax.swing.JProgressBar frequencyBar23; + private javax.swing.JProgressBar frequencyBar24; + private javax.swing.JProgressBar frequencyBar3; + private javax.swing.JProgressBar frequencyBar4; + private javax.swing.JProgressBar frequencyBar5; + private javax.swing.JProgressBar frequencyBar6; + private javax.swing.JProgressBar frequencyBar7; + private javax.swing.JProgressBar frequencyBar8; + private javax.swing.JProgressBar frequencyBar9; + private javax.swing.JMenu helpMenuItem; + private javax.swing.JMenuBar jMenuBar1; + private javax.swing.JButton listenButton; + public FftDemo() { initComponents(); - this.setResizable(false); - - this.frequencyBars = new JProgressBar[]{frequencyBar1, frequencyBar2, - frequencyBar3, frequencyBar4, - frequencyBar5, frequencyBar6, - frequencyBar7, frequencyBar8, - frequencyBar9, frequencyBar10, - frequencyBar11, frequencyBar12, - frequencyBar13, frequencyBar14, - frequencyBar15, frequencyBar16, - frequencyBar17, frequencyBar18, - frequencyBar19, frequencyBar20, - frequencyBar21, frequencyBar22, - frequencyBar23, frequencyBar24}; - - //set the colors as a fradient from blue to red - for(int index = 0; index < this.frequencyBars.length; index++) - { - final float colorPercent = ((float)index) / ((float)(this.frequencyBars.length-1)); - this.frequencyBars[index].setForeground(new Color(colorPercent, 0.0f, 1.0f - colorPercent)); - this.frequencyBars[index].setMaximum(1024); - } - - this.audioFormat = createAudioFormat(); - final DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat); - TargetDataLine myTargetDataLine = null; - try - { - myTargetDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo); - } - catch(LineUnavailableException caughtException) - { - System.out.println("Line unavailible, exiting..."); - System.exit(0); - } - this.targetDataLine = myTargetDataLine; - - this.transformer = new CooleyTukeyFastFourierTransformer(1024, 8000); + this.setResizable(false); + + this.frequencyBars = new JProgressBar[]{frequencyBar1, frequencyBar2, + frequencyBar3, frequencyBar4, + frequencyBar5, frequencyBar6, + frequencyBar7, frequencyBar8, + frequencyBar9, frequencyBar10, + frequencyBar11, frequencyBar12, + frequencyBar13, frequencyBar14, + frequencyBar15, frequencyBar16, + frequencyBar17, frequencyBar18, + frequencyBar19, frequencyBar20, + frequencyBar21, frequencyBar22, + frequencyBar23, frequencyBar24}; + + //set the colors as a fradient from blue to red + for (int index = 0; index < this.frequencyBars.length; index++) { + final float colorPercent = ((float) index) / ((float) (this.frequencyBars.length - 1)); + this.frequencyBars[index].setForeground(new Color(colorPercent, 0.0f, 1.0f - colorPercent)); + this.frequencyBars[index].setMaximum(1024); + } + + this.audioFormat = createAudioFormat(); + final DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat); + TargetDataLine myTargetDataLine = null; + try { + myTargetDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo); + } + catch (LineUnavailableException caughtException) { + System.out.println("Line unavailible, exiting..."); + System.exit(0); + } + this.targetDataLine = myTargetDataLine; + + this.transformer = new CooleyTukeyFastFourierTransformer(1024, 8000); + } + + private static AudioFormat createAudioFormat() { + return new AudioFormat(AUDIO_SAMPLE_RATE, AUDIO_SAMPLE_SIZE, AUDIO_CHANNELS, AUDIO_SIGNED, AUDIO_BIG_ENDIAN); + } + + public static void main(final String[] args) { + java.awt.EventQueue.invokeLater( + new Runnable() { + @Override + public void run() { + new FftDemo().setVisible(true); + } + }); } @SuppressWarnings("unchecked") @@ -216,213 +249,154 @@ public class FftDemo extends JFrame implements ActionListener javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(frequencyBar1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(frequencyBar2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(frequencyBar3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(frequencyBar4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(frequencyBar5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(frequencyBar6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(frequencyBar7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(frequencyBar8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(frequencyBar9, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(frequencyBar10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(frequencyBar11, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(listenButton) - .addGroup(layout.createSequentialGroup() - .addComponent(frequencyBar12, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(frequencyBar13, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(frequencyBar14, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(frequencyBar15, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(frequencyBar16, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(frequencyBar17, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(frequencyBar18, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(frequencyBar19, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(frequencyBar20, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(frequencyBar21, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(frequencyBar22, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(frequencyBar23, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(frequencyBar24, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(frequencyBar1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(frequencyBar2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(frequencyBar3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(frequencyBar4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(frequencyBar5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(frequencyBar6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(frequencyBar7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(frequencyBar8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(frequencyBar9, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(frequencyBar10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(frequencyBar11, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(listenButton) + .addGroup(layout.createSequentialGroup() + .addComponent(frequencyBar12, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(frequencyBar13, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(frequencyBar14, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(frequencyBar15, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(frequencyBar16, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(frequencyBar17, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(frequencyBar18, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(frequencyBar19, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(frequencyBar20, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(frequencyBar21, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(frequencyBar22, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(frequencyBar23, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(frequencyBar24, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(frequencyBar24, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) - .addComponent(frequencyBar23, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) - .addComponent(frequencyBar22, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) - .addComponent(frequencyBar21, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) - .addComponent(frequencyBar20, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) - .addComponent(frequencyBar19, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) - .addComponent(frequencyBar18, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) - .addComponent(frequencyBar17, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) - .addComponent(frequencyBar16, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) - .addComponent(frequencyBar15, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) - .addComponent(frequencyBar14, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) - .addComponent(frequencyBar8, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) - .addComponent(frequencyBar7, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) - .addComponent(frequencyBar6, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) - .addComponent(frequencyBar5, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) - .addComponent(frequencyBar4, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) - .addComponent(frequencyBar3, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) - .addComponent(frequencyBar2, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) - .addComponent(frequencyBar1, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) - .addComponent(frequencyBar9, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) - .addComponent(frequencyBar10, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) - .addComponent(frequencyBar11, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) - .addComponent(frequencyBar12, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) - .addComponent(frequencyBar13, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(listenButton) - .addContainerGap()) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(frequencyBar24, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) + .addComponent(frequencyBar23, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) + .addComponent(frequencyBar22, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) + .addComponent(frequencyBar21, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) + .addComponent(frequencyBar20, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) + .addComponent(frequencyBar19, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) + .addComponent(frequencyBar18, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) + .addComponent(frequencyBar17, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) + .addComponent(frequencyBar16, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) + .addComponent(frequencyBar15, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) + .addComponent(frequencyBar14, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) + .addComponent(frequencyBar8, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) + .addComponent(frequencyBar7, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) + .addComponent(frequencyBar6, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) + .addComponent(frequencyBar5, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) + .addComponent(frequencyBar4, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) + .addComponent(frequencyBar3, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) + .addComponent(frequencyBar2, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) + .addComponent(frequencyBar1, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) + .addComponent(frequencyBar9, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) + .addComponent(frequencyBar10, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) + .addComponent(frequencyBar11, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) + .addComponent(frequencyBar12, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) + .addComponent(frequencyBar13, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(listenButton) + .addContainerGap()) ); pack(); }// </editor-fold>//GEN-END:initComponents - private void exitMenuItemMouseReleased(java.awt.event.MouseEvent evt)//GEN-FIRST:event_exitMenuItemMouseReleased - {//GEN-HEADEREND:event_exitMenuItemMouseReleased - System.exit(0); - }//GEN-LAST:event_exitMenuItemMouseReleased - - private void listenButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_listenButtonActionPerformed - {//GEN-HEADEREND:event_listenButtonActionPerformed - try - { - if(this.targetDataLine.isOpen()) - { - this.sampleTimer.stop(); - - this.targetDataLine.stop(); - this.targetDataLine.close(); - - this.listenButton.setText("Listen"); - } - else - { - this.targetDataLine.open(audioFormat); - this.targetDataLine.start(); - - this.sampleTimer.start(); - - this.listenButton.setText("Stop"); - } - } - catch(LineUnavailableException caughtException) - { - System.out.println("Line unavailible, exiting..."); - System.exit(0); - } - }//GEN-LAST:event_listenButtonActionPerformed - - @Override - public void actionPerformed(final ActionEvent evt) - { - if(this.transformer.getBlockSize()*2 <= this.targetDataLine.available()) - { - final byte[] signalBytes = new byte[this.transformer.getBlockSize()*2]; - this.targetDataLine.read(signalBytes, 0, signalBytes.length); - - final double[] signal = new double[this.transformer.getBlockSize()]; - for(int signalIndex = 0; signalIndex < signal.length; signalIndex++) - { - final int signalBytesIndex = signalIndex * 2; - signal[signalIndex] = bytesToDouble(signalBytes[signalBytesIndex], signalBytes[signalBytesIndex+1]); - } - - final DiscreteFourierTransform transform = this.transformer.transform(signal); - final double maximumFrequency = transform.getMaximumFrequency(); - final double bandSize = maximumFrequency/((double)this.frequencyBars.length); - for(int frequencyBarIndex = 0; frequencyBarIndex < this.frequencyBars.length; frequencyBarIndex++) - { - final double bandPower = transform.getBandGeometricMean(((double)frequencyBarIndex) * bandSize, ((double)frequencyBarIndex + 1) * bandSize); - this.frequencyBars[frequencyBarIndex].setValue((int) (bandPower * 500.0)); - } - } - } - - private double bytesToDouble(final byte... data) - { - return ((double) (((short)data[1]) << 8) + ((short)data[0])) / ((double)Short.MAX_VALUE); - } - - private static AudioFormat createAudioFormat() - { - return new AudioFormat(AUDIO_SAMPLE_RATE, AUDIO_SAMPLE_SIZE, AUDIO_CHANNELS, AUDIO_SIGNED, AUDIO_BIG_ENDIAN); - } - - public static void main(final String[] args) - { - java.awt.EventQueue.invokeLater( - new Runnable() - { - @Override - public void run() - { - new FftDemo().setVisible(true); - } - }); + private void exitMenuItemMouseReleased(java.awt.event.MouseEvent evt)//GEN-FIRST:event_exitMenuItemMouseReleased + {//GEN-HEADEREND:event_exitMenuItemMouseReleased + System.exit(0); + }//GEN-LAST:event_exitMenuItemMouseReleased + + private void listenButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_listenButtonActionPerformed + {//GEN-HEADEREND:event_listenButtonActionPerformed + try { + if (this.targetDataLine.isOpen()) { + this.sampleTimer.stop(); + + this.targetDataLine.stop(); + this.targetDataLine.close(); + + this.listenButton.setText("Listen"); + } + else { + this.targetDataLine.open(audioFormat); + this.targetDataLine.start(); + + this.sampleTimer.start(); + + this.listenButton.setText("Stop"); + } + } + catch (LineUnavailableException caughtException) { + System.out.println("Line unavailible, exiting..."); + System.exit(0); + } + }//GEN-LAST:event_listenButtonActionPerformed + + @Override + public void actionPerformed(final ActionEvent evt) { + if (this.transformer.getBlockSize() * 2 <= this.targetDataLine.available()) { + final byte[] signalBytes = new byte[this.transformer.getBlockSize() * 2]; + this.targetDataLine.read(signalBytes, 0, signalBytes.length); + + final double[] signal = new double[this.transformer.getBlockSize()]; + for (int signalIndex = 0; signalIndex < signal.length; signalIndex++) { + final int signalBytesIndex = signalIndex * 2; + signal[signalIndex] = bytesToDouble(signalBytes[signalBytesIndex], signalBytes[signalBytesIndex + 1]); + } + + final DiscreteFourierTransform transform = this.transformer.transform(signal); + final double maximumFrequency = transform.getMaximumFrequency(); + final double bandSize = maximumFrequency / ((double) this.frequencyBars.length); + for (int frequencyBarIndex = 0; frequencyBarIndex < this.frequencyBars.length; frequencyBarIndex++) { + final double bandPower = transform.getBandGeometricMean(((double) frequencyBarIndex) * bandSize, ((double) frequencyBarIndex + 1) * bandSize); + this.frequencyBars[frequencyBarIndex].setValue((int) (bandPower * 500.0)); + } + } } - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JMenuItem aboutMenuItem; - private javax.swing.JMenuItem exitMenuItem; - private javax.swing.JMenu fileMenuItem; - private javax.swing.JProgressBar frequencyBar1; - private javax.swing.JProgressBar frequencyBar10; - private javax.swing.JProgressBar frequencyBar11; - private javax.swing.JProgressBar frequencyBar12; - private javax.swing.JProgressBar frequencyBar13; - private javax.swing.JProgressBar frequencyBar14; - private javax.swing.JProgressBar frequencyBar15; - private javax.swing.JProgressBar frequencyBar16; - private javax.swing.JProgressBar frequencyBar17; - private javax.swing.JProgressBar frequencyBar18; - private javax.swing.JProgressBar frequencyBar19; - private javax.swing.JProgressBar frequencyBar2; - private javax.swing.JProgressBar frequencyBar20; - private javax.swing.JProgressBar frequencyBar21; - private javax.swing.JProgressBar frequencyBar22; - private javax.swing.JProgressBar frequencyBar23; - private javax.swing.JProgressBar frequencyBar24; - private javax.swing.JProgressBar frequencyBar3; - private javax.swing.JProgressBar frequencyBar4; - private javax.swing.JProgressBar frequencyBar5; - private javax.swing.JProgressBar frequencyBar6; - private javax.swing.JProgressBar frequencyBar7; - private javax.swing.JProgressBar frequencyBar8; - private javax.swing.JProgressBar frequencyBar9; - private javax.swing.JMenu helpMenuItem; - private javax.swing.JMenuBar jMenuBar1; - private javax.swing.JButton listenButton; + private double bytesToDouble(final byte... data) { + return ((double) (((short) data[1]) << 8) + ((short) data[0])) / ((double) Short.MAX_VALUE); + } // End of variables declaration//GEN-END:variables } diff --git a/src/main/java/com/syncleus/dann/examples/hyperassociativemap/visualization/LayeredHyperassociativeMap.java b/src/main/java/com/syncleus/dann/examples/hyperassociativemap/visualization/LayeredHyperassociativeMap.java index a270d9d81790d55ac41af1ecc0bbac7df4c2c83d..5a22419b422da06d2bbd881deae381259d4159e6 100644 --- a/src/main/java/com/syncleus/dann/examples/hyperassociativemap/visualization/LayeredHyperassociativeMap.java +++ b/src/main/java/com/syncleus/dann/examples/hyperassociativemap/visualization/LayeredHyperassociativeMap.java @@ -18,16 +18,15 @@ ******************************************************************************/ package com.syncleus.dann.examples.hyperassociativemap.visualization; -import java.util.concurrent.ExecutorService; import com.syncleus.dann.graph.drawing.hyperassociativemap.HyperassociativeMap; -public class LayeredHyperassociativeMap extends HyperassociativeMap<SimpleGraph, SimpleNode> -{ - private static final int NODES_PER_LAYER = 16; - private static final int DIMENSION = 3; +import java.util.concurrent.ExecutorService; + +public class LayeredHyperassociativeMap extends HyperassociativeMap<SimpleGraph, SimpleNode> { + private static final int NODES_PER_LAYER = 16; + private static final int DIMENSION = 3; - LayeredHyperassociativeMap(final int layers, final ExecutorService executor) - { - super(new SimpleGraph(layers, NODES_PER_LAYER), DIMENSION, executor); - } + LayeredHyperassociativeMap(final int layers, final ExecutorService executor) { + super(new SimpleGraph(layers, NODES_PER_LAYER), DIMENSION, executor); + } } diff --git a/src/main/java/com/syncleus/dann/examples/hyperassociativemap/visualization/SimpleGraph.java b/src/main/java/com/syncleus/dann/examples/hyperassociativemap/visualization/SimpleGraph.java index 8875c8cd631243029c8454a57f584323930d4661..6cb58b977e9b1fab321c98f94002153959be15b0 100644 --- a/src/main/java/com/syncleus/dann/examples/hyperassociativemap/visualization/SimpleGraph.java +++ b/src/main/java/com/syncleus/dann/examples/hyperassociativemap/visualization/SimpleGraph.java @@ -18,128 +18,102 @@ ******************************************************************************/ package com.syncleus.dann.examples.hyperassociativemap.visualization; -import com.syncleus.dann.graph.AbstractBidirectedAdjacencyGraph; -import com.syncleus.dann.graph.BidirectedEdge; -import com.syncleus.dann.graph.ImmutableUndirectedEdge; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -public class SimpleGraph extends AbstractBidirectedAdjacencyGraph<SimpleNode, BidirectedEdge<SimpleNode>> -{ - private final SimpleNode[][] nodes; - private final Set<SimpleNode> nodeSet = new HashSet<SimpleNode>(); - private final Set<BidirectedEdge<SimpleNode>> edges = new HashSet<BidirectedEdge<SimpleNode>>(); - private final Map<SimpleNode, Set<BidirectedEdge<SimpleNode>>> neighborEdges = new HashMap<SimpleNode, Set<BidirectedEdge<SimpleNode>>>(); - private final Map<SimpleNode, Set<SimpleNode>> neighborNodes = new HashMap<SimpleNode, Set<SimpleNode>>(); - - public SimpleGraph(final int layers, final int nodesPerLayer) - { - this.nodes = new SimpleNode[layers][nodesPerLayer]; - - //construct nodes - for(int layerIndex = 0; layerIndex < layers; layerIndex++) - { - for(int nodeIndex = 0; nodeIndex < nodesPerLayer; nodeIndex++) - { - nodes[layerIndex][nodeIndex] = new SimpleNode(layerIndex); - this.nodeSet.add(nodes[layerIndex][nodeIndex]); - this.neighborEdges.put(nodes[layerIndex][nodeIndex], new HashSet<BidirectedEdge<SimpleNode>>()); - this.neighborNodes.put(nodes[layerIndex][nodeIndex], new HashSet<SimpleNode>()); - } - } - - //connect nodes - for(int layerIndex = 0; layerIndex < (layers-1); layerIndex++) - for(int nodeIndex = 0; nodeIndex < nodesPerLayer; nodeIndex++) - { - for(int nodeIndex2 = 0; nodeIndex2 < nodesPerLayer; nodeIndex2++) - { - final ImmutableUndirectedEdge<SimpleNode> newEdge = new ImmutableUndirectedEdge<SimpleNode>(nodes[layerIndex][nodeIndex], nodes[layerIndex+1][nodeIndex2]); - this.edges.add(newEdge); - this.neighborEdges.get(nodes[layerIndex][nodeIndex]).add(newEdge); - this.neighborNodes.get(nodes[layerIndex][nodeIndex]).add(nodes[layerIndex+1][nodeIndex2]); - this.neighborEdges.get(nodes[layerIndex+1][nodeIndex2]).add(newEdge); - this.neighborNodes.get(nodes[layerIndex+1][nodeIndex2]).add(nodes[layerIndex][nodeIndex]); - } - } - } - - public SimpleNode[][] getNodeInLayers() - { - return this.nodes; - } - - public SimpleNode getNode(final int layer, final int index) - { - if( (index >= nodes[0].length)||(layer >= nodes.length) ) - throw new IllegalArgumentException("coordinates are out of bounds"); - return this.nodes[layer][index]; - } - - @Override - public Set<SimpleNode> getNodes() - { - return Collections.unmodifiableSet(this.nodeSet); - } - - @Override - public Set<BidirectedEdge<SimpleNode>> getEdges() - { - return Collections.unmodifiableSet(this.edges); - } - - @Override - public Set<BidirectedEdge<SimpleNode>> getAdjacentEdges(final SimpleNode node) - { - return Collections.unmodifiableSet(this.neighborEdges.get(node)); - } - - @Override - public Set<BidirectedEdge<SimpleNode>> getTraversableEdges(final SimpleNode node) - { - return this.getAdjacentEdges(node); - } - - public Set<BidirectedEdge<SimpleNode>> getOutEdges(final SimpleNode node) - { - return this.getAdjacentEdges(node); - } - - @Override - public Set<BidirectedEdge<SimpleNode>> getInEdges(final SimpleNode node) - { - return this.getAdjacentEdges(node); - } - - public int getIndegree(final SimpleNode node) - { - return this.getInEdges(node).size(); - } - - public int getOutdegree(final SimpleNode node) - { - return this.getOutEdges(node).size(); - } - - public boolean isConnected(final SimpleNode leftNode, final SimpleNode rightNode) - { - return this.neighborNodes.get(leftNode).contains(rightNode); - } - - @Override - public List<SimpleNode> getAdjacentNodes(final SimpleNode node) - { - return Collections.unmodifiableList(new ArrayList<SimpleNode>(this.neighborNodes.get(node))); - } - - @Override - public List<SimpleNode> getTraversableNodes(final SimpleNode node) - { - return this.getAdjacentNodes(node); - } +import com.syncleus.dann.graph.*; + +import java.util.*; + +public class SimpleGraph extends AbstractBidirectedAdjacencyGraph<SimpleNode, BidirectedEdge<SimpleNode>> { + private final SimpleNode[][] nodes; + private final Set<SimpleNode> nodeSet = new HashSet<SimpleNode>(); + private final Set<BidirectedEdge<SimpleNode>> edges = new HashSet<BidirectedEdge<SimpleNode>>(); + private final Map<SimpleNode, Set<BidirectedEdge<SimpleNode>>> neighborEdges = new HashMap<SimpleNode, Set<BidirectedEdge<SimpleNode>>>(); + private final Map<SimpleNode, Set<SimpleNode>> neighborNodes = new HashMap<SimpleNode, Set<SimpleNode>>(); + + public SimpleGraph(final int layers, final int nodesPerLayer) { + this.nodes = new SimpleNode[layers][nodesPerLayer]; + + //construct nodes + for (int layerIndex = 0; layerIndex < layers; layerIndex++) { + for (int nodeIndex = 0; nodeIndex < nodesPerLayer; nodeIndex++) { + nodes[layerIndex][nodeIndex] = new SimpleNode(layerIndex); + this.nodeSet.add(nodes[layerIndex][nodeIndex]); + this.neighborEdges.put(nodes[layerIndex][nodeIndex], new HashSet<BidirectedEdge<SimpleNode>>()); + this.neighborNodes.put(nodes[layerIndex][nodeIndex], new HashSet<SimpleNode>()); + } + } + + //connect nodes + for (int layerIndex = 0; layerIndex < (layers - 1); layerIndex++) + for (int nodeIndex = 0; nodeIndex < nodesPerLayer; nodeIndex++) { + for (int nodeIndex2 = 0; nodeIndex2 < nodesPerLayer; nodeIndex2++) { + final ImmutableUndirectedEdge<SimpleNode> newEdge = new ImmutableUndirectedEdge<SimpleNode>(nodes[layerIndex][nodeIndex], nodes[layerIndex + 1][nodeIndex2]); + this.edges.add(newEdge); + this.neighborEdges.get(nodes[layerIndex][nodeIndex]).add(newEdge); + this.neighborNodes.get(nodes[layerIndex][nodeIndex]).add(nodes[layerIndex + 1][nodeIndex2]); + this.neighborEdges.get(nodes[layerIndex + 1][nodeIndex2]).add(newEdge); + this.neighborNodes.get(nodes[layerIndex + 1][nodeIndex2]).add(nodes[layerIndex][nodeIndex]); + } + } + } + + public SimpleNode[][] getNodeInLayers() { + return this.nodes; + } + + public SimpleNode getNode(final int layer, final int index) { + if ((index >= nodes[0].length) || (layer >= nodes.length)) + throw new IllegalArgumentException("coordinates are out of bounds"); + return this.nodes[layer][index]; + } + + @Override + public Set<SimpleNode> getNodes() { + return Collections.unmodifiableSet(this.nodeSet); + } + + @Override + public Set<BidirectedEdge<SimpleNode>> getEdges() { + return Collections.unmodifiableSet(this.edges); + } + + @Override + public Set<BidirectedEdge<SimpleNode>> getAdjacentEdges(final SimpleNode node) { + return Collections.unmodifiableSet(this.neighborEdges.get(node)); + } + + @Override + public Set<BidirectedEdge<SimpleNode>> getTraversableEdges(final SimpleNode node) { + return this.getAdjacentEdges(node); + } + + public Set<BidirectedEdge<SimpleNode>> getOutEdges(final SimpleNode node) { + return this.getAdjacentEdges(node); + } + + @Override + public Set<BidirectedEdge<SimpleNode>> getInEdges(final SimpleNode node) { + return this.getAdjacentEdges(node); + } + + public int getIndegree(final SimpleNode node) { + return this.getInEdges(node).size(); + } + + public int getOutdegree(final SimpleNode node) { + return this.getOutEdges(node).size(); + } + + public boolean isConnected(final SimpleNode leftNode, final SimpleNode rightNode) { + return this.neighborNodes.get(leftNode).contains(rightNode); + } + + @Override + public List<SimpleNode> getAdjacentNodes(final SimpleNode node) { + return Collections.unmodifiableList(new ArrayList<SimpleNode>(this.neighborNodes.get(node))); + } + + @Override + public List<SimpleNode> getTraversableNodes(final SimpleNode node) { + return this.getAdjacentNodes(node); + } } diff --git a/src/main/java/com/syncleus/dann/examples/hyperassociativemap/visualization/SimpleNode.java b/src/main/java/com/syncleus/dann/examples/hyperassociativemap/visualization/SimpleNode.java index 980f7b5900f5b764532dab5b91a85febe6b51ed2..42f357c2cf066c30c219bf17696b5d2955ab3389 100644 --- a/src/main/java/com/syncleus/dann/examples/hyperassociativemap/visualization/SimpleNode.java +++ b/src/main/java/com/syncleus/dann/examples/hyperassociativemap/visualization/SimpleNode.java @@ -18,17 +18,14 @@ ******************************************************************************/ package com.syncleus.dann.examples.hyperassociativemap.visualization; -public class SimpleNode -{ - private final int layer; +public class SimpleNode { + private final int layer; - public SimpleNode(final int layer) - { - this.layer = layer; - } + public SimpleNode(final int layer) { + this.layer = layer; + } - public int getLayer() - { - return this.layer; - } + public int getLayer() { + return this.layer; + } } diff --git a/src/main/java/com/syncleus/dann/examples/hyperassociativemap/visualization/UpdateViewRun.java b/src/main/java/com/syncleus/dann/examples/hyperassociativemap/visualization/UpdateViewRun.java index 3b5e0121c75f59a776e97676a4e019c2891094d2..5b20b97ade02262b1e614f02d7fabb461aec55b1 100644 --- a/src/main/java/com/syncleus/dann/examples/hyperassociativemap/visualization/UpdateViewRun.java +++ b/src/main/java/com/syncleus/dann/examples/hyperassociativemap/visualization/UpdateViewRun.java @@ -21,23 +21,19 @@ package com.syncleus.dann.examples.hyperassociativemap.visualization; import com.syncleus.dann.graph.drawing.hyperassociativemap.HyperassociativeMap; import com.syncleus.dann.graph.drawing.hyperassociativemap.visualization.HyperassociativeMapCanvas; -public class UpdateViewRun implements Runnable -{ - private final HyperassociativeMapCanvas view; - private final HyperassociativeMap map; +public class UpdateViewRun implements Runnable { + private final HyperassociativeMapCanvas view; + private final HyperassociativeMap map; - public UpdateViewRun(final HyperassociativeMapCanvas view, final HyperassociativeMap map) - { - this.view = view; - this.map = map; - } + public UpdateViewRun(final HyperassociativeMapCanvas view, final HyperassociativeMap map) { + this.view = view; + this.map = map; + } - public void run() - { - if (!this.map.isAligned()) - { - this.map.align(); - } - this.view.refresh(); - } + public void run() { + if (!this.map.isAligned()) { + this.map.align(); + } + this.view.refresh(); + } } diff --git a/src/main/java/com/syncleus/dann/examples/hyperassociativemap/visualization/ViewMap.java b/src/main/java/com/syncleus/dann/examples/hyperassociativemap/visualization/ViewMap.java index 0d668963178a75ef1a8a130f2a3c4040257e1d40..03fd5ab161d37197af22dec86b8a1049f99b5202 100644 --- a/src/main/java/com/syncleus/dann/examples/hyperassociativemap/visualization/ViewMap.java +++ b/src/main/java/com/syncleus/dann/examples/hyperassociativemap/visualization/ViewMap.java @@ -20,152 +20,70 @@ package com.syncleus.dann.examples.hyperassociativemap.visualization; import com.syncleus.dann.ComponentUnavailableException; import com.syncleus.dann.graph.drawing.hyperassociativemap.visualization.HyperassociativeMapCanvas; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyEvent; -import java.awt.event.KeyAdapter; -import java.awt.event.WindowEvent; -import java.awt.event.WindowAdapter; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.FutureTask; -import javax.swing.JFrame; -import javax.swing.Timer; - -public class ViewMap extends JFrame implements ActionListener -{ - private static final float NODE_RADIUS = 0.07F; - private final HyperassociativeMapCanvas mapVisual; - private final LayeredHyperassociativeMap associativeMap; - private final ExecutorService executor; - private FutureTask<Void> lastRun; - - public ViewMap() - { - // With only 1 thread, we would get a dead-lock when - // the view-update-thread is waiting for the alignment. - executor = Executors.newFixedThreadPool(Math.max(2, Runtime.getRuntime().availableProcessors())); - associativeMap = new LayeredHyperassociativeMap(8, executor); - - HyperassociativeMapCanvas myMapVisual = null; - try - { - myMapVisual = new HyperassociativeMapCanvas(associativeMap, NODE_RADIUS); - initComponents(); - - lastRun = new FutureTask<Void>(new UpdateViewRun(myMapVisual, associativeMap), null); - executor.execute(lastRun); - - myMapVisual.setFocusTraversalKeysEnabled(false); - AssociativeMapKeyAdapter keyAdapter = new AssociativeMapKeyAdapter(associativeMap); - myMapVisual.addKeyListener(keyAdapter); - myMapVisual.getCanvas3D().addKeyListener(keyAdapter); - addKeyListener(keyAdapter); - - new Timer(100, this).start(); - - myMapVisual.setLocation(0, 0); - myMapVisual.setSize(800, 600); - myMapVisual.setVisible(true); - myMapVisual.refresh(); - } - catch (ComponentUnavailableException exc) - { - myMapVisual = null; - add(exc.newPanel()); - } - mapVisual = myMapVisual; - if (mapVisual != null) { - add(mapVisual); - } - - addWindowListener(new WindowAdapter() - { - @Override - public void windowClosing(WindowEvent event) - { - executor.shutdown(); - } - }); - setFocusTraversalKeysEnabled(false); - - setSize(800, 600); - } - - private static class AssociativeMapKeyAdapter extends KeyAdapter - { - private final LayeredHyperassociativeMap associativeMap; - - public AssociativeMapKeyAdapter(final LayeredHyperassociativeMap associativeMap) - { - this.associativeMap = associativeMap; - } - @Override - public void keyPressed(final KeyEvent evt) - { - if (evt.getKeyCode() == KeyEvent.VK_R) - { - associativeMap.reset(); - } - if (evt.getKeyCode() == KeyEvent.VK_L) - { - associativeMap.resetLearning(); - } - else if (evt.getKeyCode() == KeyEvent.VK_UP) - { - double equilibDist = associativeMap.getEquilibriumDistance(); - if (equilibDist < 1.0) - { - equilibDist *= 1.1; - } - else - { - equilibDist += 1.0; - } - associativeMap.setEquilibriumDistance(equilibDist); - associativeMap.resetLearning(); - } - else if (evt.getKeyCode() == KeyEvent.VK_DOWN) - { - double equilibDist = associativeMap.getEquilibriumDistance(); - if (equilibDist < 2.0) - { - equilibDist *= 0.9; - } - else - { - equilibDist -= 1.0; - } - associativeMap.setEquilibriumDistance(equilibDist); - associativeMap.resetLearning(); - } - } - } - - @Override - public void actionPerformed(final ActionEvent evt) - { - if ((lastRun != null) && !lastRun.isDone()) - { - return; - } - - if (!isVisible()) - { - return; - } - - lastRun = new FutureTask<Void>(new UpdateViewRun(mapVisual, associativeMap), null); - executor.execute(lastRun); - } - - private static boolean checkClasses() - { - // This class does not exist in Java3D 1.3.1, so we can not use this - // test. Fortunately, it will still fail gracefully later, if Java3D - // is not is installed properly. - /* +import javax.swing.*; +import java.awt.event.*; +import java.util.concurrent.*; + +public class ViewMap extends JFrame implements ActionListener { + private static final float NODE_RADIUS = 0.07F; + private final HyperassociativeMapCanvas mapVisual; + private final LayeredHyperassociativeMap associativeMap; + private final ExecutorService executor; + private FutureTask<Void> lastRun; + + public ViewMap() { + // With only 1 thread, we would get a dead-lock when + // the view-update-thread is waiting for the alignment. + executor = Executors.newFixedThreadPool(Math.max(2, Runtime.getRuntime().availableProcessors())); + associativeMap = new LayeredHyperassociativeMap(8, executor); + + HyperassociativeMapCanvas myMapVisual = null; + try { + myMapVisual = new HyperassociativeMapCanvas(associativeMap, NODE_RADIUS); + initComponents(); + + lastRun = new FutureTask<Void>(new UpdateViewRun(myMapVisual, associativeMap), null); + executor.execute(lastRun); + + myMapVisual.setFocusTraversalKeysEnabled(false); + AssociativeMapKeyAdapter keyAdapter = new AssociativeMapKeyAdapter(associativeMap); + myMapVisual.addKeyListener(keyAdapter); + myMapVisual.getCanvas3D().addKeyListener(keyAdapter); + addKeyListener(keyAdapter); + + new Timer(100, this).start(); + + myMapVisual.setLocation(0, 0); + myMapVisual.setSize(800, 600); + myMapVisual.setVisible(true); + myMapVisual.refresh(); + } + catch (ComponentUnavailableException exc) { + myMapVisual = null; + add(exc.newPanel()); + } + mapVisual = myMapVisual; + if (mapVisual != null) { + add(mapVisual); + } + + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent event) { + executor.shutdown(); + } + }); + setFocusTraversalKeysEnabled(false); + + setSize(800, 600); + } + + private static boolean checkClasses() { + // This class does not exist in Java3D 1.3.1, so we can not use this + // test. Fortunately, it will still fail gracefully later, if Java3D + // is not is installed properly. + /* try { Class.forName("javax.media.j3d.NativePipeline"); @@ -177,32 +95,42 @@ public class ViewMap extends JFrame implements ActionListener } */ - return true; - } - - public static void main(final String[] args) - { - // check that the Java3D drivers are present - if (!checkClasses()) - { - return; - } - - System.out.println("controls:"); - System.out.println("R: reset"); - System.out.println("L: reset learning curve"); - System.out.println("up arrow: increase Equilibrium"); - System.out.println("down arrow: decrease Equilibrium"); - - java.awt.EventQueue.invokeLater(new Runnable() - { - @Override - public void run() - { - new ViewMap().setVisible(true); - } - }); - } + return true; + } + + public static void main(final String[] args) { + // check that the Java3D drivers are present + if (!checkClasses()) { + return; + } + + System.out.println("controls:"); + System.out.println("R: reset"); + System.out.println("L: reset learning curve"); + System.out.println("up arrow: increase Equilibrium"); + System.out.println("down arrow: decrease Equilibrium"); + + java.awt.EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + new ViewMap().setVisible(true); + } + }); + } + + @Override + public void actionPerformed(final ActionEvent evt) { + if ((lastRun != null) && !lastRun.isDone()) { + return; + } + + if (!isVisible()) { + return; + } + + lastRun = new FutureTask<Void>(new UpdateViewRun(mapVisual, associativeMap), null); + executor.execute(lastRun); + } // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { @@ -213,17 +141,57 @@ public class ViewMap extends JFrame implements ActionListener javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 400, Short.MAX_VALUE) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 400, Short.MAX_VALUE) ); layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 300, Short.MAX_VALUE) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 300, Short.MAX_VALUE) ); pack(); }//GEN-END:initComponents + + private static class AssociativeMapKeyAdapter extends KeyAdapter { + private final LayeredHyperassociativeMap associativeMap; + + public AssociativeMapKeyAdapter(final LayeredHyperassociativeMap associativeMap) { + this.associativeMap = associativeMap; + } + + @Override + public void keyPressed(final KeyEvent evt) { + if (evt.getKeyCode() == KeyEvent.VK_R) { + associativeMap.reset(); + } + if (evt.getKeyCode() == KeyEvent.VK_L) { + associativeMap.resetLearning(); + } + else if (evt.getKeyCode() == KeyEvent.VK_UP) { + double equilibDist = associativeMap.getEquilibriumDistance(); + if (equilibDist < 1.0) { + equilibDist *= 1.1; + } + else { + equilibDist += 1.0; + } + associativeMap.setEquilibriumDistance(equilibDist); + associativeMap.resetLearning(); + } + else if (evt.getKeyCode() == KeyEvent.VK_DOWN) { + double equilibDist = associativeMap.getEquilibriumDistance(); + if (equilibDist < 2.0) { + equilibDist *= 0.9; + } + else { + equilibDist -= 1.0; + } + associativeMap.setEquilibriumDistance(equilibDist); + associativeMap.resetLearning(); + } + } + } // Variables declaration - do not modify//GEN-BEGIN:variables // End of variables declaration//GEN-END:variables - // </editor-fold> + // </editor-fold> } diff --git a/src/main/java/com/syncleus/dann/examples/nci/BackPropagateRun.java b/src/main/java/com/syncleus/dann/examples/nci/BackPropagateRun.java index 7c9c2d65311ed4d00d075b99815e55cd935f5a43..2b2d7cd0a62ee4aeac4b4247e6d34fa785f4a1f4 100644 --- a/src/main/java/com/syncleus/dann/examples/nci/BackPropagateRun.java +++ b/src/main/java/com/syncleus/dann/examples/nci/BackPropagateRun.java @@ -22,32 +22,26 @@ import com.syncleus.dann.neural.backprop.BackpropNeuron; import org.apache.log4j.Logger; -public class BackPropagateRun implements Runnable -{ - private static final Logger LOGGER = Logger.getLogger(BackPropagateRun.class); - private final BackpropNeuron processor; +public class BackPropagateRun implements Runnable { + private static final Logger LOGGER = Logger.getLogger(BackPropagateRun.class); + private final BackpropNeuron processor; - public BackPropagateRun(final BackpropNeuron processor) - { - this.processor = processor; - } + public BackPropagateRun(final BackpropNeuron processor) { + this.processor = processor; + } - @Override - public void run() - { - try - { - this.processor.backPropagate(); - } - catch(Exception caught) - { - LOGGER.error("Exception was caught", caught); - throw new RuntimeException("Throwable was caught", caught); - } - catch(Error caught) - { - LOGGER.error("Error was caught", caught); - throw new Error("Throwable was caught", caught); - } - } + @Override + public void run() { + try { + this.processor.backPropagate(); + } + catch (Exception caught) { + LOGGER.error("Exception was caught", caught); + throw new RuntimeException("Throwable was caught", caught); + } + catch (Error caught) { + LOGGER.error("Error was caught", caught); + throw new Error("Throwable was caught", caught); + } + } } diff --git a/src/main/java/com/syncleus/dann/examples/nci/BrainListener.java b/src/main/java/com/syncleus/dann/examples/nci/BrainListener.java index c0631e37a8012ba42a66c6e1e742b32aadb83683..5a5f441dec42b410617212948f57e71e4448753f 100644 --- a/src/main/java/com/syncleus/dann/examples/nci/BrainListener.java +++ b/src/main/java/com/syncleus/dann/examples/nci/BrainListener.java @@ -20,9 +20,10 @@ package com.syncleus.dann.examples.nci; import java.awt.image.BufferedImage; -public interface BrainListener -{ - void brainFinishedBuffering(); - void brainSampleProcessed(BufferedImage finalImage); - void brainTrainingComplete(); +public interface BrainListener { + void brainFinishedBuffering(); + + void brainSampleProcessed(BufferedImage finalImage); + + void brainTrainingComplete(); } diff --git a/src/main/java/com/syncleus/dann/examples/nci/BrainRunner.java b/src/main/java/com/syncleus/dann/examples/nci/BrainRunner.java index 9589c8cc9b80c13cf08dbf82680337871369130b..7dbc8e7561dbccd0bc7b944c7a0d0842554b3103 100644 --- a/src/main/java/com/syncleus/dann/examples/nci/BrainRunner.java +++ b/src/main/java/com/syncleus/dann/examples/nci/BrainRunner.java @@ -18,289 +18,244 @@ ******************************************************************************/ package com.syncleus.dann.examples.nci; +import com.syncleus.dann.graph.drawing.hyperassociativemap.*; +import org.apache.log4j.Logger; + import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; import java.util.Random; -import com.syncleus.dann.graph.drawing.hyperassociativemap.HyperassociativeMap; -import com.syncleus.dann.graph.drawing.hyperassociativemap.LayeredBrainHyperassociativeMap; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.FutureTask; -import org.apache.log4j.Logger; - -public class BrainRunner implements Runnable -{ - private static final Logger LOGGER = Logger.getLogger(BrainRunner.class); - private static final Random RANDOM = new Random(); - private NciBrain brain; - private HyperassociativeMap brainMap; - private final double compression; - private final int xSize; - private final int ySize; - private final boolean extraConnectivity; - private BufferedImage[] trainingImages; - private File[] trainingFiles; - private BufferedImage sampleImage; - private volatile File sampleFile; - private final BrainListener listener; - private volatile boolean keepRunning = true; - private volatile int trainingRemaining = 0; - private volatile int sampleRemaining; - private volatile int sampleTotal; - - public BrainRunner(final BrainListener listener, final File[] trainingFiles, final double compression, final int xSize, final int ySize, final boolean extraConnectivity) - { - this.listener = listener; - this.trainingFiles = trainingFiles.clone(); - this.compression = compression; - this.xSize = xSize; - this.ySize = ySize; - this.extraConnectivity = extraConnectivity; - } - - public HyperassociativeMap getBrainMap() - { - return this.brainMap; - } - - public double getAverageAbsoluteWeights() - { - return this.brain.getAverageAbsoluteWeight(); - } - - public double getAverageWeights() - { - return this.brain.getAverageWeight(); - } - - public int getSampleProgress() - { - if (sampleTotal == 0) - { - return 100; - } - return ((sampleTotal - sampleRemaining) * 100) / sampleTotal; - } - - public void setSampleImage(final File sampleFile) - { - this.sampleFile = sampleFile; - } - - private void setTrainingImages(final File[] trainingFiles) - { - this.trainingFiles = trainingFiles; - try - { - this.trainingImages = new BufferedImage[this.trainingFiles.length]; - for (int trainingFilesIndex = 0; trainingFilesIndex < trainingFiles.length; trainingFilesIndex++) - { - this.trainingImages[trainingFilesIndex] = ImageIO.read(trainingFiles[trainingFilesIndex]); - } - } - catch (Exception exc) - { - System.out.println("Danger will robinson, Danger: " + exc); - LOGGER.error("Failed reading training image", exc); - } - } - - public void setTrainingCycles(final int cycles) - { - this.trainingRemaining = cycles; - } - - public int getTrainingCycles() - { - return this.trainingRemaining; - } - - public void shutdown() - { - this.keepRunning = false; - } - - public void stop() - { - this.trainingRemaining = 0; - this.sampleFile = null; - } - - @Override - public void run() - { - ExecutorService executor = null; - try - { - executor = Executors.newFixedThreadPool(1); - - this.brain = new NciBrain(this.compression, this.xSize, this.ySize, this.extraConnectivity); - this.brainMap = new LayeredBrainHyperassociativeMap(brain, 3); - this.setTrainingImages(trainingFiles); - - this.listener.brainFinishedBuffering(); - while (this.keepRunning) - { - - if (this.sampleFile != null) - { - this.brain.setLearning(false); - - this.sampleImage = ImageIO.read(sampleFile); - - final ArrayBlockingQueue<FutureTask<BufferedImage>> processingSampleSegments = new ArrayBlockingQueue<FutureTask<BufferedImage>>(12000, true); - - this.sampleTotal = 0; - stopProcessing: - for (int currentY = 0; currentY < this.sampleImage.getHeight(); currentY += ySize) - { - for (int currentX = 0; currentX < this.sampleImage.getWidth(); currentX += xSize) - { - final int blockWidth = this.sampleImage.getWidth() - currentX < xSize ? this.sampleImage.getWidth() - currentX : xSize; - final int blockHeight = this.sampleImage.getHeight() - currentY < ySize ? this.sampleImage.getHeight() - currentY : ySize; - final BufferedImage currentSegment = this.sampleImage.getSubimage(currentX, currentY, blockWidth, blockHeight); - - final SampleRun sampleRun = new SampleRun(this.brain, currentSegment); - final FutureTask<BufferedImage> futureSampleRun = new FutureTask<BufferedImage>(sampleRun); - - this.sampleTotal++; - - if (processingSampleSegments.remainingCapacity() <= 0) - { - System.out.println("The original image you selected is too large, aborting processing"); - break stopProcessing; - } - - processingSampleSegments.add(futureSampleRun); - executor.execute(futureSampleRun); - } - } - - this.sampleRemaining = this.sampleTotal; - - final BufferedImage finalImage = new BufferedImage(this.sampleImage.getWidth(), this.sampleImage.getHeight(), BufferedImage.TYPE_INT_RGB); - - this.sampleImage = null; - this.sampleFile = null; - - int currentX = 0; - int currentY = 0; - while (processingSampleSegments.peek() != null) - { - final FutureTask<BufferedImage> nextSegment = processingSampleSegments.take(); - - final BufferedImage currentSegment = nextSegment.get(); - - final int writeWidth = (currentSegment.getWidth() < (finalImage.getWidth() - currentX) ? currentSegment.getWidth() : finalImage.getWidth() - currentX); - final int writeHeight = (currentSegment.getHeight() < (finalImage.getHeight() - currentY) ? currentSegment.getHeight() : finalImage.getHeight() - currentY); - final int[] chunkArray = new int[writeHeight * writeWidth]; - currentSegment.getRGB(0, 0, writeWidth, writeHeight, chunkArray, 0, writeWidth); - finalImage.setRGB(currentX, currentY, writeWidth, writeHeight, chunkArray, 0, writeWidth); - - this.sampleRemaining--; - - if (currentX + writeWidth >= finalImage.getWidth()) - { - currentX = 0; - if (currentY + writeHeight >= finalImage.getHeight()) - { - currentY = 0; - } - else - { - currentY += writeHeight; - } - } - else - { - currentX += writeWidth; - } - } - - this.listener.brainSampleProcessed(finalImage); - } - else if (this.trainingRemaining > 0) - { - this.brain.setLearning(true); - - final ArrayBlockingQueue<FutureTask> trainingSegments = new ArrayBlockingQueue<FutureTask>(50, true); - - while (this.trainingRemaining > 0) - { - if (trainingSegments.remainingCapacity() <= 0) - { - final FutureTask currentTask = trainingSegments.take(); - currentTask.get(); - this.trainingRemaining--; - if (this.trainingRemaining < 0) - { - this.trainingRemaining = 0; - } - } - final TrainRun trainRun = new TrainRun(this.brain, this.getRandomTrainingBlock(xSize, ySize)); - final FutureTask<Void> trainTask = new FutureTask<Void>(trainRun, null); - - trainingSegments.add(trainTask); - executor.execute(trainTask); - } - - while (!trainingSegments.isEmpty()) - { - final FutureTask currentTask = trainingSegments.take(); - currentTask.get(); - this.trainingRemaining--; - if (this.trainingRemaining < 0) - { - this.trainingRemaining = 0; - } - } - - this.listener.brainTrainingComplete(); - } - else if (this.brainMap.isAligned()) - { - Thread.sleep(5); - } - else - { - this.brainMap.align(); - } - } - - - } - catch (Exception caught) - { - LOGGER.error("Exception was caught", caught); - throw new RuntimeException("Throwable was caught", caught); - } - catch (Error caught) - { - LOGGER.error("Error was caught", caught); - throw new Error("Throwable was caught", caught); - } - finally - { - if (executor != null) - { - executor.shutdown(); - } - } - } - - private BufferedImage getRandomTrainingBlock(final int width, final int height) throws IndexOutOfBoundsException - { - final BufferedImage randomImage = this.getRandomTrainingImage(); - - final int randomX = RANDOM.nextInt(randomImage.getWidth() - width); - final int randomY = RANDOM.nextInt(randomImage.getHeight() - height); - return randomImage.getSubimage(randomX, randomY, width, height); - } - - private BufferedImage getRandomTrainingImage() throws IndexOutOfBoundsException - { - return this.trainingImages[RANDOM.nextInt(this.trainingImages.length)]; - } +import java.util.concurrent.*; + +public class BrainRunner implements Runnable { + private static final Logger LOGGER = Logger.getLogger(BrainRunner.class); + private static final Random RANDOM = new Random(); + private final double compression; + private final int xSize; + private final int ySize; + private final boolean extraConnectivity; + private final BrainListener listener; + private NciBrain brain; + private HyperassociativeMap brainMap; + private BufferedImage[] trainingImages; + private File[] trainingFiles; + private BufferedImage sampleImage; + private volatile File sampleFile; + private volatile boolean keepRunning = true; + private volatile int trainingRemaining = 0; + private volatile int sampleRemaining; + private volatile int sampleTotal; + + public BrainRunner(final BrainListener listener, final File[] trainingFiles, final double compression, final int xSize, final int ySize, final boolean extraConnectivity) { + this.listener = listener; + this.trainingFiles = trainingFiles.clone(); + this.compression = compression; + this.xSize = xSize; + this.ySize = ySize; + this.extraConnectivity = extraConnectivity; + } + + public HyperassociativeMap getBrainMap() { + return this.brainMap; + } + + public double getAverageAbsoluteWeights() { + return this.brain.getAverageAbsoluteWeight(); + } + + public double getAverageWeights() { + return this.brain.getAverageWeight(); + } + + public int getSampleProgress() { + if (sampleTotal == 0) { + return 100; + } + return ((sampleTotal - sampleRemaining) * 100) / sampleTotal; + } + + public void setSampleImage(final File sampleFile) { + this.sampleFile = sampleFile; + } + + private void setTrainingImages(final File[] trainingFiles) { + this.trainingFiles = trainingFiles; + try { + this.trainingImages = new BufferedImage[this.trainingFiles.length]; + for (int trainingFilesIndex = 0; trainingFilesIndex < trainingFiles.length; trainingFilesIndex++) { + this.trainingImages[trainingFilesIndex] = ImageIO.read(trainingFiles[trainingFilesIndex]); + } + } + catch (Exception exc) { + System.out.println("Danger will robinson, Danger: " + exc); + LOGGER.error("Failed reading training image", exc); + } + } + + public int getTrainingCycles() { + return this.trainingRemaining; + } + + public void setTrainingCycles(final int cycles) { + this.trainingRemaining = cycles; + } + + public void shutdown() { + this.keepRunning = false; + } + + public void stop() { + this.trainingRemaining = 0; + this.sampleFile = null; + } + + @Override + public void run() { + ExecutorService executor = null; + try { + executor = Executors.newFixedThreadPool(1); + + this.brain = new NciBrain(this.compression, this.xSize, this.ySize, this.extraConnectivity); + this.brainMap = new LayeredBrainHyperassociativeMap(brain, 3); + this.setTrainingImages(trainingFiles); + + this.listener.brainFinishedBuffering(); + while (this.keepRunning) { + + if (this.sampleFile != null) { + this.brain.setLearning(false); + + this.sampleImage = ImageIO.read(sampleFile); + + final ArrayBlockingQueue<FutureTask<BufferedImage>> processingSampleSegments = new ArrayBlockingQueue<FutureTask<BufferedImage>>(12000, true); + + this.sampleTotal = 0; + stopProcessing: + for (int currentY = 0; currentY < this.sampleImage.getHeight(); currentY += ySize) { + for (int currentX = 0; currentX < this.sampleImage.getWidth(); currentX += xSize) { + final int blockWidth = this.sampleImage.getWidth() - currentX < xSize ? this.sampleImage.getWidth() - currentX : xSize; + final int blockHeight = this.sampleImage.getHeight() - currentY < ySize ? this.sampleImage.getHeight() - currentY : ySize; + final BufferedImage currentSegment = this.sampleImage.getSubimage(currentX, currentY, blockWidth, blockHeight); + + final SampleRun sampleRun = new SampleRun(this.brain, currentSegment); + final FutureTask<BufferedImage> futureSampleRun = new FutureTask<BufferedImage>(sampleRun); + + this.sampleTotal++; + + if (processingSampleSegments.remainingCapacity() <= 0) { + System.out.println("The original image you selected is too large, aborting processing"); + break stopProcessing; + } + + processingSampleSegments.add(futureSampleRun); + executor.execute(futureSampleRun); + } + } + + this.sampleRemaining = this.sampleTotal; + + final BufferedImage finalImage = new BufferedImage(this.sampleImage.getWidth(), this.sampleImage.getHeight(), BufferedImage.TYPE_INT_RGB); + + this.sampleImage = null; + this.sampleFile = null; + + int currentX = 0; + int currentY = 0; + while (processingSampleSegments.peek() != null) { + final FutureTask<BufferedImage> nextSegment = processingSampleSegments.take(); + + final BufferedImage currentSegment = nextSegment.get(); + + final int writeWidth = (currentSegment.getWidth() < (finalImage.getWidth() - currentX) ? currentSegment.getWidth() : finalImage.getWidth() - currentX); + final int writeHeight = (currentSegment.getHeight() < (finalImage.getHeight() - currentY) ? currentSegment.getHeight() : finalImage.getHeight() - currentY); + final int[] chunkArray = new int[writeHeight * writeWidth]; + currentSegment.getRGB(0, 0, writeWidth, writeHeight, chunkArray, 0, writeWidth); + finalImage.setRGB(currentX, currentY, writeWidth, writeHeight, chunkArray, 0, writeWidth); + + this.sampleRemaining--; + + if (currentX + writeWidth >= finalImage.getWidth()) { + currentX = 0; + if (currentY + writeHeight >= finalImage.getHeight()) { + currentY = 0; + } + else { + currentY += writeHeight; + } + } + else { + currentX += writeWidth; + } + } + + this.listener.brainSampleProcessed(finalImage); + } + else if (this.trainingRemaining > 0) { + this.brain.setLearning(true); + + final ArrayBlockingQueue<FutureTask> trainingSegments = new ArrayBlockingQueue<FutureTask>(50, true); + + while (this.trainingRemaining > 0) { + if (trainingSegments.remainingCapacity() <= 0) { + final FutureTask currentTask = trainingSegments.take(); + currentTask.get(); + this.trainingRemaining--; + if (this.trainingRemaining < 0) { + this.trainingRemaining = 0; + } + } + final TrainRun trainRun = new TrainRun(this.brain, this.getRandomTrainingBlock(xSize, ySize)); + final FutureTask<Void> trainTask = new FutureTask<Void>(trainRun, null); + + trainingSegments.add(trainTask); + executor.execute(trainTask); + } + + while (!trainingSegments.isEmpty()) { + final FutureTask currentTask = trainingSegments.take(); + currentTask.get(); + this.trainingRemaining--; + if (this.trainingRemaining < 0) { + this.trainingRemaining = 0; + } + } + + this.listener.brainTrainingComplete(); + } + else if (this.brainMap.isAligned()) { + Thread.sleep(5); + } + else { + this.brainMap.align(); + } + } + + + } + catch (Exception caught) { + LOGGER.error("Exception was caught", caught); + throw new RuntimeException("Throwable was caught", caught); + } + catch (Error caught) { + LOGGER.error("Error was caught", caught); + throw new Error("Throwable was caught", caught); + } + finally { + if (executor != null) { + executor.shutdown(); + } + } + } + + private BufferedImage getRandomTrainingBlock(final int width, final int height) throws IndexOutOfBoundsException { + final BufferedImage randomImage = this.getRandomTrainingImage(); + + final int randomX = RANDOM.nextInt(randomImage.getWidth() - width); + final int randomY = RANDOM.nextInt(randomImage.getHeight() - height); + return randomImage.getSubimage(randomX, randomY, width, height); + } + + private BufferedImage getRandomTrainingImage() throws IndexOutOfBoundsException { + return this.trainingImages[RANDOM.nextInt(this.trainingImages.length)]; + } } diff --git a/src/main/java/com/syncleus/dann/examples/nci/BusyException.java b/src/main/java/com/syncleus/dann/examples/nci/BusyException.java index 7bc8dbce25b0fce460a6b0eb9829d6416be53f0b..ae24c47176bc76451c75d4d7552f48be6c137618 100644 --- a/src/main/java/com/syncleus/dann/examples/nci/BusyException.java +++ b/src/main/java/com/syncleus/dann/examples/nci/BusyException.java @@ -18,15 +18,12 @@ ******************************************************************************/ package com.syncleus.dann.examples.nci; -public class BusyException extends Exception -{ - public BusyException() - { - super(); - } +public class BusyException extends Exception { + public BusyException() { + super(); + } - public BusyException(final String msg) - { - super(msg); - } + public BusyException(final String msg) { + super(msg); + } } diff --git a/src/main/java/com/syncleus/dann/examples/nci/CompressionNeuron.java b/src/main/java/com/syncleus/dann/examples/nci/CompressionNeuron.java index 9460626e7e1d70fd0af3cefcf132d38407ba845c..cb89eb2b0f84c9df9fe62395c7731b1e2792b3c9 100644 --- a/src/main/java/com/syncleus/dann/examples/nci/CompressionNeuron.java +++ b/src/main/java/com/syncleus/dann/examples/nci/CompressionNeuron.java @@ -18,8 +18,7 @@ ******************************************************************************/ package com.syncleus.dann.examples.nci; -import com.syncleus.dann.neural.Brain; -import com.syncleus.dann.neural.Synapse; +import com.syncleus.dann.neural.*; import com.syncleus.dann.neural.activation.ActivationFunction; import com.syncleus.dann.neural.backprop.AbstractBackpropNeuron; @@ -27,95 +26,85 @@ import com.syncleus.dann.neural.backprop.AbstractBackpropNeuron; * @author Jeffrey Phillips Freeman * @since 1.0 */ -public final class CompressionNeuron extends AbstractBackpropNeuron -{ - /** - * @since 1.0 - */ - private byte input = 0; - /** - * @since 1.0 - */ - private boolean inputSet = false; +public final class CompressionNeuron extends AbstractBackpropNeuron { + /** + * @since 1.0 + */ + private byte input = 0; + /** + * @since 1.0 + */ + private boolean inputSet = false; - /** - * Creates a new instance of InputNeuron<BR> - * @since 1.0 - */ - public CompressionNeuron(final Brain brain) - { - super(brain); - } + /** + * Creates a new instance of InputNeuron<BR> + * + * @since 1.0 + */ + public CompressionNeuron(final Brain brain) { + super(brain); + } - /** - * Creates a new instance of InputNeuron<BR> - * @since 1.0 - */ - public CompressionNeuron(final Brain brain, final ActivationFunction activationFunction) - { - super(brain, activationFunction); - } + /** + * Creates a new instance of InputNeuron<BR> + * + * @since 1.0 + */ + public CompressionNeuron(final Brain brain, final ActivationFunction activationFunction) { + super(brain, activationFunction); + } - public CompressionNeuron(final Brain brain, final double learningRate) - { - super(brain, learningRate); - } + public CompressionNeuron(final Brain brain, final double learningRate) { + super(brain, learningRate); + } - public CompressionNeuron(final Brain brain, final ActivationFunction activationFunction, final double learningRate) - { - super(brain, activationFunction, learningRate); - } + public CompressionNeuron(final Brain brain, final ActivationFunction activationFunction, final double learningRate) { + super(brain, activationFunction, learningRate); + } - /** - * This method sets the current input on the neuron.<BR> - * @since 1.0 - * @param inputToSet The value to set the current input to. - */ - public void setInput(final byte inputToSet) - { - this.input = inputToSet; - this.inputSet = true; - } + /** + * This method sets the current input on the neuron.<BR> + * + * @param inputToSet The value to set the current input to. + * @since 1.0 + */ + public void setInput(final byte inputToSet) { + this.input = inputToSet; + this.inputSet = true; + } - /** - * @since 1.0 - */ - public void unsetInput() - { - this.inputSet = false; - } + /** + * @since 1.0 + */ + public void unsetInput() { + this.inputSet = false; + } - /** - * @since 1.0 - */ - public byte getChannelOutput() - { - return (byte) Math.ceil(super.getOutput() * 127.5); - } + /** + * @since 1.0 + */ + public byte getChannelOutput() { + return (byte) Math.ceil(super.getOutput() * 127.5); + } - /** - * @since 1.0 - */ - private double getDoubleInput() - { - return ((double) this.input) / 127.5; - } + /** + * @since 1.0 + */ + private double getDoubleInput() { + return ((double) this.input) / 127.5; + } - @Override - public void tick() - { - if (this.inputSet) - { - // TODO we shouldnt be calling setOutput, try getting rid of the protected in the parent and instead make some abstracts - this.setOutput(this.getDoubleInput()); - for (Synapse current : this.getBrain().getTraversableEdges(this)) - { - current.setInput(this.getOutput()); - } - } - else - { - super.tick(); - } - } + @Override + public void tick() { + if (this.inputSet) { + // TODO we shouldnt be calling setOutput, try getting rid of the protected in the parent and instead make some abstracts + this.setOutput(this.getDoubleInput()); + for (Synapse current : this.getBrain().getTraversableEdges(this)) { + current.setInput(this.getOutput()); + } + } + else { + super.tick(); + } + } } diff --git a/src/main/java/com/syncleus/dann/examples/nci/NciBrain.java b/src/main/java/com/syncleus/dann/examples/nci/NciBrain.java index c4b90b7befc197876d93d0d2c2fbeba29364af96..b806049294c916c66ad85a33d173f9d8395d3c92 100644 --- a/src/main/java/com/syncleus/dann/examples/nci/NciBrain.java +++ b/src/main/java/com/syncleus/dann/examples/nci/NciBrain.java @@ -18,298 +18,255 @@ ******************************************************************************/ package com.syncleus.dann.examples.nci; -import com.syncleus.dann.neural.InputNeuron; -import com.syncleus.dann.neural.OutputNeuron; -import com.syncleus.dann.neural.Synapse; -import com.syncleus.dann.neural.activation.ActivationFunction; -import com.syncleus.dann.neural.activation.SineActivationFunction; -import com.syncleus.dann.neural.backprop.BackpropNeuron; -import com.syncleus.dann.neural.backprop.InputBackpropNeuron; -import com.syncleus.dann.neural.backprop.OutputBackpropNeuron; -import com.syncleus.dann.neural.backprop.SimpleBackpropNeuron; -import com.syncleus.dann.neural.backprop.SimpleInputBackpropNeuron; -import com.syncleus.dann.neural.backprop.SimpleOutputBackpropNeuron; +import com.syncleus.dann.neural.*; +import com.syncleus.dann.neural.activation.*; +import com.syncleus.dann.neural.backprop.*; import com.syncleus.dann.neural.backprop.brain.AbstractFullyConnectedFeedforwardBrain; + import java.awt.image.BufferedImage; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; +import java.util.*; /** * @author Jeffrey Phillips Freeman * @since 1.0 */ -public class NciBrain extends AbstractFullyConnectedFeedforwardBrain<InputBackpropNeuron, OutputBackpropNeuron, BackpropNeuron, Synapse<BackpropNeuron>> -{ - private static final int CHANNELS = 3; - private static final double DEFAULT_LEARNING_RATE = 0.001; - private final double actualCompression; - private final int xSize; - private final int ySize; - private final InputBackpropNeuron[][][] inputNeurons; - private final List<CompressionNeuron> compressedNeurons; - private final OutputBackpropNeuron[][][] outputNeurons; - private boolean learning; - private boolean compressionInputsSet; - private final ActivationFunction activationFunction; - private final double learningRate; - - /** - * Creates an instance of NciBrain. - * @param compression A value between 0.0 (inclusive) and 1.0 (exclusive) - * which represents the % of compression. - */ - public NciBrain(final double compression, final int xSize, final int ySize, final boolean extraConnectivity) - { - super(); - - this.learningRate = DEFAULT_LEARNING_RATE; - this.activationFunction = new SineActivationFunction(); - - this.xSize = xSize; - this.ySize = ySize; - final int compressedNeuronCount = ((int) Math.ceil((((double) xSize) * ((double) ySize) * ((double) CHANNELS)) * (1.0 - compression))); - this.inputNeurons = new InputBackpropNeuron[xSize][ySize][CHANNELS]; - this.compressedNeurons = new ArrayList<CompressionNeuron>(); - this.outputNeurons = new OutputBackpropNeuron[xSize][ySize][CHANNELS]; - this.learning = true; - this.compressionInputsSet = false; - this.actualCompression = 1.0 - ((double) compressedNeuronCount) / (((double) xSize) * ((double) ySize) * ((double) CHANNELS)); - final int blockSize = xSize * ySize * CHANNELS; - - this.initalizeNetwork(new int[] {blockSize, compressedNeuronCount, blockSize}); - - //assign inputs to pixels - final List<InputNeuron> inputs = new ArrayList<InputNeuron>(this.getInputNeurons()); - final List<OutputNeuron> outputs = new ArrayList<OutputNeuron>(this.getOutputNeurons()); - for (int yIndex = 0; yIndex < ySize; yIndex++) - { - for (int xIndex = 0; xIndex < xSize; xIndex++) - { - for (int rgbIndex = 0; rgbIndex < CHANNELS; rgbIndex++) - { - final int overallIndex = (yIndex * xSize * CHANNELS) + (xIndex * CHANNELS) + rgbIndex; - this.inputNeurons[xIndex][yIndex][rgbIndex] = (InputBackpropNeuron)inputs.get(overallIndex); - this.outputNeurons[xIndex][yIndex][rgbIndex] = (OutputBackpropNeuron)outputs.get(overallIndex); - } - } - } - } - - @Override - protected BackpropNeuron createNeuron(final int layer, final int index) - { - if( layer == 0 ) - return new SimpleInputBackpropNeuron(this); - else if(layer >= (this.getLayerCount() - 1)) - return new SimpleOutputBackpropNeuron(this, this.activationFunction, this.learningRate); - else if(layer == 1) - { - final CompressionNeuron compressionNeuron = new CompressionNeuron(this, this.activationFunction, this.learningRate); - this.compressedNeurons.add(compressionNeuron); - return compressionNeuron; - } - else - return new SimpleBackpropNeuron(this, this.activationFunction, this.learningRate); - } - - /** - * @since 1.0 - */ - public double getCompression() - { - return this.actualCompression; - } - - /** - * @since 1.0 - */ - public boolean isLearning() - { - return this.learning; - } - - /** - * @since 1.0 - */ - public void setLearning(final boolean learningToSet) - { - this.learning = learningToSet; - } - - public double getAverageWeight() - { - double weightSum = 0.0; - double weightCount = 0.0; - - for (BackpropNeuron child : this.getNodes()) - { - try - { - final Set<Synapse<BackpropNeuron>> childSynapses = this.getTraversableEdges(child); - - for (Synapse childSynapse : childSynapses) - { - weightSum += childSynapse.getWeight(); - weightCount++; - } - } - catch(ClassCastException caughtException) - { - throw new AssertionError(caughtException); - } - } - - return weightSum / weightCount; - } - - public double getAverageAbsoluteWeight() - { - double weightSum = 0.0; - double weightCount = 0.0; - - for (BackpropNeuron child : this.getNodes()) - { - try - { - final Set<Synapse<BackpropNeuron>> childSynapses = this.getTraversableEdges(child); - - for (Synapse childSynapse : childSynapses) - { - weightSum += Math.abs(childSynapse.getWeight()); - weightCount++; - } - } - catch(ClassCastException caughtException) - { - throw new AssertionError(caughtException); - } - } - - return weightSum / weightCount; - } - - public BufferedImage test(final BufferedImage originalImage) - { - setImageOnto(originalImage, true); - - if (this.compressionInputsSet) - { - for (CompressionNeuron compressionNeuron : this.compressedNeurons) - compressionNeuron.unsetInput(); - this.compressionInputsSet = false; - } - - //propogate the output - this.propagate(); - - if (!this.learning) - { - return createBufferedImage(); - } - - //now back propogate - this.backPropagate(); - - //all done - return null; - } - - /** - * @since 1.0 - */ - public byte[] compress(final BufferedImage originalImage) - { - setImageOnto(originalImage, false); - - if (this.compressionInputsSet) - { - for (CompressionNeuron compressionNeuron : this.compressedNeurons) - compressionNeuron.unsetInput(); - this.compressionInputsSet = false; - } - - //propogate the output - this.propagate(); - - int compressedDataIndex = 0; - byte[] compressedData = new byte[this.compressedNeurons.size()]; - for (CompressionNeuron compressionNeuron : this.compressedNeurons) - compressedData[compressedDataIndex++] = compressionNeuron.getChannelOutput(); - - return compressedData; - } - - private void setImageOnto(final BufferedImage originalImage, final boolean setDesired) - { - final int[] originalRgbArray = new int[xSize * ySize]; - originalImage.getRGB(0, 0, (originalImage.getWidth() < xSize ? originalImage.getWidth() : xSize), (originalImage.getHeight() < ySize ? originalImage.getHeight() : ySize), originalRgbArray, 0, xSize); - - //set the image onto the inputs - for (int yIndex = 0; (yIndex < ySize) && (yIndex < originalImage.getHeight()); yIndex++) - { - for (int xIndex = 0; (xIndex < xSize) && (xIndex < originalImage.getWidth()); xIndex++) - { - final int rgbCurrent = originalRgbArray[yIndex * xSize + xIndex]; - for (int rgbIndex = 0; rgbIndex < CHANNELS; rgbIndex++) - { - final int channel = (((rgbCurrent >> (rgbIndex * 8)) & 0x000000FF)); - final double input = (((double) channel) / 127.5) - 1.0; - - this.inputNeurons[xIndex][yIndex][rgbIndex].setInput(input); - if (setDesired) - { - this.outputNeurons[xIndex][yIndex][rgbIndex].setDesired(input); - } - } - } - } - } - - /** - * @since 1.0 - */ - public BufferedImage uncompress(final byte[] compressedData) - { - int compressedDataIndex = 0; - for (CompressionNeuron compressionNeuron : this.compressedNeurons) - compressionNeuron.setInput(compressedData[compressedDataIndex++]); - - this.compressionInputsSet = true; - - this.propagate(); - - return createBufferedImage(); - } - - private BufferedImage createBufferedImage() - { - final int[] finalRgbArray = new int[xSize * ySize]; - final BufferedImage uncompressedImage = new BufferedImage(this.xSize, this.ySize, BufferedImage.TYPE_INT_RGB); - for (int yIndex = 0; (yIndex < ySize) && (yIndex < uncompressedImage.getHeight()); yIndex++) - { - for (int xIndex = 0; (xIndex < xSize) && (xIndex < uncompressedImage.getWidth()); xIndex++) - { - //int rgbCurrent = imageToCompress.getRGB(xIndex, yIndex); - int rgbCurrent = 0; - for (int rgbIndex = 0; rgbIndex < 4; rgbIndex++) - { - double output; - - if (rgbIndex >= CHANNELS) - output = this.outputNeurons[xIndex][yIndex][0].getOutput(); - else - output = this.outputNeurons[xIndex][yIndex][rgbIndex].getOutput(); - - final int channel = (int)((output + 1.0d) * 127.5d); - - rgbCurrent |= (channel & 0x000000FF) << (rgbIndex * 8); - } - finalRgbArray[xSize * yIndex + (xIndex)] = rgbCurrent; - } - } - uncompressedImage.setRGB(0, 0, xSize, ySize, finalRgbArray, 0, xSize); - - return uncompressedImage; - } +public class NciBrain extends AbstractFullyConnectedFeedforwardBrain<InputBackpropNeuron, OutputBackpropNeuron, BackpropNeuron, Synapse<BackpropNeuron>> { + private static final int CHANNELS = 3; + private static final double DEFAULT_LEARNING_RATE = 0.001; + private final double actualCompression; + private final int xSize; + private final int ySize; + private final InputBackpropNeuron[][][] inputNeurons; + private final List<CompressionNeuron> compressedNeurons; + private final OutputBackpropNeuron[][][] outputNeurons; + private final ActivationFunction activationFunction; + private final double learningRate; + private boolean learning; + private boolean compressionInputsSet; + + /** + * Creates an instance of NciBrain. + * + * @param compression A value between 0.0 (inclusive) and 1.0 (exclusive) + * which represents the % of compression. + */ + public NciBrain(final double compression, final int xSize, final int ySize, final boolean extraConnectivity) { + super(); + + this.learningRate = DEFAULT_LEARNING_RATE; + this.activationFunction = new SineActivationFunction(); + + this.xSize = xSize; + this.ySize = ySize; + final int compressedNeuronCount = ((int) Math.ceil((((double) xSize) * ((double) ySize) * ((double) CHANNELS)) * (1.0 - compression))); + this.inputNeurons = new InputBackpropNeuron[xSize][ySize][CHANNELS]; + this.compressedNeurons = new ArrayList<CompressionNeuron>(); + this.outputNeurons = new OutputBackpropNeuron[xSize][ySize][CHANNELS]; + this.learning = true; + this.compressionInputsSet = false; + this.actualCompression = 1.0 - ((double) compressedNeuronCount) / (((double) xSize) * ((double) ySize) * ((double) CHANNELS)); + final int blockSize = xSize * ySize * CHANNELS; + + this.initalizeNetwork(new int[]{blockSize, compressedNeuronCount, blockSize}); + + //assign inputs to pixels + final List<InputNeuron> inputs = new ArrayList<InputNeuron>(this.getInputNeurons()); + final List<OutputNeuron> outputs = new ArrayList<OutputNeuron>(this.getOutputNeurons()); + for (int yIndex = 0; yIndex < ySize; yIndex++) { + for (int xIndex = 0; xIndex < xSize; xIndex++) { + for (int rgbIndex = 0; rgbIndex < CHANNELS; rgbIndex++) { + final int overallIndex = (yIndex * xSize * CHANNELS) + (xIndex * CHANNELS) + rgbIndex; + this.inputNeurons[xIndex][yIndex][rgbIndex] = (InputBackpropNeuron) inputs.get(overallIndex); + this.outputNeurons[xIndex][yIndex][rgbIndex] = (OutputBackpropNeuron) outputs.get(overallIndex); + } + } + } + } + + @Override + protected BackpropNeuron createNeuron(final int layer, final int index) { + if (layer == 0) + return new SimpleInputBackpropNeuron(this); + else if (layer >= (this.getLayerCount() - 1)) + return new SimpleOutputBackpropNeuron(this, this.activationFunction, this.learningRate); + else if (layer == 1) { + final CompressionNeuron compressionNeuron = new CompressionNeuron(this, this.activationFunction, this.learningRate); + this.compressedNeurons.add(compressionNeuron); + return compressionNeuron; + } + else + return new SimpleBackpropNeuron(this, this.activationFunction, this.learningRate); + } + + /** + * @since 1.0 + */ + public double getCompression() { + return this.actualCompression; + } + + /** + * @since 1.0 + */ + public boolean isLearning() { + return this.learning; + } + + /** + * @since 1.0 + */ + public void setLearning(final boolean learningToSet) { + this.learning = learningToSet; + } + + public double getAverageWeight() { + double weightSum = 0.0; + double weightCount = 0.0; + + for (BackpropNeuron child : this.getNodes()) { + try { + final Set<Synapse<BackpropNeuron>> childSynapses = this.getTraversableEdges(child); + + for (Synapse childSynapse : childSynapses) { + weightSum += childSynapse.getWeight(); + weightCount++; + } + } + catch (ClassCastException caughtException) { + throw new AssertionError(caughtException); + } + } + + return weightSum / weightCount; + } + + public double getAverageAbsoluteWeight() { + double weightSum = 0.0; + double weightCount = 0.0; + + for (BackpropNeuron child : this.getNodes()) { + try { + final Set<Synapse<BackpropNeuron>> childSynapses = this.getTraversableEdges(child); + + for (Synapse childSynapse : childSynapses) { + weightSum += Math.abs(childSynapse.getWeight()); + weightCount++; + } + } + catch (ClassCastException caughtException) { + throw new AssertionError(caughtException); + } + } + + return weightSum / weightCount; + } + + public BufferedImage test(final BufferedImage originalImage) { + setImageOnto(originalImage, true); + + if (this.compressionInputsSet) { + for (CompressionNeuron compressionNeuron : this.compressedNeurons) + compressionNeuron.unsetInput(); + this.compressionInputsSet = false; + } + + //propogate the output + this.propagate(); + + if (!this.learning) { + return createBufferedImage(); + } + + //now back propogate + this.backPropagate(); + + //all done + return null; + } + + /** + * @since 1.0 + */ + public byte[] compress(final BufferedImage originalImage) { + setImageOnto(originalImage, false); + + if (this.compressionInputsSet) { + for (CompressionNeuron compressionNeuron : this.compressedNeurons) + compressionNeuron.unsetInput(); + this.compressionInputsSet = false; + } + + //propogate the output + this.propagate(); + + int compressedDataIndex = 0; + byte[] compressedData = new byte[this.compressedNeurons.size()]; + for (CompressionNeuron compressionNeuron : this.compressedNeurons) + compressedData[compressedDataIndex++] = compressionNeuron.getChannelOutput(); + + return compressedData; + } + + private void setImageOnto(final BufferedImage originalImage, final boolean setDesired) { + final int[] originalRgbArray = new int[xSize * ySize]; + originalImage.getRGB(0, 0, (originalImage.getWidth() < xSize ? originalImage.getWidth() : xSize), (originalImage.getHeight() < ySize ? originalImage.getHeight() : ySize), originalRgbArray, 0, xSize); + + //set the image onto the inputs + for (int yIndex = 0; (yIndex < ySize) && (yIndex < originalImage.getHeight()); yIndex++) { + for (int xIndex = 0; (xIndex < xSize) && (xIndex < originalImage.getWidth()); xIndex++) { + final int rgbCurrent = originalRgbArray[yIndex * xSize + xIndex]; + for (int rgbIndex = 0; rgbIndex < CHANNELS; rgbIndex++) { + final int channel = (((rgbCurrent >> (rgbIndex * 8)) & 0x000000FF)); + final double input = (((double) channel) / 127.5) - 1.0; + + this.inputNeurons[xIndex][yIndex][rgbIndex].setInput(input); + if (setDesired) { + this.outputNeurons[xIndex][yIndex][rgbIndex].setDesired(input); + } + } + } + } + } + + /** + * @since 1.0 + */ + public BufferedImage uncompress(final byte[] compressedData) { + int compressedDataIndex = 0; + for (CompressionNeuron compressionNeuron : this.compressedNeurons) + compressionNeuron.setInput(compressedData[compressedDataIndex++]); + + this.compressionInputsSet = true; + + this.propagate(); + + return createBufferedImage(); + } + + private BufferedImage createBufferedImage() { + final int[] finalRgbArray = new int[xSize * ySize]; + final BufferedImage uncompressedImage = new BufferedImage(this.xSize, this.ySize, BufferedImage.TYPE_INT_RGB); + for (int yIndex = 0; (yIndex < ySize) && (yIndex < uncompressedImage.getHeight()); yIndex++) { + for (int xIndex = 0; (xIndex < xSize) && (xIndex < uncompressedImage.getWidth()); xIndex++) { + //int rgbCurrent = imageToCompress.getRGB(xIndex, yIndex); + int rgbCurrent = 0; + for (int rgbIndex = 0; rgbIndex < 4; rgbIndex++) { + double output; + + if (rgbIndex >= CHANNELS) + output = this.outputNeurons[xIndex][yIndex][0].getOutput(); + else + output = this.outputNeurons[xIndex][yIndex][rgbIndex].getOutput(); + + final int channel = (int) ((output + 1.0d) * 127.5d); + + rgbCurrent |= (channel & 0x000000FF) << (rgbIndex * 8); + } + finalRgbArray[xSize * yIndex + (xIndex)] = rgbCurrent; + } + } + uncompressedImage.setRGB(0, 0, xSize, ySize, finalRgbArray, 0, xSize); + + return uncompressedImage; + } } diff --git a/src/main/java/com/syncleus/dann/examples/nci/SampleRun.java b/src/main/java/com/syncleus/dann/examples/nci/SampleRun.java index d73bedb02ea70e07b32a42ef62385129c47abcdc..3f6d418ad7cc359bd7d50d416412e28fab674ba0 100644 --- a/src/main/java/com/syncleus/dann/examples/nci/SampleRun.java +++ b/src/main/java/com/syncleus/dann/examples/nci/SampleRun.java @@ -18,39 +18,34 @@ ******************************************************************************/ package com.syncleus.dann.examples.nci; +import org.apache.log4j.Logger; + import java.awt.image.BufferedImage; import java.util.concurrent.Callable; -import org.apache.log4j.Logger; -public class SampleRun implements Callable<BufferedImage> -{ - private static final Logger LOGGER = Logger.getLogger(SampleRun.class); - private final NciBrain brain; - private final BufferedImage sampleImage; +public class SampleRun implements Callable<BufferedImage> { + private static final Logger LOGGER = Logger.getLogger(SampleRun.class); + private final NciBrain brain; + private final BufferedImage sampleImage; - public SampleRun(final NciBrain brain, final BufferedImage sampleImage) - { - this.brain = brain; - this.sampleImage = sampleImage; - } + public SampleRun(final NciBrain brain, final BufferedImage sampleImage) { + this.brain = brain; + this.sampleImage = sampleImage; + } - @Override - public BufferedImage call() - { - try - { - this.brain.setLearning(false); - return this.brain.uncompress(this.brain.compress(sampleImage)); - } - catch (Exception caught) - { - LOGGER.error("Exception was caught", caught); - throw new RuntimeException("Throwable was caught", caught); - } - catch (Error caught) - { - LOGGER.error("Error was caught", caught); - throw new Error("Throwable was caught", caught); - } - } + @Override + public BufferedImage call() { + try { + this.brain.setLearning(false); + return this.brain.uncompress(this.brain.compress(sampleImage)); + } + catch (Exception caught) { + LOGGER.error("Exception was caught", caught); + throw new RuntimeException("Throwable was caught", caught); + } + catch (Error caught) { + LOGGER.error("Error was caught", caught); + throw new Error("Throwable was caught", caught); + } + } } diff --git a/src/main/java/com/syncleus/dann/examples/nci/TrainRun.java b/src/main/java/com/syncleus/dann/examples/nci/TrainRun.java index ca01aa2c15c8538fc83c34d5aec2b877a88214de..06e5278e221902b8ae77136c5d912cb15dd7cac9 100644 --- a/src/main/java/com/syncleus/dann/examples/nci/TrainRun.java +++ b/src/main/java/com/syncleus/dann/examples/nci/TrainRun.java @@ -18,38 +18,33 @@ ******************************************************************************/ package com.syncleus.dann.examples.nci; -import java.awt.image.BufferedImage; import org.apache.log4j.Logger; -public class TrainRun implements Runnable -{ - private static final Logger LOGGER = Logger.getLogger(TrainRun.class); - private final NciBrain brain; - private final BufferedImage trainImage; +import java.awt.image.BufferedImage; + +public class TrainRun implements Runnable { + private static final Logger LOGGER = Logger.getLogger(TrainRun.class); + private final NciBrain brain; + private final BufferedImage trainImage; - public TrainRun(final NciBrain brain, final BufferedImage trainImage) - { - this.brain = brain; - this.trainImage = trainImage; - } + public TrainRun(final NciBrain brain, final BufferedImage trainImage) { + this.brain = brain; + this.trainImage = trainImage; + } - @Override - public void run() - { - try - { - this.brain.setLearning(true); - this.brain.test(trainImage); - } - catch (Exception caught) - { - LOGGER.error("Exception was caught", caught); - throw new RuntimeException("Throwable was caught", caught); - } - catch (Error caught) - { - LOGGER.error("Error was caught", caught); - throw new Error("Throwable was caught", caught); - } - } + @Override + public void run() { + try { + this.brain.setLearning(true); + this.brain.test(trainImage); + } + catch (Exception caught) { + LOGGER.error("Exception was caught", caught); + throw new RuntimeException("Throwable was caught", caught); + } + catch (Error caught) { + LOGGER.error("Error was caught", caught); + throw new Error("Throwable was caught", caught); + } + } } diff --git a/src/main/java/com/syncleus/dann/examples/nci/ui/AboutDialog.java b/src/main/java/com/syncleus/dann/examples/nci/ui/AboutDialog.java index 8ab555d7a37f039a5a93f2a1477d47114c33276b..50020ff1902dec76c542c6f906e009dd58b35d88 100644 --- a/src/main/java/com/syncleus/dann/examples/nci/ui/AboutDialog.java +++ b/src/main/java/com/syncleus/dann/examples/nci/ui/AboutDialog.java @@ -18,23 +18,28 @@ ******************************************************************************/ package com.syncleus.dann.examples.nci.ui; -import java.awt.Frame; -import javax.swing.JDialog; +import javax.swing.*; +import java.awt.*; -public class AboutDialog extends JDialog -{ - public AboutDialog(final Frame parent, final boolean modal) - { - super(parent, modal); - initComponents(); - } +public class AboutDialog extends JDialog { + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton1; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JTextArea jTextArea1; + public AboutDialog(final Frame parent, final boolean modal) { + super(parent, modal); + initComponents(); + } - /** This method is called from within the constructor to - * initialize the form. - * WARNING: Do NOT modify this code. The content of this method is - * always regenerated by the Form Editor. - */ - @SuppressWarnings("unchecked") + /** + * This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { @@ -71,50 +76,44 @@ public class AboutDialog extends JDialog javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap(195, Short.MAX_VALUE) - .addComponent(jButton1) - .addGap(182, 182, 182)) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addGap(141, 141, 141) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 39, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel1) - .addGap(166, 166, 166)) - .addComponent(jLabel2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 273, Short.MAX_VALUE)) - .addContainerGap()) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 404, Short.MAX_VALUE) - .addContainerGap()) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap(195, Short.MAX_VALUE) + .addComponent(jButton1) + .addGap(182, 182, 182)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(141, 141, 141) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 39, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1) + .addGap(166, 166, 166)) + .addComponent(jLabel2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 273, Short.MAX_VALUE)) + .addContainerGap()) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 404, Short.MAX_VALUE) + .addContainerGap()) ); layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(jLabel1) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel2) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 391, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jButton1) - .addContainerGap()) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel2) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 391, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jButton1) + .addContainerGap()) ); pack(); }// </editor-fold>//GEN-END:initComponents -private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed - this.setVisible(false); -}//GEN-LAST:event_jButton1ActionPerformed - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JButton jButton1; - private javax.swing.JLabel jLabel1; - private javax.swing.JLabel jLabel2; - private javax.swing.JScrollPane jScrollPane1; - private javax.swing.JTextArea jTextArea1; + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + this.setVisible(false); + }//GEN-LAST:event_jButton1ActionPerformed // End of variables declaration//GEN-END:variables } diff --git a/src/main/java/com/syncleus/dann/examples/nci/ui/ImagePanel.java b/src/main/java/com/syncleus/dann/examples/nci/ui/ImagePanel.java index 9ffc5396892710be9ae9bc2bff3c820d0c3b3d71..3338b4138c98cbb8fb898a634eec97045866c765 100644 --- a/src/main/java/com/syncleus/dann/examples/nci/ui/ImagePanel.java +++ b/src/main/java/com/syncleus/dann/examples/nci/ui/ImagePanel.java @@ -18,53 +18,48 @@ ******************************************************************************/ package com.syncleus.dann.examples.nci.ui; -import java.awt.Graphics; -import java.awt.Image; +import java.awt.*; -public class ImagePanel extends javax.swing.JPanel -{ - private Image image = null; +public class ImagePanel extends javax.swing.JPanel { + private Image image = null; - public ImagePanel() - { - initComponents(); - } + public ImagePanel() { + initComponents(); + } - public void setImage(final Image newImage) - { - this.image = newImage; - this.repaint(); - } + public void setImage(final Image newImage) { + this.image = newImage; + this.repaint(); + } - @Override - protected void paintComponent(final Graphics graphics) - { - super.paintComponent(graphics); + @Override + protected void paintComponent(final Graphics graphics) { + super.paintComponent(graphics); - if (this.image != null) - { - graphics.drawImage(this.image, 0, 0, this); - } - } + if (this.image != null) { + graphics.drawImage(this.image, 0, 0, this); + } + } - /** This method is called from within the constructor to - * initialize the form. - * WARNING: Do NOT modify this code. The content of this method is - * always regenerated by the Form Editor. - */ - @SuppressWarnings("unchecked") + /** + * This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 400, Short.MAX_VALUE) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 400, Short.MAX_VALUE) ); layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 300, Short.MAX_VALUE) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 300, Short.MAX_VALUE) ); }// </editor-fold>//GEN-END:initComponents // Variables declaration - do not modify//GEN-BEGIN:variables diff --git a/src/main/java/com/syncleus/dann/examples/nci/ui/NciDemo.java b/src/main/java/com/syncleus/dann/examples/nci/ui/NciDemo.java index a86f67146d688bca88d0f90e125d5fc37f24d837..96dcb95f2000f1b78051d7f149c6f57178e054db 100644 --- a/src/main/java/com/syncleus/dann/examples/nci/ui/NciDemo.java +++ b/src/main/java/com/syncleus/dann/examples/nci/ui/NciDemo.java @@ -18,92 +18,130 @@ ******************************************************************************/ package com.syncleus.dann.examples.nci.ui; -import javax.imageio.ImageIO; -import javax.swing.filechooser.FileNameExtensionFilter; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; import com.syncleus.dann.ComponentUnavailableException; -import com.syncleus.dann.examples.nci.BrainListener; -import com.syncleus.dann.examples.nci.BrainRunner; +import com.syncleus.dann.examples.nci.*; import com.syncleus.dann.graph.drawing.hyperassociativemap.visualization.HyperassociativeMapCanvas; -import java.awt.Component; -import javax.swing.JDialog; -import javax.swing.JFileChooser; -import javax.swing.JFrame; -import javax.swing.JOptionPane; -import javax.swing.Timer; -import javax.swing.UIManager; import org.apache.log4j.Logger; -public class NciDemo extends JFrame implements ActionListener, BrainListener -{ - private static final Logger LOGGER = Logger.getLogger(NciDemo.class); - private static final int BLOCK_WIDTH = 7; - private static final int BLOCK_HEIGHT = 7; - private BrainRunner brainRunner; - private HyperassociativeMapCanvas brainVisual; - private Component errorPanel; - private Thread brainRunnerThread; - private File trainingDirectory; - private File originalImageLocation; - private BufferedImage originalImage; - private final ImagePanel originalImagePanel = new ImagePanel(); - private BufferedImage finalImage; - private final ImagePanel finalImagePanel = new ImagePanel(); - private boolean processing = false; - private int trainingRemaining; - private int currentTrainingCycles = 100000; - private ViewBrain viewBrain; - - public NciDemo() - { - try - { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } - catch (Exception caught) - { - LOGGER.warn("Could not set the UI to native look and feel", caught); - } - - initComponents(); - - this.add(this.originalImagePanel); - final int currentX = this.separator.getX() + 5; - int currentY = 0; - this.originalImagePanel.setLocation(currentX, currentY); - this.originalImagePanel.setSize(800, 400); - currentY = 400; - this.originalImagePanel.setVisible(true); - - this.add(this.finalImagePanel); - this.finalImagePanel.setLocation(currentX, currentY); - this.finalImagePanel.setSize(800, 600); - this.finalImagePanel.setVisible(true); - - this.setSize(600, 350); - this.setExtendedState(MAXIMIZED_BOTH); - - new Timer(250, this).start(); - } - - @Override - public void actionPerformed(final ActionEvent evt) { - - if (this.trainingRemaining > 0) - { - this.trainingRemaining = this.brainRunner.getTrainingCycles(); - final int progressPercent = ((this.currentTrainingCycles - this.trainingRemaining) * 100) / (this.currentTrainingCycles); - this.progress.setValue(progressPercent); - } - else if (this.processing) - { - this.progress.setValue(this.brainRunner.getSampleProgress()); - } - } +import javax.imageio.ImageIO; +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import java.awt.*; +import java.awt.event.*; +import java.awt.image.BufferedImage; +import java.io.*; + +public class NciDemo extends JFrame implements ActionListener, BrainListener { + private static final Logger LOGGER = Logger.getLogger(NciDemo.class); + private static final int BLOCK_WIDTH = 7; + private static final int BLOCK_HEIGHT = 7; + private final ImagePanel originalImagePanel = new ImagePanel(); + private final ImagePanel finalImagePanel = new ImagePanel(); + private BrainRunner brainRunner; + private HyperassociativeMapCanvas brainVisual; + private Component errorPanel; + private Thread brainRunnerThread; + private File trainingDirectory; + private File originalImageLocation; + private BufferedImage originalImage; + private BufferedImage finalImage; + private boolean processing = false; + private int trainingRemaining; + private int currentTrainingCycles = 100000; + private ViewBrain viewBrain; + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JMenuItem aboutMenuItem1; + private javax.swing.JMenuItem brainViewMenu; + private javax.swing.JMenu fileMenu1; + // </editor-fold> + private javax.swing.JMenu helpMenu1; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel5; + private javax.swing.JMenuBar jMenuBar2; + private javax.swing.JButton originalImageSelect; + private javax.swing.JTextField originalImageText; + private javax.swing.JButton processButton; + private javax.swing.JProgressBar progress; + private javax.swing.JMenuItem quitMenuItem1; + private javax.swing.JSeparator separator; + private javax.swing.JLabel statusLabel; + private javax.swing.JButton stopButton; + private javax.swing.JMenu toolsMenu; + private javax.swing.JButton trainButton; + private javax.swing.JSpinner trainingCylcesInput; + private javax.swing.JButton trainingDirectorySelect; + private javax.swing.JTextField trainingDirectoryText; + + public NciDemo() { + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } + catch (Exception caught) { + LOGGER.warn("Could not set the UI to native look and feel", caught); + } + + initComponents(); + + this.add(this.originalImagePanel); + final int currentX = this.separator.getX() + 5; + int currentY = 0; + this.originalImagePanel.setLocation(currentX, currentY); + this.originalImagePanel.setSize(800, 400); + currentY = 400; + this.originalImagePanel.setVisible(true); + + this.add(this.finalImagePanel); + this.finalImagePanel.setLocation(currentX, currentY); + this.finalImagePanel.setSize(800, 600); + this.finalImagePanel.setVisible(true); + + this.setSize(600, 350); + this.setExtendedState(MAXIMIZED_BOTH); + + new Timer(250, this).start(); + } + + public static void main(final String[] args) { + try { + java.awt.EventQueue.invokeAndWait(new Runnable() { + public void run() { + try { + new NciDemo().setVisible(true); + } + catch (Exception caught) { + LOGGER.error("Exception was caught", caught); + throw new RuntimeException("Throwable was caught", caught); + } + catch (Error caught) { + LOGGER.error("Error was caught", caught); + throw new Error("Throwable was caught", caught); + } + } + }); + } + catch (Exception caught) { + LOGGER.error("Exception was caught", caught); + throw new RuntimeException("Throwable was caught", caught); + } + catch (Error caught) { + LOGGER.error("Error was caught", caught); + throw new Error("Throwable was caught", caught); + } + } + + @Override + public void actionPerformed(final ActionEvent evt) { + + if (this.trainingRemaining > 0) { + this.trainingRemaining = this.brainRunner.getTrainingCycles(); + final int progressPercent = ((this.currentTrainingCycles - this.trainingRemaining) * 100) / (this.currentTrainingCycles); + this.progress.setValue(progressPercent); + } + else if (this.processing) { + this.progress.setValue(this.brainRunner.getSampleProgress()); + } + } // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { @@ -207,8 +245,10 @@ public class NciDemo extends JFrame implements ActionListener, BrainListener public void menuKeyPressed(javax.swing.event.MenuKeyEvent evt) { quitMenuItemMenuKeyPressed(evt); } + public void menuKeyReleased(javax.swing.event.MenuKeyEvent evt) { } + public void menuKeyTyped(javax.swing.event.MenuKeyEvent evt) { } }); @@ -229,8 +269,10 @@ public class NciDemo extends JFrame implements ActionListener, BrainListener public void menuKeyPressed(javax.swing.event.MenuKeyEvent evt) { brainViewMenuMenuKeyPressed(evt); } + public void menuKeyReleased(javax.swing.event.MenuKeyEvent evt) { } + public void menuKeyTyped(javax.swing.event.MenuKeyEvent evt) { } }); @@ -250,8 +292,10 @@ public class NciDemo extends JFrame implements ActionListener, BrainListener public void menuKeyPressed(javax.swing.event.MenuKeyEvent evt) { aboutMenuItemMenuKeyPressed(evt); } + public void menuKeyReleased(javax.swing.event.MenuKeyEvent evt) { } + public void menuKeyTyped(javax.swing.event.MenuKeyEvent evt) { } }); @@ -264,358 +308,275 @@ public class NciDemo extends JFrame implements ActionListener, BrainListener javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel2) - .addComponent(jLabel1) - .addComponent(statusLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 244, Short.MAX_VALUE) - .addGroup(layout.createSequentialGroup() - .addGap(27, 27, 27) - .addComponent(jLabel5) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(trainingCylcesInput, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) - .addComponent(trainingDirectoryText, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(originalImageText, javax.swing.GroupLayout.DEFAULT_SIZE, 215, Short.MAX_VALUE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(originalImageSelect, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(trainingDirectorySelect, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addGroup(layout.createSequentialGroup() - .addGap(12, 12, 12) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(progress, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(layout.createSequentialGroup() - .addComponent(trainButton) - .addGap(18, 18, 18) - .addComponent(processButton) - .addGap(18, 18, 18) - .addComponent(stopButton))))) - .addGap(18, 18, 18) - .addComponent(separator, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(10000, 10000, 10000)) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel2) + .addComponent(jLabel1) + .addComponent(statusLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 244, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addGap(27, 27, 27) + .addComponent(jLabel5) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(trainingCylcesInput, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(trainingDirectoryText, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(originalImageText, javax.swing.GroupLayout.DEFAULT_SIZE, 215, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(originalImageSelect, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(trainingDirectorySelect, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(layout.createSequentialGroup() + .addGap(12, 12, 12) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(progress, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addComponent(trainButton) + .addGap(18, 18, 18) + .addComponent(processButton) + .addGap(18, 18, 18) + .addComponent(stopButton))))) + .addGap(18, 18, 18) + .addComponent(separator, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10000, 10000, 10000)) ); layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(separator, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 715, Short.MAX_VALUE) - .addGroup(layout.createSequentialGroup() - .addComponent(jLabel1) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(trainingDirectoryText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(trainingDirectorySelect)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel2) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(originalImageText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(originalImageSelect)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 470, Short.MAX_VALUE) - .addComponent(statusLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(progress, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel5) - .addComponent(trainingCylcesInput, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(26, 26, 26) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(processButton) - .addComponent(stopButton) - .addComponent(trainButton)))) - .addContainerGap()) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(separator, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 715, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(trainingDirectoryText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(trainingDirectorySelect)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel2) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(originalImageText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(originalImageSelect)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 470, Short.MAX_VALUE) + .addComponent(statusLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(progress, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel5) + .addComponent(trainingCylcesInput, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(26, 26, 26) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(processButton) + .addComponent(stopButton) + .addComponent(trainButton)))) + .addContainerGap()) ); pack(); }// </editor-fold>//GEN-END:initComponents - // </editor-fold> - -private void quitMenuItemMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_quitMenuItemMouseReleased - if (this.brainRunner != null) - { - this.brainRunner.shutdown(); - } - System.exit(0); -}//GEN-LAST:event_quitMenuItemMouseReleased - -private void quitMenuItemMenuKeyPressed(javax.swing.event.MenuKeyEvent evt) {//GEN-FIRST:event_quitMenuItemMenuKeyPressed - if (this.brainRunner != null) - { - this.brainRunner.shutdown(); - } - System.exit(0); -}//GEN-LAST:event_quitMenuItemMenuKeyPressed - -private void aboutMenuItemMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_aboutMenuItemMouseReleased - displayAbout(); -}//GEN-LAST:event_aboutMenuItemMouseReleased - -private void aboutMenuItemMenuKeyPressed(javax.swing.event.MenuKeyEvent evt) {//GEN-FIRST:event_aboutMenuItemMenuKeyPressed - displayAbout(); -}//GEN-LAST:event_aboutMenuItemMenuKeyPressed - -private void originalImageSelectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_originalImageSelectActionPerformed - final JFileChooser chooser = new JFileChooser(); - final FileNameExtensionFilter filter = new FileNameExtensionFilter("PNG Images", "png"); - chooser.setFileFilter(filter); - chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); - chooser.setMultiSelectionEnabled(false); - chooser.setVisible(true); - if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) - { - this.originalImageText.setText(chooser.getSelectedFile().getAbsolutePath()); - this.originalImageLocation = chooser.getSelectedFile(); - - this.refreshOriginalImage(); - - if (this.brainRunnerThread != null) - { - this.processButton.setEnabled(true); - this.trainButton.setEnabled(true); - - this.statusLabel.setText("Ready!"); - } - } -}//GEN-LAST:event_originalImageSelectActionPerformed - -private void trainingDirectorySelectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_trainingDirectorySelectActionPerformed - final JFileChooser chooser = new JFileChooser(); - chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - chooser.setMultiSelectionEnabled(false); - chooser.setVisible(true); - if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) - { - this.trainingDirectoryText.setText(chooser.getSelectedFile().getAbsolutePath()); - this.trainingDirectory = chooser.getSelectedFile(); - - final File[] trainingFiles = trainingDirectory.listFiles(new PngFileFilter()); - if (trainingFiles.length <= 0) - { - this.trainingDirectory = null; - this.trainingDirectoryText.setText(""); - - JOptionPane.showMessageDialog(this, "The selected training directory does not contain *.png files! Select a new directory", "Invalid Training Directory", JOptionPane.ERROR_MESSAGE); - - return; - } - - this.brainRunner = new BrainRunner(this, trainingFiles, 0.875, BLOCK_WIDTH, BLOCK_HEIGHT, true); - this.brainRunnerThread = new Thread(this.brainRunner); - this.brainRunnerThread.start(); - - if (this.originalImageLocation != null) - { - this.processButton.setEnabled(true); - this.trainButton.setEnabled(true); - - this.statusLabel.setText("Ready!"); - } - } -}//GEN-LAST:event_trainingDirectorySelectActionPerformed - -private void trainButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_trainButtonActionPerformed - this.trainButton.setEnabled(false); - this.processButton.setEnabled(false); - this.stopButton.setEnabled(true); - - this.statusLabel.setText("Please wait, training..."); - - this.currentTrainingCycles = ((Integer) this.trainingCylcesInput.getValue()).intValue(); - this.trainingRemaining = this.currentTrainingCycles; - - this.brainRunner.setTrainingCycles(this.currentTrainingCycles); -}//GEN-LAST:event_trainButtonActionPerformed - -private void processButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_processButtonActionPerformed - if (this.processing || (finalImage == null) || (originalImage == null)) - { - return; - } - - this.processButton.setEnabled(false); - this.trainButton.setEnabled(false); - this.stopButton.setEnabled(false); - - this.processing = true; - - this.statusLabel.setText("Please wait, processing..."); - - this.brainRunner.setSampleImage(this.originalImageLocation); -}//GEN-LAST:event_processButtonActionPerformed - -private void stopButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_stopButtonActionPerformed - this.brainRunner.stop(); -}//GEN-LAST:event_stopButtonActionPerformed - - public void showBrainView() - { - if (brainVisual == null) - { - final JDialog errorDialog = new JDialog(); - errorDialog.add(errorPanel); - errorDialog.setVisible(true); - } - else - { - this.brainVisual.refresh(); - - if (this.viewBrain == null) - { - this.viewBrain = new ViewBrain(this, brainVisual); - } - - this.viewBrain.setVisible(true); - } - } - -private void brainViewMenuMenuKeyPressed(javax.swing.event.MenuKeyEvent evt) {//GEN-FIRST:event_brainViewMenuMenuKeyPressed - showBrainView(); -}//GEN-LAST:event_brainViewMenuMenuKeyPressed - -private void brainViewMenuMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_brainViewMenuMouseReleased - showBrainView(); -}//GEN-LAST:event_brainViewMenuMouseReleased - -private void quitMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_quitMenuItem1ActionPerformed - if (this.brainRunner != null) - { - this.brainRunner.shutdown(); - } - System.exit(0); -}//GEN-LAST:event_quitMenuItem1ActionPerformed - - private void refreshOriginalImage() - { - if (this.originalImageLocation == null) - { - return; - } - - try - { - originalImage = ImageIO.read(this.originalImageLocation); - } - catch (IOException caught) - { - LOGGER.warn("IO Exception when reading image", caught); - return; - } - this.originalImagePanel.setImage(this.originalImage); - this.finalImage = new BufferedImage(originalImage.getWidth(), originalImage.getHeight(), BufferedImage.TYPE_INT_RGB); - } - - private void displayAbout() - { - final AboutDialog about = new AboutDialog(this, true); - about.setVisible(true); - } - - public void brainFinishedBuffering() - { - try - { - this.brainVisual = new HyperassociativeMapCanvas(this.brainRunner.getBrainMap()); - this.brainViewMenu.setEnabled(true); - } - catch (ComponentUnavailableException exc) - { - this.brainVisual = null; - this.errorPanel = exc.newPanel(); - this.brainViewMenu.setEnabled(false); - - } - } - - public void brainSampleProcessed(final BufferedImage finalImage) - { - this.processing = false; - this.progress.setValue(100); - this.finalImage = finalImage; - this.finalImagePanel.setImage(this.finalImage); - this.finalImagePanel.repaint(); - - this.processButton.setEnabled(true); - this.trainButton.setEnabled(true); - this.stopButton.setEnabled(false); - - this.statusLabel.setText("Ready!"); - } - - public void brainTrainingComplete() - { - this.trainingRemaining = 0; - this.progress.setValue(100); - - this.processButton.setEnabled(true); - this.trainButton.setEnabled(true); - this.stopButton.setEnabled(false); - - this.statusLabel.setText("Ready!"); - } - - public static void main(final String[] args) - { - try - { - java.awt.EventQueue.invokeAndWait(new Runnable() - { - public void run() - { - try - { - new NciDemo().setVisible(true); - } - catch (Exception caught) - { - LOGGER.error("Exception was caught", caught); - throw new RuntimeException("Throwable was caught", caught); - } - catch (Error caught) - { - LOGGER.error("Error was caught", caught); - throw new Error("Throwable was caught", caught); - } - } - }); - } - catch (Exception caught) - { - LOGGER.error("Exception was caught", caught); - throw new RuntimeException("Throwable was caught", caught); - } - catch (Error caught) - { - LOGGER.error("Error was caught", caught); - throw new Error("Throwable was caught", caught); - } - } - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JMenuItem aboutMenuItem1; - private javax.swing.JMenuItem brainViewMenu; - private javax.swing.JMenu fileMenu1; - private javax.swing.JMenu helpMenu1; - private javax.swing.JLabel jLabel1; - private javax.swing.JLabel jLabel2; - private javax.swing.JLabel jLabel5; - private javax.swing.JMenuBar jMenuBar2; - private javax.swing.JButton originalImageSelect; - private javax.swing.JTextField originalImageText; - private javax.swing.JButton processButton; - private javax.swing.JProgressBar progress; - private javax.swing.JMenuItem quitMenuItem1; - private javax.swing.JSeparator separator; - private javax.swing.JLabel statusLabel; - private javax.swing.JButton stopButton; - private javax.swing.JMenu toolsMenu; - private javax.swing.JButton trainButton; - private javax.swing.JSpinner trainingCylcesInput; - private javax.swing.JButton trainingDirectorySelect; - private javax.swing.JTextField trainingDirectoryText; + + private void quitMenuItemMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_quitMenuItemMouseReleased + if (this.brainRunner != null) { + this.brainRunner.shutdown(); + } + System.exit(0); + }//GEN-LAST:event_quitMenuItemMouseReleased + + private void quitMenuItemMenuKeyPressed(javax.swing.event.MenuKeyEvent evt) {//GEN-FIRST:event_quitMenuItemMenuKeyPressed + if (this.brainRunner != null) { + this.brainRunner.shutdown(); + } + System.exit(0); + }//GEN-LAST:event_quitMenuItemMenuKeyPressed + + private void aboutMenuItemMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_aboutMenuItemMouseReleased + displayAbout(); + }//GEN-LAST:event_aboutMenuItemMouseReleased + + private void aboutMenuItemMenuKeyPressed(javax.swing.event.MenuKeyEvent evt) {//GEN-FIRST:event_aboutMenuItemMenuKeyPressed + displayAbout(); + }//GEN-LAST:event_aboutMenuItemMenuKeyPressed + + private void originalImageSelectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_originalImageSelectActionPerformed + final JFileChooser chooser = new JFileChooser(); + final FileNameExtensionFilter filter = new FileNameExtensionFilter("PNG Images", "png"); + chooser.setFileFilter(filter); + chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); + chooser.setMultiSelectionEnabled(false); + chooser.setVisible(true); + if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { + this.originalImageText.setText(chooser.getSelectedFile().getAbsolutePath()); + this.originalImageLocation = chooser.getSelectedFile(); + + this.refreshOriginalImage(); + + if (this.brainRunnerThread != null) { + this.processButton.setEnabled(true); + this.trainButton.setEnabled(true); + + this.statusLabel.setText("Ready!"); + } + } + }//GEN-LAST:event_originalImageSelectActionPerformed + + private void trainingDirectorySelectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_trainingDirectorySelectActionPerformed + final JFileChooser chooser = new JFileChooser(); + chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + chooser.setMultiSelectionEnabled(false); + chooser.setVisible(true); + if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { + this.trainingDirectoryText.setText(chooser.getSelectedFile().getAbsolutePath()); + this.trainingDirectory = chooser.getSelectedFile(); + + final File[] trainingFiles = trainingDirectory.listFiles(new PngFileFilter()); + if (trainingFiles.length <= 0) { + this.trainingDirectory = null; + this.trainingDirectoryText.setText(""); + + JOptionPane.showMessageDialog(this, "The selected training directory does not contain *.png files! Select a new directory", "Invalid Training Directory", JOptionPane.ERROR_MESSAGE); + + return; + } + + this.brainRunner = new BrainRunner(this, trainingFiles, 0.875, BLOCK_WIDTH, BLOCK_HEIGHT, true); + this.brainRunnerThread = new Thread(this.brainRunner); + this.brainRunnerThread.start(); + + if (this.originalImageLocation != null) { + this.processButton.setEnabled(true); + this.trainButton.setEnabled(true); + + this.statusLabel.setText("Ready!"); + } + } + }//GEN-LAST:event_trainingDirectorySelectActionPerformed + + private void trainButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_trainButtonActionPerformed + this.trainButton.setEnabled(false); + this.processButton.setEnabled(false); + this.stopButton.setEnabled(true); + + this.statusLabel.setText("Please wait, training..."); + + this.currentTrainingCycles = ((Integer) this.trainingCylcesInput.getValue()).intValue(); + this.trainingRemaining = this.currentTrainingCycles; + + this.brainRunner.setTrainingCycles(this.currentTrainingCycles); + }//GEN-LAST:event_trainButtonActionPerformed + + private void processButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_processButtonActionPerformed + if (this.processing || (finalImage == null) || (originalImage == null)) { + return; + } + + this.processButton.setEnabled(false); + this.trainButton.setEnabled(false); + this.stopButton.setEnabled(false); + + this.processing = true; + + this.statusLabel.setText("Please wait, processing..."); + + this.brainRunner.setSampleImage(this.originalImageLocation); + }//GEN-LAST:event_processButtonActionPerformed + + private void stopButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_stopButtonActionPerformed + this.brainRunner.stop(); + }//GEN-LAST:event_stopButtonActionPerformed + + public void showBrainView() { + if (brainVisual == null) { + final JDialog errorDialog = new JDialog(); + errorDialog.add(errorPanel); + errorDialog.setVisible(true); + } + else { + this.brainVisual.refresh(); + + if (this.viewBrain == null) { + this.viewBrain = new ViewBrain(this, brainVisual); + } + + this.viewBrain.setVisible(true); + } + } + + private void brainViewMenuMenuKeyPressed(javax.swing.event.MenuKeyEvent evt) {//GEN-FIRST:event_brainViewMenuMenuKeyPressed + showBrainView(); + }//GEN-LAST:event_brainViewMenuMenuKeyPressed + + private void brainViewMenuMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_brainViewMenuMouseReleased + showBrainView(); + }//GEN-LAST:event_brainViewMenuMouseReleased + + private void quitMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_quitMenuItem1ActionPerformed + if (this.brainRunner != null) { + this.brainRunner.shutdown(); + } + System.exit(0); + }//GEN-LAST:event_quitMenuItem1ActionPerformed + + private void refreshOriginalImage() { + if (this.originalImageLocation == null) { + return; + } + + try { + originalImage = ImageIO.read(this.originalImageLocation); + } + catch (IOException caught) { + LOGGER.warn("IO Exception when reading image", caught); + return; + } + this.originalImagePanel.setImage(this.originalImage); + this.finalImage = new BufferedImage(originalImage.getWidth(), originalImage.getHeight(), BufferedImage.TYPE_INT_RGB); + } + + private void displayAbout() { + final AboutDialog about = new AboutDialog(this, true); + about.setVisible(true); + } + + public void brainFinishedBuffering() { + try { + this.brainVisual = new HyperassociativeMapCanvas(this.brainRunner.getBrainMap()); + this.brainViewMenu.setEnabled(true); + } + catch (ComponentUnavailableException exc) { + this.brainVisual = null; + this.errorPanel = exc.newPanel(); + this.brainViewMenu.setEnabled(false); + + } + } + + public void brainSampleProcessed(final BufferedImage finalImage) { + this.processing = false; + this.progress.setValue(100); + this.finalImage = finalImage; + this.finalImagePanel.setImage(this.finalImage); + this.finalImagePanel.repaint(); + + this.processButton.setEnabled(true); + this.trainButton.setEnabled(true); + this.stopButton.setEnabled(false); + + this.statusLabel.setText("Ready!"); + } + + public void brainTrainingComplete() { + this.trainingRemaining = 0; + this.progress.setValue(100); + + this.processButton.setEnabled(true); + this.trainButton.setEnabled(true); + this.stopButton.setEnabled(false); + + this.statusLabel.setText("Ready!"); + } // End of variables declaration//GEN-END:variables } diff --git a/src/main/java/com/syncleus/dann/examples/nci/ui/PngFileFilter.java b/src/main/java/com/syncleus/dann/examples/nci/ui/PngFileFilter.java index 3d9e65e5ededbe7f9c841f33eeee97a4394316a2..bea0aa9fc416b655948c8851edd46c3fe0cbb5c5 100644 --- a/src/main/java/com/syncleus/dann/examples/nci/ui/PngFileFilter.java +++ b/src/main/java/com/syncleus/dann/examples/nci/ui/PngFileFilter.java @@ -18,14 +18,11 @@ ******************************************************************************/ package com.syncleus.dann.examples.nci.ui; -import java.io.File; -import java.io.FileFilter; +import java.io.*; -public class PngFileFilter implements FileFilter -{ - @Override - public boolean accept(final File pathname) - { - return pathname.getAbsolutePath().toLowerCase().endsWith(".png"); - } +public class PngFileFilter implements FileFilter { + @Override + public boolean accept(final File pathname) { + return pathname.getAbsolutePath().toLowerCase().endsWith(".png"); + } } diff --git a/src/main/java/com/syncleus/dann/examples/nci/ui/UpdateViewRun.java b/src/main/java/com/syncleus/dann/examples/nci/ui/UpdateViewRun.java index 614cb70e3b3ac125d7036f6200ba51bfd823539e..1bff4a0e037207d6eee8572dceb425d6ae8edab5 100644 --- a/src/main/java/com/syncleus/dann/examples/nci/ui/UpdateViewRun.java +++ b/src/main/java/com/syncleus/dann/examples/nci/ui/UpdateViewRun.java @@ -21,18 +21,15 @@ package com.syncleus.dann.examples.nci.ui; import com.syncleus.dann.graph.drawing.hyperassociativemap.visualization.HyperassociativeMapCanvas; -public class UpdateViewRun implements Runnable -{ - private final HyperassociativeMapCanvas view; +public class UpdateViewRun implements Runnable { + private final HyperassociativeMapCanvas view; - public UpdateViewRun(final HyperassociativeMapCanvas view) - { - this.view = view; - } + public UpdateViewRun(final HyperassociativeMapCanvas view) { + this.view = view; + } - @Override - public void run() - { - this.view.refresh(); - } + @Override + public void run() { + this.view.refresh(); + } } diff --git a/src/main/java/com/syncleus/dann/examples/nci/ui/ViewBrain.java b/src/main/java/com/syncleus/dann/examples/nci/ui/ViewBrain.java index 82136900bd96daae5d663b6415a3a25eeb43c0ba..29b6eb9bc271244d082ca13d38785f89640ea1f8 100644 --- a/src/main/java/com/syncleus/dann/examples/nci/ui/ViewBrain.java +++ b/src/main/java/com/syncleus/dann/examples/nci/ui/ViewBrain.java @@ -19,90 +19,75 @@ package com.syncleus.dann.examples.nci.ui; import com.syncleus.dann.graph.drawing.hyperassociativemap.visualization.HyperassociativeMapCanvas; -import java.awt.Frame; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.FutureTask; -import javax.swing.JDialog; -import javax.swing.Timer; - -public class ViewBrain extends JDialog implements ActionListener, KeyListener -{ - private final HyperassociativeMapCanvas brainVisual; - private final ExecutorService executor = Executors.newFixedThreadPool(1); - private FutureTask<Void> lastRun; - - public ViewBrain(final Frame parent, final HyperassociativeMapCanvas brainVisual) - { - super(parent, false); - - initComponents(); - - this.brainVisual = brainVisual; - - this.add(this.brainVisual); - this.brainVisual.setLocation(0, 0); - this.brainVisual.setSize(800, 600); - this.brainVisual.setVisible(true); - - this.setSize(800, 600); - - this.brainVisual.refresh(); - - this.lastRun = new FutureTask<Void>(new UpdateViewRun(this.brainVisual), null); - this.executor.execute(this.lastRun); - - new Timer(100, this).start(); - - this.addKeyListener(this); - this.brainVisual.addKeyListener(this); - } - - @Override - public void keyPressed(final KeyEvent evt) - { - if (evt.getKeyCode() == KeyEvent.VK_R) - { - this.brainVisual.getHyperassociativeMap().reset(); - } - if (evt.getKeyCode() == KeyEvent.VK_L) - { - this.brainVisual.getHyperassociativeMap().resetLearning(); - } - } - - @Override - public void keyReleased(final KeyEvent evt) - { - // unused - } - - @Override - public void keyTyped(final KeyEvent evt) - { - // unused - } - - @Override - public void actionPerformed(final ActionEvent evt) - { - if ((this.lastRun != null) && !this.lastRun.isDone()) - { - return; - } - - if (!this.isVisible()) - { - return; - } - - this.lastRun = new FutureTask<Void>(new UpdateViewRun(this.brainVisual), null); - this.executor.execute(this.lastRun); - } + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.util.concurrent.*; + +public class ViewBrain extends JDialog implements ActionListener, KeyListener { + private final HyperassociativeMapCanvas brainVisual; + private final ExecutorService executor = Executors.newFixedThreadPool(1); + private FutureTask<Void> lastRun; + + public ViewBrain(final Frame parent, final HyperassociativeMapCanvas brainVisual) { + super(parent, false); + + initComponents(); + + this.brainVisual = brainVisual; + + this.add(this.brainVisual); + this.brainVisual.setLocation(0, 0); + this.brainVisual.setSize(800, 600); + this.brainVisual.setVisible(true); + + this.setSize(800, 600); + + this.brainVisual.refresh(); + + this.lastRun = new FutureTask<Void>(new UpdateViewRun(this.brainVisual), null); + this.executor.execute(this.lastRun); + + new Timer(100, this).start(); + + this.addKeyListener(this); + this.brainVisual.addKeyListener(this); + } + + @Override + public void keyPressed(final KeyEvent evt) { + if (evt.getKeyCode() == KeyEvent.VK_R) { + this.brainVisual.getHyperassociativeMap().reset(); + } + if (evt.getKeyCode() == KeyEvent.VK_L) { + this.brainVisual.getHyperassociativeMap().resetLearning(); + } + } + + @Override + public void keyReleased(final KeyEvent evt) { + // unused + } + + @Override + public void keyTyped(final KeyEvent evt) { + // unused + } + + @Override + public void actionPerformed(final ActionEvent evt) { + if ((this.lastRun != null) && !this.lastRun.isDone()) { + return; + } + + if (!this.isVisible()) { + return; + } + + this.lastRun = new FutureTask<Void>(new UpdateViewRun(this.brainVisual), null); + this.executor.execute(this.lastRun); + } // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { @@ -112,12 +97,12 @@ public class ViewBrain extends JDialog implements ActionListener, KeyListener javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 400, Short.MAX_VALUE) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 400, Short.MAX_VALUE) ); layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 300, Short.MAX_VALUE) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 300, Short.MAX_VALUE) ); pack(); diff --git a/src/main/java/com/syncleus/dann/examples/pathfind/AbstractGridCanvas.java b/src/main/java/com/syncleus/dann/examples/pathfind/AbstractGridCanvas.java index 9194850b8e6d334486ffab83de5424cc1e408725..e0417b8426d83a9ac850efe4aa46ad9183d42dcd 100644 --- a/src/main/java/com/syncleus/dann/examples/pathfind/AbstractGridCanvas.java +++ b/src/main/java/com/syncleus/dann/examples/pathfind/AbstractGridCanvas.java @@ -18,401 +18,364 @@ ******************************************************************************/ package com.syncleus.dann.examples.pathfind; -import com.syncleus.dann.graph.BidirectedEdge; -import com.syncleus.dann.graph.SimpleWeightedUndirectedEdge; -import com.syncleus.dann.graph.WeightedBidirectedEdge; -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.awt.event.MouseMotionListener; -import java.util.LinkedList; +import com.syncleus.dann.graph.*; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.util.*; import java.util.List; -import javax.swing.JPanel; /** * Displays a WeightedGrid as a Swing component, with support for highlighting * individual nodes and edges (borders between nodes). + * * @author seh */ -public abstract class AbstractGridCanvas extends JPanel implements MouseListener, MouseMotionListener -{ - /** - * Number of times smaller that the drawn path is than nodes which it runs - * through. - */ - private static final int PATH_FRACTION = 4; - /** - * Number of times smaller that the drawn border highlighting is than nodes - * and edges which it surrounds. - */ - private static final int BORDER_FRACTION = 4; - private static final Color PATH_COLOR = new Color(0.5f, 0f, 0f); - private final WeightedGrid grid; - private final int nodeSize; - private final int edgeSize; - private List<SimpleWeightedUndirectedEdge<GridNode>> path; - private final int pathThickness; - private GridNode touchedNode = null; - private SimpleWeightedUndirectedEdge<GridNode> touchedEdge = null; - private final int selectedThickness; - - /** - * Constructs a Swing component representing a grid and a path according to - * pixel-sizing parameters. - * @param shownGrid the grid displayed by this component - * @param initialPath the initial path displayed by this component, which - * may be null - * @param initialNodeSize size (in pixels) of each displayed node square - * @param initialEdgeSize size (in pixels) of the width or height of each - * edge surrounding each node square - */ - public AbstractGridCanvas(final WeightedGrid shownGrid, final List<SimpleWeightedUndirectedEdge<GridNode>> initialPath, final int initialNodeSize, final int initialEdgeSize) - { - super(); - - this.grid = shownGrid; - this.nodeSize = initialNodeSize; - this.edgeSize = initialEdgeSize; - this.path = initialPath; - this.pathThickness = Math.max(1, nodeSize / PATH_FRACTION); - this.selectedThickness = Math.max(1, Math.min(edgeSize, nodeSize) / BORDER_FRACTION); - - final int preferredWidth = grid.getWidth() * nodeSize + (grid.getWidth() + 1) * edgeSize; - final int preferredHeight = grid.getHeight() * nodeSize + (grid.getHeight() + 1) * edgeSize; - setPreferredSize(new Dimension(preferredWidth, preferredHeight)); - - addMouseListener(this); - addMouseMotionListener(this); - } - - @Override - public void paint(final Graphics graphics) - { - super.paint(graphics); - - final Graphics2D graphics2D = (Graphics2D) graphics; - - int px = 0; - int py = 0; - for (int y = 0; y < grid.getHeight(); y++) - { - px = 0; - for (int x = 0; x < grid.getWidth(); x++) - { - final GridNode gridNode = grid.getNode(x, y); - - if (y != 0) - { - final GridNode toNode = grid.getNode(x, y - 1); - - //draw filled rect for edge - final WeightedBidirectedEdge<GridNode> upEdge = grid.getEdgeBetween(x, y, x, y - 1); - graphics2D.setColor(getEdgeColor(upEdge)); - graphics2D.fillRect(px + edgeSize, py, nodeSize, edgeSize); - - if ((touchedEdge != null) && (touchedEdge.getRightNode() == gridNode) && (touchedEdge.getLeftNode() == toNode)) - { - //draw border of selected edge - graphics2D.setStroke(new BasicStroke(selectedThickness)); - graphics2D.setColor(/*getTouchedNodeBorderColor()*/Color.ORANGE); - graphics2D.drawRect(px + edgeSize, py, nodeSize, edgeSize); - } - } - - if (x != 0) - { - final GridNode toNode = grid.getNode(x - 1, y); - - //draw filled rect for edge - final WeightedBidirectedEdge<GridNode> rightEdge = grid.getEdgeBetween(x, y, x - 1, y); - graphics2D.setColor(getEdgeColor(rightEdge)); - graphics2D.fillRect(px, py + edgeSize, edgeSize, nodeSize); - - if ((touchedEdge != null) && (touchedEdge.getRightNode() == gridNode) && (touchedEdge.getLeftNode() == toNode)) - { - //draw border of selected edge - graphics2D.setStroke(new BasicStroke(selectedThickness)); - graphics2D.setColor(/*getTouchedNodeBorderColor()*/Color.ORANGE); - graphics2D.drawRect(px, py + edgeSize, edgeSize, nodeSize); - } - } - - graphics2D.setColor(getNodeColor(gridNode)); - graphics2D.fillRect(px + edgeSize, py + edgeSize, nodeSize, nodeSize); - - if (gridNode == touchedNode) - { - graphics2D.setStroke(new BasicStroke(selectedThickness)); - graphics2D.setColor(/*getTouchedNodeBorderColor()*/Color.ORANGE); - graphics2D.drawRect(px + edgeSize, py + edgeSize, nodeSize, nodeSize); - } - - px += nodeSize + edgeSize; - } - py += nodeSize + edgeSize; - } - - if (path != null) - { - graphics2D.setColor(PATH_COLOR); - - graphics2D.setStroke(new BasicStroke(pathThickness, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); - - final int centerOffset = (edgeSize + nodeSize / 2); - - for (BidirectedEdge<GridNode> edge : path) - { - final int lastX = edge.getLeftNode().getX(); - final int lastY = edge.getLeftNode().getY(); - - final int curX = edge.getRightNode().getX(); - final int curY = edge.getRightNode().getY(); - - final int curPX = getNodePosition(curX) + centerOffset; - final int curPY = getNodePosition(curY) + centerOffset; - - final int lastPX = getNodePosition(lastX) + centerOffset; - final int lastPY = getNodePosition(lastY) + centerOffset; - - graphics2D.drawLine(lastPX, lastPY, curPX, curPY); - } - } - } - - /** - * Returns the color associated with a specific grid edge. - * @param edge the edge to get the color of - * @return the edge's color - */ - protected abstract Color getEdgeColor(WeightedBidirectedEdge<GridNode> edge); - - /** - * Returns the color associated with a specific grid node. - * @param node the node to get the color of - * @return the node's color - */ - protected abstract Color getNodeColor(GridNode node); - - /** - * Yields the pixel coordinate for a given grid coordinate of a node. The coordinate may represent either X or Y, since the grid is drawn in 1:1 "square" aspect ratio. - * @param coordinate the grid coordinate - * @return pixel coordinate of a given grid position, which may be outside of the grid's bounds - */ - private int getNodePosition(final int coordinate) - { - return coordinate * (nodeSize + edgeSize); - } - - /** - * Yields a node's grid coordinate for a given drawn pixel coordinate of a node. The coordinate may represent either X or Y, since the grid is drawn in 1:1 "square" aspect ratio. - * @param x pixel coordinate - * @return grid coordinate of a given pixel position, which may be outside of the grid's bounds - */ - protected int getNodePositionPixel(final int x) - { - return (int) Math.floor(((float) x) / ((float) (nodeSize + edgeSize))); - } - - /** - * Yields the touched edge corresponding to certain pixel coordinates in the drawn component. - * @param px x pixel coordinate - * @param py y pixel coordinate - * @return the edge corresponding to pixel (px, py), or null if no edge was drawn there - */ - public SimpleWeightedUndirectedEdge<GridNode> getTouchedEdge(final int px, final int py) - { - final int nx = getNodePositionPixel(px); - final int ny = getNodePositionPixel(py); - - if (nx * (nodeSize + edgeSize) > px + edgeSize) - { - return null; - } - - if (ny * (nodeSize + edgeSize) > py + edgeSize) - { - return null; - } - - if (Math.abs((px - nx * (nodeSize + edgeSize)) - (py - ny * (nodeSize + edgeSize))) < edgeSize) - { - return null; - } - - final boolean upOrLeft = (px - nx * (nodeSize + edgeSize) > py - ny * (nodeSize + edgeSize)) ? true : false; - - if ((nx >= (upOrLeft ? 0 : 1)) && (ny >= (!upOrLeft ? 0 : 1)) - && (nx < grid.getWidth()) && (ny < grid.getHeight())) - { - final List<SimpleWeightedUndirectedEdge<GridNode>> thisEdges; - final List<SimpleWeightedUndirectedEdge<GridNode>> otherEdges; - thisEdges = new LinkedList(grid.getAdjacentEdges(grid.getNode(nx, ny))); - //System.err.println(nx + " " + ny + " : " + thisEdges); - - if (upOrLeft) - { - //up - otherEdges = new LinkedList(grid.getAdjacentEdges(grid.getNode(nx, ny - 1))); - //System.err.println(nx + " " + (ny-1) + " : " + otherEdges); - } - else - { - //left - otherEdges = new LinkedList(grid.getAdjacentEdges(grid.getNode(nx - 1, ny))); - //System.err.println((nx-1) + " " + ny + " : " + otherEdges); - } - - SimpleWeightedUndirectedEdge<GridNode> sharedEdge = null; - for (SimpleWeightedUndirectedEdge<GridNode> eedge : thisEdges) - { - if (otherEdges.contains(eedge)) - { - sharedEdge = eedge; - break; - } - } - - if (sharedEdge == null) - { - return null; - } - else - { - return sharedEdge; - } - } - - return null; - } - - /** - * Yields the touched node corresponding to certain pixel coordinates in the drawn component. - * @param px x pixel coordinate - * @param py y pixel coordinate - * @return the node corresponding to pixel (px, py), or null if no node was drawn there - */ - public GridNode getTouchedNode(final int px, final int py) - { - final int nx = getNodePositionPixel(px); - final int ny = getNodePositionPixel(py); - - if (nx * (nodeSize + edgeSize) + edgeSize > px) - { - return null; - } - if (ny * (nodeSize + edgeSize) + edgeSize > py) - { - return null; - } - - if ((nx >= 0) && (ny >= 0) && (nx < grid.getWidth()) && (ny < grid.getHeight())) - { - return grid.getNode(nx, ny); - } - - return null; - } - - @Override - public void mouseClicked(final MouseEvent evt) - { - // unused - } - - @Override - public void mousePressed(final MouseEvent evt) - { - // unused - } - - @Override - public void mouseReleased(final MouseEvent evt) - { - // unused - } - - @Override - public void mouseEntered(final MouseEvent evt) - { - // unused - } - - @Override - public void mouseExited(final MouseEvent evt) - { - // unused - } - - @Override - public void mouseDragged(final MouseEvent evt) - { - updateMouseMoved(evt); - } - - /** - * Updates the current touchedNode or touchedEdge when the mouse is either - * moved or dragged. - * @param evt mouse event to update according to - */ - protected void updateMouseMoved(final MouseEvent evt) - { - final GridNode tNode = getTouchedNode(evt.getX(), evt.getY()); - - final SimpleWeightedUndirectedEdge<GridNode> tEdge = getTouchedEdge(evt.getX(), evt.getY()); - - this.touchedNode = null; - this.touchedEdge = null; - - if (tNode != null) - { - this.touchedNode = tNode; - } - else if (tEdge != null) - { - this.touchedEdge = tEdge; - } - - //System.out.println("touchedNode: " + touchedNode + " , touchedEdge: " + touchedEdge); - - repaint(); - } - - @Override - public void mouseMoved(final MouseEvent evt) - { - updateMouseMoved(evt); - } - - /** - * Sets a different path to draw when the component is redrawn, and then - * repaint()'s. - * @param nextPath the next path to draw - */ - void setPath(final List<SimpleWeightedUndirectedEdge<GridNode>> nextPath) - { - this.path = nextPath; - repaint(); - } - - /** - * Returns the currently pointer-touched grid Edge. - * @return currently touched edge, or null if none is touched - */ - public SimpleWeightedUndirectedEdge<GridNode> getTouchedEdge() - { - return touchedEdge; - } - - /** - * Returns the currently pointer-touched GridNode. - * @return currently touched GridNode, or null if none is touched - */ - public GridNode getTouchedNode() - { - return touchedNode; - } +public abstract class AbstractGridCanvas extends JPanel implements MouseListener, MouseMotionListener { + /** + * Number of times smaller that the drawn path is than nodes which it runs + * through. + */ + private static final int PATH_FRACTION = 4; + /** + * Number of times smaller that the drawn border highlighting is than nodes + * and edges which it surrounds. + */ + private static final int BORDER_FRACTION = 4; + private static final Color PATH_COLOR = new Color(0.5f, 0f, 0f); + private final WeightedGrid grid; + private final int nodeSize; + private final int edgeSize; + private final int pathThickness; + private final int selectedThickness; + private List<SimpleWeightedUndirectedEdge<GridNode>> path; + private GridNode touchedNode = null; + private SimpleWeightedUndirectedEdge<GridNode> touchedEdge = null; + + /** + * Constructs a Swing component representing a grid and a path according to + * pixel-sizing parameters. + * + * @param shownGrid the grid displayed by this component + * @param initialPath the initial path displayed by this component, which + * may be null + * @param initialNodeSize size (in pixels) of each displayed node square + * @param initialEdgeSize size (in pixels) of the width or height of each + * edge surrounding each node square + */ + public AbstractGridCanvas(final WeightedGrid shownGrid, final List<SimpleWeightedUndirectedEdge<GridNode>> initialPath, final int initialNodeSize, final int initialEdgeSize) { + super(); + + this.grid = shownGrid; + this.nodeSize = initialNodeSize; + this.edgeSize = initialEdgeSize; + this.path = initialPath; + this.pathThickness = Math.max(1, nodeSize / PATH_FRACTION); + this.selectedThickness = Math.max(1, Math.min(edgeSize, nodeSize) / BORDER_FRACTION); + + final int preferredWidth = grid.getWidth() * nodeSize + (grid.getWidth() + 1) * edgeSize; + final int preferredHeight = grid.getHeight() * nodeSize + (grid.getHeight() + 1) * edgeSize; + setPreferredSize(new Dimension(preferredWidth, preferredHeight)); + + addMouseListener(this); + addMouseMotionListener(this); + } + + @Override + public void paint(final Graphics graphics) { + super.paint(graphics); + + final Graphics2D graphics2D = (Graphics2D) graphics; + + int px = 0; + int py = 0; + for (int y = 0; y < grid.getHeight(); y++) { + px = 0; + for (int x = 0; x < grid.getWidth(); x++) { + final GridNode gridNode = grid.getNode(x, y); + + if (y != 0) { + final GridNode toNode = grid.getNode(x, y - 1); + + //draw filled rect for edge + final WeightedBidirectedEdge<GridNode> upEdge = grid.getEdgeBetween(x, y, x, y - 1); + graphics2D.setColor(getEdgeColor(upEdge)); + graphics2D.fillRect(px + edgeSize, py, nodeSize, edgeSize); + + if ((touchedEdge != null) && (touchedEdge.getRightNode() == gridNode) && (touchedEdge.getLeftNode() == toNode)) { + //draw border of selected edge + graphics2D.setStroke(new BasicStroke(selectedThickness)); + graphics2D.setColor(/*getTouchedNodeBorderColor()*/Color.ORANGE); + graphics2D.drawRect(px + edgeSize, py, nodeSize, edgeSize); + } + } + + if (x != 0) { + final GridNode toNode = grid.getNode(x - 1, y); + + //draw filled rect for edge + final WeightedBidirectedEdge<GridNode> rightEdge = grid.getEdgeBetween(x, y, x - 1, y); + graphics2D.setColor(getEdgeColor(rightEdge)); + graphics2D.fillRect(px, py + edgeSize, edgeSize, nodeSize); + + if ((touchedEdge != null) && (touchedEdge.getRightNode() == gridNode) && (touchedEdge.getLeftNode() == toNode)) { + //draw border of selected edge + graphics2D.setStroke(new BasicStroke(selectedThickness)); + graphics2D.setColor(/*getTouchedNodeBorderColor()*/Color.ORANGE); + graphics2D.drawRect(px, py + edgeSize, edgeSize, nodeSize); + } + } + + graphics2D.setColor(getNodeColor(gridNode)); + graphics2D.fillRect(px + edgeSize, py + edgeSize, nodeSize, nodeSize); + + if (gridNode == touchedNode) { + graphics2D.setStroke(new BasicStroke(selectedThickness)); + graphics2D.setColor(/*getTouchedNodeBorderColor()*/Color.ORANGE); + graphics2D.drawRect(px + edgeSize, py + edgeSize, nodeSize, nodeSize); + } + + px += nodeSize + edgeSize; + } + py += nodeSize + edgeSize; + } + + if (path != null) { + graphics2D.setColor(PATH_COLOR); + + graphics2D.setStroke(new BasicStroke(pathThickness, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); + + final int centerOffset = (edgeSize + nodeSize / 2); + + for (BidirectedEdge<GridNode> edge : path) { + final int lastX = edge.getLeftNode().getX(); + final int lastY = edge.getLeftNode().getY(); + + final int curX = edge.getRightNode().getX(); + final int curY = edge.getRightNode().getY(); + + final int curPX = getNodePosition(curX) + centerOffset; + final int curPY = getNodePosition(curY) + centerOffset; + + final int lastPX = getNodePosition(lastX) + centerOffset; + final int lastPY = getNodePosition(lastY) + centerOffset; + + graphics2D.drawLine(lastPX, lastPY, curPX, curPY); + } + } + } + + /** + * Returns the color associated with a specific grid edge. + * + * @param edge the edge to get the color of + * @return the edge's color + */ + protected abstract Color getEdgeColor(WeightedBidirectedEdge<GridNode> edge); + + /** + * Returns the color associated with a specific grid node. + * + * @param node the node to get the color of + * @return the node's color + */ + protected abstract Color getNodeColor(GridNode node); + + /** + * Yields the pixel coordinate for a given grid coordinate of a node. The coordinate may represent either X or Y, since the grid is drawn in 1:1 "square" aspect ratio. + * + * @param coordinate the grid coordinate + * @return pixel coordinate of a given grid position, which may be outside of the grid's bounds + */ + private int getNodePosition(final int coordinate) { + return coordinate * (nodeSize + edgeSize); + } + + /** + * Yields a node's grid coordinate for a given drawn pixel coordinate of a node. The coordinate may represent either X or Y, since the grid is drawn in 1:1 "square" aspect ratio. + * + * @param x pixel coordinate + * @return grid coordinate of a given pixel position, which may be outside of the grid's bounds + */ + protected int getNodePositionPixel(final int x) { + return (int) Math.floor(((float) x) / ((float) (nodeSize + edgeSize))); + } + + /** + * Yields the touched edge corresponding to certain pixel coordinates in the drawn component. + * + * @param px x pixel coordinate + * @param py y pixel coordinate + * @return the edge corresponding to pixel (px, py), or null if no edge was drawn there + */ + public SimpleWeightedUndirectedEdge<GridNode> getTouchedEdge(final int px, final int py) { + final int nx = getNodePositionPixel(px); + final int ny = getNodePositionPixel(py); + + if (nx * (nodeSize + edgeSize) > px + edgeSize) { + return null; + } + + if (ny * (nodeSize + edgeSize) > py + edgeSize) { + return null; + } + + if (Math.abs((px - nx * (nodeSize + edgeSize)) - (py - ny * (nodeSize + edgeSize))) < edgeSize) { + return null; + } + + final boolean upOrLeft = (px - nx * (nodeSize + edgeSize) > py - ny * (nodeSize + edgeSize)) ? true : false; + + if ((nx >= (upOrLeft ? 0 : 1)) && (ny >= (!upOrLeft ? 0 : 1)) + && (nx < grid.getWidth()) && (ny < grid.getHeight())) { + final List<SimpleWeightedUndirectedEdge<GridNode>> thisEdges; + final List<SimpleWeightedUndirectedEdge<GridNode>> otherEdges; + thisEdges = new LinkedList(grid.getAdjacentEdges(grid.getNode(nx, ny))); + //System.err.println(nx + " " + ny + " : " + thisEdges); + + if (upOrLeft) { + //up + otherEdges = new LinkedList(grid.getAdjacentEdges(grid.getNode(nx, ny - 1))); + //System.err.println(nx + " " + (ny-1) + " : " + otherEdges); + } + else { + //left + otherEdges = new LinkedList(grid.getAdjacentEdges(grid.getNode(nx - 1, ny))); + //System.err.println((nx-1) + " " + ny + " : " + otherEdges); + } + + SimpleWeightedUndirectedEdge<GridNode> sharedEdge = null; + for (SimpleWeightedUndirectedEdge<GridNode> eedge : thisEdges) { + if (otherEdges.contains(eedge)) { + sharedEdge = eedge; + break; + } + } + + if (sharedEdge == null) { + return null; + } + else { + return sharedEdge; + } + } + + return null; + } + + /** + * Yields the touched node corresponding to certain pixel coordinates in the drawn component. + * + * @param px x pixel coordinate + * @param py y pixel coordinate + * @return the node corresponding to pixel (px, py), or null if no node was drawn there + */ + public GridNode getTouchedNode(final int px, final int py) { + final int nx = getNodePositionPixel(px); + final int ny = getNodePositionPixel(py); + + if (nx * (nodeSize + edgeSize) + edgeSize > px) { + return null; + } + if (ny * (nodeSize + edgeSize) + edgeSize > py) { + return null; + } + + if ((nx >= 0) && (ny >= 0) && (nx < grid.getWidth()) && (ny < grid.getHeight())) { + return grid.getNode(nx, ny); + } + + return null; + } + + @Override + public void mouseClicked(final MouseEvent evt) { + // unused + } + + @Override + public void mousePressed(final MouseEvent evt) { + // unused + } + + @Override + public void mouseReleased(final MouseEvent evt) { + // unused + } + + @Override + public void mouseEntered(final MouseEvent evt) { + // unused + } + + @Override + public void mouseExited(final MouseEvent evt) { + // unused + } + + @Override + public void mouseDragged(final MouseEvent evt) { + updateMouseMoved(evt); + } + + /** + * Updates the current touchedNode or touchedEdge when the mouse is either + * moved or dragged. + * + * @param evt mouse event to update according to + */ + protected void updateMouseMoved(final MouseEvent evt) { + final GridNode tNode = getTouchedNode(evt.getX(), evt.getY()); + + final SimpleWeightedUndirectedEdge<GridNode> tEdge = getTouchedEdge(evt.getX(), evt.getY()); + + this.touchedNode = null; + this.touchedEdge = null; + + if (tNode != null) { + this.touchedNode = tNode; + } + else if (tEdge != null) { + this.touchedEdge = tEdge; + } + + //System.out.println("touchedNode: " + touchedNode + " , touchedEdge: " + touchedEdge); + + repaint(); + } + + @Override + public void mouseMoved(final MouseEvent evt) { + updateMouseMoved(evt); + } + + /** + * Sets a different path to draw when the component is redrawn, and then + * repaint()'s. + * + * @param nextPath the next path to draw + */ + void setPath(final List<SimpleWeightedUndirectedEdge<GridNode>> nextPath) { + this.path = nextPath; + repaint(); + } + + /** + * Returns the currently pointer-touched grid Edge. + * + * @return currently touched edge, or null if none is touched + */ + public SimpleWeightedUndirectedEdge<GridNode> getTouchedEdge() { + return touchedEdge; + } + + /** + * Returns the currently pointer-touched GridNode. + * + * @return currently touched GridNode, or null if none is touched + */ + public GridNode getTouchedNode() { + return touchedNode; + } } diff --git a/src/main/java/com/syncleus/dann/examples/pathfind/GridNode.java b/src/main/java/com/syncleus/dann/examples/pathfind/GridNode.java index 4eb2a80bc4973c7ac34b13ab45c1d58e3b798e70..926afde92d3e787486dbf4e6632293409f842bd6 100644 --- a/src/main/java/com/syncleus/dann/examples/pathfind/GridNode.java +++ b/src/main/java/com/syncleus/dann/examples/pathfind/GridNode.java @@ -21,54 +21,47 @@ package com.syncleus.dann.examples.pathfind; import com.syncleus.dann.graph.Weighted; import com.syncleus.dann.math.Vector; -public class GridNode extends Vector implements Weighted -{ - private double weight; +public class GridNode extends Vector implements Weighted { + private double weight; - public GridNode(final int x, final int y, final double weight) - { - super((double)x, (double)y); - this.weight = weight; - } + public GridNode(final int x, final int y, final double weight) { + super((double) x, (double) y); + this.weight = weight; + } - @Override - public double getWeight() - { - return this.weight; - } + @Override + public double getWeight() { + return this.weight; + } - public int getX() - { - return (int) this.getCoordinate(1); - } + /** + * Sets the weight value associated with this node. + * + * @param nextWeight the new weight value to set + */ + public void setWeight(final double nextWeight) { + this.weight = nextWeight; + } - public int getY() - { - return (int) this.getCoordinate(2); - } + public int getX() { + return (int) this.getCoordinate(1); + } - @Override - public int hashCode() - { - return (this.getX() * this.getY()) + this.getY(); - } + public int getY() { + return (int) this.getCoordinate(2); + } - @Override - public boolean equals(final Object compareToObj) - { - if(!(compareToObj instanceof GridNode)) - return false; + @Override + public int hashCode() { + return (this.getX() * this.getY()) + this.getY(); + } - final GridNode compareTo = (GridNode) compareToObj; - return ((compareTo.getX() == this.getX())&&(compareTo.getY() == this.getY())); - } + @Override + public boolean equals(final Object compareToObj) { + if (!(compareToObj instanceof GridNode)) + return false; - /** - * Sets the weight value associated with this node. - * @param nextWeight the new weight value to set - */ - public void setWeight(final double nextWeight) - { - this.weight = nextWeight; - } + final GridNode compareTo = (GridNode) compareToObj; + return ((compareTo.getX() == this.getX()) && (compareTo.getY() == this.getY())); + } } diff --git a/src/main/java/com/syncleus/dann/examples/pathfind/PathFindDemoPanel.java b/src/main/java/com/syncleus/dann/examples/pathfind/PathFindDemoPanel.java index 15a7ca0fabb405c97312de8b11a7e361fbed919b..6b98608d16689d3a2415ec44f9a71f8aefa0a891 100644 --- a/src/main/java/com/syncleus/dann/examples/pathfind/PathFindDemoPanel.java +++ b/src/main/java/com/syncleus/dann/examples/pathfind/PathFindDemoPanel.java @@ -18,403 +18,335 @@ ******************************************************************************/ package com.syncleus.dann.examples.pathfind; -import java.util.LinkedList; +import com.syncleus.dann.graph.*; +import com.syncleus.dann.graph.search.pathfinding.*; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.util.*; import java.util.List; -import com.syncleus.dann.graph.SimpleWeightedUndirectedEdge; -import com.syncleus.dann.graph.WeightedBidirectedEdge; -import com.syncleus.dann.graph.search.pathfinding.AstarPathFinder; -import com.syncleus.dann.graph.search.pathfinding.HeuristicPathCost; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.FlowLayout; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import javax.swing.ButtonGroup; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTabbedPane; -import javax.swing.JToggleButton; -import javax.swing.UIManager; /** * Demonstrates Path Finding across a Weighted Grid. * The Grid's node and edge weights can be adjusted by clicking. * The start and stop positions of the path to be found can also be specified. + * * @author seh */ -public class PathFindDemoPanel extends JPanel -{ - private AbstractGridCanvas gridCanvas; - private WeightedGrid grid; - private PathFindControlPanel controlPanel; - private List<SimpleWeightedUndirectedEdge<GridNode>> path; - private GridNode endNode; - private GridNode startNode; - private double paintWeight = 0.0; - private static final double INF = Double.POSITIVE_INFINITY; - private static final double MAX_NONINFINITE_CELL_WEIGHT = 12.0; - private static final int DEFAULT_NODE_SIZE = 24; - private static final int DEFAULT_EDGE_SIZE = 8; - private static final int DEFAULT_GRID_SIZE = 18; - private static final double MIN_GRID_WEIGHT = 1.0; - private static final double INITIAL_GRID_WEIGHT = MIN_GRID_WEIGHT; - private static final double[] PAINT_WEIGHTS = - { - 1, 2, 4, 6, 8, 10, INF - }; - - /** - * Distance heuristic used by the AStarPathFinding algorithm. - */ - private static class DistanceHeuristic implements HeuristicPathCost<GridNode> - { - @Override - public double getHeuristicPathCost(final GridNode begin, final GridNode end) - { - return begin.calculateRelativeTo(end).getDistance(); - } - - @Override - public boolean isOptimistic() - { - return true; - } - - @Override - public boolean isConsistent() - { - return true; - } - } - - private static class PaintButtonActionListener implements ActionListener - { - private final PathFindDemoPanel pathFindDemoPanel; - - public PaintButtonActionListener(final PathFindDemoPanel pathFindDemoPanel) - { - this.pathFindDemoPanel = pathFindDemoPanel; - } - - @Override - public void actionPerformed(final ActionEvent evt) - { - if (evt.getSource() instanceof PaintButton) - { - final PaintButton button = (PaintButton) evt.getSource(); - pathFindDemoPanel.paintWeight = button.getWeight(); - } - } - } - - private static class PaintButton extends JToggleButton - { - private static final int BUTTON_BORDER_SIZE = 4; - private final double weight; - - public PaintButton(final double drawWeight) - { - super(" "); - this.weight = drawWeight; - setForeground(getColor(weight)); - } - - @Override - public void paint(final Graphics graphics) - { - super.paint(graphics); - final Graphics2D graphics2D = (Graphics2D) graphics; - graphics2D.setColor(getColor(weight)); - graphics2D.fillRect(BUTTON_BORDER_SIZE, BUTTON_BORDER_SIZE, - getWidth() - BUTTON_BORDER_SIZE * 2, - getHeight() - BUTTON_BORDER_SIZE * 2); - } - - public double getWeight() - { - return weight; - } - } - - /** - * A panel that provides buttons for each of the drawable "weights". - */ - private static class DrawingPanel extends JPanel - { - private final List<PaintButton> paintButtons = new LinkedList(); - private final ButtonGroup paintButtonsGroup = new ButtonGroup(); - - public DrawingPanel(final double[] paintWeights, final PathFindDemoPanel pathFindDemoPanel) - { - super(new FlowLayout(FlowLayout.LEFT)); - - final PaintButtonActionListener paintButtonActionListener = new PaintButtonActionListener(pathFindDemoPanel); - for (double d : paintWeights) - { - final PaintButton button = new PaintButton(d); - button.addActionListener(paintButtonActionListener); - paintButtonsGroup.add(button); - paintButtons.add(button); - add(button); - } - } - - public List<PaintButton> getPaintButtons() - { - return paintButtons; - } - } - - private static class PathFindControlPanel extends JTabbedPane - { - public PathFindControlPanel(final PathFindDemoPanel pathFindDemoPanel) - { - addTab("Edit", new DrawingPanel(PAINT_WEIGHTS, pathFindDemoPanel)); - addTab("Start Position", new JLabel("Click a start position")); - addTab("Stop Position", new JLabel("Click a stop position")); - //addTab("Settings", new SettingsPanel()); - } - } - - /** - * Creates a new Swing component with an empty square grid of size - * width*width. - * @param width number of grid nodes wide and high - */ - public PathFindDemoPanel(final int width) - { - super(new BorderLayout()); - - reinit(width); - } - - /** - * Reconstructs the grid and the panel (and its components) with new grid - * dimensions. - * @param nextWidth the width and height (square) dimensions of the grid to - * (re-)initialize. - */ - protected void reinit(final int nextWidth) - { - removeAll(); - - final int width = nextWidth; - final int height = nextWidth; - - final double[][] gridWeights = new double[height][width]; - grid = new WeightedGrid(gridWeights); - grid.setAll(INITIAL_GRID_WEIGHT); - - startNode = grid.getNode(0, 0); - endNode = grid.getNode(width - 1, height - 1); - - updatePath(); - - controlPanel = new PathFindControlPanel(this); - add(controlPanel, BorderLayout.NORTH); - - gridCanvas = new AbstractGridCanvas(grid, path, DEFAULT_NODE_SIZE, DEFAULT_EDGE_SIZE) - { - private boolean mouseDown = false; - - @Override - public Color getNodeColor(final GridNode node) - { - return getColor(node.getWeight()); - } - - @Override - protected Color getEdgeColor(final WeightedBidirectedEdge<GridNode> edge) - { - return getColor(edge.getWeight()); - } - - protected void paintCells() - { - final int selectedIndex = controlPanel.getSelectedIndex(); - - if (mouseDown && (selectedIndex == 0)) - { - if (getTouchedNode() != null) - { - getTouchedNode().setWeight(paintWeight); - updatePath(); - } - else if (getTouchedEdge() != null) - { - getTouchedEdge().setWeight(paintWeight); - updatePath(); - } - } - - } - - @Override - public void mouseDragged(final MouseEvent evt) - { - super.mouseDragged(evt); - paintCells(); - } - - @Override - public void mouseMoved(final MouseEvent evt) - { - super.mouseMoved(evt); - paintCells(); - } - - @Override - public void mousePressed(final MouseEvent evt) - { - super.mousePressed(evt); - mouseDown = true; - } - - @Override - public void mouseReleased(final MouseEvent evt) - { - super.mouseReleased(evt); - mouseDown = false; - } - - @Override - public void mouseClicked(final MouseEvent evt) - { - final int selectedIndex = controlPanel.getSelectedIndex(); - - final GridNode touchedNode = getTouchedNode(); - - //starting position - if ((selectedIndex == 1) && (touchedNode != null)) - { - if (getTouchedNode() != endNode) - { - startNode = touchedNode; - updatePath(); - } - else - { - warnDifferentLocations(); - } - } //ending position - else if ((selectedIndex == 2) && (touchedNode != null)) - { - if (touchedNode != startNode) - { - endNode = touchedNode; - updatePath(); - } - else - { - warnDifferentLocations(); - } - } //paint the map - - mouseDown = true; - paintCells(); - mouseDown = false; - } - - private void warnDifferentLocations() - { - JOptionPane.showMessageDialog(this, "Start and stop locations must be different"); - } - }; - - add(new JScrollPane(gridCanvas), BorderLayout.CENTER); - } - - /** - * Returns a color associated with a specific weight value. - * This is used to draw a gray-scale gradient for the grid's weights. - * @param weight value - * @return a color value - */ - public static Color getColor(final double weight) - { - Color color; - - if (weight == MIN_GRID_WEIGHT) - { - color = Color.WHITE; - } - else if (weight == Double.POSITIVE_INFINITY) - { - color = Color.BLACK; - } - else if (weight < MAX_NONINFINITE_CELL_WEIGHT) - { - final float chanVal = 1f - (float) (weight / MAX_NONINFINITE_CELL_WEIGHT) / 2f; - color = new Color(chanVal, chanVal, chanVal); - } - else - { - color = Color.WHITE; - } - - return color; - } - - /** - * Updates the path when the starting or ending node changes, or when the - * AStarPathFinder parameters are changed. - */ - protected void updatePath() - { - final AstarPathFinder<GridNode, SimpleWeightedUndirectedEdge<GridNode>> pathFinder = new AstarPathFinder<GridNode, SimpleWeightedUndirectedEdge<GridNode>>(grid, new DistanceHeuristic()); - path = pathFinder.getBestPath(startNode, endNode); - if (gridCanvas != null) - { - gridCanvas.setPath(path); - } - } - - /** - * Entrypoint. - * @param args (not presently used) - */ - public static void main(final String[] args) - { - java.awt.EventQueue.invokeLater(new Runnable() - { - @Override - public void run() - { - final JFrame frame = new JFrame("dANN Path Finding Demo"); - frame.getContentPane().add(new PathFindDemoPanel(DEFAULT_GRID_SIZE)); - frame.addWindowListener(new WindowAdapter() - { - - @Override - public void windowClosing(final WindowEvent evt) - { - System.exit(0); - } - }); - frame.setVisible(true); - frame.setExtendedState(JFrame.MAXIMIZED_BOTH); - - } - }); - } - - static - { - // Install the look and feel - try - { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } - catch (Exception exc) - { - } - } +public class PathFindDemoPanel extends JPanel { + private static final double INF = Double.POSITIVE_INFINITY; + private static final double[] PAINT_WEIGHTS = + { + 1, 2, 4, 6, 8, 10, INF + }; + private static final double MAX_NONINFINITE_CELL_WEIGHT = 12.0; + private static final int DEFAULT_NODE_SIZE = 24; + private static final int DEFAULT_EDGE_SIZE = 8; + private static final int DEFAULT_GRID_SIZE = 18; + private static final double MIN_GRID_WEIGHT = 1.0; + private static final double INITIAL_GRID_WEIGHT = MIN_GRID_WEIGHT; + private AbstractGridCanvas gridCanvas; + private WeightedGrid grid; + private PathFindControlPanel controlPanel; + private List<SimpleWeightedUndirectedEdge<GridNode>> path; + private GridNode endNode; + private GridNode startNode; + private double paintWeight = 0.0; + + /** + * Creates a new Swing component with an empty square grid of size + * width*width. + * + * @param width number of grid nodes wide and high + */ + public PathFindDemoPanel(final int width) { + super(new BorderLayout()); + + reinit(width); + } + + /** + * Returns a color associated with a specific weight value. + * This is used to draw a gray-scale gradient for the grid's weights. + * + * @param weight value + * @return a color value + */ + public static Color getColor(final double weight) { + Color color; + + if (weight == MIN_GRID_WEIGHT) { + color = Color.WHITE; + } + else if (weight == Double.POSITIVE_INFINITY) { + color = Color.BLACK; + } + else if (weight < MAX_NONINFINITE_CELL_WEIGHT) { + final float chanVal = 1f - (float) (weight / MAX_NONINFINITE_CELL_WEIGHT) / 2f; + color = new Color(chanVal, chanVal, chanVal); + } + else { + color = Color.WHITE; + } + + return color; + } + + /** + * Entrypoint. + * + * @param args (not presently used) + */ + public static void main(final String[] args) { + java.awt.EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + final JFrame frame = new JFrame("dANN Path Finding Demo"); + frame.getContentPane().add(new PathFindDemoPanel(DEFAULT_GRID_SIZE)); + frame.addWindowListener(new WindowAdapter() { + + @Override + public void windowClosing(final WindowEvent evt) { + System.exit(0); + } + }); + frame.setVisible(true); + frame.setExtendedState(JFrame.MAXIMIZED_BOTH); + + } + }); + } + static { + // Install the look and feel + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } + catch (Exception exc) { + } + } + + /** + * Reconstructs the grid and the panel (and its components) with new grid + * dimensions. + * + * @param nextWidth the width and height (square) dimensions of the grid to + * (re-)initialize. + */ + protected void reinit(final int nextWidth) { + removeAll(); + + final int width = nextWidth; + final int height = nextWidth; + + final double[][] gridWeights = new double[height][width]; + grid = new WeightedGrid(gridWeights); + grid.setAll(INITIAL_GRID_WEIGHT); + + startNode = grid.getNode(0, 0); + endNode = grid.getNode(width - 1, height - 1); + + updatePath(); + + controlPanel = new PathFindControlPanel(this); + add(controlPanel, BorderLayout.NORTH); + + gridCanvas = new AbstractGridCanvas(grid, path, DEFAULT_NODE_SIZE, DEFAULT_EDGE_SIZE) { + private boolean mouseDown = false; + + @Override + public Color getNodeColor(final GridNode node) { + return getColor(node.getWeight()); + } + + @Override + protected Color getEdgeColor(final WeightedBidirectedEdge<GridNode> edge) { + return getColor(edge.getWeight()); + } + + protected void paintCells() { + final int selectedIndex = controlPanel.getSelectedIndex(); + + if (mouseDown && (selectedIndex == 0)) { + if (getTouchedNode() != null) { + getTouchedNode().setWeight(paintWeight); + updatePath(); + } + else if (getTouchedEdge() != null) { + getTouchedEdge().setWeight(paintWeight); + updatePath(); + } + } + + } + + @Override + public void mouseDragged(final MouseEvent evt) { + super.mouseDragged(evt); + paintCells(); + } + + @Override + public void mouseMoved(final MouseEvent evt) { + super.mouseMoved(evt); + paintCells(); + } + + @Override + public void mousePressed(final MouseEvent evt) { + super.mousePressed(evt); + mouseDown = true; + } + + @Override + public void mouseReleased(final MouseEvent evt) { + super.mouseReleased(evt); + mouseDown = false; + } + + @Override + public void mouseClicked(final MouseEvent evt) { + final int selectedIndex = controlPanel.getSelectedIndex(); + + final GridNode touchedNode = getTouchedNode(); + + //starting position + if ((selectedIndex == 1) && (touchedNode != null)) { + if (getTouchedNode() != endNode) { + startNode = touchedNode; + updatePath(); + } + else { + warnDifferentLocations(); + } + } //ending position + else if ((selectedIndex == 2) && (touchedNode != null)) { + if (touchedNode != startNode) { + endNode = touchedNode; + updatePath(); + } + else { + warnDifferentLocations(); + } + } //paint the map + + mouseDown = true; + paintCells(); + mouseDown = false; + } + + private void warnDifferentLocations() { + JOptionPane.showMessageDialog(this, "Start and stop locations must be different"); + } + }; + + add(new JScrollPane(gridCanvas), BorderLayout.CENTER); + } + + /** + * Updates the path when the starting or ending node changes, or when the + * AStarPathFinder parameters are changed. + */ + protected void updatePath() { + final AstarPathFinder<GridNode, SimpleWeightedUndirectedEdge<GridNode>> pathFinder = new AstarPathFinder<GridNode, SimpleWeightedUndirectedEdge<GridNode>>(grid, new DistanceHeuristic()); + path = pathFinder.getBestPath(startNode, endNode); + if (gridCanvas != null) { + gridCanvas.setPath(path); + } + } + + /** + * Distance heuristic used by the AStarPathFinding algorithm. + */ + private static class DistanceHeuristic implements HeuristicPathCost<GridNode> { + @Override + public double getHeuristicPathCost(final GridNode begin, final GridNode end) { + return begin.calculateRelativeTo(end).getDistance(); + } + + @Override + public boolean isOptimistic() { + return true; + } + + @Override + public boolean isConsistent() { + return true; + } + } + + private static class PaintButtonActionListener implements ActionListener { + private final PathFindDemoPanel pathFindDemoPanel; + + public PaintButtonActionListener(final PathFindDemoPanel pathFindDemoPanel) { + this.pathFindDemoPanel = pathFindDemoPanel; + } + + @Override + public void actionPerformed(final ActionEvent evt) { + if (evt.getSource() instanceof PaintButton) { + final PaintButton button = (PaintButton) evt.getSource(); + pathFindDemoPanel.paintWeight = button.getWeight(); + } + } + } + + private static class PaintButton extends JToggleButton { + private static final int BUTTON_BORDER_SIZE = 4; + private final double weight; + + public PaintButton(final double drawWeight) { + super(" "); + this.weight = drawWeight; + setForeground(getColor(weight)); + } + + @Override + public void paint(final Graphics graphics) { + super.paint(graphics); + final Graphics2D graphics2D = (Graphics2D) graphics; + graphics2D.setColor(getColor(weight)); + graphics2D.fillRect(BUTTON_BORDER_SIZE, BUTTON_BORDER_SIZE, + getWidth() - BUTTON_BORDER_SIZE * 2, + getHeight() - BUTTON_BORDER_SIZE * 2); + } + + public double getWeight() { + return weight; + } + } + + /** + * A panel that provides buttons for each of the drawable "weights". + */ + private static class DrawingPanel extends JPanel { + private final List<PaintButton> paintButtons = new LinkedList(); + private final ButtonGroup paintButtonsGroup = new ButtonGroup(); + + public DrawingPanel(final double[] paintWeights, final PathFindDemoPanel pathFindDemoPanel) { + super(new FlowLayout(FlowLayout.LEFT)); + + final PaintButtonActionListener paintButtonActionListener = new PaintButtonActionListener(pathFindDemoPanel); + for (double d : paintWeights) { + final PaintButton button = new PaintButton(d); + button.addActionListener(paintButtonActionListener); + paintButtonsGroup.add(button); + paintButtons.add(button); + add(button); + } + } + + public List<PaintButton> getPaintButtons() { + return paintButtons; + } + } + + private static class PathFindControlPanel extends JTabbedPane { + public PathFindControlPanel(final PathFindDemoPanel pathFindDemoPanel) { + addTab("Edit", new DrawingPanel(PAINT_WEIGHTS, pathFindDemoPanel)); + addTab("Start Position", new JLabel("Click a start position")); + addTab("Stop Position", new JLabel("Click a stop position")); + //addTab("Settings", new SettingsPanel()); + } + } } diff --git a/src/main/java/com/syncleus/dann/examples/pathfind/WeightedGrid.java b/src/main/java/com/syncleus/dann/examples/pathfind/WeightedGrid.java index 0045bea06d7cb7735d398687f99b7945a2eaee22..6c3e4d79c62b0e8a6daa28e96bb0bb1de2562602 100644 --- a/src/main/java/com/syncleus/dann/examples/pathfind/WeightedGrid.java +++ b/src/main/java/com/syncleus/dann/examples/pathfind/WeightedGrid.java @@ -18,278 +18,259 @@ ******************************************************************************/ package com.syncleus.dann.examples.pathfind; -import com.syncleus.dann.graph.AbstractBidirectedAdjacencyGraph; -import com.syncleus.dann.graph.SimpleWeightedUndirectedEdge; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import com.syncleus.dann.graph.*; + +import java.util.*; /** * A 2D mesh with individual weights for nodes and edges. * Each node is linked to its four neighbors by weighted undirected edges. + * * @author seh */ -public class WeightedGrid extends AbstractBidirectedAdjacencyGraph<GridNode, SimpleWeightedUndirectedEdge<GridNode>> -{ - private final GridNode[][] nodes; - private final Set<GridNode> nodeSet = new HashSet<GridNode>(); - private final Set<SimpleWeightedUndirectedEdge<GridNode>> edges = new HashSet<SimpleWeightedUndirectedEdge<GridNode>>(); - private final Map<GridNode, Set<SimpleWeightedUndirectedEdge<GridNode>>> neighborEdges = new HashMap<GridNode, Set<SimpleWeightedUndirectedEdge<GridNode>>>(); - private final Map<GridNode, Set<GridNode>> neighborNodes = new HashMap<GridNode, Set<GridNode>>(); +public class WeightedGrid extends AbstractBidirectedAdjacencyGraph<GridNode, SimpleWeightedUndirectedEdge<GridNode>> { + private final GridNode[][] nodes; + private final Set<GridNode> nodeSet = new HashSet<GridNode>(); + private final Set<SimpleWeightedUndirectedEdge<GridNode>> edges = new HashSet<SimpleWeightedUndirectedEdge<GridNode>>(); + private final Map<GridNode, Set<SimpleWeightedUndirectedEdge<GridNode>>> neighborEdges = new HashMap<GridNode, Set<SimpleWeightedUndirectedEdge<GridNode>>>(); + private final Map<GridNode, Set<GridNode>> neighborNodes = new HashMap<GridNode, Set<GridNode>>(); - /** - * Initialize the grid with a 2D array of node-weights specified as - * <code>double</code>'s. - * @param nodeWeights the 2D array of node-weights. The dimensions of the - * array specify the dimensions of the constructed grid. - */ - public WeightedGrid(final double[][] nodeWeights) - { - this.nodes = new GridNode[nodeWeights.length][nodeWeights[0].length]; + /** + * Initialize the grid with a 2D array of node-weights specified as + * <code>double</code>'s. + * + * @param nodeWeights the 2D array of node-weights. The dimensions of the + * array specify the dimensions of the constructed grid. + */ + public WeightedGrid(final double[][] nodeWeights) { + this.nodes = new GridNode[nodeWeights.length][nodeWeights[0].length]; - //construct nodes - for (int y = 0; y < nodeWeights.length; y++) - { - for (int x = 0; x < nodeWeights[0].length; x++) - { - nodes[y][x] = new GridNode(x, y, nodeWeights[y][x]); - this.nodeSet.add(nodes[y][x]); - this.neighborEdges.put(nodes[y][x], new HashSet<SimpleWeightedUndirectedEdge<GridNode>>()); - this.neighborNodes.put(nodes[y][x], new HashSet<GridNode>()); - } - } + //construct nodes + for (int y = 0; y < nodeWeights.length; y++) { + for (int x = 0; x < nodeWeights[0].length; x++) { + nodes[y][x] = new GridNode(x, y, nodeWeights[y][x]); + this.nodeSet.add(nodes[y][x]); + this.neighborEdges.put(nodes[y][x], new HashSet<SimpleWeightedUndirectedEdge<GridNode>>()); + this.neighborNodes.put(nodes[y][x], new HashSet<GridNode>()); + } + } - //connect nodes - for (int y = 0; y < nodes.length; y++) - { - for (int x = 0; x < nodes[0].length; x++) - { - //connect to the right - if (x < nodes[0].length - 1) - { - final SimpleWeightedUndirectedEdge<GridNode> newEdge = new SimpleWeightedUndirectedEdge<GridNode>(nodes[y][x], nodes[y][x + 1], 0); - this.edges.add(newEdge); - this.neighborEdges.get(nodes[y][x]).add(newEdge); - this.neighborEdges.get(nodes[y][x + 1]).add(newEdge); - this.neighborNodes.get(nodes[y][x]).add(nodes[y][x + 1]); - this.neighborNodes.get(nodes[y][x + 1]).add(nodes[y][x]); - } - //connect to the bottom - if (y < nodes.length - 1) - { - final SimpleWeightedUndirectedEdge<GridNode> newEdge = new SimpleWeightedUndirectedEdge<GridNode>(nodes[y][x], nodes[y + 1][x], 0); - this.edges.add(newEdge); - this.neighborEdges.get(nodes[y][x]).add(newEdge); - this.neighborEdges.get(nodes[y + 1][x]).add(newEdge); - this.neighborNodes.get(nodes[y][x]).add(nodes[y + 1][x]); - this.neighborNodes.get(nodes[y + 1][x]).add(nodes[y][x]); - } - } - } - } + //connect nodes + for (int y = 0; y < nodes.length; y++) { + for (int x = 0; x < nodes[0].length; x++) { + //connect to the right + if (x < nodes[0].length - 1) { + final SimpleWeightedUndirectedEdge<GridNode> newEdge = new SimpleWeightedUndirectedEdge<GridNode>(nodes[y][x], nodes[y][x + 1], 0); + this.edges.add(newEdge); + this.neighborEdges.get(nodes[y][x]).add(newEdge); + this.neighborEdges.get(nodes[y][x + 1]).add(newEdge); + this.neighborNodes.get(nodes[y][x]).add(nodes[y][x + 1]); + this.neighborNodes.get(nodes[y][x + 1]).add(nodes[y][x]); + } + //connect to the bottom + if (y < nodes.length - 1) { + final SimpleWeightedUndirectedEdge<GridNode> newEdge = new SimpleWeightedUndirectedEdge<GridNode>(nodes[y][x], nodes[y + 1][x], 0); + this.edges.add(newEdge); + this.neighborEdges.get(nodes[y][x]).add(newEdge); + this.neighborEdges.get(nodes[y + 1][x]).add(newEdge); + this.neighborNodes.get(nodes[y][x]).add(nodes[y + 1][x]); + this.neighborNodes.get(nodes[y + 1][x]).add(nodes[y][x]); + } + } + } + } - /** - * Gets the width of the grid (number of nodes horizontally). - * @return the width of the grid (number of nodes horizontal) - */ - public int getWidth() - { - return nodes[0].length; - } + /** + * Gets the width of the grid (number of nodes horizontally). + * + * @return the width of the grid (number of nodes horizontal) + */ + public int getWidth() { + return nodes[0].length; + } - /** - * Gets the height of the grid (number of nodes vertically). - * @return the height of the grid (number of nodes vertical) - */ - public int getHeight() - { - return nodes.length; - } + /** + * Gets the height of the grid (number of nodes vertically). + * + * @return the height of the grid (number of nodes vertical) + */ + public int getHeight() { + return nodes.length; + } - /** - * Gets the node coresponding to a specific X,Y coordinate. - * @param x x coordinate of a specific node - * @param y y coordinate of a specific node - * @return the node at (x,y) or null if non-existent - */ - public GridNode getNode(final int x, final int y) - { - if ((x >= nodes[0].length) || (y >= nodes.length)) - { - throw new IllegalArgumentException("coordinates are out of bounds"); - } - return this.nodes[y][x]; - } + /** + * Gets the node coresponding to a specific X,Y coordinate. + * + * @param x x coordinate of a specific node + * @param y y coordinate of a specific node + * @return the node at (x,y) or null if non-existent + */ + public GridNode getNode(final int x, final int y) { + if ((x >= nodes[0].length) || (y >= nodes.length)) { + throw new IllegalArgumentException("coordinates are out of bounds"); + } + return this.nodes[y][x]; + } - /** - * Gets all nodes in the grid. - * @return the set of all nodes in this grid - */ - @Override - public Set<GridNode> getNodes() - { - return Collections.unmodifiableSet(this.nodeSet); - } + /** + * Gets all nodes in the grid. + * + * @return the set of all nodes in this grid + */ + @Override + public Set<GridNode> getNodes() { + return Collections.unmodifiableSet(this.nodeSet); + } - /** - * Gets all edges in the grid. - * @return the set of all edges in this grid - */ - @Override - public Set<SimpleWeightedUndirectedEdge<GridNode>> getEdges() - { - return Collections.unmodifiableSet(this.edges); - } + /** + * Gets all edges in the grid. + * + * @return the set of all edges in this grid + */ + @Override + public Set<SimpleWeightedUndirectedEdge<GridNode>> getEdges() { + return Collections.unmodifiableSet(this.edges); + } - /** - * Gets all edges surrounding a specific grid node. - * @param node the node to find the edges surrounding it - * @return a list of all edges surrounding a specific grid node - */ - public Set<SimpleWeightedUndirectedEdge<GridNode>> getAdjacentEdges(final GridNode node) - { - return Collections.unmodifiableSet(this.neighborEdges.get(node)); - } + /** + * Gets all edges surrounding a specific grid node. + * + * @param node the node to find the edges surrounding it + * @return a list of all edges surrounding a specific grid node + */ + public Set<SimpleWeightedUndirectedEdge<GridNode>> getAdjacentEdges(final GridNode node) { + return Collections.unmodifiableSet(this.neighborEdges.get(node)); + } - /** - * Since all edges are traversable, this is the same as getEdges(node). - * @param node the node to find edges surrounding it - * @return all traversable edges - */ - @Override - public Set<SimpleWeightedUndirectedEdge<GridNode>> getTraversableEdges(final GridNode node) - { - return this.getAdjacentEdges(node); - } + /** + * Since all edges are traversable, this is the same as getEdges(node). + * + * @param node the node to find edges surrounding it + * @return all traversable edges + */ + @Override + public Set<SimpleWeightedUndirectedEdge<GridNode>> getTraversableEdges(final GridNode node) { + return this.getAdjacentEdges(node); + } - /** - * Since all edges are undirected, all edges are both outgoing and incoming. - * @param node the node to find edges surrounding it - * @return all edges surrounding it - */ - public Set<SimpleWeightedUndirectedEdge<GridNode>> getOutEdges(final GridNode node) - { - return this.getAdjacentEdges(node); - } + /** + * Since all edges are undirected, all edges are both outgoing and incoming. + * + * @param node the node to find edges surrounding it + * @return all edges surrounding it + */ + public Set<SimpleWeightedUndirectedEdge<GridNode>> getOutEdges(final GridNode node) { + return this.getAdjacentEdges(node); + } - /** - * Since all edges are undirected, all edges are both outgoing and incoming. - * @param node the node to find edges surrounding it - * @return all edges surrounding it - */ - @Override - public Set<SimpleWeightedUndirectedEdge<GridNode>> getInEdges(final GridNode node) - { - return this.getAdjacentEdges(node); - } + /** + * Since all edges are undirected, all edges are both outgoing and incoming. + * + * @param node the node to find edges surrounding it + * @return all edges surrounding it + */ + @Override + public Set<SimpleWeightedUndirectedEdge<GridNode>> getInEdges(final GridNode node) { + return this.getAdjacentEdges(node); + } - /** - * Gets the number of edges surrounding a specific node (which are both - * incoming and outgoing), which should range from 2 to 4. - * @param node the node to find edges surrounding it - * @return number of edges surrounding it - */ - public int getIndegree(final GridNode node) - { - return this.getInEdges(node).size(); - } + /** + * Gets the number of edges surrounding a specific node (which are both + * incoming and outgoing), which should range from 2 to 4. + * + * @param node the node to find edges surrounding it + * @return number of edges surrounding it + */ + public int getIndegree(final GridNode node) { + return this.getInEdges(node).size(); + } - /** - * Gets the number of edges surrounding a specific node (which are both - * incoming and outgoing), which should range from 2 to 4. - * @param node the node to find edges surrounding it - * @return number of edges surrounding it - */ - public int getOutdegree(final GridNode node) - { - return this.getOutEdges(node).size(); - } + /** + * Gets the number of edges surrounding a specific node (which are both + * incoming and outgoing), which should range from 2 to 4. + * + * @param node the node to find edges surrounding it + * @return number of edges surrounding it + */ + public int getOutdegree(final GridNode node) { + return this.getOutEdges(node).size(); + } - /** - * Determines whether two nodes are connected by a shared edge. - * @param leftNode first node - * @param rightNode second node - * @return whether they are connected by a shared edge - */ - public boolean isConnected(final GridNode leftNode, final GridNode rightNode) - { - return this.neighborNodes.get(leftNode).contains(rightNode); - } + /** + * Determines whether two nodes are connected by a shared edge. + * + * @param leftNode first node + * @param rightNode second node + * @return whether they are connected by a shared edge + */ + public boolean isConnected(final GridNode leftNode, final GridNode rightNode) { + return this.neighborNodes.get(leftNode).contains(rightNode); + } - /** - * Gets all neighbors surrounding a node. - * @param node to find neighbors surrounding it - * @return list of nodes that can be traversed into - */ - @Override - public List<GridNode> getAdjacentNodes(final GridNode node) - { - return Collections.unmodifiableList(new ArrayList<GridNode>(this.neighborNodes.get(node))); - } + /** + * Gets all neighbors surrounding a node. + * + * @param node to find neighbors surrounding it + * @return list of nodes that can be traversed into + */ + @Override + public List<GridNode> getAdjacentNodes(final GridNode node) { + return Collections.unmodifiableList(new ArrayList<GridNode>(this.neighborNodes.get(node))); + } - /** - * Gets all neighbors surrounding a node. - * @param node to find neighbors surrounding it - * @return list of nodes that can be traversed into - */ - @Override - public List<GridNode> getTraversableNodes(final GridNode node) - { - return this.getAdjacentNodes(node); - } + /** + * Gets all neighbors surrounding a node. + * + * @param node to find neighbors surrounding it + * @return list of nodes that can be traversed into + */ + @Override + public List<GridNode> getTraversableNodes(final GridNode node) { + return this.getAdjacentNodes(node); + } - /** - * Sets all nodes and edges to the same specific weight value. - * @param weight the weight value to set - */ - public void setAll(final double weight) - { - for (GridNode gn : getNodes()) - { - gn.setWeight(weight); - } - for (SimpleWeightedUndirectedEdge wbe : getEdges()) - { - wbe.setWeight(weight); - } - } + /** + * Sets all nodes and edges to the same specific weight value. + * + * @param weight the weight value to set + */ + public void setAll(final double weight) { + for (GridNode gn : getNodes()) { + gn.setWeight(weight); + } + for (SimpleWeightedUndirectedEdge wbe : getEdges()) { + wbe.setWeight(weight); + } + } - /** - * Returns the edge between two specified grid locations. - * @param firstX x coordinate of 1st grid location - * @param firstY y coordinate of 1st grid location - * @param secondX x coordinate of 2nd grid location - * @param secondY y coordinate of 2nd grid location - * @return the specific edge in the grid between the two points, or - * <code>null</code> if such edge is non-existent - */ - public SimpleWeightedUndirectedEdge<GridNode> getEdgeBetween(final int firstX, final int firstY, final int secondX, final int secondY) - { - if ((firstX == secondX) && (firstY == secondY)) - { - //no edge between the same gridnode - return null; - } + /** + * Returns the edge between two specified grid locations. + * + * @param firstX x coordinate of 1st grid location + * @param firstY y coordinate of 1st grid location + * @param secondX x coordinate of 2nd grid location + * @param secondY y coordinate of 2nd grid location + * @return the specific edge in the grid between the two points, or + * <code>null</code> if such edge is non-existent + */ + public SimpleWeightedUndirectedEdge<GridNode> getEdgeBetween(final int firstX, final int firstY, final int secondX, final int secondY) { + if ((firstX == secondX) && (firstY == secondY)) { + //no edge between the same gridnode + return null; + } - final GridNode gridNode = getNode(firstX, firstY); - for (SimpleWeightedUndirectedEdge<GridNode> edge : getAdjacentEdges(gridNode)) - { - final GridNode left = edge.getLeftNode(); - final GridNode right = edge.getRightNode(); - if ((left.getX() == secondX) && (left.getY() == secondY)) - { - return edge; - } + final GridNode gridNode = getNode(firstX, firstY); + for (SimpleWeightedUndirectedEdge<GridNode> edge : getAdjacentEdges(gridNode)) { + final GridNode left = edge.getLeftNode(); + final GridNode right = edge.getRightNode(); + if ((left.getX() == secondX) && (left.getY() == secondY)) { + return edge; + } - if ((right.getX() == secondX) && (right.getY() == secondY)) - { - return edge; - } - } - return null; - } + if ((right.getX() == secondX) && (right.getY() == secondY)) { + return edge; + } + } + return null; + } } diff --git a/src/main/java/com/syncleus/dann/examples/test/Test3d.java b/src/main/java/com/syncleus/dann/examples/test/Test3d.java index d7cd2a85355ef47c47155b2163782c9b515b6d72..8bec23a01f90f067415cadeead33957f6c16ba64 100644 --- a/src/main/java/com/syncleus/dann/examples/test/Test3d.java +++ b/src/main/java/com/syncleus/dann/examples/test/Test3d.java @@ -18,91 +18,80 @@ ******************************************************************************/ package com.syncleus.dann.examples.test; -import javax.media.j3d.Canvas3D; import com.syncleus.dann.genetics.wavelets.SignalProcessingWavelet; import com.syncleus.dann.genetics.wavelets.SignalProcessingWavelet.GlobalSignalConcentration; import com.syncleus.dann.math.visualization.MathFunctionCanvas; -import javax.swing.JFrame; -import javax.swing.JPanel; -public class Test3d extends JFrame -{ - private JPanel drawingPanel; +import javax.media.j3d.Canvas3D; +import javax.swing.*; + +public class Test3d extends JFrame { + private JPanel drawingPanel; - public Test3d() - { - this.initComponents(); + public Test3d() { + this.initComponents(); - final Canvas3D canvas = this.createUniverse(); - try - { - this.drawingPanel.add(canvas, java.awt.BorderLayout.CENTER); - } - catch (ArithmeticException caughtException) - { - System.out.println("Division by 0!"); - } - } + final Canvas3D canvas = this.createUniverse(); + try { + this.drawingPanel.add(canvas, java.awt.BorderLayout.CENTER); + } + catch (ArithmeticException caughtException) { + System.out.println("Division by 0!"); + } + } - private Canvas3D createUniverse() - { - final GlobalSignalConcentration signalX = new GlobalSignalConcentration(); - final GlobalSignalConcentration signalY = new GlobalSignalConcentration(); - final GlobalSignalConcentration signalZ = new GlobalSignalConcentration(); - SignalProcessingWavelet processor = new SignalProcessingWavelet(/*new Cell(),*/signalX, signalZ); - for (int index = 0; (index < 500) || (processor.getSignals().size() < 3); index++) - { - processor = processor.mutate(100000.0, signalX); - processor = processor.mutate(100000.0, signalY); - processor = processor.mutate(100000.0); - } + public static void main(final String[] args) { + java.awt.EventQueue.invokeLater( + new Runnable() { + @Override + public void run() { + for (int index = 0; index < 1; index++) { + new Test3d().setVisible(true); + } + } + }); + } - System.out.println("The current equation contains " + processor.getWaveCount() + " waves:"); - System.out.println(processor.toString()); + private Canvas3D createUniverse() { + final GlobalSignalConcentration signalX = new GlobalSignalConcentration(); + final GlobalSignalConcentration signalY = new GlobalSignalConcentration(); + final GlobalSignalConcentration signalZ = new GlobalSignalConcentration(); + SignalProcessingWavelet processor = new SignalProcessingWavelet(/*new Cell(),*/signalX, signalZ); + for (int index = 0; (index < 500) || (processor.getSignals().size() < 3); index++) { + processor = processor.mutate(100000.0, signalX); + processor = processor.mutate(100000.0, signalY); + processor = processor.mutate(100000.0); + } - processor.preTick(); - processor.tick(); + System.out.println("The current equation contains " + processor.getWaveCount() + " waves:"); + System.out.println(processor.toString()); - final MathFunctionCanvas plotCanvas = new MathFunctionCanvas( - processor.getWavelet(), - String.valueOf(signalX.getId()), - String.valueOf(signalY.getId()), - -200.0f, - 200.0f, - -200.0f, - 200.0f, - 200); + processor.preTick(); + processor.tick(); - return plotCanvas; - } + final MathFunctionCanvas plotCanvas = new MathFunctionCanvas( + processor.getWavelet(), + String.valueOf(signalX.getId()), + String.valueOf(signalY.getId()), + -200.0f, + 200.0f, + -200.0f, + 200.0f, + 200); - private void initComponents() - { - this.drawingPanel = new javax.swing.JPanel(); + return plotCanvas; + } - setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); - setTitle("Hello Universe"); - this.drawingPanel.setLayout(new java.awt.BorderLayout()); + private void initComponents() { + this.drawingPanel = new javax.swing.JPanel(); - this.drawingPanel.setPreferredSize(new java.awt.Dimension(250, 250)); - this.getContentPane().add(this.drawingPanel, java.awt.BorderLayout.CENTER); + setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); + setTitle("Hello Universe"); + this.drawingPanel.setLayout(new java.awt.BorderLayout()); - this.pack(); - } + this.drawingPanel.setPreferredSize(new java.awt.Dimension(250, 250)); + this.getContentPane().add(this.drawingPanel, java.awt.BorderLayout.CENTER); - public static void main(final String[] args) - { - java.awt.EventQueue.invokeLater( - new Runnable() - { - @Override - public void run() - { - for (int index = 0; index < 1; index++) - { - new Test3d().setVisible(true); - } - } - }); - } + this.pack(); + } } diff --git a/src/main/java/com/syncleus/dann/examples/tsp/TravellingSalesmanChromosome.java b/src/main/java/com/syncleus/dann/examples/tsp/TravellingSalesmanChromosome.java index e1a449c0f2e17a475709bf73943ea3a0b1957c88..9357ca7110033f0e5a686451ee23e004f93c0196 100644 --- a/src/main/java/com/syncleus/dann/examples/tsp/TravellingSalesmanChromosome.java +++ b/src/main/java/com/syncleus/dann/examples/tsp/TravellingSalesmanChromosome.java @@ -18,105 +18,92 @@ ******************************************************************************/ package com.syncleus.dann.examples.tsp; -import com.syncleus.dann.genetics.AbstractValueGene; -import com.syncleus.dann.genetics.GeneticAlgorithmChromosome; -import java.util.Collections; -import java.util.Comparator; -import java.util.SortedSet; -import java.util.TreeSet; - -public class TravellingSalesmanChromosome extends GeneticAlgorithmChromosome -{ - private static final double MAX_DEVIATION = 10.0; - - public TravellingSalesmanChromosome(final int cityCount) - { - super(cityCount, MAX_DEVIATION); - } - - public int getCityOrder(final int cityIndex) - { - if( cityIndex >= this.getGeneCount()) - throw new IllegalArgumentException("cityIndex is out of bounds"); - - final SortedSet<AbstractValueGene> sortedGenes = this.getSortedGenes(); - - final AbstractValueGene cityGene = this.getGenes().get(cityIndex); - int cityOrder = 0; - for(AbstractValueGene sortedGene : sortedGenes) - { - if(sortedGene == cityGene) - return cityOrder; - - cityOrder++; - } - - throw new AssertionError("Could not find matching city gene in sorted genes"); - } - - public int[] getCitiesOrder() - { - int[] citiesOrder = new int[this.getGeneCount()]; - for(int cityIndex = 0; cityIndex < citiesOrder.length; cityIndex++) - citiesOrder[cityIndex] = this.getCityOrder(cityIndex); - return citiesOrder; - } - - private static class AbstractValueGeneComparator implements Comparator<AbstractValueGene> - { - @Override - public int compare(final AbstractValueGene gene1, final AbstractValueGene gene2) - { - if( gene1.getValue().doubleValue() < gene2.getValue().doubleValue() ) - return -1; - else if( gene1.getValue().doubleValue() > gene2.getValue().doubleValue() ) - return 1; - else - return 0; - } - } - - public SortedSet<AbstractValueGene> getSortedGenes() - { - final SortedSet<AbstractValueGene> sortedGenes = new TreeSet<AbstractValueGene>(new AbstractValueGeneComparator()); - - sortedGenes.addAll(this.getGenes()); - - return Collections.unmodifiableSortedSet(sortedGenes); - } - - /** - * Creates a new instance that is a copy of this object. - * - * @return an exact copy of this object. - * @since 2.0 - */ - @Override - public TravellingSalesmanChromosome clone() - { - final TravellingSalesmanChromosome copy = (TravellingSalesmanChromosome) super.clone(); +import com.syncleus.dann.genetics.*; + +import java.util.*; + +public class TravellingSalesmanChromosome extends GeneticAlgorithmChromosome { + private static final double MAX_DEVIATION = 10.0; + + public TravellingSalesmanChromosome(final int cityCount) { + super(cityCount, MAX_DEVIATION); + } + + public int getCityOrder(final int cityIndex) { + if (cityIndex >= this.getGeneCount()) + throw new IllegalArgumentException("cityIndex is out of bounds"); + + final SortedSet<AbstractValueGene> sortedGenes = this.getSortedGenes(); + + final AbstractValueGene cityGene = this.getGenes().get(cityIndex); + int cityOrder = 0; + for (AbstractValueGene sortedGene : sortedGenes) { + if (sortedGene == cityGene) + return cityOrder; + + cityOrder++; + } + + throw new AssertionError("Could not find matching city gene in sorted genes"); + } + + public int[] getCitiesOrder() { + int[] citiesOrder = new int[this.getGeneCount()]; + for (int cityIndex = 0; cityIndex < citiesOrder.length; cityIndex++) + citiesOrder[cityIndex] = this.getCityOrder(cityIndex); + return citiesOrder; + } + + public SortedSet<AbstractValueGene> getSortedGenes() { + final SortedSet<AbstractValueGene> sortedGenes = new TreeSet<AbstractValueGene>(new AbstractValueGeneComparator()); + + sortedGenes.addAll(this.getGenes()); + + return Collections.unmodifiableSortedSet(sortedGenes); + } + + /** + * Creates a new instance that is a copy of this object. + * + * @return an exact copy of this object. + * @since 2.0 + */ + @Override + public TravellingSalesmanChromosome clone() { + final TravellingSalesmanChromosome copy = (TravellingSalesmanChromosome) super.clone(); // copy.sortedGenes.clear(); // copy.sortedGenes.addAll(copy.getGenes()); - return copy; - } - - /** - * This will make a copy of the object and mutate it. The mutation has - * a normal distribution multiplied by the deviation. This will be applied - * to each gene in the chromosome. - * - * @param deviation A double indicating how extreme the mutation will be. - * The greater the deviation the more drastically the object will mutate. - * A deviation of 0 should cause no mutation. - * @return A copy of the current object with potential mutations. - * @since 2.0 - */ - @Override - public TravellingSalesmanChromosome mutate(final double deviation) - { - final TravellingSalesmanChromosome mutated = (TravellingSalesmanChromosome)super.mutate(deviation); + return copy; + } + + /** + * This will make a copy of the object and mutate it. The mutation has + * a normal distribution multiplied by the deviation. This will be applied + * to each gene in the chromosome. + * + * @param deviation A double indicating how extreme the mutation will be. + * The greater the deviation the more drastically the object will mutate. + * A deviation of 0 should cause no mutation. + * @return A copy of the current object with potential mutations. + * @since 2.0 + */ + @Override + public TravellingSalesmanChromosome mutate(final double deviation) { + final TravellingSalesmanChromosome mutated = (TravellingSalesmanChromosome) super.mutate(deviation); // mutated.sortedGenes.clear(); // mutated.sortedGenes.addAll(mutated.getGenes()); - return mutated; - } + return mutated; + } + + private static class AbstractValueGeneComparator implements Comparator<AbstractValueGene> { + @Override + public int compare(final AbstractValueGene gene1, final AbstractValueGene gene2) { + if (gene1.getValue().doubleValue() < gene2.getValue().doubleValue()) + return -1; + else if (gene1.getValue().doubleValue() > gene2.getValue().doubleValue()) + return 1; + else + return 0; + } + } } diff --git a/src/main/java/com/syncleus/dann/examples/tsp/TravellingSalesmanDemo.java b/src/main/java/com/syncleus/dann/examples/tsp/TravellingSalesmanDemo.java index 8a022410f12c8d754aa8fa4229f69b5db0ce7e78..f7d750733f80a73731aa1cf960cb224c71b410bd 100644 --- a/src/main/java/com/syncleus/dann/examples/tsp/TravellingSalesmanDemo.java +++ b/src/main/java/com/syncleus/dann/examples/tsp/TravellingSalesmanDemo.java @@ -18,231 +18,183 @@ ******************************************************************************/ package com.syncleus.dann.examples.tsp; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.HashSet; -import java.util.Random; import com.syncleus.dann.math.Vector; -import java.awt.Graphics; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import javax.swing.JFrame; -import javax.swing.SpinnerNumberModel; -import javax.swing.Timer; -import javax.swing.UIManager; import org.apache.log4j.Logger; -public class TravellingSalesmanDemo extends JFrame implements ActionListener -{ - private static final Logger LOGGER = Logger.getLogger(TravellingSalesmanDemo.class); - private static final Random RANDOM = new Random(); - - private final SpinnerNumberModel citiesModel = new SpinnerNumberModel(10, 1, 100, 1); - private final SpinnerNumberModel mutabilityModel = new SpinnerNumberModel(1.0, Double.MIN_VALUE, 10000, 0.1); - private final SpinnerNumberModel populationModel = new SpinnerNumberModel(100, 4, 1000, 10); - private final SpinnerNumberModel crossoverModel = new SpinnerNumberModel(0.1, Double.MIN_VALUE, 1.0, 0.01); - private final SpinnerNumberModel dieOffModel = new SpinnerNumberModel(0.4, Double.MIN_VALUE, 1.0, 0.01); - private final SpinnerNumberModel generationsModel = new SpinnerNumberModel(100, 1, 100000, 100); - - private static final int MAP_X = 12; - private static final int MAP_Y = 130; - private static final int MAP_WIDTH = 635; - private static final int MAP_HEIGHT = 500; - - private final ExecutorService executor = Executors.newFixedThreadPool(1); - - private final Timer progressTimer = new Timer(100, this); - - private PopulationEvolveCallable populationCallable = null; - private Future<TravellingSalesmanChromosome> futureWinner = null; - private TravellingSalesmanChromosome currentWinner = null; - private Vector[] cities = null; - - private static class PopulationEvolveCallable implements Callable<TravellingSalesmanChromosome> - { - private final TravellingSalesmanPopulation population; - private volatile int iterations = 0; - private final int iterationsMax; - private static final Logger LOGGER = Logger.getLogger(PopulationEvolveCallable.class); - - public PopulationEvolveCallable(final TravellingSalesmanPopulation population, final int iterationsMax) - { - if(iterationsMax <= 0) - throw new IllegalArgumentException("iterationsMax must be greater than 0"); - - this.population = population; - this.iterationsMax = iterationsMax; - } - - @Override - public TravellingSalesmanChromosome call() - { - try - { - for(; this.iterations < this.iterationsMax; this.iterations++) - this.population.nextGeneration(); - - return this.population.getWinner(); - } - catch(Exception caught) - { - LOGGER.error("Exception was caught", caught); - throw new RuntimeException("Throwable was caught", caught); - } - catch(Error caught) - { - LOGGER.error("Error was caught", caught); - throw new Error("Throwable was caught", caught); - } - } - - public int getIterations() - { - return this.iterations; - } - - public int getIterationsMax() - { - return this.iterationsMax; - } - } - - public TravellingSalesmanDemo() - { - LOGGER.info("Instantiating Travelling Salesman Demo Frame"); - - try - { +import javax.swing.*; +import javax.swing.Timer; +import java.awt.*; +import java.awt.event.*; +import java.util.*; +import java.util.concurrent.*; + +public class TravellingSalesmanDemo extends JFrame implements ActionListener { + private static final Logger LOGGER = Logger.getLogger(TravellingSalesmanDemo.class); + private static final Random RANDOM = new Random(); + private static final int MAP_X = 12; + private static final int MAP_Y = 130; + private static final int MAP_WIDTH = 635; + private static final int MAP_HEIGHT = 500; + private final SpinnerNumberModel citiesModel = new SpinnerNumberModel(10, 1, 100, 1); + private final SpinnerNumberModel mutabilityModel = new SpinnerNumberModel(1.0, Double.MIN_VALUE, 10000, 0.1); + private final SpinnerNumberModel populationModel = new SpinnerNumberModel(100, 4, 1000, 10); + private final SpinnerNumberModel crossoverModel = new SpinnerNumberModel(0.1, Double.MIN_VALUE, 1.0, 0.01); + private final SpinnerNumberModel dieOffModel = new SpinnerNumberModel(0.4, Double.MIN_VALUE, 1.0, 0.01); + private final SpinnerNumberModel generationsModel = new SpinnerNumberModel(100, 1, 100000, 100); + private final ExecutorService executor = Executors.newFixedThreadPool(1); + + private final Timer progressTimer = new Timer(100, this); + + private PopulationEvolveCallable populationCallable = null; + private Future<TravellingSalesmanChromosome> futureWinner = null; + private TravellingSalesmanChromosome currentWinner = null; + private Vector[] cities = null; + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JMenuItem aboutMenuItem; + private javax.swing.JLabel citiesLabel; + private javax.swing.JSpinner citiesSpinner; + private javax.swing.JLabel crossoverLabel; + private javax.swing.JSpinner crossoverSpinner; + private javax.swing.JLabel dieOffLabel; + private javax.swing.JSpinner dieOffSpinner; + private javax.swing.JButton evolveDisplayButton; + private javax.swing.JMenu fileMenuItem; + private javax.swing.JLabel generationsLabel; + private javax.swing.JSpinner generationsSpinner; + private javax.swing.JMenu helpMenuItem; + private javax.swing.JMenuBar menuBar; + private javax.swing.JLabel mutabilityLabel; + private javax.swing.JSpinner mutabilitySpinner; + private javax.swing.JLabel populationLabel; + private javax.swing.JSpinner populationSpinner; + private javax.swing.JProgressBar progressBar; + private javax.swing.JMenuItem quitMenuItem; + public TravellingSalesmanDemo() { + LOGGER.info("Instantiating Travelling Salesman Demo Frame"); + + try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } - catch(Exception caught) - { + catch (Exception caught) { LOGGER.warn("Could not set the UI to native look and feel", caught); } initComponents(); - this.citiesSpinner.setModel(this.citiesModel); - this.mutabilitySpinner.setModel(this.mutabilityModel); - this.populationSpinner.setModel(this.populationModel); - this.crossoverSpinner.setModel(this.crossoverModel); - this.dieOffSpinner.setModel(this.dieOffModel); - this.generationsSpinner.setModel(this.generationsModel); + this.citiesSpinner.setModel(this.citiesModel); + this.mutabilitySpinner.setModel(this.mutabilityModel); + this.populationSpinner.setModel(this.populationModel); + this.crossoverSpinner.setModel(this.crossoverModel); + this.dieOffSpinner.setModel(this.dieOffModel); + this.generationsSpinner.setModel(this.generationsModel); + + this.setResizable(false); + this.repaint(); + } + + private static Vector[] getRandomPoints(final int cityCount) { + if (cityCount < 4) + throw new IllegalArgumentException("cityCount must have atleast 4 elements"); + + final HashSet<Vector> pointsSet = new HashSet<Vector>(); + while (pointsSet.size() < cityCount) + pointsSet.add(new Vector(new double[]{RANDOM.nextDouble() * MAP_WIDTH, RANDOM.nextDouble() * MAP_HEIGHT})); + + final Vector[] points = new Vector[cityCount]; + pointsSet.toArray(points); + + return points; + } + + public static void main(final String[] args) { + LOGGER.info("Starting Travelling Salesman Demo from main()"); + java.awt.EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + new TravellingSalesmanDemo().setVisible(true); + } + }); + } + + @Override + public void paint(final Graphics graphics) { + super.paint(graphics); + graphics.drawRect(MAP_X, MAP_Y, MAP_WIDTH, MAP_HEIGHT); + + if (this.cities != null) { + for (Vector city : this.cities) { + final int currentX = (int) city.getCoordinate(1); + final int currentY = (int) city.getCoordinate(2); + + graphics.fillArc((currentX + MAP_X) - 5, (currentY + MAP_Y) - 5, 10, 10, 0, 360); + } + } + + if ((this.cities != null) && (this.currentWinner != null)) { + final int[] ordering = this.currentWinner.getCitiesOrder(); + final Vector[] orderedPoints = new Vector[ordering.length]; + for (int cityIndex = 0; cityIndex < this.cities.length; cityIndex++) { + orderedPoints[ordering[cityIndex]] = this.cities[cityIndex]; + } + + //draw the points + Vector firstPoint = null; + Vector lastPoint = null; + for (Vector point : orderedPoints) { + if (lastPoint == null) { + lastPoint = point; + firstPoint = point; + } + else { + final int lastX = (int) lastPoint.getCoordinate(1); + final int lastY = (int) lastPoint.getCoordinate(2); + + final int currentX = (int) point.getCoordinate(1); + final int currentY = (int) point.getCoordinate(2); + + graphics.drawLine(lastX + MAP_X, lastY + MAP_Y, currentX + MAP_X, currentY + MAP_Y); + + lastPoint = point; + } + } + if ((lastPoint != null) && (firstPoint != null)) { + final int lastX = (int) lastPoint.getCoordinate(1); + final int lastY = (int) lastPoint.getCoordinate(2); + + final int firstX = (int) firstPoint.getCoordinate(1); + final int firstY = (int) firstPoint.getCoordinate(2); + + graphics.drawLine(lastX + MAP_X, lastY + MAP_Y, firstX + MAP_X, firstY + MAP_Y); + } + } - this.setResizable(false); - this.repaint(); } - @Override - public void paint(final Graphics graphics) - { - super.paint(graphics); - graphics.drawRect(MAP_X, MAP_Y, MAP_WIDTH, MAP_HEIGHT); - - if(this.cities != null) - { - for(Vector city : this.cities) - { - final int currentX = (int) city.getCoordinate(1); - final int currentY = (int) city.getCoordinate(2); - - graphics.fillArc((currentX + MAP_X) - 5, (currentY + MAP_Y) - 5, 10, 10, 0, 360); - } - } - - if((this.cities != null) && (this.currentWinner != null)) - { - final int[] ordering = this.currentWinner.getCitiesOrder(); - final Vector[] orderedPoints = new Vector[ordering.length]; - for(int cityIndex = 0; cityIndex < this.cities.length; cityIndex++) - { - orderedPoints[ordering[cityIndex]] = this.cities[cityIndex]; - } - - //draw the points - Vector firstPoint = null; - Vector lastPoint = null; - for(Vector point : orderedPoints) - { - if(lastPoint == null) - { - lastPoint = point; - firstPoint = point; - } - else - { - final int lastX = (int) lastPoint.getCoordinate(1); - final int lastY = (int) lastPoint.getCoordinate(2); - - final int currentX = (int) point.getCoordinate(1); - final int currentY = (int) point.getCoordinate(2); - - graphics.drawLine(lastX + MAP_X, lastY + MAP_Y, currentX + MAP_X, currentY + MAP_Y); - - lastPoint = point; - } - } - if((lastPoint != null)&&(firstPoint != null)) - { - final int lastX = (int) lastPoint.getCoordinate(1); - final int lastY = (int) lastPoint.getCoordinate(2); - - final int firstX = (int) firstPoint.getCoordinate(1); - final int firstY = (int) firstPoint.getCoordinate(2); - - graphics.drawLine(lastX + MAP_X, lastY + MAP_Y, firstX + MAP_X, firstY + MAP_Y); - } - } - - } - - private static Vector[] getRandomPoints(final int cityCount) - { - if(cityCount < 4) - throw new IllegalArgumentException("cityCount must have atleast 4 elements"); - - final HashSet<Vector> pointsSet = new HashSet<Vector>(); - while(pointsSet.size() < cityCount) - pointsSet.add(new Vector(new double[]{RANDOM.nextDouble() * MAP_WIDTH, RANDOM.nextDouble() * MAP_HEIGHT})); - - final Vector[] points = new Vector[cityCount]; - pointsSet.toArray(points); - - return points; - } - - @Override - public void actionPerformed(final ActionEvent evt) - { - if((this.futureWinner != null) && (this.populationCallable != null)) - { - this.progressBar.setValue(this.populationCallable.getIterations()); - - if( this.futureWinner.isDone() ) - { - LOGGER.debug("this.futureWinner.isDone() == true"); - - try - { - this.currentWinner = this.futureWinner.get(); - } - catch(Exception caught) - { - LOGGER.error("futureWinner threw an unexpected exception", caught); - throw new Error("futureWinner threw an unexpected exception", caught); - } - this.populationCallable = null; - this.futureWinner = null; - - this.progressTimer.stop(); - this.evolveDisplayButton.setEnabled(true); - - this.repaint(); - } - } - } + @Override + public void actionPerformed(final ActionEvent evt) { + if ((this.futureWinner != null) && (this.populationCallable != null)) { + this.progressBar.setValue(this.populationCallable.getIterations()); + + if (this.futureWinner.isDone()) { + LOGGER.debug("this.futureWinner.isDone() == true"); + + try { + this.currentWinner = this.futureWinner.get(); + } + catch (Exception caught) { + LOGGER.error("futureWinner threw an unexpected exception", caught); + throw new Error("futureWinner threw an unexpected exception", caught); + } + this.populationCallable = null; + this.futureWinner = null; + + this.progressTimer.stop(); + this.evolveDisplayButton.setEnabled(true); + + this.repaint(); + } + } + } @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents @@ -316,130 +268,137 @@ public class TravellingSalesmanDemo extends JFrame implements ActionListener javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(citiesLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(citiesSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(populationLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(populationSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 51, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(mutabilityLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(mutabilitySpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(crossoverLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(crossoverSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 47, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(dieOffLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(dieOffSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 46, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(generationsLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(generationsSpinner, javax.swing.GroupLayout.DEFAULT_SIZE, 62, Short.MAX_VALUE)) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, 501, Short.MAX_VALUE) - .addGap(10, 10, 10) - .addComponent(evolveDisplayButton))) - .addContainerGap()) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(citiesLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(citiesSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(populationLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(populationSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 51, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(mutabilityLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(mutabilitySpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(crossoverLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(crossoverSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 47, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(dieOffLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(dieOffSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 46, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(generationsLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(generationsSpinner, javax.swing.GroupLayout.DEFAULT_SIZE, 62, Short.MAX_VALUE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, 501, Short.MAX_VALUE) + .addGap(10, 10, 10) + .addComponent(evolveDisplayButton))) + .addContainerGap()) ); layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(citiesLabel) - .addComponent(citiesSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(populationLabel) - .addComponent(populationSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(mutabilityLabel) - .addComponent(mutabilitySpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(crossoverLabel) - .addComponent(crossoverSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(dieOffLabel) - .addComponent(dieOffSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(generationsLabel) - .addComponent(generationsSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(evolveDisplayButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap(520, Short.MAX_VALUE)) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(citiesLabel) + .addComponent(citiesSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(populationLabel) + .addComponent(populationSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(mutabilityLabel) + .addComponent(mutabilitySpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(crossoverLabel) + .addComponent(crossoverSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(dieOffLabel) + .addComponent(dieOffSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(generationsLabel) + .addComponent(generationsSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(evolveDisplayButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(520, Short.MAX_VALUE)) ); pack(); }// </editor-fold>//GEN-END:initComponents - private void quitMenuItemMouseReleased(java.awt.event.MouseEvent evt)//GEN-FIRST:event_quitMenuItemMouseReleased - {//GEN-HEADEREND:event_quitMenuItemMouseReleased - System.exit(0); - }//GEN-LAST:event_quitMenuItemMouseReleased + private void quitMenuItemMouseReleased(java.awt.event.MouseEvent evt)//GEN-FIRST:event_quitMenuItemMouseReleased + {//GEN-HEADEREND:event_quitMenuItemMouseReleased + System.exit(0); + }//GEN-LAST:event_quitMenuItemMouseReleased - private void evolveDisplayButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_evolveDisplayButtonActionPerformed - {//GEN-HEADEREND:event_evolveDisplayButtonActionPerformed - this.currentWinner = null; - this.cities = getRandomPoints(this.citiesModel.getNumber().intValue()); + private void evolveDisplayButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_evolveDisplayButtonActionPerformed + {//GEN-HEADEREND:event_evolveDisplayButtonActionPerformed + this.currentWinner = null; + this.cities = getRandomPoints(this.citiesModel.getNumber().intValue()); - final int populationSize = this.populationModel.getNumber().intValue(); - final double mutability = this.mutabilityModel.getNumber().doubleValue(); - final double crossover = this.crossoverModel.getNumber().doubleValue(); - final double dieOff = this.dieOffModel.getNumber().doubleValue(); - final int generations = this.generationsModel.getNumber().intValue(); + final int populationSize = this.populationModel.getNumber().intValue(); + final double mutability = this.mutabilityModel.getNumber().doubleValue(); + final double crossover = this.crossoverModel.getNumber().doubleValue(); + final double dieOff = this.dieOffModel.getNumber().doubleValue(); + final int generations = this.generationsModel.getNumber().intValue(); - final TravellingSalesmanPopulation population = new TravellingSalesmanPopulation(this.cities, mutability, crossover, dieOff); - population.initializePopulation(populationSize); + final TravellingSalesmanPopulation population = new TravellingSalesmanPopulation(this.cities, mutability, crossover, dieOff); + population.initializePopulation(populationSize); - this.populationCallable = new PopulationEvolveCallable(population, generations); - this.futureWinner = this.executor.submit(this.populationCallable); + this.populationCallable = new PopulationEvolveCallable(population, generations); + this.futureWinner = this.executor.submit(this.populationCallable); - this.progressBar.setMaximum(generations); + this.progressBar.setMaximum(generations); - this.evolveDisplayButton.setEnabled(false); - this.progressTimer.start(); + this.evolveDisplayButton.setEnabled(false); + this.progressTimer.start(); - this.repaint(); - }//GEN-LAST:event_evolveDisplayButtonActionPerformed + this.repaint(); + }//GEN-LAST:event_evolveDisplayButtonActionPerformed - public static void main(final String[] args) - { - LOGGER.info("Starting Travelling Salesman Demo from main()"); - java.awt.EventQueue.invokeLater(new Runnable() - { - @Override - public void run() - { - new TravellingSalesmanDemo().setVisible(true); + private static class PopulationEvolveCallable implements Callable<TravellingSalesmanChromosome> { + private static final Logger LOGGER = Logger.getLogger(PopulationEvolveCallable.class); + private final TravellingSalesmanPopulation population; + private final int iterationsMax; + private volatile int iterations = 0; + + public PopulationEvolveCallable(final TravellingSalesmanPopulation population, final int iterationsMax) { + if (iterationsMax <= 0) + throw new IllegalArgumentException("iterationsMax must be greater than 0"); + + this.population = population; + this.iterationsMax = iterationsMax; + } + + @Override + public TravellingSalesmanChromosome call() { + try { + for (; this.iterations < this.iterationsMax; this.iterations++) + this.population.nextGeneration(); + + return this.population.getWinner(); } - }); - } + catch (Exception caught) { + LOGGER.error("Exception was caught", caught); + throw new RuntimeException("Throwable was caught", caught); + } + catch (Error caught) { + LOGGER.error("Error was caught", caught); + throw new Error("Throwable was caught", caught); + } + } - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JMenuItem aboutMenuItem; - private javax.swing.JLabel citiesLabel; - private javax.swing.JSpinner citiesSpinner; - private javax.swing.JLabel crossoverLabel; - private javax.swing.JSpinner crossoverSpinner; - private javax.swing.JLabel dieOffLabel; - private javax.swing.JSpinner dieOffSpinner; - private javax.swing.JButton evolveDisplayButton; - private javax.swing.JMenu fileMenuItem; - private javax.swing.JLabel generationsLabel; - private javax.swing.JSpinner generationsSpinner; - private javax.swing.JMenu helpMenuItem; - private javax.swing.JMenuBar menuBar; - private javax.swing.JLabel mutabilityLabel; - private javax.swing.JSpinner mutabilitySpinner; - private javax.swing.JLabel populationLabel; - private javax.swing.JSpinner populationSpinner; - private javax.swing.JProgressBar progressBar; - private javax.swing.JMenuItem quitMenuItem; + public int getIterations() { + return this.iterations; + } + + public int getIterationsMax() { + return this.iterationsMax; + } + } // End of variables declaration//GEN-END:variables } diff --git a/src/main/java/com/syncleus/dann/examples/tsp/TravellingSalesmanFitnessFunction.java b/src/main/java/com/syncleus/dann/examples/tsp/TravellingSalesmanFitnessFunction.java index 25979930a538f2eee873e0b0d05dd538a73866da..c767b5245e57059e06055b577956bf3037b45d4c 100644 --- a/src/main/java/com/syncleus/dann/examples/tsp/TravellingSalesmanFitnessFunction.java +++ b/src/main/java/com/syncleus/dann/examples/tsp/TravellingSalesmanFitnessFunction.java @@ -18,94 +18,85 @@ ******************************************************************************/ package com.syncleus.dann.examples.tsp; -import java.util.List; -import java.util.SortedSet; -import com.syncleus.dann.genetics.AbstractGeneticAlgorithmFitnessFunction; -import com.syncleus.dann.genetics.AbstractValueGene; +import com.syncleus.dann.genetics.*; import com.syncleus.dann.math.Vector; -public class TravellingSalesmanFitnessFunction extends AbstractGeneticAlgorithmFitnessFunction<TravellingSalesmanFitnessFunction> -{ - public static final int MINIMUM_CITIES = 4; - private final Vector[] cities; - private double totalDistance = 0.0; +import java.util.*; - public TravellingSalesmanFitnessFunction(final TravellingSalesmanChromosome chromosome, final Vector[] cities) - { - super(chromosome); +public class TravellingSalesmanFitnessFunction extends AbstractGeneticAlgorithmFitnessFunction<TravellingSalesmanFitnessFunction> { + public static final int MINIMUM_CITIES = 4; + private final Vector[] cities; + private double totalDistance = 0.0; - if(chromosome == null) - throw new IllegalArgumentException("chromosome can not be null"); - if(cities == null) - throw new IllegalArgumentException("cities can not be null"); - if(cities.length < MINIMUM_CITIES) - throw new IllegalArgumentException("cities must have atleast " + MINIMUM_CITIES + " elements"); - if(chromosome.getGeneCount() != cities.length) - throw new IllegalArgumentException("Cities must have the same number of elements as genes in the chromosome"); + public TravellingSalesmanFitnessFunction(final TravellingSalesmanChromosome chromosome, final Vector[] cities) { + super(chromosome); - this.cities = cities.clone(); - } + if (chromosome == null) + throw new IllegalArgumentException("chromosome can not be null"); + if (cities == null) + throw new IllegalArgumentException("cities can not be null"); + if (cities.length < MINIMUM_CITIES) + throw new IllegalArgumentException("cities must have atleast " + MINIMUM_CITIES + " elements"); + if (chromosome.getGeneCount() != cities.length) + throw new IllegalArgumentException("Cities must have the same number of elements as genes in the chromosome"); - @Override - public TravellingSalesmanChromosome getChromosome() - { - return ((TravellingSalesmanChromosome)(super.getChromosome())); - } + this.cities = cities.clone(); + } - /** - * Evaluates the fitness of the chromosome being wrapped relative to the - * specified chromosome. - * - * @param compareWith The fitness function containing a chromosome to - * compare to. - * @return If this chromosome is more fit it will return a - * positive value, if it is less fit it will be negative. If they are - * both equally as fit it will return 0. - * @since 2.0 - */ - @Override - public int compareTo(final TravellingSalesmanFitnessFunction compareWith) - { - if(this.totalDistance < compareWith.totalDistance) - return 1; - else if(this.totalDistance > compareWith.totalDistance) - return -1; - else - return 0; - } + @Override + public TravellingSalesmanChromosome getChromosome() { + return ((TravellingSalesmanChromosome) (super.getChromosome())); + } - /** - * Called once after the class is initialized in case child implementations - * want to cash a value for compareTo. This must be thread safe. - * - * @since 2.0 - */ - @Override - public synchronized void process() - { - final SortedSet<AbstractValueGene> sortedGenes = this.getChromosome().getSortedGenes(); - final List<AbstractValueGene> indexedGenes = this.getChromosome().getGenes(); + /** + * Evaluates the fitness of the chromosome being wrapped relative to the + * specified chromosome. + * + * @param compareWith The fitness function containing a chromosome to + * compare to. + * @return If this chromosome is more fit it will return a + * positive value, if it is less fit it will be negative. If they are + * both equally as fit it will return 0. + * @since 2.0 + */ + @Override + public int compareTo(final TravellingSalesmanFitnessFunction compareWith) { + if (this.totalDistance < compareWith.totalDistance) + return 1; + else if (this.totalDistance > compareWith.totalDistance) + return -1; + else + return 0; + } - //calculate the distance going through the genes sorted by city priority - double currentDistance = 0.0; - Vector firstPosition = null; - Vector lastPosition = null; - for(AbstractValueGene sortedGene : sortedGenes) - { - final Vector currentPosition = this.cities[indexedGenes.indexOf(sortedGene)]; - if(lastPosition == null) - { - lastPosition = currentPosition; - firstPosition = currentPosition; - } - else - { - currentDistance += lastPosition.calculateRelativeTo(currentPosition).getDistance(); - lastPosition = currentPosition; - } - } - currentDistance += firstPosition.calculateRelativeTo(lastPosition).getDistance(); + /** + * Called once after the class is initialized in case child implementations + * want to cash a value for compareTo. This must be thread safe. + * + * @since 2.0 + */ + @Override + public synchronized void process() { + final SortedSet<AbstractValueGene> sortedGenes = this.getChromosome().getSortedGenes(); + final List<AbstractValueGene> indexedGenes = this.getChromosome().getGenes(); - this.totalDistance = currentDistance; - } + //calculate the distance going through the genes sorted by city priority + double currentDistance = 0.0; + Vector firstPosition = null; + Vector lastPosition = null; + for (AbstractValueGene sortedGene : sortedGenes) { + final Vector currentPosition = this.cities[indexedGenes.indexOf(sortedGene)]; + if (lastPosition == null) { + lastPosition = currentPosition; + firstPosition = currentPosition; + } + else { + currentDistance += lastPosition.calculateRelativeTo(currentPosition).getDistance(); + lastPosition = currentPosition; + } + } + currentDistance += firstPosition.calculateRelativeTo(lastPosition).getDistance(); + + this.totalDistance = currentDistance; + } } diff --git a/src/main/java/com/syncleus/dann/examples/tsp/TravellingSalesmanPopulation.java b/src/main/java/com/syncleus/dann/examples/tsp/TravellingSalesmanPopulation.java index 3d60e1039864b9f3346ab8f59f5ecec35a9acd52..f757a2103f9951da9c67622fb1f42e29dd18bd8d 100644 --- a/src/main/java/com/syncleus/dann/examples/tsp/TravellingSalesmanPopulation.java +++ b/src/main/java/com/syncleus/dann/examples/tsp/TravellingSalesmanPopulation.java @@ -18,81 +18,72 @@ ******************************************************************************/ package com.syncleus.dann.examples.tsp; -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.ThreadPoolExecutor; -import com.syncleus.dann.genetics.AbstractGeneticAlgorithmPopulation; -import com.syncleus.dann.genetics.GeneticAlgorithmChromosome; +import com.syncleus.dann.genetics.*; import com.syncleus.dann.math.Vector; -public class TravellingSalesmanPopulation extends AbstractGeneticAlgorithmPopulation -{ - private final Vector[] cities; - - public TravellingSalesmanPopulation(final Vector[] cities, final double mutationDeviation, final double crossoverPercentage, final double dieOffPercentage) - { - super(mutationDeviation, crossoverPercentage, dieOffPercentage); - - if(cities == null) - throw new IllegalArgumentException("cities can not be null"); - if(cities.length < TravellingSalesmanFitnessFunction.MINIMUM_CITIES) - throw new IllegalArgumentException("cities must have atleast " + TravellingSalesmanFitnessFunction.MINIMUM_CITIES + " elements"); - - this.cities = cities.clone(); - } - - public TravellingSalesmanPopulation(final Vector[] cities, final double mutationDeviation, final double crossoverPercentage, final double dieOffPercentage, final ThreadPoolExecutor threadExecutor) - { - super(mutationDeviation, crossoverPercentage, dieOffPercentage, threadExecutor); - - if(cities == null) - throw new IllegalArgumentException("cities can not be null"); - if(cities.length < TravellingSalesmanFitnessFunction.MINIMUM_CITIES) - throw new IllegalArgumentException("cities must have atleast " + TravellingSalesmanFitnessFunction.MINIMUM_CITIES + " elements"); - - this.cities = cities.clone(); - } - - public void initializePopulation(final int populationSize) - { - if(populationSize < TravellingSalesmanFitnessFunction.MINIMUM_CITIES) - throw new IllegalArgumentException("populationSize must have atleast " + TravellingSalesmanFitnessFunction.MINIMUM_CITIES + " elements"); - - this.addAll(initialChromosomes(cities.length, populationSize)); - } - - @Override - protected TravellingSalesmanFitnessFunction packageChromosome(final GeneticAlgorithmChromosome chromosome) - { - if(!(chromosome instanceof TravellingSalesmanChromosome)) - throw new IllegalArgumentException("Chromosome must be a TravellingSalesmanChromosome"); - - return new TravellingSalesmanFitnessFunction((TravellingSalesmanChromosome)chromosome, this.cities); - } - - private static Set<GeneticAlgorithmChromosome> initialChromosomes(final int cityCount, final int populationSize) - { - if(populationSize < TravellingSalesmanFitnessFunction.MINIMUM_CITIES) - throw new IllegalArgumentException("populationSize must have atleast " + TravellingSalesmanFitnessFunction.MINIMUM_CITIES + " elements"); - if(cityCount < TravellingSalesmanFitnessFunction.MINIMUM_CITIES) - throw new IllegalArgumentException("cityCount must be atleast " + TravellingSalesmanFitnessFunction.MINIMUM_CITIES); - - final HashSet<GeneticAlgorithmChromosome> returnValue = new HashSet<GeneticAlgorithmChromosome>(); - while(returnValue.size() < populationSize) - returnValue.add(new TravellingSalesmanChromosome(cityCount)); - return returnValue; - } - - @Override - public final TravellingSalesmanChromosome getWinner() - { - final GeneticAlgorithmChromosome winner = super.getWinner(); - assert(winner instanceof TravellingSalesmanChromosome); - return (TravellingSalesmanChromosome) winner; - } - - public Vector[] getCities() - { - return cities.clone(); - } +import java.util.*; +import java.util.concurrent.ThreadPoolExecutor; + +public class TravellingSalesmanPopulation extends AbstractGeneticAlgorithmPopulation { + private final Vector[] cities; + + public TravellingSalesmanPopulation(final Vector[] cities, final double mutationDeviation, final double crossoverPercentage, final double dieOffPercentage) { + super(mutationDeviation, crossoverPercentage, dieOffPercentage); + + if (cities == null) + throw new IllegalArgumentException("cities can not be null"); + if (cities.length < TravellingSalesmanFitnessFunction.MINIMUM_CITIES) + throw new IllegalArgumentException("cities must have atleast " + TravellingSalesmanFitnessFunction.MINIMUM_CITIES + " elements"); + + this.cities = cities.clone(); + } + + public TravellingSalesmanPopulation(final Vector[] cities, final double mutationDeviation, final double crossoverPercentage, final double dieOffPercentage, final ThreadPoolExecutor threadExecutor) { + super(mutationDeviation, crossoverPercentage, dieOffPercentage, threadExecutor); + + if (cities == null) + throw new IllegalArgumentException("cities can not be null"); + if (cities.length < TravellingSalesmanFitnessFunction.MINIMUM_CITIES) + throw new IllegalArgumentException("cities must have atleast " + TravellingSalesmanFitnessFunction.MINIMUM_CITIES + " elements"); + + this.cities = cities.clone(); + } + + private static Set<GeneticAlgorithmChromosome> initialChromosomes(final int cityCount, final int populationSize) { + if (populationSize < TravellingSalesmanFitnessFunction.MINIMUM_CITIES) + throw new IllegalArgumentException("populationSize must have atleast " + TravellingSalesmanFitnessFunction.MINIMUM_CITIES + " elements"); + if (cityCount < TravellingSalesmanFitnessFunction.MINIMUM_CITIES) + throw new IllegalArgumentException("cityCount must be atleast " + TravellingSalesmanFitnessFunction.MINIMUM_CITIES); + + final HashSet<GeneticAlgorithmChromosome> returnValue = new HashSet<GeneticAlgorithmChromosome>(); + while (returnValue.size() < populationSize) + returnValue.add(new TravellingSalesmanChromosome(cityCount)); + return returnValue; + } + + public void initializePopulation(final int populationSize) { + if (populationSize < TravellingSalesmanFitnessFunction.MINIMUM_CITIES) + throw new IllegalArgumentException("populationSize must have atleast " + TravellingSalesmanFitnessFunction.MINIMUM_CITIES + " elements"); + + this.addAll(initialChromosomes(cities.length, populationSize)); + } + + @Override + protected TravellingSalesmanFitnessFunction packageChromosome(final GeneticAlgorithmChromosome chromosome) { + if (!(chromosome instanceof TravellingSalesmanChromosome)) + throw new IllegalArgumentException("Chromosome must be a TravellingSalesmanChromosome"); + + return new TravellingSalesmanFitnessFunction((TravellingSalesmanChromosome) chromosome, this.cities); + } + + @Override + public final TravellingSalesmanChromosome getWinner() { + final GeneticAlgorithmChromosome winner = super.getWinner(); + assert (winner instanceof TravellingSalesmanChromosome); + return (TravellingSalesmanChromosome) winner; + } + + public Vector[] getCities() { + return cities.clone(); + } } diff --git a/src/main/java/com/syncleus/dann/examples/xor/XorDemo.java b/src/main/java/com/syncleus/dann/examples/xor/XorDemo.java index 97d8822e7055056156acae46c39bbec1fa51102c..26831d69228428002bb3b13f34d775e13a01f422 100644 --- a/src/main/java/com/syncleus/dann/examples/xor/XorDemo.java +++ b/src/main/java/com/syncleus/dann/examples/xor/XorDemo.java @@ -18,370 +18,325 @@ ******************************************************************************/ package com.syncleus.dann.examples.xor; -import java.util.ArrayList; -import com.syncleus.dann.neural.InputNeuron; -import com.syncleus.dann.neural.OutputNeuron; -import com.syncleus.dann.neural.activation.ActivationFunction; -import com.syncleus.dann.neural.activation.SineActivationFunction; -import com.syncleus.dann.neural.backprop.InputBackpropNeuron; -import com.syncleus.dann.neural.backprop.OutputBackpropNeuron; +import com.syncleus.dann.neural.*; +import com.syncleus.dann.neural.activation.*; +import com.syncleus.dann.neural.backprop.*; import com.syncleus.dann.neural.backprop.brain.FullyConnectedFeedforwardBrain; -import java.io.BufferedReader; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.List; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; import org.apache.log4j.Logger; +import java.io.*; +import java.util.*; +import java.util.concurrent.*; + /** * An example main class that shows using dANN to solve an XOR problem. An XOR * is a circuit that returns true (1) when only one of its inputs is true. It * returns false (-1) if none all of its inputs are false or if more then one * of its inputs are true. * - * @since 0.1 * @author Jeffrey Phillips Freeman + * @since 0.1 */ -public final class XorDemo -{ - private static final Logger LOGGER = Logger.getLogger(XorDemo.class); - private static final double LEARNING_RATE = 0.0175; - private static final long KEEP_ALIVE_TIME = 20; - private static final int INPUTS = 3; - private static BufferedReader inReader = null; - private static InputBackpropNeuron[] input = null; - private static OutputBackpropNeuron output = null; - private static FullyConnectedFeedforwardBrain brain; - private static String saveLocation = "default.dann"; - - private XorDemo() - { - } - - public static void main(final String[] args) - { - try - { - if( args.length > 0 ) - saveLocation = args[0]; - - inReader = new BufferedReader(new InputStreamReader(System.in)); - - //Adjust the learning rate - final ActivationFunction activationFunction = new SineActivationFunction(); - - final int cores = Runtime.getRuntime().availableProcessors(); - final ThreadPoolExecutor executer = new ThreadPoolExecutor(cores+1, cores*2, KEEP_ALIVE_TIME, TimeUnit.SECONDS, new LinkedBlockingQueue()); - try - { - brain = new FullyConnectedFeedforwardBrain(new int[] {INPUTS, INPUTS, 1}, LEARNING_RATE, activationFunction, executer); - final List<InputNeuron> inputs = new ArrayList<InputNeuron>(brain.getInputNeurons()); - for (int ii = 0; ii < INPUTS; ii++) - { - input[ii] = (InputBackpropNeuron) inputs.get(ii); - } - final List<OutputNeuron> outputs = new ArrayList<OutputNeuron>(brain.getOutputNeurons()); - output = (OutputBackpropNeuron) outputs.get(0); - - //now that we have created the neural network lets put it to use. - System.out.println("dANN nXOR Example"); - - int currentCommand = 'q'; - do - { - boolean received = false; - while( !received ) - { - System.out.println(); - System.out.println("D) display current circuit pin-out"); - System.out.println("T) train the current circuit"); - System.out.println("S) save"); - System.out.println("L) load"); - System.out.println("Q) quit"); - System.out.println("\tEnter command: "); - - received = true; - try - { - final String lastInput = inReader.readLine(); - if( lastInput == null) - currentCommand = 'q'; - else - currentCommand = lastInput.toLowerCase().toCharArray()[0]; - } - catch(ArrayIndexOutOfBoundsException caughtException) - { - received = false; - } - } - - System.out.println(); - - switch( currentCommand ) - { - case 'd': - testOutput(); - break; - case 't': - int cycles = 750; - System.out.println("How many training cycles [Default: " + cycles + "]: "); - try - { - cycles = Integer.parseInt(inReader.readLine()); - } - catch(NumberFormatException caughtException) - { - } - System.out.println(); - train(cycles); - System.out.println("Training Complete!"); - break; - case 's': - save(); - break; - case 'l': - load(); - break; - case 'q': - System.out.print("Quiting..."); - break; - default: - System.out.println("Invalid command"); - } - } while( (currentCommand != 'q')&&(currentCommand >= 0) ); - } - finally - { - executer.shutdown(); - System.out.println("Quit"); - } - } - catch(Exception caught) - { - LOGGER.error("Exception was caught", caught); - throw new RuntimeException("Throwable was caught", caught); - } - catch(Error caught) - { - LOGGER.error("Error was caught", caught); - throw new Error("Throwable was caught", caught); - } - } - - private static void save() throws IOException, ClassNotFoundException - { - final ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(saveLocation)); - try - { - out.writeObject(brain); - out.writeObject(output); - for (int ii = 0; ii < INPUTS; ii++) - { - out.writeObject(input[ii]); - } - out.flush(); - } - finally - { - out.close(); - } - - LOGGER.debug("File Saved"); - System.out.println("File Saved"); - } - - private static void load() throws IOException, ClassNotFoundException - { - ObjectInputStream inStream = null; - try - { - inStream = new ObjectInputStream(new FileInputStream(saveLocation)); - } - catch(FileNotFoundException caught) - { - LOGGER.warn("the specified file does not exist!", caught); - return; - } - - try - { - brain = (FullyConnectedFeedforwardBrain) inStream.readObject(); - output = (OutputBackpropNeuron) inStream.readObject(); - for (int ii = 0; ii < INPUTS; ii++) - { - input[ii] = (InputBackpropNeuron) inStream.readObject(); - } - } - finally - { - inStream.close(); - } - - LOGGER.debug("File Loaded"); - System.out.println("File Loaded"); - } - - private static void propogateOutput() - { - brain.propagate(); - } - - private static void backPropogateTraining() - { - brain.backPropagate(); - } - - private static void setCurrentInput(final double[] inputToSet) - { - for (int ii = 0; ii < INPUTS; ii++) - { - input[ii].setInput(inputToSet[ii]); - } - } - - private static void testOutput() - { - double[] curInput = - { - 0, 0, 0 - }; - setCurrentInput(curInput); - propogateOutput(); - System.out.println(curInput[0] + ", " + curInput[1] + ", " + curInput[2] + ":\t" + output.getOutput()); - - curInput[0] = 1; - curInput[1] = 0; - curInput[2] = 0; - setCurrentInput(curInput); - propogateOutput(); - System.out.println(curInput[0] + ", " + curInput[1] + ", " + curInput[2] + ":\t" + output.getOutput()); - - curInput[0] = 0; - curInput[1] = 1; - curInput[2] = 0; - setCurrentInput(curInput); - propogateOutput(); - System.out.println(curInput[0] + ", " + curInput[1] + ", " + curInput[2] + ":\t" + output.getOutput()); - - curInput[0] = 0; - curInput[1] = 0; - curInput[2] = 1; - setCurrentInput(curInput); - propogateOutput(); - System.out.println(curInput[0] + ", " + curInput[1] + ", " + curInput[2] + ":\t" + output.getOutput()); - - curInput[0] = 1; - curInput[1] = 1; - curInput[2] = 0; - setCurrentInput(curInput); - propogateOutput(); - System.out.println(curInput[0] + ", " + curInput[1] + ", " + curInput[2] + ":\t" + output.getOutput()); - - curInput[0] = 0; - curInput[1] = 1; - curInput[2] = 1; - setCurrentInput(curInput); - propogateOutput(); - System.out.println(curInput[0] + ", " + curInput[1] + ", " + curInput[2] + ":\t" + output.getOutput()); - - curInput[0] = 1; - curInput[1] = 0; - curInput[2] = 1; - setCurrentInput(curInput); - propogateOutput(); - System.out.println(curInput[0] + ", " + curInput[1] + ", " + curInput[2] + ":\t" + output.getOutput()); - - curInput[0] = 1; - curInput[1] = 1; - curInput[2] = 1; - setCurrentInput(curInput); - propogateOutput(); - System.out.println(curInput[0] + ", " + curInput[1] + ", " + curInput[2] + ":\t" + output.getOutput()); - } - - private static void train(final int count) - { - for (int lcv = 0; lcv < count; lcv++) - { - double[] curInput = - { - 0, 0, 0 - }; - double curTrain = -1; - setCurrentInput(curInput); - propogateOutput(); - output.setDesired(curTrain); - backPropogateTraining(); - - curInput[0] = 1; - curInput[1] = 0; - curInput[2] = 0; - curTrain = 1; - setCurrentInput(curInput); - propogateOutput(); - output.setDesired(curTrain); - backPropogateTraining(); - - curInput[0] = 0; - curInput[1] = 1; - curInput[2] = 0; - curTrain = 1; - setCurrentInput(curInput); - propogateOutput(); - output.setDesired(curTrain); - backPropogateTraining(); - - curInput[0] = 0; - curInput[1] = 0; - curInput[2] = 1; - curTrain = 1; - setCurrentInput(curInput); - propogateOutput(); - output.setDesired(curTrain); - backPropogateTraining(); - - curInput[0] = 1; - curInput[1] = 1; - curInput[2] = 0; - curTrain = -1; - setCurrentInput(curInput); - propogateOutput(); - output.setDesired(curTrain); - backPropogateTraining(); - - curInput[0] = 0; - curInput[1] = 1; - curInput[2] = 1; - curTrain = -1; - setCurrentInput(curInput); - propogateOutput(); - output.setDesired(curTrain); - backPropogateTraining(); - - curInput[0] = 1; - curInput[1] = 0; - curInput[2] = 1; - curTrain = -1; - setCurrentInput(curInput); - propogateOutput(); - output.setDesired(curTrain); - backPropogateTraining(); - - curInput[0] = 1; - curInput[1] = 1; - curInput[2] = 1; - curTrain = -1; - setCurrentInput(curInput); - propogateOutput(); - output.setDesired(curTrain); - backPropogateTraining(); - } - } +public final class XorDemo { + private static final Logger LOGGER = Logger.getLogger(XorDemo.class); + private static final double LEARNING_RATE = 0.0175; + private static final long KEEP_ALIVE_TIME = 20; + private static final int INPUTS = 3; + private static BufferedReader inReader = null; + private static InputBackpropNeuron[] input = null; + private static OutputBackpropNeuron output = null; + private static FullyConnectedFeedforwardBrain brain; + private static String saveLocation = "default.dann"; + + private XorDemo() { + } + + public static void main(final String[] args) { + try { + if (args.length > 0) + saveLocation = args[0]; + + inReader = new BufferedReader(new InputStreamReader(System.in)); + + //Adjust the learning rate + final ActivationFunction activationFunction = new SineActivationFunction(); + + final int cores = Runtime.getRuntime().availableProcessors(); + final ThreadPoolExecutor executer = new ThreadPoolExecutor(cores + 1, cores * 2, KEEP_ALIVE_TIME, TimeUnit.SECONDS, new LinkedBlockingQueue()); + try { + brain = new FullyConnectedFeedforwardBrain(new int[]{INPUTS, INPUTS, 1}, LEARNING_RATE, activationFunction, executer); + final List<InputNeuron> inputs = new ArrayList<InputNeuron>(brain.getInputNeurons()); + for (int ii = 0; ii < INPUTS; ii++) { + input[ii] = (InputBackpropNeuron) inputs.get(ii); + } + final List<OutputNeuron> outputs = new ArrayList<OutputNeuron>(brain.getOutputNeurons()); + output = (OutputBackpropNeuron) outputs.get(0); + + //now that we have created the neural network lets put it to use. + System.out.println("dANN nXOR Example"); + + int currentCommand = 'q'; + do { + boolean received = false; + while (!received) { + System.out.println(); + System.out.println("D) display current circuit pin-out"); + System.out.println("T) train the current circuit"); + System.out.println("S) save"); + System.out.println("L) load"); + System.out.println("Q) quit"); + System.out.println("\tEnter command: "); + + received = true; + try { + final String lastInput = inReader.readLine(); + if (lastInput == null) + currentCommand = 'q'; + else + currentCommand = lastInput.toLowerCase().toCharArray()[0]; + } + catch (ArrayIndexOutOfBoundsException caughtException) { + received = false; + } + } + + System.out.println(); + + switch (currentCommand) { + case 'd': + testOutput(); + break; + case 't': + int cycles = 750; + System.out.println("How many training cycles [Default: " + cycles + "]: "); + try { + cycles = Integer.parseInt(inReader.readLine()); + } + catch (NumberFormatException caughtException) { + } + System.out.println(); + train(cycles); + System.out.println("Training Complete!"); + break; + case 's': + save(); + break; + case 'l': + load(); + break; + case 'q': + System.out.print("Quiting..."); + break; + default: + System.out.println("Invalid command"); + } + } while ((currentCommand != 'q') && (currentCommand >= 0)); + } + finally { + executer.shutdown(); + System.out.println("Quit"); + } + } + catch (Exception caught) { + LOGGER.error("Exception was caught", caught); + throw new RuntimeException("Throwable was caught", caught); + } + catch (Error caught) { + LOGGER.error("Error was caught", caught); + throw new Error("Throwable was caught", caught); + } + } + + private static void save() throws IOException, ClassNotFoundException { + final ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(saveLocation)); + try { + out.writeObject(brain); + out.writeObject(output); + for (int ii = 0; ii < INPUTS; ii++) { + out.writeObject(input[ii]); + } + out.flush(); + } + finally { + out.close(); + } + + LOGGER.debug("File Saved"); + System.out.println("File Saved"); + } + + private static void load() throws IOException, ClassNotFoundException { + ObjectInputStream inStream = null; + try { + inStream = new ObjectInputStream(new FileInputStream(saveLocation)); + } + catch (FileNotFoundException caught) { + LOGGER.warn("the specified file does not exist!", caught); + return; + } + + try { + brain = (FullyConnectedFeedforwardBrain) inStream.readObject(); + output = (OutputBackpropNeuron) inStream.readObject(); + for (int ii = 0; ii < INPUTS; ii++) { + input[ii] = (InputBackpropNeuron) inStream.readObject(); + } + } + finally { + inStream.close(); + } + + LOGGER.debug("File Loaded"); + System.out.println("File Loaded"); + } + + private static void propogateOutput() { + brain.propagate(); + } + + private static void backPropogateTraining() { + brain.backPropagate(); + } + + private static void setCurrentInput(final double[] inputToSet) { + for (int ii = 0; ii < INPUTS; ii++) { + input[ii].setInput(inputToSet[ii]); + } + } + + private static void testOutput() { + double[] curInput = + { + 0, 0, 0 + }; + setCurrentInput(curInput); + propogateOutput(); + System.out.println(curInput[0] + ", " + curInput[1] + ", " + curInput[2] + ":\t" + output.getOutput()); + + curInput[0] = 1; + curInput[1] = 0; + curInput[2] = 0; + setCurrentInput(curInput); + propogateOutput(); + System.out.println(curInput[0] + ", " + curInput[1] + ", " + curInput[2] + ":\t" + output.getOutput()); + + curInput[0] = 0; + curInput[1] = 1; + curInput[2] = 0; + setCurrentInput(curInput); + propogateOutput(); + System.out.println(curInput[0] + ", " + curInput[1] + ", " + curInput[2] + ":\t" + output.getOutput()); + + curInput[0] = 0; + curInput[1] = 0; + curInput[2] = 1; + setCurrentInput(curInput); + propogateOutput(); + System.out.println(curInput[0] + ", " + curInput[1] + ", " + curInput[2] + ":\t" + output.getOutput()); + + curInput[0] = 1; + curInput[1] = 1; + curInput[2] = 0; + setCurrentInput(curInput); + propogateOutput(); + System.out.println(curInput[0] + ", " + curInput[1] + ", " + curInput[2] + ":\t" + output.getOutput()); + + curInput[0] = 0; + curInput[1] = 1; + curInput[2] = 1; + setCurrentInput(curInput); + propogateOutput(); + System.out.println(curInput[0] + ", " + curInput[1] + ", " + curInput[2] + ":\t" + output.getOutput()); + + curInput[0] = 1; + curInput[1] = 0; + curInput[2] = 1; + setCurrentInput(curInput); + propogateOutput(); + System.out.println(curInput[0] + ", " + curInput[1] + ", " + curInput[2] + ":\t" + output.getOutput()); + + curInput[0] = 1; + curInput[1] = 1; + curInput[2] = 1; + setCurrentInput(curInput); + propogateOutput(); + System.out.println(curInput[0] + ", " + curInput[1] + ", " + curInput[2] + ":\t" + output.getOutput()); + } + + private static void train(final int count) { + for (int lcv = 0; lcv < count; lcv++) { + double[] curInput = + { + 0, 0, 0 + }; + double curTrain = -1; + setCurrentInput(curInput); + propogateOutput(); + output.setDesired(curTrain); + backPropogateTraining(); + + curInput[0] = 1; + curInput[1] = 0; + curInput[2] = 0; + curTrain = 1; + setCurrentInput(curInput); + propogateOutput(); + output.setDesired(curTrain); + backPropogateTraining(); + + curInput[0] = 0; + curInput[1] = 1; + curInput[2] = 0; + curTrain = 1; + setCurrentInput(curInput); + propogateOutput(); + output.setDesired(curTrain); + backPropogateTraining(); + + curInput[0] = 0; + curInput[1] = 0; + curInput[2] = 1; + curTrain = 1; + setCurrentInput(curInput); + propogateOutput(); + output.setDesired(curTrain); + backPropogateTraining(); + + curInput[0] = 1; + curInput[1] = 1; + curInput[2] = 0; + curTrain = -1; + setCurrentInput(curInput); + propogateOutput(); + output.setDesired(curTrain); + backPropogateTraining(); + + curInput[0] = 0; + curInput[1] = 1; + curInput[2] = 1; + curTrain = -1; + setCurrentInput(curInput); + propogateOutput(); + output.setDesired(curTrain); + backPropogateTraining(); + + curInput[0] = 1; + curInput[1] = 0; + curInput[2] = 1; + curTrain = -1; + setCurrentInput(curInput); + propogateOutput(); + output.setDesired(curTrain); + backPropogateTraining(); + + curInput[0] = 1; + curInput[1] = 1; + curInput[2] = 1; + curTrain = -1; + setCurrentInput(curInput); + propogateOutput(); + output.setDesired(curTrain); + backPropogateTraining(); + } + } } diff --git a/src/main/resources/checks.xml b/src/main/resources/checks.xml index 5da443ae69e848d4b39e56a08d0d5a707bf07b3e..6c9e67e6a0fe44e51d2a377f96a1340a52441417 100644 --- a/src/main/resources/checks.xml +++ b/src/main/resources/checks.xml @@ -1,7 +1,7 @@ <?xml version="1.0"?> <!DOCTYPE module PUBLIC - "-//Puppy Crawl//DTD Check Configuration 1.2//EN" - "http://www.puppycrawl.com/dtds/configuration_1_2.dtd"> + "-//Puppy Crawl//DTD Check Configuration 1.2//EN" + "http://www.puppycrawl.com/dtds/configuration_1_2.dtd"> <!-- @@ -64,10 +64,10 @@ <!-- Miscellaneous other checks. --> <!-- See http://checkstyle.sf.net/config_misc.html --> <module name="RegexpSingleline"> - <property name="format" value="\s+$"/> - <property name="minimum" value="0"/> - <property name="maximum" value="0"/> - <property name="message" value="Line has trailing spaces."/> + <property name="format" value="\s+$"/> + <property name="minimum" value="0"/> + <property name="maximum" value="0"/> + <property name="message" value="Line has trailing spaces."/> </module> <module name="TreeWalker"> @@ -75,21 +75,21 @@ <!-- Checks for Javadoc comments. --> <!-- See http://checkstyle.sf.net/config_javadoc.html --> <module name="JavadocMethod"> - <property name="scope" value="package"/> - <property name="severity" value="warning"/> + <property name="scope" value="package"/> + <property name="severity" value="warning"/> </module> <module name="JavadocType"> - <property name="scope" value="package"/> - <property name="authorFormat" value=".*"/> - <property name="severity" value="warning"/> + <property name="scope" value="package"/> + <property name="authorFormat" value=".*"/> + <property name="severity" value="warning"/> </module> <module name="JavadocVariable"> - <property name="scope" value="package"/> - <property name="severity" value="warning"/> + <property name="scope" value="package"/> + <property name="severity" value="warning"/> </module> <module name="JavadocStyle"> - <property name="checkEmptyJavadoc" value="true"/> - <property name="severity" value="warning"/> + <property name="checkEmptyJavadoc" value="true"/> + <property name="severity" value="warning"/> </module> @@ -109,15 +109,15 @@ <!-- Checks for Headers --> <!-- See http://checkstyle.sf.net/config_header.html --> <!-- <module name="Header"> --> - <!-- The follow property value demonstrates the ability --> - <!-- to have access to ANT configuration. In this case it uses --> - <!-- the ${basedir} property to allow Checkstyle to be run --> - <!-- from any directory within a project. See property --> - <!-- expansion, --> - <!-- http://checkstyle.sf.net/config.html#configuration --> - <!-- <property --> - <!-- name="headerFile" --> - <!-- value="${basedir}/java.header"/> --> + <!-- The follow property value demonstrates the ability --> + <!-- to have access to ANT configuration. In this case it uses --> + <!-- the ${basedir} property to allow Checkstyle to be run --> + <!-- from any directory within a project. See property --> + <!-- expansion, --> + <!-- http://checkstyle.sf.net/config.html#configuration --> + <!-- <property --> + <!-- name="headerFile" --> + <!-- value="${basedir}/java.header"/> --> <!-- </module> --> <!-- Following interprets the header file as regular expressions. --> @@ -127,7 +127,8 @@ <!-- Checks for imports --> <!-- See http://checkstyle.sf.net/config_import.html --> <!--module name="AvoidStarImport"/--> - <module name="IllegalImport"/> <!-- defaults to sun.* packages --> + <module name="IllegalImport"/> + <!-- defaults to sun.* packages --> <module name="RedundantImport"/> <module name="UnusedImports"/> @@ -150,10 +151,11 @@ <!--module name="ParenPad"/--> <module name="TypecastParenPad"/> <module name="WhitespaceAfter"> - <property name="tokens" value="COMMA, SEMI"/> + <property name="tokens" value="COMMA, SEMI"/> </module> <module name="WhitespaceAround"> - <property name="tokens" value="ASSIGN, BAND_ASSIGN, BOR_ASSIGN, BSR_ASSIGN, BXOR_ASSIGN, COLON, DIV_ASSIGN, EQUAL, GE, GT, LE, LITERAL_RETURN, LT, MINUS_ASSIGN, MOD_ASSIGN, NOT_EQUAL, PLUS_ASSIGN, QUESTION, SL_ASSIGN, SR_ASSIGN, STAR_ASSIGN"/> + <property name="tokens" + value="ASSIGN, BAND_ASSIGN, BOR_ASSIGN, BSR_ASSIGN, BXOR_ASSIGN, COLON, DIV_ASSIGN, EQUAL, GE, GT, LE, LITERAL_RETURN, LT, MINUS_ASSIGN, MOD_ASSIGN, NOT_EQUAL, PLUS_ASSIGN, QUESTION, SL_ASSIGN, SR_ASSIGN, STAR_ASSIGN"/> </module> @@ -168,18 +170,19 @@ <module name="AvoidNestedBlocks"/> <!--module name="EmptyBlock"/--> <module name="LeftCurly"> - <property name="option" value="nl"/> + <property name="option" value="nl"/> </module> <!--module name="NeedBraces"/--> <module name="RightCurly"> - <property name="option" value="alone"/> + <property name="option" value="alone"/> </module> <!-- Checks for common coding problems --> <!-- See http://checkstyle.sf.net/config_coding.html --> <!--module name="AvoidInlineConditionals"/--> - <module name="DoubleCheckedLocking"/> <!-- MY FAVOURITE --> + <module name="DoubleCheckedLocking"/> + <!-- MY FAVOURITE --> <module name="EmptyStatement"/> <module name="EqualsHashCode"/> <module name="HiddenField"> diff --git a/src/main/resources/log4j.xml b/src/main/resources/log4j.xml index 38f1f3c21f1b446daa139bcd23dc2ccfe03b8d61..a5fd4fa3d495e0108f57ed9a561a576644841dc8 100644 --- a/src/main/resources/log4j.xml +++ b/src/main/resources/log4j.xml @@ -7,17 +7,17 @@ <layout class="org.apache.log4j.SimpleLayout"/> </appender> - <appender name="appender" class="org.apache.log4j.FileAppender"> - <param name="File" value="log.html"/> - <param name="Append" value="false"/> - <layout class="org.apache.log4j.HTMLLayout"/> - </appender> + <appender name="appender" class="org.apache.log4j.FileAppender"> + <param name="File" value="log.html"/> + <param name="Append" value="false"/> + <layout class="org.apache.log4j.HTMLLayout"/> + </appender> <root> - <priority value ="warn" /> + <priority value="warn"/> <appender-ref ref="ConsoleAppender"/> - <appender-ref ref="appender"/> + <appender-ref ref="appender"/> </root> </log4j:configuration> \ No newline at end of file diff --git a/src/main/resources/pmd.xml b/src/main/resources/pmd.xml index 7a7741b4430fbb0c6ee6b5c3541d570736462b10..c647fcf66a0e0fd58dce97e522bc377d14e39d6e 100644 --- a/src/main/resources/pmd.xml +++ b/src/main/resources/pmd.xml @@ -1,46 +1,46 @@ <?xml version="1.0"?> -<ruleset name="Custom ruleset" - xmlns="http://pmd.sf.net/ruleset/1.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd" - xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd"> +<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + name="Custom ruleset" + xmlns="http://pmd.sf.net/ruleset/1.0.0" + xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd" + xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd"> - <description> - Standard ruleset. - </description> + <description> + Standard ruleset. + </description> - <rule ref="rulesets/sunsecure.xml"/> - <rule ref="rulesets/logging-java.xml"/> - <rule ref="rulesets/logging-jakarta-commons.xml"/> - <rule ref="rulesets/migrating.xml"> - <exclude name="ReplaceVectorWithList"/> - <exclude name="ReplaceHashtableWithMap"/> - </rule> - <rule ref="rulesets/naming.xml"> - <exclude name="LongVariable"/> - </rule> - <rule ref="rulesets/optimizations.xml"> - <exclude name="AvoidInstantiatingObjectsInLoops"/> - </rule> - <rule ref="rulesets/strictexception.xml"> - <exclude name="AvoidThrowingRawExceptionTypes"/> - </rule> - <rule ref="rulesets/strings.xml"> - <exclude name="AvoidDuplicateLiterals"/> - </rule> - <rule ref="rulesets/basic.xml"/> - <rule ref="rulesets/unusedcode.xml"/> - <rule ref="rulesets/codesize.xml"/> - <rule ref="rulesets/clone.xml"> - <exclude name="CloneThrowsCloneNotSupportedException"/> - </rule> - <rule ref="rulesets/coupling.xml"/> - <rule ref="rulesets/design.xml"> - <exclude name="EmptyMethodInAbstractClassShouldBeAbstract"/> - </rule> - <rule ref="rulesets/finalizers.xml"/> - <rule ref="rulesets/imports.xml"/> - <rule ref="rulesets/junit.xml"> - <exclude name="JUnitTestsShouldIncludeAssert"/> - </rule> + <rule ref="rulesets/sunsecure.xml"/> + <rule ref="rulesets/logging-java.xml"/> + <rule ref="rulesets/logging-jakarta-commons.xml"/> + <rule ref="rulesets/migrating.xml"> + <exclude name="ReplaceVectorWithList"/> + <exclude name="ReplaceHashtableWithMap"/> + </rule> + <rule ref="rulesets/naming.xml"> + <exclude name="LongVariable"/> + </rule> + <rule ref="rulesets/optimizations.xml"> + <exclude name="AvoidInstantiatingObjectsInLoops"/> + </rule> + <rule ref="rulesets/strictexception.xml"> + <exclude name="AvoidThrowingRawExceptionTypes"/> + </rule> + <rule ref="rulesets/strings.xml"> + <exclude name="AvoidDuplicateLiterals"/> + </rule> + <rule ref="rulesets/basic.xml"/> + <rule ref="rulesets/unusedcode.xml"/> + <rule ref="rulesets/codesize.xml"/> + <rule ref="rulesets/clone.xml"> + <exclude name="CloneThrowsCloneNotSupportedException"/> + </rule> + <rule ref="rulesets/coupling.xml"/> + <rule ref="rulesets/design.xml"> + <exclude name="EmptyMethodInAbstractClassShouldBeAbstract"/> + </rule> + <rule ref="rulesets/finalizers.xml"/> + <rule ref="rulesets/imports.xml"/> + <rule ref="rulesets/junit.xml"> + <exclude name="JUnitTestsShouldIncludeAssert"/> + </rule> </ruleset> \ No newline at end of file diff --git a/src/test/java/com/syncleus/dann/examples/colormap/TestAboutDialog.java b/src/test/java/com/syncleus/dann/examples/colormap/TestAboutDialog.java index 31d420562e2a2d98d5d338a83be6ddae945ad94c..5fa031d6a4d4c71234be0657d9d7a36e44934bd4 100644 --- a/src/test/java/com/syncleus/dann/examples/colormap/TestAboutDialog.java +++ b/src/test/java/com/syncleus/dann/examples/colormap/TestAboutDialog.java @@ -18,50 +18,41 @@ ******************************************************************************/ package com.syncleus.dann.examples.colormap; +import org.fest.swing.edt.*; import org.fest.swing.fixture.DialogFixture; -import org.fest.swing.edt.FailOnThreadViolationRepaintManager; -import org.fest.swing.edt.GuiQuery; -import org.fest.swing.edt.GuiActionRunner; import org.junit.*; -public class TestAboutDialog -{ - private DialogFixture aboutFixture; - - @BeforeClass - public static void setUpOnce() - { - FailOnThreadViolationRepaintManager.install(); - } - - - @Before - public void onSetUp() - { - AboutDialog aboutDialog = GuiActionRunner.execute(new GuiQuery<AboutDialog>() - { - @Override - protected AboutDialog executeInEDT() - { - return new AboutDialog(null, false); - } - }); - - aboutFixture = new DialogFixture(aboutDialog); - aboutFixture.show(); - } - - @After - public void tearDown() - { - aboutFixture.cleanUp(); - } - - @Test - public void testDisplays() - { - aboutFixture.requireVisible(); - aboutFixture.button("ok button").click(); - aboutFixture.requireNotVisible(); - } +public class TestAboutDialog { + private DialogFixture aboutFixture; + + @BeforeClass + public static void setUpOnce() { + FailOnThreadViolationRepaintManager.install(); + } + + + @Before + public void onSetUp() { + AboutDialog aboutDialog = GuiActionRunner.execute(new GuiQuery<AboutDialog>() { + @Override + protected AboutDialog executeInEDT() { + return new AboutDialog(null, false); + } + }); + + aboutFixture = new DialogFixture(aboutDialog); + aboutFixture.show(); + } + + @After + public void tearDown() { + aboutFixture.cleanUp(); + } + + @Test + public void testDisplays() { + aboutFixture.requireVisible(); + aboutFixture.button("ok button").click(); + aboutFixture.requireNotVisible(); + } } diff --git a/src/test/java/com/syncleus/dann/examples/colormap/TestColorMapDemo.java b/src/test/java/com/syncleus/dann/examples/colormap/TestColorMapDemo.java index 267b622eb1befd3b904fcfb0739ae60b517bfab5..9d83dd1d04d5dc3959304a6d02c9680a3b3846ca 100644 --- a/src/test/java/com/syncleus/dann/examples/colormap/TestColorMapDemo.java +++ b/src/test/java/com/syncleus/dann/examples/colormap/TestColorMapDemo.java @@ -18,159 +18,145 @@ ******************************************************************************/ package com.syncleus.dann.examples.colormap; +import org.fest.swing.edt.*; import org.fest.swing.exception.UnexpectedException; import org.fest.swing.fixture.FrameFixture; -import org.fest.swing.edt.FailOnThreadViolationRepaintManager; -import org.fest.swing.edt.GuiQuery; -import org.fest.swing.edt.GuiActionRunner; import org.fest.swing.timing.Timeout; import org.junit.*; -public class TestColorMapDemo -{ - private FrameFixture colorMapDemoFixture; - - @BeforeClass - public static void setUpOnce() - { - FailOnThreadViolationRepaintManager.install(); - } - - - @Before - public void onSetUp() - { - ColorMapDemo colorMapDemo = GuiActionRunner.execute(new GuiQuery<ColorMapDemo>() - { - @Override - protected ColorMapDemo executeInEDT() - { - return new ColorMapDemo(); - } - }); - - colorMapDemoFixture = new FrameFixture(colorMapDemo); - colorMapDemoFixture.show(); - } - - @After - public void tearDown() - { - colorMapDemoFixture.cleanUp(); - } - - @Test - public void testComponents() - { - colorMapDemoFixture.requireVisible(); - - //test the spinner - //spinners should take values of arbitrary granularity - colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("257"); - colorMapDemoFixture.spinner("iterationsSpinner").requireValue(257); - colorMapDemoFixture.spinner("learningRateSpinner").enterTextAndCommit("0.16492"); - colorMapDemoFixture.spinner("learningRateSpinner").requireValue(0.16492); - //lets try incrementing - colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("100"); - colorMapDemoFixture.spinner("iterationsSpinner").requireValue(100); - colorMapDemoFixture.spinner("iterationsSpinner").increment(9); - colorMapDemoFixture.spinner("iterationsSpinner").requireValue(1000); - colorMapDemoFixture.spinner("iterationsSpinner").increment(100); - colorMapDemoFixture.spinner("iterationsSpinner").requireValue(10000); - colorMapDemoFixture.spinner("learningRateSpinner").enterTextAndCommit("0.01"); - colorMapDemoFixture.spinner("learningRateSpinner").increment(9); - double currentValue = Double.valueOf(colorMapDemoFixture.spinner("learningRateSpinner").text()); - Assert.assertTrue("learning rate spinner did not increment properly", (currentValue - 0.1) < 0.00001); - colorMapDemoFixture.spinner("learningRateSpinner").increment(100); - currentValue = Double.valueOf(colorMapDemoFixture.spinner("learningRateSpinner").text()); - Assert.assertTrue("learning rate spinner did not increment properly", (currentValue - 1.0) < 0.001); - //lets try decrementing - colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("10000"); - colorMapDemoFixture.spinner("iterationsSpinner").requireValue(10000); - colorMapDemoFixture.spinner("iterationsSpinner").decrement(10); - colorMapDemoFixture.spinner("iterationsSpinner").requireValue(9000); - colorMapDemoFixture.spinner("iterationsSpinner").decrement(100); - colorMapDemoFixture.spinner("iterationsSpinner").requireValue(100); - colorMapDemoFixture.spinner("learningRateSpinner").enterTextAndCommit("1.0"); - colorMapDemoFixture.spinner("learningRateSpinner").decrement(10); - currentValue = Double.valueOf(colorMapDemoFixture.spinner("learningRateSpinner").text()); - Assert.assertTrue("learning rate spinner did not increment properly", (currentValue - 0.9) < 0.00001); - colorMapDemoFixture.spinner("learningRateSpinner").decrement(100); - currentValue = Double.valueOf(colorMapDemoFixture.spinner("learningRateSpinner").text()); - Assert.assertTrue("learning rate spinner did not increment properly", (currentValue - 0.01) < 0.00001); - } - - @Test(expected=UnexpectedException.class) - public void testIterationsMinimum() - { - colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("1000"); - colorMapDemoFixture.spinner("iterationsSpinner").requireValue(1000); - colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("0"); - } - - @Test(expected=UnexpectedException.class) - public void testIterationsMaximum() - { - colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("1000"); - colorMapDemoFixture.spinner("iterationsSpinner").requireValue(1000); - colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("100000"); - } - - @Test(expected=UnexpectedException.class) - public void testLearningRateMinimum() - { - colorMapDemoFixture.spinner("learningRateSpinner").enterTextAndCommit("0.5"); - colorMapDemoFixture.spinner("learningRateSpinner").requireValue(0.5); - colorMapDemoFixture.spinner("learningRateSpinner").enterTextAndCommit("0"); - } - - @Test(expected=UnexpectedException.class) - public void testLearningRateMaximum() - { - colorMapDemoFixture.spinner("learningRateSpinner").enterTextAndCommit("0.5"); - colorMapDemoFixture.spinner("learningRateSpinner").requireValue(0.5); - colorMapDemoFixture.spinner("learningRateSpinner").enterTextAndCommit("1.001"); - } - - @Test - public void testTrainingDisplay() - { - colorMapDemoFixture.requireVisible(); - - //train and display for various parameters - colorMapDemoFixture.button("trainDisplayButton").requireEnabled(); - - colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("10000"); - colorMapDemoFixture.button("trainDisplayButton").click(); - colorMapDemoFixture.button("trainDisplayButton").requireDisabled(); - colorMapDemoFixture.button("trainDisplayButton").requireEnabled(Timeout.timeout(30000)); - - colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("5000"); - colorMapDemoFixture.spinner("iterationsSpinner").requireValue(5000); - colorMapDemoFixture.button("trainDisplayButton").click(); - colorMapDemoFixture.button("trainDisplayButton").requireDisabled(); - colorMapDemoFixture.button("trainDisplayButton").requireEnabled(Timeout.timeout(30000)); - - colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("100"); - colorMapDemoFixture.spinner("iterationsSpinner").requireValue(100); - colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("5000"); - colorMapDemoFixture.spinner("learningRateSpinner").enterTextAndCommit("0.1"); - colorMapDemoFixture.spinner("learningRateSpinner").requireValue(0.1); - colorMapDemoFixture.comboBox("dimentionalityComboBox").selectItem("2D"); - colorMapDemoFixture.comboBox("dimentionalityComboBox").requireSelection(1); - colorMapDemoFixture.button("trainDisplayButton").click(); - colorMapDemoFixture.button("trainDisplayButton").requireDisabled(); - colorMapDemoFixture.button("trainDisplayButton").requireEnabled(Timeout.timeout(30000)); - - colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("250"); - colorMapDemoFixture.spinner("iterationsSpinner").requireValue(250); - colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("5000"); - colorMapDemoFixture.spinner("learningRateSpinner").enterTextAndCommit("1.0"); - colorMapDemoFixture.spinner("learningRateSpinner").requireValue(1.0); - colorMapDemoFixture.comboBox("dimentionalityComboBox").selectItem("1D"); - colorMapDemoFixture.comboBox("dimentionalityComboBox").requireSelection(0); - colorMapDemoFixture.button("trainDisplayButton").click(); - colorMapDemoFixture.button("trainDisplayButton").requireDisabled(); - colorMapDemoFixture.button("trainDisplayButton").requireEnabled(Timeout.timeout(30000)); - } +public class TestColorMapDemo { + private FrameFixture colorMapDemoFixture; + + @BeforeClass + public static void setUpOnce() { + FailOnThreadViolationRepaintManager.install(); + } + + + @Before + public void onSetUp() { + ColorMapDemo colorMapDemo = GuiActionRunner.execute(new GuiQuery<ColorMapDemo>() { + @Override + protected ColorMapDemo executeInEDT() { + return new ColorMapDemo(); + } + }); + + colorMapDemoFixture = new FrameFixture(colorMapDemo); + colorMapDemoFixture.show(); + } + + @After + public void tearDown() { + colorMapDemoFixture.cleanUp(); + } + + @Test + public void testComponents() { + colorMapDemoFixture.requireVisible(); + + //test the spinner + //spinners should take values of arbitrary granularity + colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("257"); + colorMapDemoFixture.spinner("iterationsSpinner").requireValue(257); + colorMapDemoFixture.spinner("learningRateSpinner").enterTextAndCommit("0.16492"); + colorMapDemoFixture.spinner("learningRateSpinner").requireValue(0.16492); + //lets try incrementing + colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("100"); + colorMapDemoFixture.spinner("iterationsSpinner").requireValue(100); + colorMapDemoFixture.spinner("iterationsSpinner").increment(9); + colorMapDemoFixture.spinner("iterationsSpinner").requireValue(1000); + colorMapDemoFixture.spinner("iterationsSpinner").increment(100); + colorMapDemoFixture.spinner("iterationsSpinner").requireValue(10000); + colorMapDemoFixture.spinner("learningRateSpinner").enterTextAndCommit("0.01"); + colorMapDemoFixture.spinner("learningRateSpinner").increment(9); + double currentValue = Double.valueOf(colorMapDemoFixture.spinner("learningRateSpinner").text()); + Assert.assertTrue("learning rate spinner did not increment properly", (currentValue - 0.1) < 0.00001); + colorMapDemoFixture.spinner("learningRateSpinner").increment(100); + currentValue = Double.valueOf(colorMapDemoFixture.spinner("learningRateSpinner").text()); + Assert.assertTrue("learning rate spinner did not increment properly", (currentValue - 1.0) < 0.001); + //lets try decrementing + colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("10000"); + colorMapDemoFixture.spinner("iterationsSpinner").requireValue(10000); + colorMapDemoFixture.spinner("iterationsSpinner").decrement(10); + colorMapDemoFixture.spinner("iterationsSpinner").requireValue(9000); + colorMapDemoFixture.spinner("iterationsSpinner").decrement(100); + colorMapDemoFixture.spinner("iterationsSpinner").requireValue(100); + colorMapDemoFixture.spinner("learningRateSpinner").enterTextAndCommit("1.0"); + colorMapDemoFixture.spinner("learningRateSpinner").decrement(10); + currentValue = Double.valueOf(colorMapDemoFixture.spinner("learningRateSpinner").text()); + Assert.assertTrue("learning rate spinner did not increment properly", (currentValue - 0.9) < 0.00001); + colorMapDemoFixture.spinner("learningRateSpinner").decrement(100); + currentValue = Double.valueOf(colorMapDemoFixture.spinner("learningRateSpinner").text()); + Assert.assertTrue("learning rate spinner did not increment properly", (currentValue - 0.01) < 0.00001); + } + + @Test(expected = UnexpectedException.class) + public void testIterationsMinimum() { + colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("1000"); + colorMapDemoFixture.spinner("iterationsSpinner").requireValue(1000); + colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("0"); + } + + @Test(expected = UnexpectedException.class) + public void testIterationsMaximum() { + colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("1000"); + colorMapDemoFixture.spinner("iterationsSpinner").requireValue(1000); + colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("100000"); + } + + @Test(expected = UnexpectedException.class) + public void testLearningRateMinimum() { + colorMapDemoFixture.spinner("learningRateSpinner").enterTextAndCommit("0.5"); + colorMapDemoFixture.spinner("learningRateSpinner").requireValue(0.5); + colorMapDemoFixture.spinner("learningRateSpinner").enterTextAndCommit("0"); + } + + @Test(expected = UnexpectedException.class) + public void testLearningRateMaximum() { + colorMapDemoFixture.spinner("learningRateSpinner").enterTextAndCommit("0.5"); + colorMapDemoFixture.spinner("learningRateSpinner").requireValue(0.5); + colorMapDemoFixture.spinner("learningRateSpinner").enterTextAndCommit("1.001"); + } + + @Test + public void testTrainingDisplay() { + colorMapDemoFixture.requireVisible(); + + //train and display for various parameters + colorMapDemoFixture.button("trainDisplayButton").requireEnabled(); + + colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("10000"); + colorMapDemoFixture.button("trainDisplayButton").click(); + colorMapDemoFixture.button("trainDisplayButton").requireDisabled(); + colorMapDemoFixture.button("trainDisplayButton").requireEnabled(Timeout.timeout(30000)); + + colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("5000"); + colorMapDemoFixture.spinner("iterationsSpinner").requireValue(5000); + colorMapDemoFixture.button("trainDisplayButton").click(); + colorMapDemoFixture.button("trainDisplayButton").requireDisabled(); + colorMapDemoFixture.button("trainDisplayButton").requireEnabled(Timeout.timeout(30000)); + + colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("100"); + colorMapDemoFixture.spinner("iterationsSpinner").requireValue(100); + colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("5000"); + colorMapDemoFixture.spinner("learningRateSpinner").enterTextAndCommit("0.1"); + colorMapDemoFixture.spinner("learningRateSpinner").requireValue(0.1); + colorMapDemoFixture.comboBox("dimentionalityComboBox").selectItem("2D"); + colorMapDemoFixture.comboBox("dimentionalityComboBox").requireSelection(1); + colorMapDemoFixture.button("trainDisplayButton").click(); + colorMapDemoFixture.button("trainDisplayButton").requireDisabled(); + colorMapDemoFixture.button("trainDisplayButton").requireEnabled(Timeout.timeout(30000)); + + colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("250"); + colorMapDemoFixture.spinner("iterationsSpinner").requireValue(250); + colorMapDemoFixture.spinner("iterationsSpinner").enterTextAndCommit("5000"); + colorMapDemoFixture.spinner("learningRateSpinner").enterTextAndCommit("1.0"); + colorMapDemoFixture.spinner("learningRateSpinner").requireValue(1.0); + colorMapDemoFixture.comboBox("dimentionalityComboBox").selectItem("1D"); + colorMapDemoFixture.comboBox("dimentionalityComboBox").requireSelection(0); + colorMapDemoFixture.button("trainDisplayButton").click(); + colorMapDemoFixture.button("trainDisplayButton").requireDisabled(); + colorMapDemoFixture.button("trainDisplayButton").requireEnabled(Timeout.timeout(30000)); + } } diff --git a/src/test/java/com/syncleus/dann/examples/fft/TestFftDemo.java b/src/test/java/com/syncleus/dann/examples/fft/TestFftDemo.java index 63c4e17c0c52ef55f95c2a7c548982772578f8b4..e04461e0fe07813e9afe9bfa31172a04e8c5ea79 100644 --- a/src/test/java/com/syncleus/dann/examples/fft/TestFftDemo.java +++ b/src/test/java/com/syncleus/dann/examples/fft/TestFftDemo.java @@ -18,60 +18,51 @@ ******************************************************************************/ package com.syncleus.dann.examples.fft; +import org.fest.swing.edt.*; import org.fest.swing.fixture.FrameFixture; -import org.fest.swing.edt.FailOnThreadViolationRepaintManager; -import org.fest.swing.edt.GuiQuery; -import org.fest.swing.edt.GuiActionRunner; import org.junit.*; -public class TestFftDemo -{ - private FrameFixture fftDemoFixture; +public class TestFftDemo { + private FrameFixture fftDemoFixture; - @BeforeClass - public static void setUpOnce() - { - FailOnThreadViolationRepaintManager.install(); - } + @BeforeClass + public static void setUpOnce() { + FailOnThreadViolationRepaintManager.install(); + } - @Before - public void onSetUp() - { - FftDemo fftDemo = GuiActionRunner.execute(new GuiQuery<FftDemo>() - { - @Override - protected FftDemo executeInEDT() - { - return new FftDemo(); - } - }); + @Before + public void onSetUp() { + FftDemo fftDemo = GuiActionRunner.execute(new GuiQuery<FftDemo>() { + @Override + protected FftDemo executeInEDT() { + return new FftDemo(); + } + }); - fftDemoFixture = new FrameFixture(fftDemo); - fftDemoFixture.show(); - } + fftDemoFixture = new FrameFixture(fftDemo); + fftDemoFixture.show(); + } - @After - public void tearDown() - { - fftDemoFixture.cleanUp(); - } + @After + public void tearDown() { + fftDemoFixture.cleanUp(); + } - @Test - public void testComponents() - { - fftDemoFixture.requireVisible(); + @Test + public void testComponents() { + fftDemoFixture.requireVisible(); - //start listening - fftDemoFixture.button("listenButton").click(); + //start listening + fftDemoFixture.button("listenButton").click(); - //check that its listening - fftDemoFixture.button("listenButton").requireText("Stop"); + //check that its listening + fftDemoFixture.button("listenButton").requireText("Stop"); - //stop listening - fftDemoFixture.button("listenButton").click(); + //stop listening + fftDemoFixture.button("listenButton").click(); - //check if stopped - fftDemoFixture.button("listenButton").requireText("Listen"); - } + //check if stopped + fftDemoFixture.button("listenButton").requireText("Listen"); + } } diff --git a/src/test/java/com/syncleus/dann/examples/nci/ui/TestAboutDialog.java b/src/test/java/com/syncleus/dann/examples/nci/ui/TestAboutDialog.java index 234eeb1f3054540ef783e579002c82364aa4ea2a..0596116b38e1adbb33528b68e395f7326ba6d2a8 100644 --- a/src/test/java/com/syncleus/dann/examples/nci/ui/TestAboutDialog.java +++ b/src/test/java/com/syncleus/dann/examples/nci/ui/TestAboutDialog.java @@ -18,51 +18,42 @@ ******************************************************************************/ package com.syncleus.dann.examples.nci.ui; +import org.fest.swing.edt.*; import org.fest.swing.fixture.DialogFixture; -import org.fest.swing.edt.FailOnThreadViolationRepaintManager; -import org.fest.swing.edt.GuiQuery; -import org.fest.swing.edt.GuiActionRunner; import org.junit.*; -public class TestAboutDialog -{ - private DialogFixture aboutFixture; +public class TestAboutDialog { + private DialogFixture aboutFixture; - @BeforeClass - public static void setUpOnce() - { - FailOnThreadViolationRepaintManager.install(); - } + @BeforeClass + public static void setUpOnce() { + FailOnThreadViolationRepaintManager.install(); + } - @Before - public void onSetUp() - { - AboutDialog aboutDialog = GuiActionRunner.execute(new GuiQuery<AboutDialog>() - { - @Override - protected AboutDialog executeInEDT() - { - return new AboutDialog(null, false); - } - }); + @Before + public void onSetUp() { + AboutDialog aboutDialog = GuiActionRunner.execute(new GuiQuery<AboutDialog>() { + @Override + protected AboutDialog executeInEDT() { + return new AboutDialog(null, false); + } + }); - aboutFixture = new DialogFixture(aboutDialog); - aboutFixture.show(); - } + aboutFixture = new DialogFixture(aboutDialog); + aboutFixture.show(); + } - @After - public void tearDown() - { - aboutFixture.cleanUp(); - } + @After + public void tearDown() { + aboutFixture.cleanUp(); + } - @Test - public void testDisplays() - { - aboutFixture.requireVisible(); - aboutFixture.button("ok button").click(); - aboutFixture.requireNotVisible(); - } + @Test + public void testDisplays() { + aboutFixture.requireVisible(); + aboutFixture.button("ok button").click(); + aboutFixture.requireNotVisible(); + } }