[英]Boost directed graph: comparing edges of a vertex
簡要背景:我正在使用帶有鄰接列表的BGL有向圖來構建語義圖:
class SemanticGraph
{
public:
typedef std::shared_ptr< Node > Node_ptr;
typedef boost::adjacency_list< boost::vecS, boost::vecS, boost::directedS, Node_ptr > Graph;
typedef boost::graph_traits< Graph >::vertex_descriptor Vertex;
typedef boost::graph_traits< Graph >::edge_descriptor Edge;
我需要做的一件事是將一個較小的圖(一個子圖)處理到我的主圖中。
為此,需要復制節點指針;如果子頂點不存在,則將其從子圖中復制到主圖中;最重要的是,如果需要,將子圖中找到的每個頂點的邊復制到主圖中。尚未建立。
前兩個任務並不那么復雜。 但是,我無法終生,無法找到一種比較兩個優勢的方法:
void AddSubGraph( SemanticGraph subgraph )
{
typename boost::graph_traits<Graph>::vertex_iterator it, end;
Vertex vertex;
for ( auto node : subgraph._nodes )
{
if ( !findNode( node ) )
_nodes.push_back( node );
boost::tie( it, end ) = boost::vertices( _graph );
std::find_if( it, end, [&]( const Vertex vertex ){ return _graph[*it]->Hash() == node->Hash(); });
if ( it == end )
vertex = boost::add_vertex( node, _graph );
else
vertex = boost::vertex( *it, _graph );
boost::tie( it, end ) = boost::vertices( subgraph._graph );
std::find_if( it, end, [&]( const Vertex vertex ){ return subgraph._graph[*it]->Hash() == node->Hash(); });
auto subgraph_vertex = boost::vertex( *it, subgraph._graph );
typename boost::graph_traits<Graph>::out_edge_iterator a, z;
// Iterate subgraph's vertex out edges
for ( boost::tie ( a, z ) = boost::out_edges( subgraph_vertex, subgraph._graph );
a != z;
++a )
{
typename boost::graph_traits<Graph>::out_edge_iterator my_edge, edge_end;
boost::tie ( my_edge, edge_end ) = boost::out_edges( vertex, _graph );
// How can I see if the same edge as the one pointed by edge iterator a, exists in my vertex's edges?
std::find_if( my_edge, edge_end, [&]( const Edge edge ){ return edge == a; });
}
}
}
編譯器在^^上方的最后一個std :: find_if處發出警告:
‘const Edge {aka const boost::detail::edge_desc_impl<boost::directed_tag, long unsigned int>}’ is not derived from ‘const std::pair<_T1, _T2>’
提示我的lambda捕獲參數應該是一對(我猜是實際邊緣嗎?)。
因此,我的問題是: 如何找到頂點的外邊緣中是否存在相似的邊緣?
您聲明a
一個迭代器:
typename boost::graph_traits<Graph>::out_edge_iterator a, z;
將迭代器與邊緣進行比較沒有任何意義。
相反,請取消引用迭代器以獲取其“指向”的邊緣:
std::find_if(my_edge, edge_end,
[&](const Edge edge) { return edge == *a; });
這為我編譯: 在Coliru上實時觀看
std::find_if(it, end, [&](const Vertex vertex) { return _graph[*it]->Hash() == node->Hash(); });
Hash()
返回哈希,則不能使用它來標識節點。 相反,哈希表使用它來標識在其中對節點進行排序的存儲桶。 但是,要標識節點,您需要進行相等性測試 (不同的節點可以共享相同的哈希) Lambda通過值來接受論點。 這是低效的
典型的代碼會看到
vertex_iterator match = std::find_if(it, end, [&](Vertex const& vertex) { return _graph[*it] == node; });` if (end != match) { // yes `match` is a match }
#include <boost/graph/adjacency_list.hpp>
#include <memory>
struct Node
{
int id;
size_t Hash() const { return id; }
bool operator<(const Node& other) const { return id < other.id; }
bool operator==(const Node& other) const { return id==other.id; }
};
class SemanticGraph
{
public:
typedef std::shared_ptr< Node > Node_ptr;
typedef boost::adjacency_list< boost::vecS, boost::vecS, boost::directedS, Node_ptr > Graph;
typedef boost::graph_traits< Graph >::vertex_descriptor Vertex;
typedef boost::graph_traits< Graph >::edge_descriptor Edge;
std::vector<Node_ptr> _nodes;
Graph _graph;
bool findNode(Node_ptr const& n) const { return std::find(begin(_nodes), end(_nodes), n) != end(_nodes); }
void AddSubGraph(SemanticGraph subgraph)
{
typename boost::graph_traits<Graph>::vertex_iterator it, end;
Vertex vertex;
for(auto node : subgraph._nodes)
{
if(!findNode(node))
{
_nodes.push_back(node);
}
boost::tie(it, end) = boost::vertices(_graph);
std::find_if(it, end, [&](const Vertex vertex) { return _graph[*it]->Hash() == node->Hash(); });
if(it == end)
vertex = boost::add_vertex(node, _graph);
else
vertex = boost::vertex(*it, _graph);
boost::tie(it, end) = boost::vertices(subgraph._graph);
std::find_if(it, end, [&](const Vertex vertex) { return subgraph._graph[*it]->Hash() == node->Hash(); });
auto subgraph_vertex = boost::vertex(*it, subgraph._graph);
typename boost::graph_traits<Graph>::out_edge_iterator a, z;
// Iterate subgraph's vertex out edges
for(boost::tie(a, z) = boost::out_edges(subgraph_vertex, subgraph._graph);
a != z;
++a)
{
typename boost::graph_traits<Graph>::out_edge_iterator my_edge, edge_end;
boost::tie(my_edge, edge_end) = boost::out_edges(vertex, _graph);
// How can I see if the same edge as the one pointed by edge iterator a, exists in my vertex's edges?
std::find_if(my_edge, edge_end, [&](const Edge edge) { return edge == *a; });
}
}
}
};
int main()
{
SemanticGraph g;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.