庞大的图形存储问题

时间:2011-12-26 05:35:17

标签: c++ algorithm data-structures

我想了解如何存储包含大量数据的图表。我正在设计一个具有巨大铁路网络图的应用程序。其中verticesrailway station name。我在adjacency list中使用C++进行了设计。但现在我发现它耗费了很高的内存,有时我也会遇到no-memory错误。我想知道如何存储这么大的图表,以便可以使用图表上的algorithm

图表定义为

std::map<std::string, std::set<std::string> > railway_graph;

或google / facebook如何存储图形数据结构。

5 个答案:

答案 0 :(得分:1)

使用邻接矩阵表示而不是邻接列表可以减少密集矩阵的内存分配。

因为您没有提到系统的大小或您尝试运行的算法类型,所以很难判断您的算法是否需要检查是否存在不适当的内存消耗,或者您是否确实需要在整个程序中使用文件作为间歇性的“记忆”,以便使计算成为可能。

答案 1 :(得分:0)

您选择的数据结构将需要大量多余的内存,在堆上动态分配。 std::mapstd::string将为每个单独的条目分配一块内存(加上它自己的开销)。 std::string还将为字符串分配一段内存。

对于许多情况来说,这很舒服并且完全没问题。但对大型数据结构来说还不行。

最后你有一个映射,它包含指针(它本身被逐个分配)到集合,其中包含指针(它本身被逐个分配)到字符串,其中包含指向实际字符串缓冲区的指针。

您的实际问题是动态分配产生的开销。在大多数平台上,堆分配只需要额外的16字节内存用于堆管理(尽管数字不同......)。

我建议您按以下方式重新定义图表:

// a list of node names, its index (a size_t) is used in the following data structures
// - alternatively, you may use an std::map<int,std::string> here, to simplify the
//   "index" to "name" lookup...
typedef size_t NodeId;
typedef std::vector<std::string> NodeList;

// an edge
typedef std::pair<NodeId,NodeId> Edge;
// or alternatively:
struct Edge {
    NodeId from, to;
};

// a plain list of edges
typedef std::vector<Edge> EdgeList;

或者,对于您的用例,以下数据结构可能更容易。它与您的示例类似,但在内存表示中更紧凑:

// a list of node names, its index (a size_t) is used in the following data structures
typedef size_t NodeId;
typedef std::vector<std::string> NodeList;

typedef std::vector<NodeId> NodeIdList;

// a map from one node to its adjacent nodes
typedef std::map< NodeId, NodeIdList > Graph;

编辑:添加并使用NodeIdList ...

如果这仍然消耗太多内存,那么你应该考虑将数据保存在磁盘上并按需加载。

如果您的节点名称是常量,那么您还应该考虑某种字符串表,这是内存中字符串数据的更紧凑的表示形式。但这是相当低级的东西。

首先尝试使用更好的数据结构!

答案 2 :(得分:0)

class Node
{
   string id; 
   Data data; // fetch data by ID when required from some database 
}

您可以将与每个工作站相关的数据存储在数据库中,并在需要时按id获取。

图形密度定义为D = 2|E|/(|V|(|V|-1))。您必须根据D设计数据结构。

如果你有密集图,那么你可以使用矩阵表示。您只需要| V | * | V |位大约。

对于稀疏图边缘列表表示是好的。

答案 3 :(得分:0)

使用这样的map和string会增加很多冗余内存的使用。如果将名称存储在一个向量中,并使用整数索引存储邻接列表,那么它应该更加紧凑。

std::vector<std::string> name;
std::vector<std::vector<size_t> > adj_list;

答案 4 :(得分:0)

看看

http://redis.io/

我建议将您的地图转换为redis地图,然后可以将其保存在本地文件系统中。查找非常快,不应该损害性能。