Compaction.java 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. package Algorithms.Animated.BK;
  2. import java.util.ArrayList;
  3. import Algorithms.Animated.AlgorithmStep;
  4. import Algorithms.Animated.BackwardAction;
  5. import Model.LayeredGraphNode;
  6. public class Compaction implements AlgorithmStep{
  7. private enum CompactionState
  8. {
  9. PLACE_BLOCKS,
  10. APPLY_SHIFT
  11. }
  12. private class StackFrame
  13. {
  14. public LayeredGraphNode v;
  15. public LayeredGraphNode u;
  16. public LayeredGraphNode w;
  17. }
  18. private CompactionState state;
  19. private LayeredGraphNode graph;
  20. private int vIndex;
  21. private ArrayList< StackFrame > stack;
  22. private ArrayList< BackwardAction > actions;
  23. public Compaction( LayeredGraphNode graph )
  24. {
  25. this.graph = graph;
  26. state = CompactionState.PLACE_BLOCKS;
  27. stack = new ArrayList<>();
  28. vIndex = 0;
  29. actions = new ArrayList<>();
  30. }
  31. @Override
  32. public StepStatus forwardStep() {
  33. int acSize = actions.size();
  34. if( state == CompactionState.PLACE_BLOCKS )
  35. {
  36. if( stack.size() == 0 )
  37. {
  38. ArrayList< LayeredGraphNode > nodes = graph.getContainedNodes();
  39. boolean found = false;
  40. int oldVIndex = vIndex;
  41. for( ; vIndex < nodes.size(); vIndex++ )
  42. {
  43. if( nodes.get( vIndex ).isXUndefined() && nodes.get( vIndex ) == nodes.get( vIndex ).getRoot() )
  44. {
  45. found = true;
  46. break;
  47. }
  48. }
  49. if( !found )
  50. {
  51. state = CompactionState.APPLY_SHIFT;
  52. vIndex = 0;
  53. actions.add( 0, ()-> {
  54. vIndex = oldVIndex;
  55. state = CompactionState.PLACE_BLOCKS;
  56. } );
  57. }
  58. else
  59. {
  60. StackFrame f = new StackFrame();
  61. f.v = nodes.get( vIndex );
  62. double oldX = f.v.getX();
  63. f.v.setX( 0, true );
  64. f.v.setSelected();
  65. f.w = f.v;
  66. stack.add( 0, f );
  67. actions.add( 0, ()-> {
  68. stack.get( 0 ).v.setX( oldX, false );
  69. stack.get( 0 ).v.setSelected();
  70. stack.remove( 0 );
  71. vIndex = oldVIndex;
  72. state = CompactionState.PLACE_BLOCKS;
  73. });
  74. }
  75. }
  76. else
  77. {
  78. StackFrame sf = stack.get( 0 );
  79. if( sf.u == null )
  80. {
  81. if( graph.getContainedLayers().get( sf.w.getLayer() ).indexOf( sf.w ) > 1 )
  82. {
  83. sf.u = graph.getContainedLayers().get( sf.w.getLayer() ).get( graph.getContainedLayers().get( sf.w.getLayer() ).indexOf( sf.w ) - 1 );
  84. if( sf.u.isXUndefined() )
  85. {
  86. StackFrame nsf = new StackFrame();
  87. nsf.v = sf.u;
  88. double oldX = nsf.v.getX();
  89. nsf.v.setX( 0, true );
  90. nsf.v.setSelected();
  91. nsf.w = nsf.v;
  92. stack.add( 0, nsf );
  93. actions.add( 0, ()-> {
  94. stack.get( 0 ).v.setX( oldX, false );
  95. stack.get( 0 ).v.setSelected();
  96. stack.remove( 0 );
  97. stack.get( 0 ).u = null;
  98. });
  99. }
  100. else
  101. {
  102. sf.u.setSelected();
  103. actions.add( 0, ()-> {
  104. stack.get( 0 ).u = null;
  105. });
  106. }
  107. }
  108. else
  109. {
  110. LayeredGraphNode oldW = sf.w;
  111. sf.v.setSelected();
  112. sf.w = sf.w.getAlignedTo();
  113. if( sf.w == sf.v )
  114. {
  115. stack.remove( 0 );
  116. actions.add( 0, ()-> {
  117. stack.add( 0, sf );
  118. sf.v.setSelected();
  119. sf.w = oldW;
  120. });
  121. }
  122. else
  123. {
  124. actions.add( 0, ()-> {
  125. sf.w = oldW;
  126. sf.v.setSelected();
  127. });
  128. }
  129. }
  130. }
  131. else
  132. {
  133. LayeredGraphNode oldSink = sf.v.getSink();
  134. if( sf.v.getSink() == sf.v )
  135. sf.v.setSink( sf.u.getSink() );
  136. LayeredGraphNode sinkOfU = sf.u.getSink();
  137. double oldShift = sinkOfU.getShift();
  138. double oldX = sf.v.getX();
  139. boolean oldDef = !sf.v.isXUndefined();
  140. sf.v.setSelected();
  141. if( sf.v.getSink() != sf.u.getSink() )
  142. sf.u.getSink().setShift( Math.min( sf.u.getSink().getShift(), sf.v.getX() - sf.u.getX() - 50 ) );
  143. else
  144. sf.v.setX( Math.max( sf.v.getX(), sf.u.getX() + 50 ), true );
  145. LayeredGraphNode oldW = sf.w;
  146. sf.w = sf.w.getAlignedTo();
  147. if( sf.w == sf.v )
  148. {
  149. stack.remove( 0 );
  150. actions.add( 0, ()-> {
  151. stack.add( 0, sf );
  152. stack.get( 0 ).v.setSink( oldSink );
  153. sinkOfU.setShift( oldShift );
  154. sf.v.setX( oldX, oldDef );
  155. sf.v.setSelected();
  156. sf.w = oldW;
  157. });
  158. }
  159. else
  160. {
  161. actions.add( 0, ()-> {
  162. stack.get( 0 ).v.setSink( oldSink );
  163. sinkOfU.setShift( oldShift );
  164. sf.v.setX( oldX, oldDef );
  165. sf.v.setSelected();
  166. sf.w = oldW;
  167. });
  168. }
  169. }
  170. }
  171. }
  172. else if( state == CompactionState.APPLY_SHIFT )
  173. {
  174. LayeredGraphNode v = graph.getContainedNodes().get( vIndex );
  175. double oldX = v.getX();
  176. boolean oldDef = !v.isXUndefined();
  177. v.setSelected();
  178. v.setX( v.getRoot().getX(), true );
  179. if( v == v.getRoot() && v.getSink().getShift() < Double.POSITIVE_INFINITY )
  180. v.setX( v.getX() + v.getSink().getShift(), true );
  181. actions.add( 0, ()-> {
  182. v.setX( oldX, oldDef );
  183. v.setSelected();
  184. vIndex--;
  185. } );
  186. vIndex++;
  187. if( vIndex >= graph.getContainedNodes().size() )
  188. return StepStatus.FINISHED;
  189. }
  190. if( actions.size() != acSize + 1 )
  191. System.out.println( "ERROR" );
  192. return StepStatus.UNFINISHED;
  193. }
  194. @Override
  195. public StepStatus backwardStep() {
  196. if( actions.size() == 0 )
  197. return StepStatus.FINISHED;
  198. actions.get( 0 ).reverse();
  199. actions.remove( 0 );
  200. return StepStatus.UNFINISHED;
  201. }
  202. }