Advertisement
Guest User

StateProcessor.java

a guest
May 17th, 2021
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 6.86 KB | None | 0 0
  1. //  Sokoban brute solver.
  2. //  2021, May, B@R5uk
  3. //  Discussion: https://dxdy.ru/topic144781.html
  4.  
  5. import java.util.*;
  6.  
  7. public class StateProcessor {
  8.    
  9.     private static final int MEMORY_RESERVE_PERCENT = 20;
  10.     private static final Runtime rt = Runtime .getRuntime ();
  11.    
  12.     private SortedMap <State, State> statesCollection;
  13.     private Queue     <State>        statesQueue;
  14.     State solutionRoot;
  15.    
  16.     public StateProcessor () {
  17.         statesCollection = new TreeMap <> ();
  18.         solutionRoot = null;
  19.     }
  20.    
  21.     public boolean run (MapHandler mapHandler, boolean priorityType, Random rng) {
  22.         int k, l, value, interCount;
  23.         short cell;
  24.         short [] cellsAdjValues, stateCells;
  25.         int   [] cellsAdjIndices;
  26.         State state, oldState, finalState;
  27.         State [] nextStates;
  28.         CellsAdjacency cellsAdjacency;
  29.         Comparator <State> stateComparator;
  30.         long startTime, nextTime, currentTime, memoryLimit;
  31.        
  32.         if (priorityType) {
  33.             stateComparator = new State .PushPriorityComparator ();
  34.         } else {
  35.             stateComparator = new State .MovePriorityComparator ();
  36.         }
  37.         statesQueue = new PriorityQueue <> (stateComparator);
  38.         cellsAdjacency = mapHandler .getCellsAdjacency ();
  39.         State .init (cellsAdjacency);
  40.         statesCollection .clear ();
  41.         statesQueue      .clear ();
  42.         solutionRoot = null;
  43.        
  44.         cellsAdjValues  = cellsAdjacency .getValues ();
  45.         cellsAdjIndices = cellsAdjacency .getIndices ();
  46.         finalState = new State (mapHandler .getPorterCell (), mapHandler .getBoxCells ());
  47.         stateCells = mapHandler .getTargetCells ();
  48.         Arrays .sort (stateCells);
  49.        
  50.         for (k = 0; stateCells .length > k; ++k) {
  51.             cell = stateCells [k];
  52.             value = cellsAdjIndices [cell + 1];
  53.             for (l = cellsAdjIndices [cell] + 1; value > l; l += 4) {
  54.                 cell = cellsAdjValues [l];
  55.                 if (0 > Arrays .binarySearch (stateCells, cell)) {
  56.                     state = new State (cell, stateCells);
  57.                     if (!statesCollection .containsKey (state)) {
  58.                         statesCollection .put (state, state);
  59.                         statesQueue      .add (state);
  60.                     }
  61.                 }
  62.             }
  63.         }
  64.        
  65.         interCount = 0;
  66.         startTime = System .currentTimeMillis ();
  67.         nextTime = startTime + 500;
  68.         memoryLimit = (long) ((1.0 - MEMORY_RESERVE_PERCENT / 100.0) * rt .maxMemory ());
  69.         while (!statesQueue .isEmpty ()) {
  70.             state = statesQueue .poll ();
  71.             if (state .isObsolete ()) {
  72.                 continue;
  73.             }
  74.             if (null != solutionRoot && 0 >= stateComparator .compare (solutionRoot, state)) {
  75.                 continue;
  76.             }
  77.             nextStates = state .expandBack ();
  78.             for (k = 0; nextStates .length > k; ++k) {
  79.                 state = nextStates [k];
  80.                 if (finalState .equals (state) && null == solutionRoot) {
  81.                     solutionRoot = state;
  82.                 }
  83.                 if (statesCollection .containsKey (state)) {
  84.                     oldState = statesCollection .get (state);
  85.                     value = stateComparator .compare (oldState, state);
  86.                     if (0 > value) {
  87.                         continue;
  88.                     }
  89.                     if (0 == value) {
  90.                         if (null == rng) {
  91.                             oldState .updatePathCountWith (state);
  92.                             continue;
  93.                         }
  94.                         state = oldState .selectRandomState (state, rng);
  95.                         if (oldState == state) {
  96.                             continue;
  97.                         }
  98.                     }
  99.                     statesCollection .remove (oldState);
  100.                     oldState .markObsolete ();
  101.                 }
  102.                 statesCollection .put (state, state);
  103.                 statesQueue      .add (state);
  104.             }
  105.             ++interCount;
  106.             if (0 != (interCount & 1023)) {
  107.                 continue;
  108.             }
  109.             currentTime = System .currentTimeMillis ();
  110.             if (nextTime > currentTime) {
  111.                 continue;
  112.             }
  113.             nextTime = currentTime + 500;
  114.             if (memoryLimit > rt .totalMemory () - rt .freeMemory ()) {
  115.                 continue;
  116.             }
  117.             solutionRoot = null;
  118.             return true;
  119.         }
  120.        
  121.         solutionRoot = statesCollection .get (finalState);
  122.         return false;
  123.     }
  124.    
  125.     public String getSolutionString () {
  126.         int move;
  127.         StringBuilder moveSequence;
  128.         State state, prevState;
  129.        
  130.         if (null == solutionRoot) {
  131.             return null;
  132.         }
  133.        
  134.         moveSequence = new StringBuilder ();
  135.         state = solutionRoot;
  136.         prevState = state .getPreviousState ();
  137.        
  138.         while (null != prevState) {
  139.             move = state .getMove ();
  140.             if (0 > move) {
  141.                 moveSequence .append (Character .toUpperCase (CellVector .rearMoveLetter (-move - 1)));
  142.             } else {
  143.                 moveSequence .append (CellVector .rearMoveLetter (move));
  144.             }
  145.             state = prevState;
  146.             prevState = state .getPreviousState ();
  147.         }
  148.        
  149.         return moveSequence .toString ();
  150.     }
  151.    
  152.     public void displaySolution () {
  153.         int k, l, m, length;
  154.         String moveSequence;
  155.        
  156.         if (null == solutionRoot) {
  157.             System .out .println ();
  158.             System .out .println ("No solution found.");
  159.             return;
  160.         }
  161.        
  162.         moveSequence = getSolutionString ();
  163.         length = moveSequence .length ();
  164.        
  165.         System .out .println ();
  166.         System .out .println (String .format ("Moves  number: %5d", solutionRoot .getMoveCount ()));
  167.         System .out .println (String .format ("Pushes number: %5d", solutionRoot .getPushCount ()));
  168.         System .out .println ();
  169.        
  170.         k = 0;
  171.         m = 0;
  172.         while (true) {
  173.             l = Integer .min (k + 5, length);
  174.             System .out .print (moveSequence .substring (k, l));
  175.             k += 5;
  176.             if (length <= k) {
  177.                 System .out .println ();
  178.                 break;
  179.             }
  180.             ++m;
  181.             if (6 == m) {
  182.                 System .out .println ();
  183.                 m = 0;
  184.             } else {
  185.                 System .out .print (" ");
  186.             }
  187.         }
  188.         System .out .println ();
  189.         System .out .println ("Total number of different solutions: " + (Long .MAX_VALUE == solutionRoot .getPathCount () ? "exceeded counter limit" : solutionRoot .getPathCount ()));
  190.     }
  191. }
  192.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement