2011-08-23 16 views
9

Jestem całkiem nowy na wykresie zwiększenia. Próbuję zaadaptować przykład do znalezienia algorytmu Dijkstra Shortest Path, który używał VertexList = vecS. Zmieniłem kontener vertex na ListS. Nauczyłem się, że musimy podać własny argument vertex_index, aby algorytm zadziałał, jeśli użyjemy listS.Najkrótsza ścieżka Dijkstry z VertexList = Listy na wykresie zwiększenia

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; 
} 

pojawia się następujący błąd:

/spvec.cpp:62:20: błąd: nie pasuje do 'operator =' w „index.boost :: adj_list_vertex_property_map :: operator [] [z Graph = boost :: adjacency_list>, boost :: property>, ValueType = boost :: szczegóły :: error_property_not_found, Reference = boost :: szczegóły :: error_property_not_found &, Tag = boost :: vertex_index_t, boost :: adj_list_vertex_property_map :: key_type = void *] (i.std :: _ List_iterator < _Tp> :: operator * z _Tp = void *, _Tp & = void * &) = c '

Jestem pewien, że popełniłem błąd, tworząc własny indeks werteksów. Ale nie mogłem się dowiedzieć, o co dokładnie chodzi. Czy ktoś ma jakieś sugestie na temat tego, co robię źle ..

+2

Czy możesz zgłosić błąd? – Dani

+0

Nie znając błędu, jest to igła w stogu siana, a igła może nawet nie znajdować się w tym fragmencie kodu. –

Odpowiedz

8

BGL faktycznie ma przykład użycia dijkstra_shortest_paths z listami/lists, ale to nie jest związana z dokumentacją HTML: http://www.boost.org/doc/libs/release/libs/graph/example/dijkstra-example-listS.cpp

Jaki jest komunikat o błędzie próbuję ci powiedzieć (error: no match for ‘operator=’ in ‘index.boost::adj_list_vertex_property_map...ValueType = boost::detail::error_property_not_found...), że nie ma żadnych magazynów na jeden wierzchołek dla właściwości vertex_index_t, co jest wymagane w przypadku potrzebnych adj_list_vertex_property_map. Aby rozwiązać ten problem, możesz zmienić swój Graphtypedef, aby uwzględnić pamięć na jeden wierzchołek dla właściwości vertex_index_t lub użyć "zewnętrznej" mapy właściwości, takiej jak associative_property_map.

W przykładzie dijkstra-example-listS.cpp zastosowano metodę zmiany wykresu typedef. Aby skorzystać z tej metody w kodzie, można zdefiniować:

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

Nie dodałem właściwości vertex_index_t we właściwości vertex wykresu, jak podano w przykładzie. W ten sposób nie mogłem użyć podejścia z pakietem właściwości. Chociaż powyższy kod nie używa właściwości związanych z pakietami, w końcu je wykorzystam. Ale jak zasugerowałeś, powinieneś użyć właściwości associative_property_map. Spróbuję tego. – srkrish

6

Jeśli ktoś jest zainteresowany w roztworze, tworząc associative_property_map jak zasugerowano w poprzedniej odpowiedzi rozwiązał problem:

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++); 
    } 

następnie przekazać to Indeks indeksu wierzchołków do wywołania dijkstra_shortest_paths() jako nazwanego parametru. PS: BGL_FORALL_VERTICES() jest zdefiniowany w < boost/graph/iteration/iteration_macros.hpp>

+0

Czy można podać pełny kod? A co z mapą index_map poprzednika i mapy dystansowej? Musisz także przekazać im propmapIndex? A czym jest vdesc? Czy to własność Vector? – blakeO

+1

Dziękuję za ten fragment. Użyłem go do stworzenia vertex_index_map i przekazania go do funkcji breadth_first_search. Wysłałem roboczą próbkę: http://stackoverflow.com/a/43780529/779446 – opetroch

Powiązane problemy