Sto utilizzando la libreria del grafico boost e sto provando initalamente un MutableGraph
per iniziare la vita come una griglia. I bordi saranno aggiunti e rimossi più tardi nella vita, quindi penso che adjacency_list<vecS,listS,undirectedS>
sia la scelta giusta.Copia da grid_graph a adjacency_list con boost :: copy_graph
La mia lettura su BGL ha indicato che il modo sensato initalise con questi bordi sarebbe di sfruttare boost::grid_graph
utilizzando boost::copy_graph
copiare da un boost::grid_graph
che può fare tutti i bordi iniziali per me gratuitamente. Ho pensato che fosse logico - copy_graph
copie da un modello di a un modello di un MutableGraph
, che è esattamente quello che ho.
Inizialmente ho provato a utilizzare la versione a 2 argomenti di copy_graph
, con la vaga speranza che qualcosa di sensato sarebbe accaduto con le impostazioni predefinite per il resto. Non è questo il caso, grid_graph
(per ragioni che non riuscivo a capire) non sembra avere una funzionalità per l'utilizzo di PropertyMap
s con bordi o vertici, quindi il default vertex_copy
e edge_copy
non riuscito (con un compilatore errore) copiando le proprietà.
Poiché la versione a 2 argomenti chiaramente non sembra appropriata, passo avanti e ho cercato di implementare il mio operatore binario per copiare vertici e spigoli. Anche con una copia 'no-op' questo non funziona come spero (cioè non si compila).
Ho messo insieme un esempio di lavoro minima che illustra il problema:
#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));
}
questo esempio non può essere compilato:
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> >&)
La mia analisi di tale errore è che sembra essere cercando di default costruisci parte dell'intero interno di grid_graph
, che non può essere costruito in modo predefinito, per qualche ragione che non mi è molto chiaro. (clang in realtà non mi dice nulla che non riesco a vedere da g ++ qui).
Domande:
- È questo il modo giusto per andare su un grafico, inizializzazione mutabile per iniziare come una griglia regolare? Inizialmente pensavo che fosse molto più facile che scrivere una funzione per farlo da solo, ma ora non ne sono così sicuro!
- Perché il valore predefinito di
orig_to_copy
e/overtex_index
non è appropriato qui? Suppongo che quei due siano la causa dell'errore. (Che, se del caso, di quelli in realtà sta causando il problema? Non riesco a decifrare quale sia la causa principale dell'errore corrente). - Qual è il modo "corretto" per risolvere questo problema?
controllo rapido: quando si parla di parametri denominati lei ha fatto riferimento ad esso come '' named_param1' e named_param2' tutto il percorso attraverso il testo fino agli esempi in cui all'improvviso è diventato 'boost :: named_parameter1' e' boost :: named_parameter2' per la prima parte della catena - era un refuso? – Flexo
@awoodland: non è un refuso, perché il primo è una * funzione * nello spazio dei nomi 'boost', che restituisce un oggetto che ha * metodi * per gli altri parametri denominati. 'boost :: named_parameter1 (val1) .named_param2 (val2)' configura il parametro 'named_parameter1' prima chiamando la funzione' boost :: named_parameter1' * *. Quindi configura il parametro 'named_parameter2' chiamando il metodo' named_parameter2' * * sull'oggetto restituito da 'boost :: named_parameter1()'. –
Si è scoperto che la macchina su cui ho provato questa risposta originariamente era in esecuzione 1.46. Su una macchina con 1.42, non riesce a compilare esattamente lo stesso errore che stavo vedendo. Immagino che sia un bug in 1.42? Questa risposta risolve comunque tutti gli altri problemi che ho avuto nel mio tentativo, per il quale sono molto grato. – Flexo