Копирование из grid_graph в adjacency_list с помощью boost :: copy_graph

Я использую библиотеку графов ускорений и пытаюсь инициализировать MutableGraph , чтобы начать жизнь в виде сетки. Ребра будут добавляться и удаляться позже, поэтому я думаю, что adjacency_list - правильный выбор.

Мои чтения о BGL показали, что разумным способом инициализировать его с помощью этих ребер было бы воспользоваться преимуществом boost :: grid_graph с помощью boost :: copy_graph для копирования из boost :: grid_graph , который может сделать все начальные ребра для меня бесплатно. Я подумал, что это имеет смысл - copy_graph копирует модель VertexListGraph в модель MutableGraph , что у меня есть.

Сначала я пробовал использовать версию copy_graph с двумя аргументами, имея смутную надежду, что что-то разумное произойдет со значениями по умолчанию для остальных. Оказалось, что это не так, grid_graph (по причинам, которые я не мог понять), похоже, не имеет возможности использовать PropertyMap s ни с ребрами, ни с вершинами , поэтому по умолчанию vertex_copy и edge_copy не удалось (с ошибкой компилятора) скопировать свойства.

Поскольку версия с двумя аргументами явно не казалась подходящей, я двинулся дальше и попытался реализовать свой собственный бинарный оператор для копирования вершин и ребер. Даже с «безоперационной» копией это работает не так хорошо, как я бы надеялся (то есть не компилируется).

Я собрал минимальный рабочий пример, который иллюстрирует проблему:

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/grid_graph.hpp>
#include <boost/graph/copy.hpp>

struct Position {
  int x, y;
};

struct VertexProperties {
  Position pos;
};

typedef boost::adjacency_list<boost::vecS, boost::listS, boost::undirectedS, 
                      VertexProperties> Graph;

struct MyCopy {
  template <typename S, typename D>
  void operator()(const S& /*src*/, D& /*dest*/) {
    // Nothing for now, deduced types to try and just make it compile
    // TODO: set values for pos to reflect position on grid.
  }
};

int main() {
    boost::array<std::size_t, 2> lengths = { { 3, 3 } };
    boost::grid_graph<2> grid(lengths);

    Graph graph;
    MyCopy copier;
    // Using 3-Arg version of copy_graph so we can specify a custom way of copying to create the properties
    boost::copy_graph(grid,graph,boost::bgl_named_params<MyCopy,boost::vertex_copy_t,
                                 boost::bgl_named_params<MyCopy,boost::edge_copy_t> >(copier));
}

Этот пример не компилируется:

g++ -Wextra -Wall -O2 -g -o copytest.o -c copytest.cc
In file included from /usr/include/boost/graph/grid_graph.hpp:24:0,
                 from copytest.cc:2:
/usr/include/boost/iterator/transform_iterator.hpp: In constructor ‘boost::transform_iterator<UnaryFunction, Iterator, Reference, Value>::transform_iterator() [with UnaryFunc = boost::detail::grid_graph_vertex_at<boost::grid_graph<2u> >, Iterator = boost::counting_iterator<unsigned int, boost::use_default, boost::use_default>, Reference = boost::use_default, Value = boost::use_default]’:
/usr/include/boost/graph/copy.hpp:115:55:   instantiated from ‘static void boost::detail::copy_graph_impl<0>::apply(const Graph&, MutableGraph&, CopyVertex, CopyEdge, Orig2CopyVertexIndexMap, IndexMap) [with Graph = boost::grid_graph<2u>, MutableGraph = boost::adjacency_list<boost::vecS, boost::listS, boost::undirectedS, VertexProperties>, CopyVertex = MyCopy, CopyEdge = MyCopy, IndexMap = boost::grid_graph_index_map<boost::grid_graph<2u>, boost::array<unsigned int, 2u>, unsigned int>, Orig2CopyVertexIndexMap = boost::iterator_property_map<__gnu_cxx::__normal_iterator<void**, std::vector<void*, std::allocator<void*> > >, boost::grid_graph_index_map<boost::grid_graph<2u>, boost::array<unsigned int, 2u>, unsigned int>, void*, void*&>]’
/usr/include/boost/graph/copy.hpp:327:5:   instantiated from ‘void boost::copy_graph(const VertexListGraph&, MutableGraph&, const boost::bgl_named_params<P, T, R>&) [with VertexListGraph = boost::grid_graph<2u>, MutableGraph = boost::adjacency_list<boost::vecS, boost::listS, boost::undirectedS, VertexProperties>, P = MyCopy, T = boost::vertex_copy_t, R = boost::bgl_named_params<MyCopy, boost::edge_copy_t>]’
/mnt/home/ajw/code/hpcwales/copytest.cc:31:66:   instantiated from here
/usr/include/boost/iterator/transform_iterator.hpp:100:26: error: no matching function for call to ‘boost::detail::grid_graph_vertex_at<boost::grid_graph<2u> >::grid_graph_vertex_at()’
/usr/include/boost/graph/grid_graph.hpp:104:7: note: candidates are: boost::detail::grid_graph_vertex_at<Graph>::grid_graph_vertex_at(const Graph*) [with Graph = boost::grid_graph<2u>]
/usr/include/boost/graph/grid_graph.hpp:100:33: note:                 boost::detail::grid_graph_vertex_at<boost::grid_graph<2u> >::grid_graph_vertex_at(const boost::detail::grid_graph_vertex_at<boost::grid_graph<2u> >&)

Мой анализ этой ошибки заключается в том, что, похоже, он пытается по умолчанию построить часть внутренних компонентов grid_graph , который не может быть сконструирован по умолчанию, по какой-то непонятной мне причине. (clang на самом деле не говорит мне ничего, чего я не вижу здесь из g ++ ).

Вопросы:

  1. Правильно ли это начать инициализацию изменяемого графа как регулярную сетку? Сначала я думал, что это намного проще, чем написать функцию самому, но теперь я не уверен!
  2. Почему значение по умолчанию orig_to_copy и / или vertex_index здесь не подходит? Я предполагаю, что эти двое являются причиной ошибки. (Что из них действительно вызывает проблему? Я не могу понять, в чем заключается основная причина текущей ошибки).
  3. Каков «правильный» способ исправить это?
7
задан Flexo 23 September 2011 в 17:24
поделиться