将bgl dijsktra代码与策略模式中的自定义属性一起使用

时间:2017-04-05 03:22:11

标签: c++ design-patterns boost-graph

以下是我的代码:

---------------|
|   worker     |      ____________________
|  ---------   |<-----|                  |                 
|  | graph  |  |      |strategy interface|<----- concrete strategy
|  |--------|  |      --------------------
|--------------|

图表类是worker内部的嵌套类,带有一些boost图形代码,如'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 个答案:

答案 0 :(得分: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。我不知道为什么设计模式很重要。可能会有帮助,可能不会。