ошибка при увеличении ширины графа при первом поиске - PullRequest
1 голос
/ 09 февраля 2020

почему этот код

#include <vector>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/breadth_first_search.hpp>
int main() {
        // set up syntax
       using namespace boost;
       typedef adjacency_list<vecS, vecS, bidirectionalS> graph_t;
       typedef graph_traits<graph_t>::vertex_descriptor v_t;

       // create simple test graph
       graph_t g( 3 );
       add_edge( 0, 1, g );
       add_edge( 1, 2, g );
       add_edge( 2, 3, g );

       // construct predecessors
       std::vector< v_t > predecessors(3);

       // search
       breadth_first_search(
            g,
            0,
            boost::visitor(
                boost::make_bfs_visitor(
                    boost::record_predecessors(predecessors.begin(),
                                               boost::on_tree_edge{}))));
        // display results
        for( v_t v : predecessors )
            std::cout << v;

return 0
}

выдает ошибку компилятора

C:\Users\James\code\boost\boost_1_70_0\boost\graph\visitors.hpp||In instantiation of 'void boost::predecessor_recorder<PredecessorMap, Tag>::operator()(Edge, const Graph&) [with Edge = boost::detail::edge_desc_impl<boost::bidirectional_tag, long long unsigned int>; Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS>; PredecessorMap = __gnu_cxx::__normal_iterator<long long unsigned int*, std::vector<long long unsigned int> >; Tag = boost::on_tree_edge]':|
C:\Users\James\code\boost\boost_1_70_0\boost\graph\visitors.hpp|105|required from 'void boost::detail::invoke_dispatch(Visitor&, T, Graph&, mpl_::true_) [with Visitor = boost::predecessor_recorder<__gnu_cxx::__normal_iterator<long long unsigned int*, std::vector<long long unsigned int> >, boost::on_tree_edge>; T = boost::detail::edge_desc_impl<boost::bidirectional_tag, long long unsigned int>; Graph = const boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS>; mpl_::true_ = mpl_::bool_<true>]'|
C:\Users\James\code\boost\boost_1_70_0\boost\graph\visitors.hpp|126|required from 'void boost::invoke_visitors(Visitor&, T, Graph&, Tag) [with Visitor = boost::predecessor_recorder<__gnu_cxx::__normal_iterator<long long unsigned int*, std::vector<long long unsigned int> >, boost::on_tree_edge>; T = boost::detail::edge_desc_impl<boost::bidirectional_tag, long long unsigned int>; Graph = const boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS>; Tag = boost::on_tree_edge]'|
C:\Users\James\code\boost\boost_1_70_0\boost\graph\breadth_first_search.hpp|183|required from 'boost::graph::bfs_visitor_event_not_overridden boost::bfs_visitor<Visitors>::tree_edge(Edge, Graph&) [with Edge = boost::detail::edge_desc_impl<boost::bidirectional_tag, long long unsigned int>; Graph = const boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS>; Visitors = boost::predecessor_recorder<__gnu_cxx::__normal_iterator<long long unsigned int*, std::vector<long long unsigned int> >, boost::on_tree_edge>]'|
C:\Users\James\code\boost\boost_1_70_0\boost\graph\breadth_first_search.hpp|83|required from 'void boost::breadth_first_visit(const IncidenceGraph&, SourceIterator, SourceIterator, Buffer&, BFSVisitor, ColorMap) [with IncidenceGraph = boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS>; Buffer = boost::queue<long long unsigned int, std::deque<long long unsigned int, std::allocator<long long unsigned int> > >; BFSVisitor = boost::bfs_visitor<boost::predecessor_recorder<__gnu_cxx::__normal_iterator<long long unsigned int*, std::vector<long long unsigned int> >, boost|
C:\Users\James\code\boost\boost_1_70_0\boost\graph\breadth_first_search.hpp|124|required from 'void boost::breadth_first_search(const VertexListGraph&, SourceIterator, SourceIterator, Buffer&, BFSVisitor, ColorMap) [with VertexListGraph = boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS>; SourceIterator = long long unsigned int*; Buffer = boost::queue<long long unsigned int, std::deque<long long unsigned int, std::allocator<long long unsigned int> > >; BFSVisitor = boost::bfs_visitor<boost::predecessor_recorder<__gnu_cxx::__normal_iterator<long long unsigned int*,|
C:\Users\James\code\boost\boost_1_70_0\boost\graph\breadth_first_search.hpp|135|required from 'void boost::breadth_first_search(const VertexListGraph&, typename boost::graph_traits<Graph>::vertex_descriptor, Buffer&, BFSVisitor, ColorMap) [with VertexListGraph = boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS>; Buffer = boost::queue<long long unsigned int, std::deque<long long unsigned int, std::allocator<long long unsigned int> > >; BFSVisitor = boost::bfs_visitor<boost::predecessor_recorder<__gnu_cxx::__normal_iterator<long long unsigned int*, std::vector<long |
C:\Users\James\code\boost\boost_1_70_0\boost\graph\breadth_first_search.hpp|258|required from 'void boost::detail::bfs_helper(VertexListGraph&, typename boost::graph_traits<Graph>::vertex_descriptor, ColorMap, BFSVisitor, const boost::bgl_named_params<P, T, R>&, mpl_::false_) [with VertexListGraph = boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS>; ColorMap = boost::two_bit_color_map<boost::vec_adj_list_vertex_id_map<boost::no_property, long long unsigned int> >; BFSVisitor = boost::bfs_visitor<boost::predecessor_recorder<__gnu_cxx::__normal_iterator<long long un|
C:\Users\James\code\boost\boost_1_70_0\boost\graph\breadth_first_search.hpp|313|required from 'static void boost::detail::bfs_dispatch<boost::param_not_found>::apply(VertexListGraph&, typename boost::graph_traits<Graph>::vertex_descriptor, const boost::bgl_named_params<T, Tag, Base>&, boost::param_not_found) [with VertexListGraph = boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS>; P = boost::bfs_visitor<boost::predecessor_recorder<__gnu_cxx::__normal_iterator<long long unsigned int*, std::vector<long long unsigned int> >, boost::on_tree_edge> >; T = boost::graph_|
C:\Users\James\code\boost\boost_1_70_0\boost\graph\breadth_first_search.hpp|344|required from 'void boost::breadth_first_search(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::bidirectionalS>; P = boost::bfs_visitor<boost::predecessor_recorder<__gnu_cxx::__normal_iterator<long long unsigned int*, std::vector<long long unsigned int> >, boost::on_tree_edge> >; T = boost::graph_visitor_t; R = boost::no_property; typename boost::graph|
C:\Users\James\code\maze\src\cMaze.cpp|440|required from here|
C:\Users\James\code\boost\boost_1_70_0\boost\graph\visitors.hpp|140|error: no matching function for call to 'put(__gnu_cxx::__normal_iterator<long long unsigned int*, std::vector<long long unsigned int> >&, long long unsigned int, long long unsigned int)'|
C:\Users\James\code\boost\boost_1_70_0\boost\property_map\property_map.hpp|195|note: candidate: 'template<class K, class V> void boost::put(const boost::writable_property_map_archetype<K, V>&, const typename boost::writable_property_map_archetype<K, V>::key_type&, const typename boost::writable_property_map_archetype<K, V>::value_type&)'|
C:\Users\James\code\boost\boost_1_70_0\boost\property_map\property_map.hpp|195|note:   template argument deduction/substitution failed:|
C:\Users\James\code\boost\boost_1_70_0\boost\graph\visitors.hpp|140|note:   '__gnu_cxx::__normal_iterator<long long unsigned int*, std::vector<long long unsigned int> >' is not derived from 'const boost::writable_property_map_archetype<K, V>'|
C:\Users\James\code\boost\boost_1_70_0\boost\property_map\property_map.hpp|309|note: candidate: 'template<class PropertyMap, class Reference, class K, class V> void boost::put(const boost::put_get_helper<Reference, PropertyMap>&, K, const V&)'|
C:\Users\James\code\boost\boost_1_70_0\boost\property_map\property_map.hpp|309|note:   template argument deduction/substitution failed:|
C:\Users\James\code\boost\boost_1_70_0\boost\graph\visitors.hpp|140|note:   '__gnu_cxx::__normal_iterator<long long unsigned int*, std::vector<long long unsigned int> >' is not derived from 'const boost::put_get_helper<Reference, PropertyMap>'|
C:\Users\James\code\boost\boost_1_70_0\boost\graph\property_maps\null_property_map.hpp|32|note: candidate: 'template<class K, class V> void boost::put(boost::null_property_map<K, V>&, const K&, const V&)'|
C:\Users\James\code\boost\boost_1_70_0\boost\graph\property_maps\null_property_map.hpp|32|note:   template argument deduction/substitution failed:|
C:\Users\James\code\boost\boost_1_70_0\boost\graph\visitors.hpp|140|note:   '__gnu_cxx::__normal_iterator<long long unsigned int*, std::vector<long long unsigned int> >' is not derived from 'boost::null_property_map<K, V>'|
C:\Users\James\code\boost\boost_1_70_0\boost\graph\detail\adjacency_list.hpp|1765|note: candidate: 'template<class Config, class Base, class Property, class Key, class Value> void boost::put(Property, boost::adj_list_helper<Config, Base>&, const Key&, const Value&)'|
C:\Users\James\code\boost\boost_1_70_0\boost\graph\detail\adjacency_list.hpp|1765|note:   template argument deduction/substitution failed:|
C:\Users\James\code\boost\boost_1_70_0\boost\graph\visitors.hpp|140|note:   mismatched types 'boost::adj_list_helper<Config, Base>' and 'long long unsigned int'|
C:\Users\James\code\boost\boost_1_70_0\boost\property_map\property_map.hpp|126|note: candidate: 'template<class T, class V> void put(T*, std::ptrdiff_t, const V&)'|
C:\Users\James\code\boost\boost_1_70_0\boost\property_map\property_map.hpp|126|note:   template argument deduction/substitution failed:|
C:\Users\James\code\boost\boost_1_70_0\boost\graph\visitors.hpp|140|note:   mismatched types 'T*' and '__gnu_cxx::__normal_iterator<long long unsigned int*, std::vector<long long unsigned int> >'|
||=== Build failed: 1 error(s), 15 warning(s) (0 minute(s), 5 second(s)) ===|

Ответы [ 2 ]

2 голосов
/ 10 февраля 2020

Голый итератор не может рассматриваться как карта свойств. Если ваш итератор указывает на непрерывную память, необработанный указатель БУДЕТ в порядке, хотя и относительно небезопасен, поскольку не происходит проверка концепции или границ:

auto vis = boost::make_bfs_visitor(
    boost::record_predecessors(&*predecessors.begin(), boost::on_tree_edge{}));

breadth_first_search(g, 0, boost::visitor(vis));

Если у вас конечно, пользу predecessors.data(). Тем не менее, я бы сказал, предпочитаете безопасные опции ниже

Однако вы обычно предпочитаете использовать итератор-свойства-карты:

auto pmap = make_iterator_property_map(predecessors.begin(), get(boost::vertex_index, g));
auto vis = make_bfs_visitor(
    boost::record_predecessors(pmap, boost::on_tree_edge{}));

, который затем предлагает опцию границ -checking:

auto pmap = make_safe_iterator_property_map(
    predecessors.begin(),
    predecessors.size(),
    get(boost::vertex_index, g));
auto vis = make_bfs_visitor(
    boost::record_predecessors(pmap, boost::on_tree_edge{}));

Фиксированный код

Обратите внимание, что БЫЛА ошибка границ из-за того, что вершина 3 находится вне диапазона. Вот почему вам нужны проверенные итераторы.

Это также было исправлено ниже, путем увеличения аргумента конструктора И с использованием boost::num_vertices вместо последующего жесткого кодирования числа.

Live On Coliru

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/breadth_first_search.hpp>
#include <boost/core/demangle.hpp>
#include <vector>
#include <iostream>

int main() {
    // set up syntax
    using namespace boost;
    using graph_t = adjacency_list<vecS, vecS, bidirectionalS>;
    using v_t = graph_traits<graph_t>::vertex_descriptor;

    // create simple test graph
    graph_t g(4);
    add_edge(0, 1, g);
    add_edge(1, 2, g);
    add_edge(2, 3, g);

    // construct predecessors
    std::vector<v_t> predecessors(num_vertices(g));

    // search
    auto do_it = [&](auto pmap) {
        std::cout << "\nRunning with " << boost::core::demangle(typeid(pmap).name()) << "\n";
        auto vis = make_bfs_visitor(
            boost::record_predecessors(pmap, boost::on_tree_edge{}));

        breadth_first_search(g, 0, boost::visitor(vis));

        // display results
        for (v_t v : predecessors)
            std::cout << v << " ";
    };

    do_it(&*predecessors.begin());

    do_it(make_iterator_property_map(
        predecessors.begin(),
        get(boost::vertex_index, g)));

    do_it(make_safe_iterator_property_map(
        predecessors.begin(),
        predecessors.size(),
        get(boost::vertex_index, g)));
}

Печать

Running with unsigned long*
0 0 1 2 
Running with boost::iterator_property_map<__gnu_cxx::__normal_iterator<unsigned long*, std::vector<unsigned long, std::allocator<unsigned long> > >, boost::vec_adj_list_vertex_id_map<boost::no_property, unsigned long>, unsigned long, unsigned long&>
0 0 1 2 
Running with boost::safe_iterator_property_map<__gnu_cxx::__normal_iterator<unsigned long*, std::vector<unsigned long, std::allocator<unsigned long> > >, boost::vec_adj_list_vertex_id_map<boost::no_property, unsigned long>, unsigned long, unsigned long&>
0 0 1 2 
0 голосов
/ 10 февраля 2020

@ sehe wrote

Голый итератор не может рассматриваться как карта свойств. Если ваш итератор указывает на непрерывную память, необработанный указатель будет в порядке

Понятно! Проблема передавалась в predecessors.begin(), что должно сбивать с толку компилятор.

Это прекрасно работает:

breadth_first_search(
    g,
    start,
    boost::visitor(
        boost::make_bfs_visitor(
            boost::record_predecessors(
                predecessors.data(),
                boost::on_tree_edge{}))));
...