package Algorithms.Animated.BK; import java.awt.Color; import java.util.ArrayList; import Algorithms.Animated.AlgorithmStage; import Algorithms.Animated.BackwardAction; import Model.LayeredGraphEdge; import Model.LayeredGraphNode; /** * The stage of the BK node placement algorithm where the blocks are computed. * @author kolja * */ public class BlockCalc implements AlgorithmStage { private int layerIndex; private int nodeIndex; private int r; private LayeredGraphNode graph; private ArrayList< ArrayList< BKNodePlacement > > subgraphAlgs; private ArrayList< BackwardAction > backwards; int step; public BlockCalc( LayeredGraphNode graph ) { step = 0; this.graph = graph; layerIndex = 0; nodeIndex = 0; r = 0; subgraphAlgs = new ArrayList<>(); for( ArrayList l : graph.getContainedLayers() ) { ArrayList< BKNodePlacement > algs = new ArrayList<>(); for( int i = 0; i < l.size(); i++ ) algs.add( null ); subgraphAlgs.add( algs ); } backwards = new ArrayList<>(); } @Override public StageStatus forwardStep() { LayeredGraphNode current = graph.getContainedLayers().get( layerIndex ).get( nodeIndex ); current.setSelected(); if( current.getContainedNodes().size() > 0 ) { if( subgraphAlgs.get( layerIndex ).get( nodeIndex ) == null ) subgraphAlgs.get( layerIndex ).set( nodeIndex, new BKNodePlacement( null, current ) ); if( subgraphAlgs.get( layerIndex ).get( nodeIndex ).forwardStep() == StageStatus.UNFINISHED ) return StageStatus.UNFINISHED; } ArrayList< LayeredGraphEdge > incommingEdges = current.getIncomingEdges(); if( incommingEdges.size() == 0 ) { backwards.add( 0, () -> { System.out.println( "Performing Empty Backwards Step..." ); }); return calcNextState(); } int[] ms = {(incommingEdges.size() + 1) / 2, (int)( (incommingEdges.size() + 1) / 2.0 + 0.5 )}; boolean backwardsAdded = false; for( int m : ms ) { if( current.getAlignedTo() == current ) { LayeredGraphNode u = incommingEdges.get( m - 1 ).getSources().get( 0 ); ArrayList conflicts = incommingEdges.get( m - 1 ).calcConflictedEdges(); if( !incommingEdges.get( m - 1 ).isConflicted() && r < graph.getContainedLayers().get( layerIndex - 1 ).indexOf( u ) + 1 ) { System.out.println( "" ); ArrayList< Boolean > oldConflicts = new ArrayList<>(); for( LayeredGraphEdge e : conflicts ) { oldConflicts.add( e.isConflicted() ); e.setConflicted( true ); } LayeredGraphNode oldAlignU = u.getAlignedTo(); Color oldColorCurrent = current.getColor(); LayeredGraphNode oldRootCurrent = current.getRoot(); LayeredGraphNode oldAlignCurrent = current.getAlignedTo(); int oldR = r; u.setAlignTo( current ); current.setColor( u.getRoot().getColor() ); 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... (Step " + oldStep + ")" ); for( int i = 0; i < conflicts.size(); i++ ) conflicts.get( i ).setConflicted( oldConflicts.get( i ) ); u.setAlignTo( oldAlignU ); current.setColor( oldColorCurrent ); current.setRoot( oldRootCurrent ); current.setAlignTo( oldAlignCurrent ); r = oldR; }); backwardsAdded = true; } } } if( !backwardsAdded ) { backwards.add( 0, () -> { System.out.println( "Performing Empty Backwards Step..." ); }); } //current.update(); return calcNextState(); } private StageStatus calcNextState() { if( layerIndex >= graph.getContainedLayers().size() - 1 ) { if( nodeIndex >= graph.getContainedLayers().get( layerIndex ).size() -1 ) return StageStatus.FINISHED; } nodeIndex++; if( nodeIndex >= graph.getContainedLayers().get( layerIndex ).size() ) { layerIndex++; nodeIndex = 0; int oldR = r; r = 0; backwards.add(0, ()->{ this.r = oldR; }); } return StageStatus.UNFINISHED; } @Override public StageStatus backwardStep() { if( subgraphAlgs.get( layerIndex ).get( nodeIndex ) != null ) { if( subgraphAlgs.get( layerIndex ).get( nodeIndex ).backwardStep() == StageStatus.UNFINISHED ) { LayeredGraphNode current = graph.getContainedLayers().get( layerIndex ).get( nodeIndex ); current.setSelected(); //current.update(); return StageStatus.UNFINISHED; } } StageStatus status = calcBeforeState(); if( status == StageStatus.FINISHED ) return status; LayeredGraphNode current = graph.getContainedLayers().get( layerIndex ).get( nodeIndex ); current.setSelected(); //current.update(); if( !backwards.isEmpty() ) { backwards.get( 0 ).reverse(); backwards.remove( 0 ); } return status; } private StageStatus calcBeforeState() { if( layerIndex == 0 ) { if( nodeIndex == 0 ) return StageStatus.FINISHED; } nodeIndex--; if( nodeIndex < 0 ) { layerIndex--; backwards.get( 0 ).reverse(); backwards.remove( 0 ); nodeIndex = graph.getContainedLayers().get( layerIndex ).size() - 1; } return StageStatus.UNFINISHED; } }