在策略模式中使用带有自定义属性的 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 中为开发人员获取自定义属性值?

蔚蓝 B2C。使用 Azure 门户编辑自定义属性

Kubernetes HPA(带有自定义指标)扩展策略

如何使用自定义策略模式实现 jwt 令牌基础身份验证以在 .net 核心中进行授权?

角色分配策略中无法识别 aws 自定义属性