Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

FCSOptimizeSolvingAlgorithm.h

Go to the documentation of this file.
00001 #ifndef MMANN_FCS_OPTIMIZE_SOLVING_ALGORITHM_H
00002 #define MMANN_FCS_OPTIMIZE_SOLVING_ALGORITHM_H
00003 
00011 
00012 #include "FCSBFSSolvingAlgorithm.h"
00013 
00017 template <class SolvingAlgorithmType>
00018 class FCSOptimizeSolvingAlgorithm : public FCSBFSSolvingAlgorithm<SolvingAlgorithmType>
00019 {
00020 public:
00022     FCSOptimizeSolvingAlgorithm(SolvingAlgorithmType* SolvingAlgorithm);
00023 
00028     virtual ~FCSOptimizeSolvingAlgorithm();
00029 
00035     virtual FCSStateSolvingReturnCodes Solve(FCSStateWithLocations* StateWithLocations, int Depth);
00036 
00043     virtual FCSStateSolvingReturnCodes Resume(int Depth);
00044 
00045 protected:
00056     virtual inline bool CheckStateEnd(FCSStateWithLocations** NewStateWithLocations, FCSStateWithLocations* StateWithLocations, 
00057                                         FCSDerivedStatesList** DerivedStateList, FCSMoveStack** Move, FCSMove** TempMove, int depth, 
00058                                         FCSStateSolvingReturnCodes* ReturnCode);
00059 
00061     int m_SavedNumberOfStatePacks;
00062 
00064     AFCSStateWithLocationsMatrix** m_SavedStatePacks;
00065 };
00066 
00067 template <class SolvingAlgorithmType>
00068 FCSOptimizeSolvingAlgorithm<SolvingAlgorithmType>::FCSOptimizeSolvingAlgorithm(SolvingAlgorithmType* SolvingAlgorithm) : FCSBFSSolvingAlgorithm<SolvingAlgorithmType>()
00069 {
00070     IsOptimizeClass = true;
00071 
00072     // Initialize the BFS queue. We have one dummy element at the beginning
00073     // in order to make operations simpler.
00074     m_BFSQueue = new FCSStateWithLocationsLinkedList();
00075     m_BFSQueue->m_Next = new FCSStateWithLocationsLinkedList();
00076     m_BFSQueueLastItem = m_BFSQueue->m_Next;
00077     m_BFSQueueLastItem->m_Next = NULL;
00078 
00079     //copy over everything needed from other solving algorithm.
00080     m_StateType = SolvingAlgorithm->m_StateType;
00081     m_StatePacks = SolvingAlgorithm->m_StatePacks;
00082     m_SavedStatePacks = &SolvingAlgorithm->m_StatePacks;
00083     m_MaxNumberOfStatePacks = SolvingAlgorithm->m_MaxNumberOfStatePacks;
00084     m_SavedNumberOfStatePacks = m_NumberOfStatePacks = SolvingAlgorithm->m_NumberOfStatePacks;
00085     m_NumberOfStatesInLastPack = SolvingAlgorithm->m_NumberOfStatesInLastPack;
00086     m_StatePackLength = SolvingAlgorithm->m_StatePackLength;
00087 
00088     m_FinalState = SolvingAlgorithm->m_FinalState;
00089 
00090     m_NumberOfCheckedStates = SolvingAlgorithm->m_NumberOfCheckedStates;
00091     m_MaxDepth = SolvingAlgorithm->m_MaxDepth;
00092     m_MaxNumberOfCheckedStates = SolvingAlgorithm->m_MaxNumberOfCheckedStates;
00093 
00094     m_DebugDisplayInfo = SolvingAlgorithm->m_DebugDisplayInfo;
00095     m_TestsOrderNumber = SolvingAlgorithm->m_TestsOrderNumber;
00096     memcpy(m_TestsOrder, SolvingAlgorithm->m_TestsOrder, sizeof(int)*FCS_TESTS_NUM);
00097 
00098     m_StateStorage = SolvingAlgorithm->m_StateStorage;
00099     m_StackStorage = SolvingAlgorithm->m_StackStorage;
00100 
00101     m_NumberOfFreecells = SolvingAlgorithm->m_NumberOfFreecells;
00102     m_NumberOfStacks = SolvingAlgorithm->m_NumberOfStacks;
00103     m_NumberOfDecks = SolvingAlgorithm->m_NumberOfDecks;
00104 
00105     m_SequencesAreBuiltBy = SolvingAlgorithm->m_SequencesAreBuiltBy;
00106     m_IsUnlimitedSequenceMove = SolvingAlgorithm->m_IsUnlimitedSequenceMove;
00107     m_EmptyStacksFill = SolvingAlgorithm->m_EmptyStacksFill;
00108     m_OptimizeSolutionPath = SolvingAlgorithm->m_OptimizeSolutionPath;
00109 
00110     m_CompareFunction = SolvingAlgorithm->m_CompareFunction;
00111     m_MD5Hash = SolvingAlgorithm->m_MD5Hash;
00112     
00113     m_IndirectCompare = SolvingAlgorithm->m_IndirectCompare;
00114     m_IndirectHash = SolvingAlgorithm->m_IndirectHash;
00115 }
00116 
00117 template <class SolvingAlgorithmType>
00118 FCSOptimizeSolvingAlgorithm<SolvingAlgorithmType>::~FCSOptimizeSolvingAlgorithm()
00119 {
00120     for(int p=m_SavedNumberOfStatePacks; p<m_NumberOfStatePacks;p++)
00121         m_StatePacks->DeleteArray(p);
00122 
00123     (*m_SavedStatePacks) = m_StatePacks;
00124 }
00125 
00126 template <class SolvingAlgorithmType>
00127 bool FCSOptimizeSolvingAlgorithm<SolvingAlgorithmType>::CheckStateEnd(FCSStateWithLocations** NewStateWithLocations, FCSStateWithLocations* StateWithLocations, 
00128                                         FCSDerivedStatesList** DerivedStateList, FCSMoveStack** Move, FCSMove** TempMove, int depth, 
00129                                         FCSStateSolvingReturnCodes* ReturnCode)
00130 {
00131     FCSStateWithLocations* ExistingState;
00132     FCSStateSolvingReturnCodes Check;
00133 
00134 // The last move in a move stack should be FCS_MOVE_TYPE_CANONIZE
00135 // because it indicates that the order of the stacks and freecells
00136 // need to be recalculated 
00137 
00138     (*TempMove)->SetType(FCS_MOVE_TYPE_CANONIZE);
00139     (*Move)->Push(*TempMove);
00140 
00141     Check = CheckAndAddState(*NewStateWithLocations, &ExistingState, depth);
00142         
00143     if ((Check == FCS_STATE_BEGIN_SUSPEND_PROCESS) ||
00144         (Check == FCS_STATE_SUSPEND_PROCESS))
00145     {
00146         // This state is not going to be used, so
00147         // let's clean it.
00148         (*NewStateWithLocations)->CleanState();
00149         *ReturnCode = Check;
00150         return true;
00151     }
00152     else if (Check == FCS_STATE_ALREADY_EXISTS)
00153     {
00154         StatePackRelease();
00155 
00156         // Re-parent the existing state to this one.
00157         // What it means is that if the depth of the state if it
00158         // can be reached from this one is lower than what it
00159         // already have, then re-assign its parent to this state.
00160         if (ExistingState->m_Depth > StateWithLocations->m_Depth+1)
00161         {
00162             // Make a copy of "moves" because "moves will be destroyed
00163             FCSMoveStack* MovesCopy = (*Move)->Copy();
00164 
00165             // Destroy the old moves stack of the state, because we are going to
00166             // override it.
00167             delete [] ExistingState->m_MovesToParent;
00168             ExistingState->m_MovesToParent = MovesCopy;
00169             ExistingState->m_Parent = StateWithLocations;
00170             ExistingState->m_Depth = StateWithLocations->m_Depth + 1;
00171         }
00172 
00173         (*DerivedStateList)->AddState(ExistingState);
00174     }
00175     else
00176     {   
00177         // We duplicate the move stack so it won't be
00178         // destroyed twice as it exists in both the state
00179         // moves_to_parent member variable and in the derived
00180         // states list
00181         (*DerivedStateList)->AddState(*NewStateWithLocations);
00182 
00183         // moves is already used inside the states_list, so we
00184         // need to get a fresh one.
00185         (*Move) = CreateMoveStack();
00186     }
00187 
00188     return false;
00189 }
00190 
00191 template <class SolvingAlgorithmType>
00192 FCSStateSolvingReturnCodes FCSOptimizeSolvingAlgorithm<SolvingAlgorithmType>::Resume(int Depth)
00193 {
00194     return FCS_STATE_IS_NOT_SOLVEABLE;
00195 }
00196 
00197 template <class SolvingAlgorithmType>
00198 FCSStateSolvingReturnCodes FCSOptimizeSolvingAlgorithm<SolvingAlgorithmType>::Solve(FCSStateWithLocations* StateWithLocations, int Depth)
00199 {
00200 
00201     int NumberOfFreeStacks = 0,
00202         NumberOfFreecells = 0,
00203         DerivedIndex, a;
00204 
00205     FCSStateSolvingReturnCodes Check;
00206 
00207     FCSDerivedStatesList Derived;
00208 
00209     // Initialize the first element to indicate it is the first
00210     StateWithLocations->m_Parent = NULL;
00211     StateWithLocations->m_MovesToParent = NULL;
00212     StateWithLocations->m_Depth = 0;
00213   
00214     // Continue as long as there are states in the queue or priority queue.
00215     while (StateWithLocations != NULL)
00216     {
00217         if (!(StateWithLocations->m_Visited & FCS_VISITED_IN_SOLUTION_PATH))
00218         {
00219             goto NextState;
00220         }
00221 
00222         if (StateWithLocations->m_Visited & FCS_VISITED_IN_OPTIMIZED_PATH)
00223         {
00224             goto NextState;
00225         }
00226 
00227         // Count the freecells
00228         NumberOfFreecells = 0;
00229         for(a=0;a<m_NumberOfFreecells;a++)
00230         {
00231             if (StateWithLocations->GetFreecellCardNumber(a) == 0)
00232                 NumberOfFreecells++;
00233         }
00234 
00235         // Count the number of unoccupied stacks
00236         NumberOfFreeStacks = 0;
00237         for(a=0;a<m_NumberOfStacks;a++)
00238         {
00239             if (StateWithLocations->GetStackLength(a) == 0)
00240                 NumberOfFreeStacks++;
00241         }
00242 
00243         m_DebugDisplayInfo->Display(m_StateType, m_NumberOfCheckedStates, StateWithLocations->m_Depth, StateWithLocations,  
00244             ((StateWithLocations->m_Parent == NULL) ? 0 : StateWithLocations->m_Parent->m_VisitIterations), m_NumberOfStatesInCollection);
00245 
00246         if ((NumberOfFreeStacks == m_NumberOfStacks) && (NumberOfFreecells == m_NumberOfFreecells))
00247         {
00248             m_FinalState = StateWithLocations;
00249 
00250             // Free the memory that was allocated by derived.
00251             DeleteDerived(&Derived);
00252             return FCS_STATE_WAS_SOLVED;
00253         }
00254 
00255         // Increase the number of iterations by one . This
00256         // is meant to make sure we do not entered this state before which
00257         // will lead to a false iterations count.
00258         m_NumberOfCheckedStates++;
00259 
00260         // Do all the tests at one go, because that the way it should be
00261         //  done for BFS and A*
00262 
00263         Derived.m_NumberOfStates = 0;
00264         for(a=0 ; a < m_TestsOrderNumber; a++)
00265         {
00266             Check = RunTest(m_TestsOrder[a] & FCS_TEST_ORDER_NO_FLAGS_MASK, StateWithLocations, 
00267                             StateWithLocations->m_Depth, NumberOfFreeStacks,
00268                             NumberOfFreecells, &Derived);
00269 
00270             if ((Check == FCS_STATE_BEGIN_SUSPEND_PROCESS) ||
00271                 (Check == FCS_STATE_EXCEEDS_MAX_NUM_TIMES) ||
00272                 (Check == FCS_STATE_SUSPEND_PROCESS))
00273             {
00274                 // Save the current position in the scan
00275                 m_FirstStateToCheck = StateWithLocations;
00276 
00277                 DeleteDerived(&Derived);
00278                 return FCS_STATE_SUSPEND_PROCESS;
00279             }
00280         }    
00281 
00282         // Insert all the derived states into the PQ or Queue
00283         for(DerivedIndex = 0; DerivedIndex < Derived.m_NumberOfStates; DerivedIndex++)
00284             BFSEnqueueState(Derived.m_States[DerivedIndex]);              
00285 
00286         StateWithLocations->m_Visited |= FCS_VISITED_IN_OPTIMIZED_PATH;
00287         StateWithLocations->m_VisitIterations = m_NumberOfCheckedStates-1;
00288 
00289 NextState:
00290 
00291         // Extract the next item in the queue/priority queue.
00292         if (m_BFSQueue->m_Next != m_BFSQueueLastItem)
00293         {
00294             FCSStateWithLocationsLinkedList* SaveItem = m_BFSQueue->m_Next;
00295             StateWithLocations = SaveItem->m_State;
00296             m_BFSQueue->m_Next = m_BFSQueue->m_Next->m_Next;
00297             delete SaveItem;
00298         }
00299         else
00300         {
00301             StateWithLocations = NULL;
00302         }
00303     }
00304 
00305     // Free the memory that was allocated by derived.
00306     DeleteDerived(&Derived);
00307 
00308     return FCS_STATE_IS_NOT_SOLVEABLE;
00309 }
00310 #endif

Generated on Sat Nov 5 11:20:15 2005 for Cpp Freecell Solver by  doxygen 1.4.4