簡體   English   中英

C ++ A-star實現—確定一個節點是否已經在未清項目的優先級隊列中

[英]C++ A-star implementation — determining whether a node is already in the priority queue of open items

A *尋路算法的一個步驟要求在打開的節點列表中搜索您當前正在與之交互的節點,如果該節點尚不存在,則將該節點添加到列表中,或者更新該節點的值和父節點(如果存在)但是權重比當前版本的節點高。

STL priority_queue結構不支持這些行為。 我應該如何執行該步驟?

由於此問題引起了很多關注,因此進行了更新

  • std :: priority_queue看起來可能是個不錯的選擇,但事實並非如此。

  • 自己實現A *可以極大地增強信心,但是在完成之后,您應該嘗試改用boost提供的方法。 當我問這個問題時,我對安裝它感到不安,但是安裝非常簡單,不會產生任何麻煩。 A *不是boost提供的唯一有用的功能。 (特別是,如果您不使用它們的字符串處理功能,您最終將自己編寫它的副本;我的經驗是……)

STL priority_queue不適合A *實現。 您需要支持increase操作的堆結構,以更改已插入項目的優先級。 使用Boost.Heap實現許多經典堆的實現。

編輯: Boost.Graph庫也具有A *搜索的實現

如果限於STL,則可以使用STL集並不斷擦除和重新插入元素(具有新的優先級)。

Set< pair<int,int> > s; // < priority,value >
s.insert( make_pair(0,5) );

// Decrease Key operation //
s.erase( s.find( make_pair(0,5) ) );
s.insert( make_pair(1,5) );

時間復雜度仍為O(log N),但大型集合可能會花費更多時間。

如果您真的想使用std :: priority_queue,這是我用於此的解決方案:

當您需要更新優先級隊列中已經存在的節點時,只需將狀態相同,新的成本值和父節點的新節點插入隊列中即可。 該節點的最新副本將首先從隊列中移出,並添加到您的訪問集中。 要處理較舊的重復項,請在處理之前對照訪問的集合檢查從隊列中移出的任何節點。 如果它在訪問集中,則已經看到了通過此節點的成本最低的路徑,因此只需忽略它並處理下一個節點。

您可以使用簡單的向量或數組來存儲元素,然后使用std::make_heapstd::push_heapstd::pop_heapstd::sort_heapstd::is_heapstd::is_heap_until進行管理。

這使您可以打破包含並在優先級隊列上實現自定義操作,而不必自己實現標准操作。

有三種可能的解決方案:

  1. 跟蹤當前打開的節點列表,而與優先級隊列無關。 嘗試以與關閉節點相同的方式創建節點列表。

  2. 創建節點地圖(按坐標)到開閉狀態。

  3. 安裝Boost庫,其中包括A *的模板實現(我認為在<graph> )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM