【问题标题】:Efficient representation of edges in a C++ graph structureC++ 图结构中边的有效表示
【发布时间】:2012-09-06 17:05:55
【问题描述】:

我计划用 C++ 表示一个相当大的、稀疏的、无向图结构。这将是大约 10,000 多个顶点,每个顶点的度数约为 10。

我已经阅读了一些关于将图表示为邻接矩阵或列表的 background,但它们似乎都不适合我想做的事情。在我的场景中:

  • 图表中的每条边都会附加一些属性(数值)
  • 初始图创建后,边可以删除,但永远不会创建
  • 永远不会创建或删除顶点
  • 图上的主要查询操作将是查找边 E,以了解哪些其他边连接到它。这相当于在 E 的每一端找到连接到顶点的边。

正是这最后一点使邻接矩阵看起来不合适。据我所知,每个查询都需要 2*N 次操作,其中 N 是图中的节点数。

我相信邻接表会减少所需的操作,但似乎不合适,因为我在每条边中都包含了参数 - 即因为邻接表存储了每个

有没有更好的方法来存储我的数据,以便这些查询操作更快,并且我可以存储每条边及其参数?我不想开始实施不正确的方法。

【问题讨论】:

  • 邻接表没问题,可以把数据和边一起附加。怎么了?邻接矩阵是不可能的,除非您有大量可用内存(接近 100 MB),而总共只有 10^5 条边。
  • 好的,谢谢。但是我该如何处理邻接列表中的重复呢?每条边将被表示两次,一次在节点 i 的行中,一次在节点 j 的行中。

标签: c++ data-structures graph


【解决方案1】:

在这里,我认为通常的面向对象方法没有问题。有你的Edge<V,E>Vertex<V,E> 类型,其中V 是顶点存储的内容,E 是边缘存储的内容。每条边都有两个对其各自顶点的引用和两个索引,表示在各自顶点的哪个槽中查找该边:

template <typename V, typename E>
class Edge {
  struct Incidence {
    size_t index;
    Vertex<V,E>& v;
  };
  std::array<Incidence,2> vertices;
  E content;
};

template <typename V, typename E>
class Vertex {
  std::vector<Edge<V,E>*> edges;
};

如果删除边e,则转到Vertex&lt;V,E&gt;::edges 并将back 的位置移动到e 的前一个位置。恒定时间去除。将所有相邻边枚举到特定边的线性时间(在操作结果的大小中)。听起来不错。

【讨论】:

  • 太棒了,这看起来符合所有条件。不过,我不太明白您关于删除边缘的评论。您的意思是当您从Vertex&lt;V,E&gt;::edges 中删除一条边时,您将其在向量中的位置替换为向量末尾的边(可能还会更新该替换边的vertices 条目之一)?
  • @BillCheatham:是的,没错。因为否则你的向量中会有未定义的间隙,这是很成问题的。但由于事件边的顺序无关紧要,您只需将 back 元素移动到现在为空的插槽并将向量缩小一即可。
  • 好的,我现在几乎完成了这个系统的实现。我还有一个问题,即如何存储我的EdgeVertex 元素。我尝试了vector,但删除的每条边都使指向向量中其他边的指针无效。 array 不允许有效删除元素,list 不允许随机访问单个边。
【解决方案2】:

这样的事情看起来可信吗?这存储边缘邻接:

#include <vector>
#include <map>

typedef int vertex;

struct edge
{
    vertex a,b;
    // other data
};

bool operator< (const edge &a, const edge &b)
{
    unsigned long long ahash = a.a;
    ahash << 32;
    ahash |= a.b;
    unsigned long long bhash = b.a;
    bhash << 32;
    bhash |= b.b;
    return ahash < bhash;
}

// support for your query operation
typedef std::map<edge, std::vector<edge &> > edge_adjacency;

您似乎有点想将边映射到顶点,然后使用一些非常标准的东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-01
    • 2012-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-16
    相关资源
    最近更新 更多