00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <iostream>
00028 #include <stdio.h>
00029
00030 #include <assert.h>
00031
00032
00033 #include <stdint.h>
00034
00035
00036 #include <algorithm>
00037 #include <set>
00038 #include <vector>
00039
00040 using namespace std;
00041
00042
00043 #include "fsa.h"
00044
00045
00046
00047 #define USE_FSA_MEMORY 0
00048
00049
00050
00051
00052
00053
00054 template <class UserState> class AStarSearch
00055 {
00056
00057 public:
00058
00059 enum
00060 {
00061 SEARCH_STATE_NOT_INITIALISED,
00062 SEARCH_STATE_SEARCHING,
00063 SEARCH_STATE_SUCCEEDED,
00064 SEARCH_STATE_FAILED,
00065 SEARCH_STATE_OUT_OF_MEMORY,
00066 SEARCH_STATE_INVALID
00067 };
00068
00069
00070
00071
00072
00073 public:
00074
00075 class Node
00076 {
00077 public:
00078
00079 Node *parent;
00080 Node *child;
00081
00082 float g;
00083 float h;
00084 float f;
00085
00086 Node() :
00087 parent( 0 ),
00088 child( 0 ),
00089 g( 0.0f ),
00090 h( 0.0f ),
00091 f( 0.0f )
00092 {
00093 }
00094
00095 UserState m_UserState;
00096 };
00097
00098
00099
00100
00101
00102 class HeapCompare_f
00103 {
00104 public:
00105
00106 bool operator() ( const Node *x, const Node *y ) const
00107 {
00108 return x->f > y->f;
00109 }
00110 };
00111
00112
00113 public:
00114
00115
00116
00117 AStarSearch( int MaxNodes = 2000 ) :
00118 #if USE_FSA_MEMORY
00119 m_FixedSizeAllocator( MaxNodes ),
00120 #endif
00121 m_State( SEARCH_STATE_NOT_INITIALISED ),
00122 m_CurrentSolutionNode( NULL ),
00123 m_AllocateNodeCount(0),
00124 m_CancelRequest( false )
00125 {
00126 }
00127
00128
00129 void CancelSearch()
00130 {
00131 m_CancelRequest = true;
00132 }
00133
00134
00135 void SetStartAndGoalStates( UserState &Start, UserState &Goal )
00136 {
00137 m_CancelRequest = false;
00138
00139 m_Start = AllocateNode();
00140 m_Goal = AllocateNode();
00141
00142 assert((m_Start != NULL && m_Goal != NULL));
00143
00144 m_Start->m_UserState = Start;
00145 m_Goal->m_UserState = Goal;
00146
00147 m_State = SEARCH_STATE_SEARCHING;
00148
00149
00150
00151
00152 m_Start->g = 0;
00153 m_Start->h = m_Start->m_UserState.GoalDistanceEstimate( m_Goal->m_UserState );
00154 m_Start->f = m_Start->g + m_Start->h;
00155 m_Start->parent = 0;
00156
00157
00158
00159 m_OpenList.push_back( m_Start );
00160
00161
00162 push_heap( m_OpenList.begin(), m_OpenList.end(), HeapCompare_f() );
00163
00164
00165 m_Steps = 0;
00166 }
00167
00168
00169 unsigned int SearchStep()
00170 {
00171
00172 assert( (m_State > SEARCH_STATE_NOT_INITIALISED) &&
00173 (m_State < SEARCH_STATE_INVALID) );
00174
00175
00176 if( (m_State == SEARCH_STATE_SUCCEEDED) ||
00177 (m_State == SEARCH_STATE_FAILED)
00178 )
00179 {
00180 return m_State;
00181 }
00182
00183
00184
00185
00186 if( m_OpenList.empty() || m_CancelRequest )
00187 {
00188 FreeAllNodes();
00189 m_State = SEARCH_STATE_FAILED;
00190 return m_State;
00191 }
00192
00193
00194 m_Steps ++;
00195
00196
00197 Node *n = m_OpenList.front();
00198 pop_heap( m_OpenList.begin(), m_OpenList.end(), HeapCompare_f() );
00199 m_OpenList.pop_back();
00200
00201
00202 if( n->m_UserState.IsGoal( m_Goal->m_UserState ) )
00203 {
00204
00205
00206 m_Goal->parent = n->parent;
00207
00208
00209
00210 if( false == n->m_UserState.IsSameState( m_Start->m_UserState ) )
00211 {
00212 FreeNode( n );
00213
00214
00215 Node *nodeChild = m_Goal;
00216 Node *nodeParent = m_Goal->parent;
00217
00218 do
00219 {
00220 nodeParent->child = nodeChild;
00221
00222 nodeChild = nodeParent;
00223 nodeParent = nodeParent->parent;
00224
00225 }
00226 while( nodeChild != m_Start );
00227
00228 }
00229
00230
00231 FreeUnusedNodes();
00232
00233 m_State = SEARCH_STATE_SUCCEEDED;
00234
00235 return m_State;
00236 }
00237 else
00238 {
00239
00240
00241
00242
00243
00244 m_Successors.clear();
00245
00246
00247
00248 bool ret = n->m_UserState.GetSuccessors( this, n->parent ? &n->parent->m_UserState : NULL );
00249
00250 if( !ret )
00251 {
00252
00253 typename vector< Node * >::iterator successor;
00254
00255
00256 for( successor = m_Successors.begin(); successor != m_Successors.end(); successor ++ )
00257 {
00258 FreeNode( (*successor) );
00259 }
00260
00261 m_Successors.clear();
00262
00263
00264 FreeAllNodes();
00265
00266 m_State = SEARCH_STATE_OUT_OF_MEMORY;
00267 return m_State;
00268 }
00269
00270
00271 for( typename vector< Node * >::iterator successor = m_Successors.begin(); successor != m_Successors.end(); successor ++ )
00272 {
00273
00274
00275 float newg = n->g + n->m_UserState.GetCost( (*successor)->m_UserState );
00276
00277
00278
00279
00280
00281
00282
00283 typename vector< Node * >::iterator openlist_result;
00284
00285 for( openlist_result = m_OpenList.begin(); openlist_result != m_OpenList.end(); openlist_result ++ )
00286 {
00287 if( (*openlist_result)->m_UserState.IsSameState( (*successor)->m_UserState ) )
00288 {
00289 break;
00290 }
00291 }
00292
00293 if( openlist_result != m_OpenList.end() )
00294 {
00295
00296
00297
00298 if( (*openlist_result)->g <= newg )
00299 {
00300 FreeNode( (*successor) );
00301
00302
00303 continue;
00304 }
00305 }
00306
00307 typename vector< Node * >::iterator closedlist_result;
00308
00309 for( closedlist_result = m_ClosedList.begin(); closedlist_result != m_ClosedList.end(); closedlist_result ++ )
00310 {
00311 if( (*closedlist_result)->m_UserState.IsSameState( (*successor)->m_UserState ) )
00312 {
00313 break;
00314 }
00315 }
00316
00317 if( closedlist_result != m_ClosedList.end() )
00318 {
00319
00320
00321
00322 if( (*closedlist_result)->g <= newg )
00323 {
00324
00325 FreeNode( (*successor) );
00326
00327 continue;
00328 }
00329 }
00330
00331
00332
00333
00334 (*successor)->parent = n;
00335 (*successor)->g = newg;
00336 (*successor)->h = (*successor)->m_UserState.GoalDistanceEstimate( m_Goal->m_UserState );
00337 (*successor)->f = (*successor)->g + (*successor)->h;
00338
00339
00340
00341 if( closedlist_result != m_ClosedList.end() )
00342 {
00343
00344 FreeNode( (*closedlist_result) );
00345 m_ClosedList.erase( closedlist_result );
00346
00347
00348
00349
00350
00351
00352
00353 }
00354
00355
00356 if( openlist_result != m_OpenList.end() )
00357 {
00358
00359 FreeNode( (*openlist_result) );
00360 m_OpenList.erase( openlist_result );
00361
00362
00363
00364
00365
00366 make_heap( m_OpenList.begin(), m_OpenList.end(), HeapCompare_f() );
00367
00368 }
00369
00370
00371 m_OpenList.push_back( (*successor) );
00372
00373
00374 push_heap( m_OpenList.begin(), m_OpenList.end(), HeapCompare_f() );
00375
00376 }
00377
00378
00379
00380 m_ClosedList.push_back( n );
00381
00382 }
00383
00384 return m_State;
00385
00386 }
00387
00388
00389
00390 bool AddSuccessor( UserState &State )
00391 {
00392 Node *node = AllocateNode();
00393
00394 if( node )
00395 {
00396 node->m_UserState = State;
00397
00398 m_Successors.push_back( node );
00399
00400 return true;
00401 }
00402
00403 return false;
00404 }
00405
00406
00407
00408
00409 void FreeSolutionNodes()
00410 {
00411 Node *n = m_Start;
00412
00413 if( m_Start->child )
00414 {
00415 do
00416 {
00417 Node *del = n;
00418 n = n->child;
00419 FreeNode( del );
00420
00421 del = NULL;
00422
00423 } while( n != m_Goal );
00424
00425 FreeNode( n );
00426
00427 }
00428 else
00429 {
00430
00431
00432 FreeNode( m_Start );
00433 FreeNode( m_Goal );
00434 }
00435
00436 }
00437
00438
00439
00440
00441 UserState *GetSolutionStart()
00442 {
00443 m_CurrentSolutionNode = m_Start;
00444 if( m_Start )
00445 {
00446 return &m_Start->m_UserState;
00447 }
00448 else
00449 {
00450 return NULL;
00451 }
00452 }
00453
00454
00455 UserState *GetSolutionNext()
00456 {
00457 if( m_CurrentSolutionNode )
00458 {
00459 if( m_CurrentSolutionNode->child )
00460 {
00461
00462 Node *child = m_CurrentSolutionNode->child;
00463
00464 m_CurrentSolutionNode = m_CurrentSolutionNode->child;
00465
00466 return &child->m_UserState;
00467 }
00468 }
00469
00470 return NULL;
00471 }
00472
00473
00474 UserState *GetSolutionEnd()
00475 {
00476 m_CurrentSolutionNode = m_Goal;
00477 if( m_Goal )
00478 {
00479 return &m_Goal->m_UserState;
00480 }
00481 else
00482 {
00483 return NULL;
00484 }
00485 }
00486
00487
00488 UserState *GetSolutionPrev()
00489 {
00490 if( m_CurrentSolutionNode )
00491 {
00492 if( m_CurrentSolutionNode->parent )
00493 {
00494
00495 Node *parent = m_CurrentSolutionNode->parent;
00496
00497 m_CurrentSolutionNode = m_CurrentSolutionNode->parent;
00498
00499 return &parent->m_UserState;
00500 }
00501 }
00502
00503 return NULL;
00504 }
00505
00506
00507
00508
00509 UserState *GetOpenListStart()
00510 {
00511 float f,g,h;
00512 return GetOpenListStart( f,g,h );
00513 }
00514
00515 UserState *GetOpenListStart( float &f, float &g, float &h )
00516 {
00517 iterDbgOpen = m_OpenList.begin();
00518 if( iterDbgOpen != m_OpenList.end() )
00519 {
00520 f = (*iterDbgOpen)->f;
00521 g = (*iterDbgOpen)->g;
00522 h = (*iterDbgOpen)->h;
00523 return &(*iterDbgOpen)->m_UserState;
00524 }
00525
00526 return NULL;
00527 }
00528
00529 UserState *GetOpenListNext()
00530 {
00531 float f,g,h;
00532 return GetOpenListNext( f,g,h );
00533 }
00534
00535 UserState *GetOpenListNext( float &f, float &g, float &h )
00536 {
00537 iterDbgOpen++;
00538 if( iterDbgOpen != m_OpenList.end() )
00539 {
00540 f = (*iterDbgOpen)->f;
00541 g = (*iterDbgOpen)->g;
00542 h = (*iterDbgOpen)->h;
00543 return &(*iterDbgOpen)->m_UserState;
00544 }
00545
00546 return NULL;
00547 }
00548
00549 UserState *GetClosedListStart()
00550 {
00551 float f,g,h;
00552 return GetClosedListStart( f,g,h );
00553 }
00554
00555 UserState *GetClosedListStart( float &f, float &g, float &h )
00556 {
00557 iterDbgClosed = m_ClosedList.begin();
00558 if( iterDbgClosed != m_ClosedList.end() )
00559 {
00560 f = (*iterDbgClosed)->f;
00561 g = (*iterDbgClosed)->g;
00562 h = (*iterDbgClosed)->h;
00563
00564 return &(*iterDbgClosed)->m_UserState;
00565 }
00566
00567 return NULL;
00568 }
00569
00570 UserState *GetClosedListNext()
00571 {
00572 float f,g,h;
00573 return GetClosedListNext( f,g,h );
00574 }
00575
00576 UserState *GetClosedListNext( float &f, float &g, float &h )
00577 {
00578 iterDbgClosed++;
00579 if( iterDbgClosed != m_ClosedList.end() )
00580 {
00581 f = (*iterDbgClosed)->f;
00582 g = (*iterDbgClosed)->g;
00583 h = (*iterDbgClosed)->h;
00584
00585 return &(*iterDbgClosed)->m_UserState;
00586 }
00587
00588 return NULL;
00589 }
00590
00591
00592
00593 int GetStepCount() { return m_Steps; }
00594
00595 void EnsureMemoryFreed()
00596 {
00597 #if USE_FSA_MEMORY
00598 assert(m_AllocateNodeCount == 0);
00599 #endif
00600
00601 }
00602
00603 private:
00604
00605
00606
00607 void FreeAllNodes()
00608 {
00609
00610 typename vector< Node * >::iterator iterOpen = m_OpenList.begin();
00611
00612 while( iterOpen != m_OpenList.end() )
00613 {
00614 Node *n = (*iterOpen);
00615 FreeNode( n );
00616
00617 iterOpen ++;
00618 }
00619
00620 m_OpenList.clear();
00621
00622
00623 typename vector< Node * >::iterator iterClosed;
00624
00625 for( iterClosed = m_ClosedList.begin(); iterClosed != m_ClosedList.end(); iterClosed ++ )
00626 {
00627 Node *n = (*iterClosed);
00628 FreeNode( n );
00629 }
00630
00631 m_ClosedList.clear();
00632
00633
00634
00635 FreeNode(m_Goal);
00636 }
00637
00638
00639
00640
00641
00642 void FreeUnusedNodes()
00643 {
00644
00645 typename vector< Node * >::iterator iterOpen = m_OpenList.begin();
00646
00647 while( iterOpen != m_OpenList.end() )
00648 {
00649 Node *n = (*iterOpen);
00650
00651 if( !n->child )
00652 {
00653 FreeNode( n );
00654
00655 n = NULL;
00656 }
00657
00658 iterOpen ++;
00659 }
00660
00661 m_OpenList.clear();
00662
00663
00664 typename vector< Node * >::iterator iterClosed;
00665
00666 for( iterClosed = m_ClosedList.begin(); iterClosed != m_ClosedList.end(); iterClosed ++ )
00667 {
00668 Node *n = (*iterClosed);
00669
00670 if( !n->child )
00671 {
00672 FreeNode( n );
00673 n = NULL;
00674
00675 }
00676 }
00677
00678 m_ClosedList.clear();
00679
00680 }
00681
00682
00683 Node *AllocateNode()
00684 {
00685
00686 #if !USE_FSA_MEMORY
00687 Node *p = new Node;
00688 return p;
00689 #else
00690 Node *address = m_FixedSizeAllocator.alloc();
00691
00692 if( !address )
00693 {
00694 return NULL;
00695 }
00696 m_AllocateNodeCount ++;
00697 Node *p = new (address) Node;
00698 return p;
00699 #endif
00700 }
00701
00702 void FreeNode( Node *node )
00703 {
00704
00705 m_AllocateNodeCount --;
00706
00707 #if !USE_FSA_MEMORY
00708 delete node;
00709 #else
00710 m_FixedSizeAllocator.free( node );
00711 #endif
00712 }
00713
00714 private:
00715
00716
00717 vector< Node *> m_OpenList;
00718
00719
00720 vector< Node * > m_ClosedList;
00721
00722
00723
00724 vector< Node * > m_Successors;
00725
00726
00727 unsigned int m_State;
00728
00729
00730 int m_Steps;
00731
00732
00733 Node *m_Start;
00734 Node *m_Goal;
00735
00736 Node *m_CurrentSolutionNode;
00737
00738 #if USE_FSA_MEMORY
00739
00740 FixedSizeAllocator<Node> m_FixedSizeAllocator;
00741 #endif
00742
00743
00744
00745 typename vector< Node * >::iterator iterDbgOpen;
00746 typename vector< Node * >::iterator iterDbgClosed;
00747
00748
00749 int m_AllocateNodeCount;
00750
00751 bool m_CancelRequest;
00752
00753 };
00754
00755
00756
00757