Advertisement
Guest User

StateProcessor.java

a guest
May 15th, 2021
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 11.19 KB | None | 0 0
  1. //  Sokoban state space explorer.
  2. //  Discussion: https://dxdy.ru/topic144781.html
  3.  
  4. import java.util.*;
  5.  
  6. public class StateProcessor {
  7.    
  8.     private MapHandler mapHandler;
  9.     private CellsAdjacency cellsAdjacency;
  10.    
  11.     private Queue     <State> stateQueue;
  12.     private SortedSet <State> forwardStateSet, backwardStateSet;
  13.     private ArrayList <State> uniqueForwardStates, uniqueBackwardStates;
  14.     private ArrayList <State> matchedForwardStates, matchedBackwardStates;
  15.    
  16.     private static String formatString;
  17.    
  18.     public StateProcessor (MapHandler mapHandler) {
  19.         this .mapHandler = mapHandler;
  20.         stateQueue = new ArrayDeque <> ();
  21.     }
  22.    
  23.     public void run (boolean flag) {
  24.         if (flag) {
  25.             cellsAdjacency = mapHandler .getCellsAdjacencySmart ();
  26.         } else {
  27.             cellsAdjacency = mapHandler .getCellsAdjacencySimple ();
  28.         }
  29.         State .init (cellsAdjacency);
  30.         processForward ();
  31.         processBackward ();
  32.         matchStates ();
  33.     }
  34.    
  35.     private void processForward () {
  36.         int k;
  37.         State state;
  38.         State [] states;
  39.        
  40.         stateQueue .clear ();
  41.         forwardStateSet = new TreeSet <> ();
  42.         state = new State (mapHandler .getPorterCell (), mapHandler .getBoxCells ());
  43.         forwardStateSet .add (state);
  44.         stateQueue      .add (state);
  45.        
  46.         while (!stateQueue .isEmpty ()) {
  47.             states = stateQueue .poll () .expandForth ();
  48.             for (k = 0; states .length > k; ++k) {
  49.                 state = states [k];
  50.                 if (forwardStateSet .add (state)) {
  51.                     stateQueue      .add (state);
  52.                     //MapHandler .displayState (state .stateCells ());
  53.                 }
  54.             }
  55.         }
  56.     }
  57.    
  58.     private void processBackward () {
  59.         int k, l, length, limit;
  60.         short cell;
  61.         short [] netrepValues, stateCells;
  62.         int   [] netrepIndices;
  63.         State state;
  64.         State [] states;
  65.        
  66.         netrepValues  = cellsAdjacency .getValues ();
  67.         netrepIndices = cellsAdjacency .getIndices ();
  68.         stateQueue .clear ();
  69.         backwardStateSet = new TreeSet <> ();
  70.         stateCells = mapHandler .getTargetCells ();
  71.         Arrays .sort (stateCells);
  72.         length = stateCells .length;
  73.        
  74.         for (k = 0; length > k; ++k) {
  75.             cell = stateCells [k];
  76.             limit = netrepIndices [cell + 1];
  77.             for (l = netrepIndices [cell] + 1; limit > l; l += 4) {
  78.                 cell = netrepValues [l];
  79.                 if (0 > Arrays .binarySearch (stateCells, cell)) {
  80.                     state = new State (cell, stateCells);
  81.                     if (backwardStateSet .add (state)) {
  82.                         stateQueue       .add (state);
  83.                         //MapHandler .displayState (newStateCells);
  84.                     }
  85.                 }
  86.             }
  87.         }
  88.        
  89.         while (!stateQueue .isEmpty ()) {
  90.             states = stateQueue .poll () .expandBack ();
  91.             for (k = 0; states .length > k; ++k) {
  92.                 state = states [k];
  93.                 if (backwardStateSet .add (state)) {
  94.                     stateQueue       .add (state);
  95.                     //MapHandler .displayState (state .stateCells ());
  96.                 }
  97.             }
  98.         }
  99.     }
  100.    
  101.     private void matchStates () {
  102.         Iterator <State> forwardStatesIterator, backwardStatesIterator;
  103.         State forwardState, backwardState;
  104.        
  105.         uniqueForwardStates    = new ArrayList <> ();
  106.         uniqueBackwardStates   = new ArrayList <> ();
  107.         matchedForwardStates   = new ArrayList <> ();
  108.         matchedBackwardStates  = new ArrayList <> ();
  109.         forwardStatesIterator  = forwardStateSet  .iterator ();
  110.         backwardStatesIterator = backwardStateSet .iterator ();
  111.         forwardState  = forwardStatesIterator  .next ();
  112.         backwardState = backwardStatesIterator .next ();
  113.        
  114.         while (forwardStatesIterator .hasNext () && backwardStatesIterator .hasNext ()) {
  115.             switch (forwardState .compareTo (backwardState)) {
  116.             case 0:
  117.                 matchedForwardStates  .add (forwardState);
  118.                 matchedBackwardStates .add (backwardState);
  119.                 forwardState  = forwardStatesIterator  .next ();
  120.                 backwardState = backwardStatesIterator .next ();
  121.                 break;
  122.             case -1:
  123.                 uniqueForwardStates   .add (forwardState);
  124.                 forwardState  = forwardStatesIterator  .next ();
  125.                 break;
  126.             case 1:
  127.                 uniqueBackwardStates  .add (backwardState);
  128.                 backwardState = backwardStatesIterator .next ();
  129.                 break;
  130.             }
  131.         }
  132.        
  133.         if (forwardStatesIterator .hasNext ()) {
  134.             while (forwardStatesIterator  .hasNext () && 0 != forwardState .compareTo (backwardState)) {
  135.                 uniqueForwardStates   .add (forwardState);
  136.                 forwardState  = forwardStatesIterator .next ();
  137.             }
  138.             if (forwardStatesIterator .hasNext ()) {
  139.                 matchedForwardStates  .add (forwardState);
  140.                 matchedBackwardStates .add (backwardState);
  141.                 while (forwardStatesIterator .hasNext ()) {
  142.                     uniqueForwardStates .add (forwardStatesIterator .next ());
  143.                 }
  144.             } else {
  145.                 uniqueForwardStates   .add (forwardState);
  146.                 uniqueBackwardStates  .add (backwardState);
  147.             }
  148.         } else {
  149.             while (backwardStatesIterator .hasNext () && 0 != forwardState .compareTo (backwardState)) {
  150.                 uniqueBackwardStates  .add (backwardState);
  151.                 backwardState = backwardStatesIterator .next ();
  152.             }
  153.             if (backwardStatesIterator .hasNext ()) {
  154.                 matchedForwardStates  .add (forwardState);
  155.                 matchedBackwardStates .add (backwardState);
  156.                 while (backwardStatesIterator .hasNext ()) {
  157.                     uniqueBackwardStates .add (backwardStatesIterator .next ());
  158.                 }
  159.             } else {
  160.                 uniqueForwardStates   .add (forwardState);
  161.                 uniqueBackwardStates  .add (backwardState);
  162.             }
  163.         }
  164.     }
  165.    
  166.     public void displayMapStats () {
  167.         int cellsCount, boxesCount, activeCellsCount;
  168.         long placementsCount, statesCount;
  169.         long placementsCount2, statesCount2;
  170.         String placementsString, statesString;
  171.         String placementsString2, statesString2;
  172.        
  173.         cellsCount = mapHandler .getCellsNumber ();
  174.         boxesCount = mapHandler .getBoxesNumber ();
  175.         placementsCount = nchoosek (cellsCount, boxesCount);
  176.         statesCount = placementsCount * (cellsCount - boxesCount);
  177.        
  178.         placementsString = formattedNumber (placementsCount);
  179.         statesString     = formattedNumber (statesCount);
  180.         formatString = String .format (
  181.                 "%%s   %%%ds   %%%ds",
  182.                 Integer .max (10, placementsString .length ()),
  183.                 Integer .max (6,  statesString     .length ()));
  184.        
  185.         activeCellsCount = mapHandler .getActiveCellsNumber ();
  186.         placementsCount2 = nchoosek (activeCellsCount, boxesCount);
  187.         statesCount2 = placementsCount2 * (cellsCount - boxesCount);
  188.         placementsString2 = formattedNumber (placementsCount2);
  189.         statesString2     = formattedNumber (statesCount2);
  190.        
  191.         System .out .println (String .format ("Cells:  %5d", cellsCount));
  192.         System .out .println (String .format ("Active: %5d", activeCellsCount));
  193.         System .out .println (String .format ("Boxes:  %5d", boxesCount));
  194.         System .out .println (String .format (formatString, "                ", "Placements", "States"));
  195.         System .out .println (String .format (formatString, "Theoretical:    ", placementsString, statesString));
  196.         System .out .println (String .format (formatString, "Reduced:        ", placementsString2, statesString2));
  197.     }
  198.    
  199.     public void displaySetStats () {
  200.         String placementsString, statesString;
  201.        
  202.         placementsString = formattedNumber (countPlacements (forwardStateSet));
  203.         statesString     = formattedNumber (forwardStateSet      .size ());
  204.         System .out .println (String .format (formatString, "Forward total:  ", placementsString, statesString));
  205.         placementsString = formattedNumber (countPlacements (uniqueForwardStates));
  206.         statesString     = formattedNumber (uniqueForwardStates  .size ());
  207.         System .out .println (String .format (formatString, "Forward dead:   ", placementsString, statesString));
  208.         placementsString = formattedNumber (countPlacements (matchedForwardStates));
  209.         statesString     = formattedNumber (matchedForwardStates .size ());
  210.         System .out .println (String .format (formatString, "Matched:        ", placementsString, statesString));
  211.         placementsString = formattedNumber (countPlacements (uniqueBackwardStates));
  212.         statesString     = formattedNumber (uniqueBackwardStates .size ());
  213.         System .out .println (String .format (formatString, "Backward dead:  ", placementsString, statesString));
  214.         placementsString = formattedNumber (countPlacements (backwardStateSet));
  215.         statesString     = formattedNumber (backwardStateSet     .size ());
  216.         System .out .println (String .format (formatString, "Backward total: ", placementsString, statesString));
  217.         System .out .println ();
  218.     }
  219.    
  220.     private static long nchoosek (int n, int k) {
  221.         long result = 1;
  222.         for (int l = 1; 0 < k; ++l, --k, --n) {
  223.             result *= n;
  224.             result /= l;
  225.         }
  226.         return result;
  227.     }
  228.    
  229.     private static String formattedNumber (long number) {
  230.         int k, l, length;
  231.         String numberString;
  232.         StringBuilder result;
  233.        
  234.         numberString = Long .toString (number);
  235.         length = numberString .length ();
  236.         k = 0;
  237.         l = length % 3;
  238.         if (0 == l) {
  239.             l = 3;
  240.         }
  241.         result = new StringBuilder ();
  242.        
  243.         while (true) {
  244.             result .append (numberString .substring (k, l));
  245.             k = l;
  246.             l += 3;
  247.             if (length == k) {
  248.                 break;
  249.             }
  250.             result .append (' ');
  251.         }
  252.        
  253.         return result .toString ();
  254.     }
  255.    
  256.     private static int countPlacements (Collection <State> statesCollection) {
  257.         int result;
  258.         Iterator <State> statesIterator;
  259.         State state, oldState;
  260.        
  261.         if (statesCollection .isEmpty ()) {
  262.             return 0;
  263.         }
  264.        
  265.         statesIterator = statesCollection .iterator ();
  266.         oldState = statesIterator .next ();
  267.         result = 1;
  268.        
  269.         while (statesIterator .hasNext ()) {
  270.             state = statesIterator .next ();
  271.             if (oldState .isSamePlacementAs (state)) {
  272.                 continue;
  273.             }
  274.             oldState = state;
  275.             ++result;
  276.         }
  277.        
  278.         return result;
  279.     }
  280. }
  281.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement