2011-08-23 9 views
9

Sono abbastanza nuovo per il grafico Boost. Sto cercando di adattare un esempio per trovare l'algoritmo Dijkstra Shortest Path che utilizzava VertexList = vecS. Ho cambiato il contenitore del vertice in ListS. Ho imparato che dobbiamo fornire il nostro vertex_index affinché l'algoritmo funzioni se usiamo listS.Dijkstra Shortest Path with VertexList = ListS nel grafico boost

int main(int, char *[]) 
{ 
    typedef float Weight; 
    typedef boost::property<boost::edge_weight_t, Weight> WeightProperty; 
    typedef boost::property<boost::vertex_name_t, std::string> NameProperty; 
    typedef boost::property<boost::vertex_index_t, int> IndexProperty; 

    typedef boost::adjacency_list < boost::listS, boost::listS, boost::directedS, 
    NameProperty, WeightProperty > Graph; 

    typedef boost::graph_traits <Graph>::vertex_descriptor Vertex; 
    typedef boost::graph_traits <Graph>::vertex_iterator Viter; 

    typedef boost::property_map < Graph, boost::vertex_index_t >::type IndexMap; 
    typedef boost::property_map < Graph, boost::vertex_name_t >::type NameMap; 

    typedef boost::iterator_property_map < Vertex*, IndexMap, Vertex, Vertex& > PredecessorMap; 
    typedef boost::iterator_property_map < Weight*, IndexMap, Weight, Weight& > DistanceMap; 

    Graph g; 


    Vertex v0 = boost::add_vertex(std::string("v0"), g); 
    Vertex v1 = boost::add_vertex(std::string("v1"), g); 
    Vertex v2 = boost::add_vertex(std::string("v2"), g); 
    Vertex v3 = boost::add_vertex(std::string("v3"), g); 

    Weight weight0 = 5; 
    Weight weight1 = 3; 
    Weight weight2 = 2; 
    Weight weight3 = 4; 

    boost::add_edge(v0, v1, weight0, g); 
    boost::add_edge(v1, v3, weight1, g); 
    boost::add_edge(v0, v2, weight2, g); 
    boost::add_edge(v2, v3, weight3, g); 


    std::vector<Vertex> predecessors(boost::num_vertices(g)); // To store parents 
    std::vector<Weight> distances(boost::num_vertices(g)); // To store distances 

    IndexMap indexMap; // = boost::get(boost::vertex_index, g); 
    NameMap name; 
    Viter i, iend; 
//Create our own vertex index. This is what I changed in the original code 
    int c = 0; 
    for (boost::tie(i, iend) = vertices(g); i != iend; ++i, ++c) { 
     indexMap[*i] = c; // **Error points to this line** 
     name[*i] = 'A' + c; 
    } 
PredecessorMap predecessorMap(&predecessors[0], indexMap); 
DistanceMap distanceMap(&distances[0], indexMap); 
boost::dijkstra_shortest_paths(g, v0, boost::distance_map(distanceMap).predecessor_map(predecessorMap)); 


    // Extract a shortest path 
    std::cout << std::endl; 
    typedef std::vector<Graph::edge_descriptor> PathType; 
    PathType path; 
    Vertex v = v3; 
    for(Vertex u = predecessorMap[v]; 
    u != v; // Keep tracking the path until we get to the source 
    v = u, u = predecessorMap[v]) // Set the current vertex to the current predecessor,  and the predecessor to one level up 
    { 
    std::pair<Graph::edge_descriptor, bool> edgePair = boost::edge(u, v, g); 
    Graph::edge_descriptor edge = edgePair.first; 
    path.push_back(edge); 
    } 

    // Write shortest path 
    std::cout << "Shortest path from v0 to v3:" << std::endl; 
    float totalDistance = 0; 
    for(PathType::reverse_iterator pathIterator = path.rbegin(); pathIterator !=  path.rend(); ++pathIterator) 
    { 
    std::cout << name[boost::source(*pathIterator, g)] << " -> " <<  name[boost::target(*pathIterator, g)] 
       << " = " << boost::get(boost::edge_weight, g, *pathIterator) <<  std::endl; 

    } 

    std::cout << std::endl; 

    std::cout << "Distance: " << distanceMap[v3] << std::endl; 

    return EXIT_SUCCESS; 
} 

ottengo il seguente errore:

/spvec.cpp:62:20: errore: non è partita per 'operatore =' a 'index.boost :: :: adj_list_vertex_property_map operator [] [con Graph = boost :: adjacency_list>, boost :: proprietà>, ValueType = boost :: detail :: error_property_not_found, Reference = boost :: detail :: error_property_not_found &, Tag = boost :: vertex_index_t, boost :: adj_list_vertex_property_map :: key_type = void *] (i.std :: _ List_iterator < _Tp> :: operator * con _Tp = void *, _Tp & = void * &) = c '

Sono sicuro di aver fatto un errore nel creare il mio indice di vertice. Ma non è riuscito a scoprire esattamente qual è il problema. Qualcuno ha qualche suggerimento su quello che sto facendo male ..

+2

Puoi pubblicare l'errore? – Dani

+0

Senza conoscere l'errore, è un ago nel pagliaio e l'ago potrebbe non essere nemmeno in quel frammento di codice. –

risposta

8

BGL ha in realtà un esempio di utilizzo dijkstra_shortest_paths con liste/elenchi, ma non è legato alla dalla documentazione HTML: http://www.boost.org/doc/libs/release/libs/graph/example/dijkstra-example-listS.cpp

Quello che il messaggio di errore è provare a dirti (error: no match for ‘operator=’ in ‘index.boost::adj_list_vertex_property_map...ValueType = boost::detail::error_property_not_found...) è che non esiste spazio di archiviazione per vertice per la proprietà vertex_index_t, che è ciò che è richiesto da adj_list_vertex_property_map. Per risolvere il problema, è possibile modificare Graphtypedef in modo da includere l'archiviazione per vertice per la proprietà vertex_index_t o utilizzare una mappa delle proprietà "esterna" come associative_property_map.

L'esempio dijkstra-example-listS.cpp utilizza l'approccio di modifica del grafico typedef. Per utilizzare questo metodo nel codice, si potrebbe definire:

typedef boost::adjacency_list <boost::listS, boost::listS, boost::directedS, 
    boost::property<boost::vertex_name_t, std::string, boost::property<boost::vertex_index_t, int> >, 
    boost::property<boost::edge_weight_t, Weight> > Graph; 
+0

Non volevo aggiungere la proprietà vertex_index_t all'interno della proprietà vertice del grafo come indicato nell'esempio. In questo modo non ho potuto utilizzare l'approccio delle proprietà in bundle. Sebbene il codice sopra non usi le proprietà raggruppate, finirò per usarle. Ma come hai suggerito, la carta associativa dovrebbe funzionare. Ci proverò. – srkrish

6

Se qualcuno è interessato a una soluzione, Creazione di un associative_property_map come suggerito nella risposta precedente risolto il problema:

typedef std::map<vertex_desc, size_t>IndexMap; 
    IndexMap mapIndex; 
    boost::associative_property_map<IndexMap> propmapIndex(mapIndex); 
    //indexing the vertices 
    int i=0; 
    BGL_FORALL_VERTICES(v, g, pGraph) 
    { 
     boost::put(propmapIndex, v, i++); 
    } 

quindi passare questo Mappa dell'indice vertice alla chiamata dijkstra_shortest_paths() come parametro con nome. PS: BGL_FORALL_VERTICES() è definito in < boost/graph/iteration/iteration_macros.hpp>

+0

È possibile fornire un codice completo? Che dire della mappa indice del predecessore e della mappa di distanza? Devi anche passarli a propmapIndex? E qual è il vdesc? È la proprietà vettoriale? – blakeO

+1

Grazie per questo snippet. L'ho usato per creare una vertex_index_map e passarla alla funzione breadth_first_search. Ho pubblicato un esempio funzionante: http://stackoverflow.com/a/43780529/779446 – opetroch

Problemi correlati