Initial opendaylight infrastructure commit!!
[controller.git] / third-party / net.sf.jung2 / src / main / java / edu / uci / ics / jung / algorithms / layout / ISOMLayout.java
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/ISOMLayout.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/ISOMLayout.java
new file mode 100644 (file)
index 0000000..bea8eda
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+* Copyright (c) 2003, the JUNG Project and the Regents of the University
+* of California
+* All rights reserved.
+*
+* This software is open-source under the BSD license; see either
+* "license.txt" or
+* http://jung.sourceforge.net/license.txt for a description.
+*/
+package edu.uci.ics.jung.algorithms.layout;
+
+import edu.uci.ics.jung.algorithms.layout.util.RandomLocationTransformer;
+import edu.uci.ics.jung.algorithms.util.IterativeContext;
+import edu.uci.ics.jung.graph.Graph;
+
+import org.apache.commons.collections15.Factory;
+import org.apache.commons.collections15.map.LazyMap;
+
+import java.awt.geom.Point2D;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Implements a self-organizing map layout algorithm, based on Meyer's
+ * self-organizing graph methods.
+ *
+ * @author Yan Biao Boey
+ */
+public class ISOMLayout<V, E> extends AbstractLayout<V,E> implements IterativeContext {
+
+       Map<V, ISOMVertexData> isomVertexData =
+               LazyMap.decorate(new HashMap<V, ISOMVertexData>(),
+                               new Factory<ISOMVertexData>() {
+                                       public ISOMVertexData create() {
+                                               return new ISOMVertexData();
+                                       }});
+
+       private int maxEpoch;
+       private int epoch;
+
+       private int radiusConstantTime;
+       private int radius;
+       private int minRadius;
+
+       private double adaption;
+       private double initialAdaption;
+       private double minAdaption;
+
+    protected GraphElementAccessor<V,E> elementAccessor =
+       new RadiusGraphElementAccessor<V,E>();
+
+       private double coolingFactor;
+
+       private List<V> queue = new ArrayList<V>();
+       private String status = null;
+
+       /**
+        * Returns the current number of epochs and execution status, as a string.
+        */
+       public String getStatus() {
+               return status;
+       }
+
+       /**
+        * Creates an <code>ISOMLayout</code> instance for the specified graph <code>g</code>.
+        * @param g
+        */
+       public ISOMLayout(Graph<V,E> g) {
+               super(g);
+       }
+
+       public void initialize() {
+
+               setInitializer(new RandomLocationTransformer<V>(getSize()));
+               maxEpoch = 2000;
+               epoch = 1;
+
+               radiusConstantTime = 100;
+               radius = 5;
+               minRadius = 1;
+
+               initialAdaption = 90.0D / 100.0D;
+               adaption = initialAdaption;
+               minAdaption = 0;
+
+               //factor = 0; //Will be set later on
+               coolingFactor = 2;
+
+               //temperature = 0.03;
+               //initialJumpRadius = 100;
+               //jumpRadius = initialJumpRadius;
+
+               //delay = 100;
+       }
+
+
+       /**
+       * Advances the current positions of the graph elements.
+       */
+       public void step() {
+               status = "epoch: " + epoch + "; ";
+               if (epoch < maxEpoch) {
+                       adjust();
+                       updateParameters();
+                       status += " status: running";
+
+               } else {
+                       status += "adaption: " + adaption + "; ";
+                       status += "status: done";
+//                     done = true;
+               }
+       }
+
+       private synchronized void adjust() {
+               //Generate random position in graph space
+               Point2D tempXYD = new Point2D.Double();
+
+               // creates a new XY data location
+        tempXYD.setLocation(10 + Math.random() * getSize().getWidth(),
+                10 + Math.random() * getSize().getHeight());
+
+               //Get closest vertex to random position
+               V winner = elementAccessor.getVertex(this, tempXYD.getX(), tempXYD.getY());
+
+               while(true) {
+                   try {
+                       for(V v : getGraph().getVertices()) {
+                           ISOMVertexData ivd = getISOMVertexData(v);
+                           ivd.distance = 0;
+                           ivd.visited = false;
+                       }
+                       break;
+                   } catch(ConcurrentModificationException cme) {}
+        }
+               adjustVertex(winner, tempXYD);
+       }
+
+       private synchronized void updateParameters() {
+               epoch++;
+               double factor = Math.exp(-1 * coolingFactor * (1.0 * epoch / maxEpoch));
+               adaption = Math.max(minAdaption, factor * initialAdaption);
+               //jumpRadius = (int) factor * jumpRadius;
+               //temperature = factor * temperature;
+               if ((radius > minRadius) && (epoch % radiusConstantTime == 0)) {
+                       radius--;
+               }
+       }
+
+       private synchronized void adjustVertex(V v, Point2D tempXYD) {
+               queue.clear();
+               ISOMVertexData ivd = getISOMVertexData(v);
+               ivd.distance = 0;
+               ivd.visited = true;
+               queue.add(v);
+               V current;
+
+               while (!queue.isEmpty()) {
+                       current = queue.remove(0);
+                       ISOMVertexData currData = getISOMVertexData(current);
+                       Point2D currXYData = transform(current);
+
+                       double dx = tempXYD.getX() - currXYData.getX();
+                       double dy = tempXYD.getY() - currXYData.getY();
+                       double factor = adaption / Math.pow(2, currData.distance);
+
+                       currXYData.setLocation(currXYData.getX()+(factor*dx), currXYData.getY()+(factor*dy));
+
+                       if (currData.distance < radius) {
+                           Collection<V> s = getGraph().getNeighbors(current);
+                           while(true) {
+                               try {
+                                       for(V child : s) {
+                                       ISOMVertexData childData = getISOMVertexData(child);
+                                       if (childData != null && !childData.visited) {
+                                           childData.visited = true;
+                                           childData.distance = currData.distance + 1;
+                                           queue.add(child);
+                                       }
+                                   }
+                                   break;
+                               } catch(ConcurrentModificationException cme) {}
+                           }
+                       }
+               }
+       }
+
+       protected ISOMVertexData getISOMVertexData(V v) {
+               return isomVertexData.get(v);
+       }
+
+       /**
+        * This one is an incremental visualization.
+        * @return <code>true</code> is the layout algorithm is incremental, <code>false</code> otherwise
+        */
+       public boolean isIncremental() {
+               return true;
+       }
+
+       /**
+        * Returns <code>true</code> if the vertex positions are no longer being
+        * updated.  Currently <code>ISOMLayout</code> stops updating vertex
+        * positions after a certain number of iterations have taken place.
+        * @return <code>true</code> if the vertex position updates have stopped,
+        * <code>false</code> otherwise
+        */
+       public boolean done() {
+               return epoch >= maxEpoch;
+       }
+
+       protected static class ISOMVertexData {
+               int distance;
+               boolean visited;
+
+               protected ISOMVertexData() {
+                   distance = 0;
+                   visited = false;
+               }
+       }
+
+       /**
+        * Resets the layout iteration count to 0, which allows the layout algorithm to
+        * continue updating vertex positions.
+        */
+       public void reset() {
+               epoch = 0;
+       }
+}
\ No newline at end of file