在策略模式中使用带有自定义属性的 bgl dijsktra 代码
Posted
技术标签:
【中文标题】在策略模式中使用带有自定义属性的 bgl dijsktra 代码【英文标题】:Use bgl dijsktra code with custom properties in strategy pattern 【发布时间】:2017-04-05 03:22:10 【问题描述】:这是我的代码的样子:
---------------|
| worker | ____________________
| --------- |<-----| |
| | graph | | |strategy interface|<----- concrete strategy
| |--------| | --------------------
|--------------|
Graph class 是 worker 内部的一个嵌套类,带有一些 boost-graph 代码,例如“type define”和“add_edge”。 策略接口只有一个接口'int DoRoute(int src, int dst)'。
那么,问题是,我如何在“DoRoute”中使用像 dijsktra 这样的 boost-graph 算法?
示例代码如下:
enum edge_mycost_t edge_mycost;
namespace boost
BOOST_INSTALL_PROPERTY(edge, mycost);
class woker
public :
class graph
public :
using EdgeProperties = boost::property<edge_mycost_t, int>;
using NameProperties = boost::property<boost::vertex_name_t, std::string>;
using Graph = boost::adjacency_list < boost::vecS, boost::vecS, boost::directedS, NameProperties, EdgeProperties, boost::no_property>;
graph()
//... add_edge etc...
work()
// create g_ etc...
graph g_;
strategy_interface* p_si_;
friend strategy_interface;
class strategy_interface
public :
stategy_interface(worker& w) : work_(w)
int DoRoute(int, int) = 0;
protected :
worker::graph get_graph()
return work_.g_;
private :
worker& work_;
class concrete_strategy : public strategy_interface
public :
concrete_strategy(worker& w) : strategy_interface(w)
int DoRoute(int s, int d) override
auto g = strategy_interface::get_graph();
using Graph_T = decltype(g);
std::vector<Vertex_D> pm(num_vertices(g));
std::vector<int> dm(num_vertices(g));
auto s_des = pm[s];
boost::dijkstra_shortest_paths(g, s_des,
predecessor_map(boost::make_iterator_property_map(pm.begin(), get(boost::vertex_index,
distance_map(boost::make_iterator_property_map(dm.begin(), get(boost::vertex_index, g)))
);
// can't compile
错误:
In file included from /usr/include/boost/graph/adjacency_list.hpp:246:0,
from ./ns3/common_header.h:27,
from ./ns3/dtn_package.h:14,
from ./ns3/ns3dtn-bit.h:20,
from ./ns3/ns3dtn-bit-helper.h:6,
from ../src/ns3dtn-bit/examples/ns3dtn-bit-your-example.cpp:7:
/usr/include/boost/graph/detail/adjacency_list.hpp: In instantiation of ‘struct boost::detail::adj_list_any_edge_pmap::bind_<boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::property<boost::vertex_name_t, std::__cxx11::basic_string<char> >, boost::property<edge_mycost_t, int>, boost::no_property>, boost::property<edge_mycost_t, int>, boost::edge_weight_t>’:
/usr/include/boost/graph/detail/adjacency_list.hpp:2728:12: required from ‘struct boost::detail::adj_list_choose_edge_pmap<boost::edge_weight_t, boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::property<boost::vertex_name_t, std::__cxx11::basic_string<char> >, boost::property<edge_mycost_t, int>, boost::no_property>, boost::property<edge_mycost_t, int> >’
/usr/include/boost/graph/detail/adjacency_list.hpp:2733:14: required from ‘struct boost::detail::adj_list_edge_property_selector::bind_<boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::property<boost::vertex_name_t, std::__cxx11::basic_string<char> >, boost::property<edge_mycost_t, int>, boost::no_property>, boost::property<edge_mycost_t, int>, boost::edge_weight_t>’
/usr/include/boost/graph/properties.hpp:192:12: required from ‘struct boost::detail::edge_property_map<boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::property<boost::vertex_name_t, std::__cxx11::basic_string<char> >, boost::property<edge_mycost_t, int>, boost::no_property>, boost::edge_weight_t>’
/usr/include/boost/graph/properties.hpp:212:10: required from ‘struct boost::property_map<boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::property<boost::vertex_name_t, std::__cxx11::basic_string<char> >, boost::property<edge_mycost_t, int>, boost::no_property>, boost::edge_weight_t, void>’
/usr/include/boost/mpl/eval_if.hpp:38:31: recursively required from ‘struct boost::mpl::eval_if<mpl_::bool_<true>, boost::detail::const_type_as_type<boost::property_map<boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::property<boost::vertex_name_t, std::__cxx11::basic_string<char> >, boost::property<edge_mycost_t, int>, boost::no_property>, boost::edge_weight_t, void> >, boost::property_map<boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::property<boost::vertex_name_t, std::__cxx11::basic_string<char> >, boost::property<edge_mycost_t, int>, boost::no_property>, boost::edge_weight_t, void> >’
/usr/include/boost/mpl/eval_if.hpp:38:31: required from ‘struct boost::mpl::eval_if<boost::is_same<boost::param_not_found, boost::param_not_found>, boost::mpl::eval_if<mpl_::bool_<true>, boost::detail::const_type_as_type<boost::property_map<boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::property<boost::vertex_name_t, std::__cxx11::basic_string<char> >, boost::property<edge_mycost_t, int>, boost::no_property>, boost::edge_weight_t, void> >, boost::property_map<boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::property<boost::vertex_name_t, std::__cxx11::basic_string<char> >, boost::property<edge_mycost_t, int>, boost::no_property>, boost::edge_weight_t, void> >, boost::mpl::identity<boost::param_not_found> >’
/usr/include/boost/graph/named_function_params.hpp:269:12: required from ‘struct boost::detail::choose_impl_result<mpl_::bool_<true>, boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::property<boost::vertex_name_t, std::__cxx11::basic_string<char> >, boost::property<edge_mycost_t, int>, boost::no_property>, boost::param_not_found, boost::edge_weight_t>’
/usr/include/boost/graph/named_function_params.hpp:305:3: required by substitution of ‘template<class Param, class Graph, class PropertyTag> typename boost::detail::choose_impl_result<mpl_::bool_<true>, Graph, Param, PropertyTag>::type boost::choose_const_pmap(const Param&, const Graph&, PropertyTag) [with Param = boost::param_not_found; Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::property<boost::vertex_name_t, std::__cxx11::basic_string<char> >, boost::property<edge_mycost_t, int>, boost::no_property>; PropertyTag = boost::edge_weight_t]’
/usr/include/boost/graph/dijkstra_shortest_paths.hpp:612:25: required from ‘void boost::dijkstra_shortest_paths(const VertexListGraph&, typename boost::graph_traits<Graph>::vertex_descriptor, const boost::bgl_named_params<T, Tag, Base>&) [with VertexListGraph = boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::property<boost::vertex_name_t, std::__cxx11::basic_string<char> >, boost::property<edge_mycost_t, int>, boost::no_property>; Param = boost::iterator_property_map<__gnu_cxx::__normal_iterator<int*, std::vector<int> >, boost::vec_adj_list_vertex_id_map<boost::property<boost::vertex_name_t, std::__cxx11::basic_string<char> >, long unsigned int>, int, int&>; Tag = boost::vertex_distance_t; Rest = boost::bgl_named_params<boost::iterator_property_map<__gnu_cxx::__normal_iterator<long unsigned int*, std::vector<long unsigned int> >, boost::vec_adj_list_vertex_id_map<boost::property<boost::vertex_name_t, std::__cxx11::basic_string<char> >, long unsigned int>, long unsigned int, long unsigned int&>, boost::vertex_predecessor_t, boost::no_property>; typename boost::graph_traits<Graph>::vertex_descriptor = long unsigned int]’
../src/ns3dtn-bit/examples/ns3dtn-bit-your-example.cpp:36:29: required from here
/usr/include/boost/graph/detail/adjacency_list.hpp:2696:29: error: forming reference to void
typedef value_type& reference;
^
/usr/include/boost/graph/detail/adjacency_list.hpp:2697:35: error: forming reference to void
typedef const value_type& const_reference;
^
/usr/include/boost/graph/detail/adjacency_list.hpp:2701:61: error: forming reference to void
typename Graph::vertex_descriptor,Property,Tag> type;
^
/usr/include/boost/graph/detail/adjacency_list.hpp:2704:68: error: forming reference to void
typename Graph::vertex_descriptor,const Property, Tag> const_type;
^
In file included from ./ns3/common_header.h:29:0,
from ./ns3/dtn_package.h:14,
from ./ns3/ns3dtn-bit.h:20,
from ./ns3/ns3dtn-bit-helper.h:6,
from ../src/ns3dtn-bit/examples/ns3dtn-bit-your-example.cpp:7:
/usr/include/boost/graph/dijkstra_shortest_paths.hpp: In instantiation of ‘void boost::dijkstra_shortest_paths(const VertexListGraph&, typename boost::graph_traits<Graph>::vertex_descriptor, const boost::bgl_named_params<T, Tag, Base>&) [with VertexListGraph = boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::property<boost::vertex_name_t, std::__cxx11::basic_string<char> >, boost::property<edge_mycost_t, int>, boost::no_property>; Param = boost::iterator_property_map<__gnu_cxx::__normal_iterator<int*, std::vector<int> >, boost::vec_adj_list_vertex_id_map<boost::property<boost::vertex_name_t, std::__cxx11::basic_string<char> >, long unsigned int>, int, int&>; Tag = boost::vertex_distance_t; Rest = boost::bgl_named_params<boost::iterator_property_map<__gnu_cxx::__normal_iterator<long unsigned int*, std::vector<long unsigned int> >, boost::vec_adj_list_vertex_id_map<boost::property<boost::vertex_name_t, std::__cxx11::basic_string<char> >, long unsigned int>, long unsigned int, long unsigned int&>, boost::vertex_predecessor_t, boost::no_property>; typename boost::graph_traits<Graph>::vertex_descriptor = long unsigned int]’:
../src/ns3dtn-bit/examples/ns3dtn-bit-your-example.cpp:36:29: required from here
/usr/include/boost/graph/dijkstra_shortest_paths.hpp:612:25: error: no matching function for call to ‘choose_const_pmap(const type&, const boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::property<boost::vertex_name_t, std::__cxx11::basic_string<char> >, boost::property<edge_mycost_t, int>, boost::no_property>&, boost::edge_weight_t)’
choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
^
In file included from /usr/include/boost/graph/dijkstra_shortest_paths.hpp:20:0,
from ./ns3/common_header.h:29,
from ./ns3/dtn_package.h:14,
from ./ns3/ns3dtn-bit.h:20,
from ./ns3/ns3dtn-bit-helper.h:6,
from ../src/ns3dtn-bit/examples/ns3dtn-bit-your-example.cpp:7:
/usr/include/boost/graph/named_function_params.hpp:305:3: note: candidate: template<class Param, class Graph, class PropertyTag> typename boost::detail::choose_impl_result<mpl_::bool_<true>, Graph, Param, PropertyTag>::type boost::choose_const_pmap(const Param&, const Graph&, PropertyTag)
choose_const_pmap(const Param& p, const Graph& g, PropertyTag tag)
^
/usr/include/boost/graph/named_function_params.hpp:305:3: note: substitution of deduced template arguments resulted in errors seen above
【问题讨论】:
我正在努力,每个建议都会有所帮助。 【参考方案1】:您可能更愿意使用捆绑属性,而不是使用“内部属性”。就像这样:
struct your_edge_properties
//...
graph
using EdgeProperties = your_edge_properties;
//...
int DoRoute(int s, int d)
//...
dijkstra_shortest_paths(g, s_des,
weight_map(get(&your_edge_properties::cost, g)).
distance_map(make_iterator_property_map(distances.begin(), get(vertex_index, g))));
// then process for your result
检查it。我不知道为什么设计模式很重要。可能有帮助,也可能没有。
【讨论】:
以上是关于在策略模式中使用带有自定义属性的 bgl dijsktra 代码的主要内容,如果未能解决你的问题,请参考以下文章
IAM 策略条件中的 cognito 用户池自定义属性与 Dynamodb 细粒度访问
在 Apigee 中,如何使用 AccessEntity 策略以及稍后在 Javascript 中为开发人员获取自定义属性值?