受約束的最短路徑中的曲線圖G=(V,E)
是,給定的源節點s
和宿節點t
問題,找到從s
到食用的t
使得總資源的最短路徑路徑最多是標量R
。圖中的每個弧線(i,j)
具有標量c_{ij}
的成本,並且將資源用於標量r_{ij}
的曲調。路徑的成本是構成路徑的各個弧的成本的總和,並且路徑消耗的資源是構成路徑的各個弧的資源的總和。這個問題已知爲NP-HARD
。高效的數據結構
解決此問題的大多數實現都使用動態編程方法,該方法基本上會執行某種強力枚舉以及其他聰明的方法來減少搜索量。
動態編程通過使用labelling approach來實現。
我已經實現了這個算法,使用了幾種不同的方法,我想確保如果我儘可能有效地做到這一點。
該標籤方法創建了多個標籤,這些標籤基本上是從s
到各個其他節點的部分路徑。在算法期間會創建大量標籤(請注意,問題是NP HARD
),直到滿足停止條件。
每個標籤可以表示爲struct
,如下所示。
struct labels_s {
double current_states[10];
double unscanned_states[10];
int already_visited[100];//If node i is already visited on partial path, already_visited[i] = 1, else 0
int do_not_visit[100];//if node i is not to be visited from this label, do_not_visit[i] = 1; 0 otherwise
struct labels_s* prev;
struct labels_s* next;
};
隨着算法的進行,需要創建和存儲上述許多結構。
方法1:
一個非常早期的實現我的這個是非常低效的計算。這涉及到需要新標籤時的結構,並使用struct
的成員next
和prev
明確地將這些結構保存在鏈接列表中。
方法2:
而不是new
荷蘭國際集團structs
,我開始進行存儲在std::vector
容器中的新結構:
vector <labels_s> labels;
要做到這一點,因爲vector
給出整數索引訪問到各種標籤,prev
和next
的struct labels_s
可改爲int prev;
和int next;
存儲一個標籤涉及以下內容:
struct labels_s newlabel;//Step 1
//populate newlabel's members//Step 2
labels.push_back(newlabel);//Step 3
使用方法2是顯著優於方法1同樣的問題計算次。標籤只添加在矢量的末尾。不需要插入矢量的中間或從矢量中刪除。
除方法2之外還有其他管理這些標籤的方法嗎?
我主要關注的是方法2的步驟3。由於push_back()
創建了newlabel
的副本,此複製操作代價高昂,可以避免這種情況嗎?
我正在考慮的一種替代方法是維護一個指向標籤結構的指針向量,而不是像當前那樣使用標籤結構向量。但是在我看來,維護指向標籤結構的向量應該不如方法1更高效。
任何輸入表示讚賞。
您的「約束最短路徑」聽起來像「首先,對於每個頂點權重,執行:if(weight> max)then weight = max。然後,進行正常的最短路徑搜索」。 ...鑑於此,這可能有助於尋找正常最短路徑問題的解決方案。儘管目前我並沒有掌握Dijkstra的所有細節,但我相當確信動態縮小/增長的矢量是不必要的。 – deviantfan
通常,A *只存儲一個指向前一個節點的指針。 – o11c
由於(全局)開集和閉集,您不必擔心循環,並且您只能從最短節點前進。 – o11c