在 Boost.Graph 中向图形添加边

the*_*sys 3 c++ boost boost-graph

我正在尝试使用 Boost.Graph 库来运行 Goldberg 的 Max-Flow 算法。Boost.Graph 称之为push_relabel_max_flow

但是,我很难理解库及其类型系统。我在上面链接的文档提供了示例代码。但在该示例中,图形是从文件中读取的。我想在运行时生成图形。这是我到目前为止的代码(主要是从示例中复制的):

typedef boost::adjacency_list_traits<boost::vecS, boost::vecS, boost::directedS> Traits;
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, 
        boost::property<boost::vertex_name_t, std::string>, 
        boost::property<boost::edge_capacity_t, long, 
            boost::property<boost::edge_residual_capacity_t, long, 
                boost::property<boost::edge_reverse_t, Traits::edge_descriptor>>>> DirectedGraph;

DirectedGraph g;
Traits::vertex_descriptor s, t;


s = boost::add_vertex(g);
t = boost::add_vertex(g);
boost::add_vertex(g);
boost::add_vertex(g);
Run Code Online (Sandbox Code Playgroud)

在我向图中添加 4 个顶点后,我应该“连接”它们,即制作具有容量、剩余容量和反向值的边。此任务的功能是,boost::add_edge()但我不知道如何传递我的参数。示例代码没有显示,因为正如我所说,数据是从文件中读取的,然后直接解析为图形。也许有 Boost.Graph 库经验的人可以告诉我怎么做。

Nic*_*teo 7

您可以在顶点之间添加一条边st如下所示:

boost::add_edge(s, t, {33, 44}, g);
Run Code Online (Sandbox Code Playgroud)

这里设置edge_capacity为 33,然后设置edge_residual_capacity为 44。

要实际访问边缘属性,据我所知,您必须执行以下操作:

std::cout << boost::get(boost::edge_capacity, g, boost::edge(s,t,g).first) << '\n';
Run Code Online (Sandbox Code Playgroud)

这很烦人。如果您改用捆绑属性会更容易,如下所示:

typedef boost::adjacency_list_traits<boost::vecS, boost::vecS, boost::directedS> Traits;

struct VertexProps {
    std::string name;
};

struct EdgeProps {
    long capacity;
    long residual_capacity;
    Traits::edge_descriptor reverse;
};

typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS,
                              VertexProps, EdgeProps > DirectedGraph;
Run Code Online (Sandbox Code Playgroud)

然后你可以用同样的方式添加顶点和边,但访问边属性更容易,例如

auto e = boost::edge(s,t,g).first; // get the edge descriptor for an edge from s to t, if any
std::cout << g[e].capacity << '\n';
Run Code Online (Sandbox Code Playgroud)

要在您添加的匿名第三个和第四个顶点之间添加一条边,您可以使用

boost::add_edge(2, 3, {17, 26}, g);
Run Code Online (Sandbox Code Playgroud)

因为底层存储是vector,所以vertex_descriptor只是向量索引(又名size_t,又名unsigned long在这里)。但要更严格地正确,你应该做

boost:add_edge(boost::vertex(2, g), boost::vertex(3, g), {17, 26}, g);
Run Code Online (Sandbox Code Playgroud)

为了获得vertex_descriptor第三和第四个顶点。