我想了解如何存储包含大量数据的图表。我正在设计一个具有巨大铁路网络图的应用程序。其中vertices
是railway station name
。我在adjacency list
中使用C++
进行了设计。但现在我发现它耗费了很高的内存,有时我也会遇到no-memory
错误。我想知道如何存储这么大的图表,以便可以使用图表上的algorithm
。
图表定义为
std::map<std::string, std::set<std::string> > railway_graph;
或google / facebook如何存储图形数据结构。
答案 0 :(得分:1)
使用邻接矩阵表示而不是邻接列表可以减少密集矩阵的内存分配。
因为您没有提到系统的大小或您尝试运行的算法类型,所以很难判断您的算法是否需要检查是否存在不适当的内存消耗,或者您是否确实需要在整个程序中使用文件作为间歇性的“记忆”,以便使计算成为可能。
答案 1 :(得分:0)
您选择的数据结构将需要大量多余的内存,在堆上动态分配。 std::map
和std::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地图,然后可以将其保存在本地文件系统中。查找非常快,不应该损害性能。