Selaa lähdekoodia

compaction fast fertig

Kolja Strohm 7 vuotta sitten
vanhempi
commit
e3aa7864f3

+ 1 - 1
src/Algorithms/Animated/BK/BKNodePlacement.java

@@ -32,7 +32,7 @@ public class BKNodePlacement extends AnnimatedAlgorithm {
 		layouts[ 1 ] = new Layout( Layout.LayoutType.TOP_BOTTOM_RIGHT, graph );
 		layouts[ 2 ] = new Layout( Layout.LayoutType.BOTTOM_TOP_LEFT, graph );
 		layouts[ 3 ] = new Layout( Layout.LayoutType.BOTTOM_TOP_RIGHT, graph );
-		combine = new Combine();
+		combine = new Combine( graph );
 	}
 
 	@Override

+ 15 - 9
src/Algorithms/Animated/BK/BlockCalc.java

@@ -4,7 +4,7 @@ import java.awt.Color;
 import java.util.ArrayList;
 
 import Algorithms.Animated.AlgorithmStep;
-import Algorithms.Animated.BackwordAction;
+import Algorithms.Animated.BackwardAction;
 import Model.LayeredGraphEdge;
 import Model.LayeredGraphNode;
 
@@ -15,10 +15,12 @@ public class BlockCalc implements AlgorithmStep {
 	private int r;
 	private LayeredGraphNode graph;
 	private ArrayList< ArrayList< BKNodePlacement > > subgraphAlgs;
-	private ArrayList< BackwordAction > backwards;
+	private ArrayList< BackwardAction > backwards;
+	int step;
 	
 	public BlockCalc( LayeredGraphNode graph )
 	{
+		step = 0;
 		this.graph = graph;
 		layerIndex = 0;
 		nodeIndex = 0;
@@ -49,7 +51,7 @@ public class BlockCalc implements AlgorithmStep {
 		ArrayList< LayeredGraphEdge > incommingEdges = current.getIncomingEdges();
 		if( incommingEdges.size() == 0 )
 		{
-			current.update();
+			//current.update();
 			backwards.add( 0, () -> {
 				System.out.println( "Performing Empty Backwards Step..." );
 			});
@@ -75,8 +77,9 @@ public class BlockCalc implements AlgorithmStep {
 		            current.setRoot( u.getRoot() );
 		            current.setAlignTo( current.getRoot() );
 		            r = graph.getContainedLayers().get( layerIndex - 1 ).indexOf( u );
+		            int oldStep = step++;
 		            backwards.add( 0, () -> {
-		                System.out.println( "Stepping Backwards..." );
+		                System.out.println( "Stepping Backwards... (Step " + oldStep + ")" );
 		                u.setAlignTo( oldAlignU );
 		                current.setColor( oldColorCurrent );
 		                current.setRoot( oldRootCurrent );
@@ -93,7 +96,7 @@ public class BlockCalc implements AlgorithmStep {
                 System.out.println( "Performing Empty Backwards Step..." );
     		});
 		}
-		current.update();
+		//current.update();
 		return calcNextState();
 	}
 	
@@ -126,7 +129,7 @@ public class BlockCalc implements AlgorithmStep {
 			{
 				LayeredGraphNode current = graph.getContainedLayers().get( layerIndex ).get( nodeIndex );
 				current.setSelected();
-				current.update();
+				//current.update();
 				return StepStatus.UNFINISHED;
 			}
 		}
@@ -135,9 +138,12 @@ public class BlockCalc implements AlgorithmStep {
 			return status;
 		LayeredGraphNode current = graph.getContainedLayers().get( layerIndex ).get( nodeIndex );
 		current.setSelected();
-		current.update();
-		backwards.get( 0 ).reverse();
-		backwards.remove( 0 );
+		//current.update();
+		if( !backwards.isEmpty() )
+		{
+			backwards.get( 0 ).reverse();
+			backwards.remove( 0 );
+		}
 		return status;
 	}
 	

+ 6 - 0
src/Algorithms/Animated/BK/Combine.java

@@ -1,9 +1,15 @@
 package Algorithms.Animated.BK;
 
 import Algorithms.Animated.AlgorithmStep;
+import Model.LayeredGraphNode;
 
 public class Combine implements AlgorithmStep {
 
+	public Combine( LayeredGraphNode graph )
+	{
+		
+	}
+	
 	@Override
 	public StepStatus forwardStep() {
 		// TODO Auto-generated method stub

+ 211 - 0
src/Algorithms/Animated/BK/Compaction.java

@@ -0,0 +1,211 @@
+package Algorithms.Animated.BK;
+
+import java.util.ArrayList;
+
+import Algorithms.Animated.AlgorithmStep;
+import Algorithms.Animated.BackwardAction;
+import Model.LayeredGraphNode;
+
+public class Compaction implements AlgorithmStep{
+
+	private enum CompactionState
+	{
+		PLACE_BLOCKS,
+		APPLY_SHIFT
+	}
+	
+	private class StackFrame
+	{
+		public LayeredGraphNode v;
+		public LayeredGraphNode u;
+		public LayeredGraphNode w;
+	}
+	
+	private CompactionState state;
+	private LayeredGraphNode graph;
+	private int vIndex;
+	
+	private ArrayList< StackFrame > stack;
+	private ArrayList< BackwardAction > actions;
+	
+	public Compaction( LayeredGraphNode graph )
+	{
+		this.graph = graph;
+		state = CompactionState.PLACE_BLOCKS;
+		stack = new ArrayList<>();
+		vIndex = 0;
+		actions = new ArrayList<>();
+	}
+	
+	
+	@Override
+	public StepStatus forwardStep() {
+		if( state == CompactionState.PLACE_BLOCKS )
+		{
+			if( stack.size() == 0 )
+			{
+				ArrayList< LayeredGraphNode > nodes = graph.getContainedNodes();
+				boolean found = false;
+				int oldVIndex = vIndex;
+				for( ; vIndex < nodes.size(); vIndex++ )
+				{
+					if( nodes.get( vIndex ).isXUndefined() && nodes.get( vIndex ) == nodes.get( vIndex ).getRoot() )
+					{
+						found = true;
+						break;
+					}
+				}
+				if( !found )
+				{
+					state = CompactionState.APPLY_SHIFT;
+					vIndex = 0;
+					actions.add( 0, ()-> {
+						vIndex = oldVIndex;
+						state = CompactionState.PLACE_BLOCKS;
+					} );
+				}
+				else
+				{
+					StackFrame f = new StackFrame();
+					f.v = nodes.get( vIndex );
+					double oldX = f.v.getX();
+					f.v.setX( 0, true );
+					f.v.setSelected();
+					f.w = f.v;
+					stack.add( 0, f );
+					actions.add( 0, ()-> {
+						stack.get( 0 ).v.setX( oldX, false );
+						stack.get( 0 ).v.setSelected();
+						stack.remove( 0 );
+						vIndex = oldVIndex;
+						state = CompactionState.PLACE_BLOCKS;
+					});
+				}
+			}
+			else
+			{
+				StackFrame sf = stack.get( 0 );
+				if( sf.u == null )
+				{
+					if( graph.getContainedLayers().get( sf.w.getLayer() ).indexOf( sf.w ) > 1 )
+					{
+						sf.u = graph.getContainedLayers().get( sf.w.getLayer() ).get( graph.getContainedLayers().get( sf.w.getLayer() ).indexOf( sf.w ) - 1 );
+						if( sf.u.isXUndefined() )
+						{
+							StackFrame nsf = new StackFrame();
+							nsf.v = sf.u;
+							double oldX = nsf.v.getX();
+							nsf.v.setX( 0, true );
+							nsf.v.setSelected();
+							nsf.w = nsf.v;
+							stack.add( 0, nsf );
+							actions.add( 0, ()-> {
+								stack.get( 0 ).v.setX( oldX, false );
+								stack.get( 0 ).v.setSelected();
+								stack.remove( 0 );
+								stack.get( 0 ).u = null;
+							});
+						}
+						else
+						{
+							sf.u.setSelected();
+							actions.add( 0, ()-> {
+								stack.get( 0 ).u = null;
+							});
+						}
+					}
+					else
+					{
+						LayeredGraphNode oldW = sf.w;
+						sf.v.setSelected();
+						sf.w = sf.w.getAlignedTo();
+						if( sf.w == sf.v )
+						{
+							stack.remove( 0 );
+							actions.add( 0, ()-> {
+								stack.add( 0, sf );
+								sf.v.setSelected();
+								sf.w = oldW;
+							});
+						}
+						else
+						{
+							actions.add( 0, ()-> {
+								sf.w = oldW;
+								sf.v.setSelected();
+							});
+						}
+					}	
+				}
+				else
+				{
+					LayeredGraphNode oldSink = sf.v.getSink();
+					if( sf.v.getSink() == sf.v )
+						sf.v.setSink( sf.u.getSink() );
+					LayeredGraphNode sinkOfU = sf.u.getSink();
+					double oldShift = sinkOfU.getShift();
+					double oldX = sf.v.getX();
+					boolean oldDef = !sf.v.isXUndefined();
+					sf.v.setSelected();
+					if( sf.v.getSink() != sf.u.getSink() )
+						sf.u.getSink().setShift( Math.min( sf.u.getSink().getShift(), sf.v.getX() - sf.u.getX() - 50 ) );
+					else
+						sf.v.setX( Math.max( sf.v.getX(), sf.u.getX() + 50 ), true );
+					LayeredGraphNode oldW = sf.w;
+					sf.w = sf.w.getAlignedTo();
+					if( sf.w == sf.v )
+					{
+						stack.remove( 0 );
+						actions.add( 0, ()-> {
+							stack.add( 0, sf );
+							stack.get( 0 ).v.setSink(  oldSink );
+							sinkOfU.setShift( oldShift );
+							sf.v.setX( oldX, oldDef );
+							sf.v.setSelected();
+							sf.w = oldW;
+						});
+					}
+					else
+					{
+						actions.add( 0, ()-> {
+							stack.get( 0 ).v.setSink(  oldSink );
+							sinkOfU.setShift( oldShift );
+							sf.v.setX( oldX, oldDef );
+							sf.v.setSelected();
+							sf.w = oldW;
+						});
+					}
+				}
+			}
+		}
+		else if( state == CompactionState.APPLY_SHIFT )
+		{
+			LayeredGraphNode v = graph.getContainedNodes().get( vIndex );
+			double oldX = v.getX();
+			boolean oldDef = !v.isXUndefined();
+			v.setSelected();
+			v.setX( v.getRoot().getX(), true );
+			if( v == v.getRoot() && v.getSink().getShift() < Double.POSITIVE_INFINITY )
+				v.setX( v.getX() + v.getSink().getShift(), true );
+			actions.add( 0, ()-> {
+				v.setX( oldX, oldDef );
+				v.setSelected();
+				vIndex--;
+			} );
+			vIndex++;
+			if( vIndex >= graph.getContainedNodes().size() )
+				return StepStatus.FINISHED;
+		}
+		return StepStatus.UNFINISHED;
+	}
+
+	@Override
+	public StepStatus backwardStep() {
+		if( actions.size() == 0 )
+			return StepStatus.FINISHED;
+		actions.get( 0 ).reverse();
+		actions.remove( 0 );
+		return StepStatus.UNFINISHED;
+	}
+
+}

+ 30 - 3
src/Algorithms/Animated/BK/Layout.java

@@ -12,24 +12,51 @@ public class Layout implements AlgorithmStep {
 		BOTTOM_TOP_RIGHT
 	}
 	
+	private enum LayoutState
+	{
+		BLOCK_CALCULATION,
+		COMPACTION
+	}
+	
 	private LayoutType typ;
-	BlockCalc bc;
+	private BlockCalc bc;
+	private Compaction cp;
+	private LayoutState status;
+	
 	
 	public Layout( LayoutType typ, LayeredGraphNode graph )
 	{
+		status = LayoutState.BLOCK_CALCULATION;
 		this.typ = typ;
 		bc = new BlockCalc( graph );
+		cp = new Compaction( graph );
 	}
 	
 	@Override
 	public StepStatus forwardStep() {
-		bc.forwardStep();
+		if( status == LayoutState.BLOCK_CALCULATION )
+		{
+			if( bc.forwardStep() == StepStatus.FINISHED )
+			{
+				status = LayoutState.COMPACTION;
+			}
+			return StepStatus.UNFINISHED;
+		}
+		if( status == LayoutState.COMPACTION )
+			return cp.forwardStep();
 		return StepStatus.UNFINISHED;
 	}
 
 	@Override
 	public StepStatus backwardStep() {
-		return bc.backwardStep();
+		if( status == LayoutState.BLOCK_CALCULATION )
+			return bc.backwardStep();
+		if( status == LayoutState.COMPACTION )
+		{
+			if( cp.backwardStep() == StepStatus.FINISHED )
+				status = LayoutState.BLOCK_CALCULATION;
+		}
+		return StepStatus.UNFINISHED;
 	}
 
 }

+ 1 - 1
src/Algorithms/Animated/BackwordAction.java → src/Algorithms/Animated/BackwardAction.java

@@ -1,6 +1,6 @@
 package Algorithms.Animated;
 
-public interface BackwordAction {
+public interface BackwardAction {
 
 	public void reverse();
 }

+ 1 - 1
src/Algorithms/InitializeNodePositions.java

@@ -39,7 +39,7 @@ public class InitializeNodePositions {
             }
             int curX = 0;
             for (LayeredGraphNode node : layer) { // Gehe alle Knoten durch
-                node.setX(curX + maxWidth / 2 - node.getWidth() / 2);
+                node.setX(curX + maxWidth / 2 - node.getWidth() / 2, false);
                 node.setY(curY + maxHeight / 2 - node.getHeight() / 2); // Position setzen
                 curX += maxWidth + 25;
             }

+ 6 - 6
src/Model/LayeredEdge.java

@@ -55,14 +55,14 @@ public class LayeredEdge implements LayeredGraphEdge {
     @Override
     public ArrayList<Point> getLinePoints()
     {
-        if( bindPoints.get( 0 ) == null && sources.size() > 0 )
-        {
+        //if( bindPoints.get( 0 ) == null && sources.size() > 0 )
+        //{
             setStartPoint( (int)sources.get( 0 ).getX() + (int)sources.get( 0 ).getWidth() / 2, (int)sources.get( 0 ).getY() + (int)sources.get( 0 ).getHeight() );
-        }
-        if( bindPoints.get( bindPoints.size() - 1 ) == null && targets.size() > 0 )
-        {
+        //}
+        //if( bindPoints.get( bindPoints.size() - 1 ) == null && targets.size() > 0 )
+        //{
             setEndPoint( (int)targets.get( 0 ).getX() + (int)targets.get( 0 ).getWidth() / 2, (int)targets.get( 0 ).getY() );
-        }
+        //}
         return bindPoints;
     }
     

+ 7 - 2
src/Model/LayeredGraphNode.java

@@ -22,7 +22,12 @@ public interface LayeredGraphNode {
      * @return
      */
     ElkNode getOriginalNode();
-    
+
+    public void setShift( double shift );
+    public double getShift();
+    public void setSink( LayeredGraphNode sink );
+    public LayeredGraphNode getSink();
+    public boolean isXUndefined();
     public void setAlignTo( LayeredGraphNode align );
     public LayeredGraphNode getAlignedTo();
     public void setRoot( LayeredGraphNode root );
@@ -74,7 +79,7 @@ public interface LayeredGraphNode {
      * Legt die X Koordinate des Knotens fest
      * @param x die X Koordinate in Pixeln
      */
-    void setX( double x );
+    void setX( double x, boolean def );
     /**
      * Legt die Y Koordinate des Knotens Fest
      * @param y die Y Koordinate in Pixeln

+ 56 - 8
src/Model/LayeredNode.java

@@ -32,9 +32,14 @@ public class LayeredNode implements LayeredGraphNode {
     String name;
     JPanel view;
     boolean selected;
+    boolean xUndef;
     
+    // Block Calculation
     LayeredGraphNode align;
     LayeredGraphNode root;
+    // Compaction
+    LayeredGraphNode sink;
+    double shift;
     
     // for subgraph in this node
     private ArrayList< LayeredGraphEdge > edges;
@@ -58,28 +63,66 @@ public class LayeredNode implements LayeredGraphNode {
         }
         align = this;
         root = this;
+        sink = this;
+        shift = Double.POSITIVE_INFINITY;
+        xUndef = true;
     }
     
+    @Override
+    public void setShift( double shift )
+    {
+    	this.shift = shift;
+    }
+    
+    @Override
+    public double getShift()
+    {
+    	return shift;
+    }
+
+    @Override
+    public void setSink( LayeredGraphNode sink )
+    {
+    	this.sink = sink;
+    }
+    
+    @Override
+    public LayeredGraphNode getSink()
+    {
+    	return sink;
+    }
+    
+    @Override
+    public boolean isXUndefined()
+    {
+    	return xUndef;
+    }
+
+    @Override
     public void setAlignTo( LayeredGraphNode align )
     {
         this.align = align;
     }
-    
+
+    @Override
     public LayeredGraphNode getAlignedTo()
     {
         return align;
     }
-    
+
+    @Override
     public void setRoot( LayeredGraphNode root )
     {
         this.root = root;
     }
-    
+
+    @Override
     public LayeredGraphNode getRoot()
     {
         return root;
     }
-    
+
+    @Override
     public void update()
     {
     	SwingUtilities.invokeLater(new Runnable() {
@@ -89,19 +132,23 @@ public class LayeredNode implements LayeredGraphNode {
 		    }
 		});
     }
-    
+
+    @Override
     public void setSelected()
     {
     	selected = true;
+    	update();
     }
-    
+
+    @Override
     public boolean isSelected()
     {
     	boolean tmp = selected;
     	selected = false;
     	return tmp;
     }
-    
+
+    @Override
     public void setView( JPanel v )
     {
     	view = v;
@@ -156,9 +203,10 @@ public class LayeredNode implements LayeredGraphNode {
     }
 
     @Override
-    public void setX(double x) {
+    public void setX(double x, boolean def) {
         if( original != null )
             original.setX( x );
+        xUndef = !def;
         this.x = x;
     }