【问题标题】:Some questions about the C++ boost graph library关于C++ boost图形库的一些问题
【发布时间】:2017-11-26 04:45:53
【问题描述】:

所以我发布这个是因为我目前正在从事一个算法项目,并且可能会使用 boost 库从输入文本文件构建图形。所以我注意到图中的顶点有一个描述符,但是由于我要构建一个非常大的图,我是否需要为该图中的每个顶点分配一个描述符?如果我不这样做,我可以在构建后遍历整个图吗?

我是 boost 库的新手,这有点紧急,所以如果有人能解释一下,我将非常感激!

【问题讨论】:

标签: c++ boost graph


【解决方案1】:

顶点描述符描述了一个顶点(以廉价、独立于图模型的方式)。

图模型描述图。

迭代器

当你想遍历一个图时,你可以使用迭代器来遍历这个图:

typedef boost::adjacency_list<> Graph;
typedef Graph::vertex_iterator Vit;

Vit begin, end;
boost::tie(begin, end) = vertices(g);

解除对有效迭代器的引用会为您提供描述符(边缘迭代器也是如此)。

简单演示:

Live On Coliru

#include <boost/graph/adjacency_list.hpp>
#include <iostream>

int main () {
    typedef boost::adjacency_list<> Graph;
    typedef Graph::vertex_iterator Vit;
    Graph g(10);

    add_edge(2,5,g);
    add_edge(5,3,g);
    add_edge(3,8,g);

    Vit begin, end;
    boost::tie(begin, end) = vertices(g);

    for (Vit it = begin; it != end; ++it) {
        unsigned edges = out_degree(*it, g);
        if (edges)
            std::cout << "vertex #" << *it << " has " << edges << " outgoing edge(s)\n";
    }
}

打印:

vertex #2 has 1 outgoing edge(s)
vertex #3 has 1 outgoing edge(s)
vertex #5 has 1 outgoing edge(s)

具有基于节点的顶点容器的图形模型

并非所有图都有完整的顶点描述符,因此添加边变得更加复杂,并且打印它们看起来并不那么“友好”

Live On Coliru

#include <boost/graph/adjacency_list.hpp>
#include <iostream>

int main () {
    typedef boost::adjacency_list<boost::setS, boost::listS/*, boost::undirectedS*/> Graph;
    typedef Graph::vertex_iterator Vit;
    Graph g(10);

    Vit begin, end;
    boost::tie(begin, end) = vertices(g);

    {
        std::vector<Graph::vertex_descriptor> vindex(begin, end);
        add_edge(vindex[2], vindex[5], g);
        add_edge(vindex[5], vindex[3], g);
        add_edge(vindex[3], vindex[8], g);
    }

    for (Vit it = begin; it != end; ++it) {
        unsigned edges = out_degree(*it, g);
        if (edges)
            std::cout << "vertex #" << *it << " has " << edges << " outgoing edge(s)\n";
    }
}

打印

vertex #0x994d00 has 1 outgoing edge(s)
vertex #0x994d70 has 1 outgoing edge(s)
vertex #0x994e50 has 1 outgoing edge(s)

属性

在这种情况下,请考虑添加property bundle

这样,任意特定于应用程序的信息可以附加到模型顶点(或边,或图)。

在我看来,主要的缺点是属性没有自然索引,因此除非您在外部保留额外的索引,否则通过其(捆绑)属性查找图形实体可能会导致性能不佳(线性搜索)手动绘制图表。

Live On Coliru

#include <boost/graph/adjacency_list.hpp>
#include <iostream>

struct VertexProperties {
    std::string name;
    VertexProperties(std::string name) : name(name) {}
};

int main () {
    typedef boost::adjacency_list<boost::setS, boost::listS, boost::directedS, VertexProperties> Graph;
    typedef Graph::vertex_iterator Vit;
    Graph g;

    add_vertex(VertexProperties ("zero"), g);
    add_vertex(VertexProperties ("one"), g);
    add_vertex(VertexProperties ("two"), g);
    add_vertex(VertexProperties ("three"), g);
    add_vertex(VertexProperties ("four"), g);
    add_vertex(VertexProperties ("five"), g);
    add_vertex(VertexProperties ("six"), g);
    add_vertex(VertexProperties ("seven"), g);
    add_vertex(VertexProperties ("eight"), g);
    add_vertex(VertexProperties ("nine"), g);

    Vit begin, end;
    boost::tie(begin, end) = vertices(g);

    {
        std::vector<Graph::vertex_descriptor> vindex(begin, end);

        add_edge(vindex[2], vindex[5], g);
        add_edge(vindex[5], vindex[3], g);
        add_edge(vindex[3], vindex[8], g);
    }

    for (Vit it = begin; it != end; ++it) {
        unsigned edges = out_degree(*it, g);
        if (edges)
            std::cout << "vertex '" << g[*it].name << "' has " << edges << " outgoing edge(s)\n";
    }
}

打印

vertex 'two' has 1 outgoing edge(s)
vertex 'three' has 1 outgoing edge(s)
vertex 'five' has 1 outgoing edge(s)

【讨论】:

  • 过去几天我一直在努力理解 BGL!谢谢你这个了不起的整洁的小答案。
猜你喜欢
  • 1970-01-01
  • 2018-10-26
  • 2016-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-13
  • 2012-05-14
  • 1970-01-01
相关资源
最近更新 更多