Tôi đang sử dụng thư viện đồ thị tăng cường và cố gắng đầu tư một số MutableGraph
để bắt đầu cuộc sống dưới dạng lưới. Các cạnh sẽ được thêm và xóa sau này trong cuộc sống, vì vậy tôi nghĩ rằng adjacency_list<vecS,listS,undirectedS>
là lựa chọn đúng đắn.Sao chép từ grid_graph sang adjacency_list với boost :: copy_graph
đọc của tôi về BGL chỉ ra rằng cách hợp lý để initalise nó với những cạnh sẽ tận dụng lợi thế của boost::grid_graph
bằng cách sử dụng boost::copy_graph
để sao chép từ một boost::grid_graph
có thể làm cho tất cả các cạnh ban đầu cho tôi miễn phí. Tôi nghĩ rằng có ý nghĩa - copy_graph
các bản sao từ một mô hình VertexListGraph
đến một mô hình của một MutableGraph
, đó là chính xác những gì tôi có.
Ban đầu tôi đã thử sử dụng phiên bản 2 đối số copy_graph
, với hy vọng mơ hồ rằng một điều gì đó hợp lý sẽ xảy ra với các giá trị mặc định cho phần còn lại. Điều đó hóa ra không phải là trường hợp, grid_graph
(vì lý do tôi không thể tìm ra) dường như không có cơ sở để sử dụng PropertyMap
s với một trong hai cạnh hoặc đỉnh, do đó, mặc định vertex_copy
và edge_copy
không thành công (với trình biên dịch lỗi) sao chép các thuộc tính.
Vì phiên bản 2 đối số rõ ràng dường như không thích hợp nên tôi tiếp tục và cố gắng triển khai toán tử nhị phân của riêng mình để sao chép các đỉnh và cạnh. Ngay cả với bản sao 'no-op', nó không hoạt động tốt như tôi mong đợi (tức là nó không biên dịch).
tôi đã đặt cùng một ví dụ làm việc tối thiểu mà minh họa các vấn đề:
#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));
}
Ví dụ này không biên dịch:
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> >&)
phân tích của tôi về lỗi đó là nó có vẻ là cố gắng để mặc định xây dựng một phần của các bên trong của grid_graph
, không thể được xây dựng mặc định, vì một số lý do không rõ ràng đối với tôi. (clang không thực sự cho tôi biết bất cứ điều gì tôi không thể nhìn thấy từ g + + ở đây).
Câu hỏi:
- Đây có phải là cách đúng đắn để đi về initalising một đồ thị có thể thay đổi để bắt đầu như một mạng lưới thường xuyên? Ban đầu tôi nghĩ rằng nó dễ dàng hơn nhiều so với việc viết một hàm để tự làm như vậy, nhưng bây giờ tôi không chắc lắm!
- Tại sao giá trị mặc định là
orig_to_copy
và/hoặcvertex_index
không phù hợp ở đây? Tôi giả định rằng hai nguyên nhân đó là nguyên nhân gây ra lỗi. (Mà, nếu có, trong số đó thực sự gây ra vấn đề? Tôi không thể giải mã nguyên nhân gốc rễ của lỗi hiện tại). - Cách sửa lỗi này "đúng" là gì?
Kiểm tra nhanh: khi nói về tên tham số bạn gọi nó là 'named_param1' và 'named_param2' tất cả các cách thức thông qua các văn bản cho đến khi các ví dụ mà nó đột nhiên trở thành 'boost :: named_parameter1' và' boost :: named_parameter2' cho phần đầu tiên của chuỗi - đó là một lỗi đánh máy? – Flexo
@awoodland: Không phải lỗi đánh máy, bởi vì cái đầu tiên là một hàm * trong không gian tên 'boost', trả về một đối tượng có * phương thức * cho các tham số có tên khác. 'boost :: named_parameter1 (val1) .named_param2 (val2)' cấu hình tham số 'named_parameter1' trước bằng cách gọi hàm' boost :: named_parameter1' * *. Sau đó nó cấu hình tham số 'named_parameter2' bằng cách gọi phương thức' named_parameter2' * * trên đối tượng được trả về bởi 'boost :: named_parameter1()'. –
Hóa ra máy tôi đã thử câu trả lời này ban đầu đang chạy 1,46. Trên một máy tính với 1,42, nó không biên dịch chính xác cùng một lỗi tôi đã nhìn thấy. Tôi đoán đó là một lỗi trong 1,42? Câu trả lời này vẫn sửa chữa tất cả các vấn đề khác mà tôi đã có trong nỗ lực của tôi mặc dù, mà tôi rất biết ơn. – Flexo