如何使用 Boost Graph 库更改图中的边权重?

9
我使用Boost图形库定义了一个图形。
typedef boost::property<boost::edge_weight_t, int> EdgeWeightProperty;
typedef boost::adjacency_list<boost::listS, boost::vecS,boost::undirectedS,boost::no_property,EdgeWeightProperty> Graph;

使用以下方法添加边缘非常简单:

boost::add_edge(vertice1, vertice2, weight, graph);

我还没想出如何在边权重被设置后更改它。一个可能的解决方案是删除该边,然后重新添加它并更新其权重值,但是这似乎有点过度。

2个回答

14

一个解决方案是执行以下步骤

typedef boost::adjacency_list<boost::setS, boost::vecS, boost::undirectedS,boost::no_property,EdgeWeightProperty> Graph;
typedef Graph::edge_descriptor Edge;
Graph g;
std::pair<Edge, bool> ed = boost::edge(v1,v2,g);
int weight = get(boost::edge_weight_t(), g, ed.first);
int weightToAdd = 10;
boost::put(boost::edge_weight_t(), g, ed.first, weight+weightToAdd);

1
如果您将边属性定义为具有元素“weight”的结构体,则可以使用int weight = g[ed.first].weight;g[ed.first].weight = weight + weightToAdd;分别替代boost::getboost::put函数。 - Abdullah Giray Yağlıkçı
1
@agy,是否可以轻松地在边属性结构中使用带权重的内置算法,而不是edge_weight_t() - lucidbrot

4
另一种解决方案是使用属性映射。以下是一个示例。
// Edge weight.
typedef boost::property<boost::edge_weight_t, int> EdgeWeightProperty;

// Graph.
typedef boost::adjacency_list< boost::listS,
                               boost::vecS,
                               boost::undirectedS,
                               boost::no_property,
                               EdgeWeightProperty > Graph;

// Vertex descriptor.
typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;

// The Graph object
Graph g;

// Populates the graph.
Vertex v1 = boost::add_vertex(g);
Vertex v2 = boost::add_vertex(g);
Vertex v3 = boost::add_vertex(g);
boost::add_edge(v1, v2, EdgeWeightProperty(2), g);
boost::add_edge(v1, v3, EdgeWeightProperty(4), g);
boost::add_edge(v2, v3, EdgeWeightProperty(5), g);

// The property map associated with the weights.
boost::property_map < Graph,
                      boost::edge_weight_t >::type EdgeWeightMap = get(boost::edge_weight, g);

// Loops over all edges and add 10 to their weight.
boost::graph_traits< Graph >::edge_iterator e_it, e_end;
for(std::tie(e_it, e_end) = boost::edges(g); e_it != e_end; ++e_it)
{
  EdgeWeightMap[*e_it] += 10;
}

// Prints the weighted edgelist.
for(std::tie(e_it, e_end) = boost::edges(g); e_it != e_end; ++e_it)
{
  std::cout << boost::source(*e_it, g) << " "
            << boost::target(*e_it, g) << " "
            << EdgeWeightMap[*e_it] << std::endl;
}

1
如果我的重量是边的起点和终点顶点的函数,会怎样? - Jim
@Jim 你的意思是:如果权重是某些顶点变量(例如状态)的函数,会怎样呢?因为现在,由于每条边都连接着两个节点,所以权重从技术上讲是两个顶点的函数。如果“源/目标”顺序很重要,你可以使用双向图。 - JosephD

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接