我想在带有黑名单边缘的图表上运行Dijkstra,即我想计算不使用这些链接的最短路径。 目前,我首先定义过滤器:
typedef std::pair<int, int> Edge;
typedef boost::adjacency_list<boost::listS, boost::vecS, boost::directedS, boost::no_property, boost::property<boost::edge_weight_t, int> > graph_t;
struct BlackListEdgeConstraint { 私人的: std :: set blackList; graph_t * g;
public:
BlackListEdgeConstraint():blackList(std::set<Edge>() ),g(NULL){};
BlackListEdgeConstraint(std::set<Edge>& list, graph_t* g_) : blackList(list), g(g_)
{
}
/**
* This is the "predicate function" used by boost::filtered_graph (
* see http://www.boost.org/doc/libs/1_64_0/libs/graph/doc/filtered_graph.html )
* It it returns true, the edge is included in the filtered graph, otherwise it is excluded.
*/
bool operator()(const boost::graph_traits<graph_t>::edge_descriptor& e) const
{
Edge edge(source(e,*g), target(e,*g) );
//Include the edge if it's not in the blacklist.
return blackList.find( edge ) == blackList.end();
}
};
然后我在may main(...)
function
... I fill the graph g ...
std::set<Edge> blacklist; blacklist.insert( Edge(0,1) );
BlackListEdgeConstraint filter(blacklist, &g);
boost::filtered_graph<graph_t, BlackListEdgeConstraint> filtered(g, filter);
... I run Dikjstra on the filtered graph ...
现在,我做了什么,但很奇怪。实际上,我首先在顶点0和1之间创建一个边。然后,在operator() (...)
内,我有一个edge_descriptor
而不是Edge
(如果我把Edge作为参数,编译器就会抱怨正如here所解释的那样,我猜boost
正在某处进行某种转换,原因我不知道。然后,我再次检索operator() (...)
内的顶点0和1,然后重建Edge
。您了解我正在进行长途旅行,如果仅operator()(..)
直接Edge
接受Ab5sS
,则可以轻松完成。
你认为我能以更优雅和有效的方式做同样的操作吗?