如何在BGL c ++中更新边的值?

时间:2016-03-08 01:40:43

标签: c++ algorithm boost graph edges

我尝试更新图表中边缘的值,但是,当我使用以下属性贴图更新值时:

property_map<Graph, edge_weight_t>::type weight = get(edge_weight, g);
weight[*edgeIndex] = new_value;

它更新了值,但是当我尝试使用dijkstra算法获得最短路径时,算法得到权重的old_value。但是当我在图表中列出所有边和权重时,更新的权重与new_value一致。

我试图使用boost :: put();然而,出现同样的问题。它仅在new_value小于old_value

时有效

有人能帮帮我吗?

换句话说,我只想在边缘设置名称和重量并动态更新此权重。

这是我的代码:

#include <iostream>                  // for std::cout
#include <utility>                   // for std::pair
#include <algorithm>                 // for std::for_each
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/config.hpp>
#include <string>
#include <string.h>
#include <list>
#include <fstream>

using namespace boost;

//define de Edges and Vertex property
typedef property<edge_weight_t, float, property<edge_name_t, std::string> > EdgeWeightProperty;
typedef property<vertex_name_t, std::string> VertexProperty;

//define the type of the Graph
typedef adjacency_list<vecS, vecS, undirectedS, VertexProperty, EdgeWeightProperty> Graph;



int main(){
    typedef float Weight;

    //Graph instance
    Graph g;

    //property accessors
    property_map<Graph, vertex_name_t>::type node = get(vertex_name, g);
    property_map<Graph, edge_weight_t>::type weight = get(edge_weight, g);
    property_map<Graph, edge_name_t>::type edge = get(edge_name, g);

    // Create the vertices  
    typedef graph_traits<Graph>::vertex_descriptor Vertex;
    std::vector<Vertex> vertex_list;

    typedef graph_traits<Graph>::edge_descriptor Edge;
    std::vector<Edge> edges_list;

    typedef boost::property_map <Graph, vertex_index_t >::type IndexMap;
    typedef boost::property_map <Graph, 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;

    std::string vertex_name;
    std::ifstream vertex_file;
    vertex_file.open("vertex_file.txt");

    if (vertex_file.is_open()){
            for(int index = 0; vertex_file.peek() != EOF; index++){

                vertex_file >> vertex_name;
                vertex_list.push_back(add_vertex(g));
                node[vertex_list.at(index)] = vertex_name;

            }
            vertex_file.close();
    }

    std::string edge_name, from, to;
    std::ifstream edges_file;
    edges_file.open("edge.txt");

    int index_from, index_to;

    if(edges_file.is_open()){
        for(int index=0; edges_file.peek() != EOF; index++){
            edges_file >> edge_name;
            edges_file >> from;
            edges_file >> to;

            for(index_from=0; index_from < vertex_list.size(); index_from++){
                if(strcmp(from.c_str(), node[vertex_list.at(index_from)].c_str()) == 0){
                    break;
                }
            }

            for(index_to=0; index_to < vertex_list.size(); index_to++){
                if(strcmp(to.c_str(), node[vertex_list.at(index_to)].c_str()) == 0){
                    break;
                }
            }


            edges_list.push_back((add_edge(vertex_list.at(index_from), vertex_list.at(index_to), g)).first);
            edge[edges_list.at(index)] = edge_name;
            //std::cout << edges_list.at(index) << std::endl;
            weight[edges_list.at(index)] = 10;


        }
    }


    typedef graph_traits<Graph>::edge_iterator edge_iter;
    std::pair<edge_iter, edge_iter> ep;
    edge_iter ei, ei_end;
    std::string teste = "0/0to0/1";

    for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei){
        //std::cout << edge[*ei] << std::endl;
        if(strcmp(edge[*ei].c_str(), teste.c_str()) == 0){
            weight[*ei] = 700;

        }
    }


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

    PredecessorMap predecessorMap(&predecessors[0], indexMap);
    DistanceMap distanceMap(&distances[0], indexMap);

    boost::dijkstra_shortest_paths(g, vertex_list.at(0), boost::distance_map(distanceMap).predecessor_map(predecessorMap));

    std::cout << "distances and parents:" << std::endl;
    NameMap nameMap = boost::get(boost::vertex_name, g);


      std::cout << std::endl;

    typedef std::vector<Graph::edge_descriptor> PathType;

    PathType path;

  Vertex v = vertex_list.at(1); // We want to start at the destination and work our way back to the source
  for(Vertex u = predecessorMap[v]; // Start by setting 'u' to the destintaion node's predecessor
      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 << nameMap[boost::source(*pathIterator, g)] << " to " << nameMap[boost::target(*pathIterator, g)]
              << " = " << boost::get( boost::edge_weight, g, *pathIterator ) << std::endl;

  }

  std::cout << std::endl;

  std::cout << "Distance: " << distanceMap[vertex_list.at(1)] << std::endl;



  return 0;
}

0 个答案:

没有答案