[英]How do I cover all the edges of a graph with the minimum amount of nodes?
通過選擇最小數量的頂點來覆蓋圖中的所有邊是(最小)頂點覆蓋問題。 這是一個 NP完全問題,因此解決一般實例的最著名算法需要指數級的時間。 (就像所有的 NP 完全問題一樣,它也在 NP 中,但這在這里不是一個有用的描述,因為許多簡單的問題也是如此。)
然而,一些圖的子類可以更快地解決。 二分圖就是這樣的 class,而網格圖(或此類的子圖)是二分圖,所以你很幸運。 對於網格圖,坐標和為偶數的頂點(圖中的黑點)構成分區中的一個部分,坐標和為奇數的頂點構成另一個部分:注意同一部分內的頂點之間沒有邊. 可以通過首先找到最大基數二分匹配來找到最小頂點覆蓋,例如在 O(|E|*sqrt(|V|)) 時間內使用Hopcroft-Karp 算法,然后應用該算法。
該算法快速且易於實現。 它給出了一個很好但並不總是最優的答案。
PathFinder cams選項是該算法的 C++ 實現,使用 C++ 和 boost 圖形庫。
這個輸入
l 0 1 1
l 0 2 1
l 1 2 1
l 2 3 1
l 2 4 1
l 2 5 1
給
C++ 代碼:
// store indices of nodes that cover links
std::set< int > setCover;
// working copy on input graph
auto work = myGraph;
graph_traits<graph_t>::out_edge_iterator ei, ei_end;
// loop until all links are covered
while (num_edges(work))
{
// select first link in working graph
auto it = edges(work).first;
int u = source(*it, work);
int v = target(*it, work);
// add non leaf nodes on selected link to cover
if( out_degree( u, myGraph ) > 1 )
setCover.insert( u );
if( out_degree( v, myGraph ) > 1 )
setCover.insert( v );
// remove all links that can be seen from new cover nodes
for (boost::tie(ei, ei_end) = out_edges(u, work); ei != ei_end; ++ei)
{
remove_edge(*ei, work);
}
for (boost::tie(ei, ei_end) = out_edges(v, work); ei != ei_end; ++ei)
{
remove_edge(*ei, work);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.