Python:在以边列表表示的图形中查找连接的组件
我在表格中有一个边缘列表Python:在以边列表表示的图形中查找连接的组件,python,algorithm,search,graph,networkx,Python,Algorithm,Search,Graph,Networkx,我在表格中有一个边缘列表 start | end a c b d e b 我有几千万条边(大约3000万条),我无法将整个图形读入内存-至少不能使用networkx这样的库,因为它有点内存密集 我的目标是在该列表所表示的图中找到包含少于x个节点的所有连接组件 例如,我希望获得节点数小于x=30的所有连接组件。但我不想通过构建整个图然后搜索连接的组件(例如,调用此networkx命令:nx.connected\u component\u子图(nxg))来
start | end
a c
b d
e b
我有几千万条边(大约3000万条),我无法将整个图形读入内存-至少不能使用networkx这样的库,因为它有点内存密集
我的目标是在该列表所表示的图中找到包含少于x
个节点的所有连接组件
例如,我希望获得节点数小于x=30
的所有连接组件。但我不想通过构建整个图然后搜索连接的组件(例如,调用此networkx命令:nx.connected\u component\u子图(nxg)
)来实现这一点
是否有一种方法可以只使用边缘列表文件搜索连接的组件,而不必构建整个图形
附加信息:节点名称是长度为10-20 asci值的字符串。首先需要为节点分配较短的标识符,以减少数据占用空间。您可以将这些较短的标识符和原始名称之间的映射写入另一个文件,以便在运行算法后将任何解决方案转换为这些名称 假设您有足够短的节点标识符,您可以将内存中的所有内容加载到由节点标识符键入的字典中 然后使用Union Find结构和算法来识别连接的组件 最后,按允许的最大大小过滤这些内容 有一些库提供了unionfind实现,可以提供更好的性能。下面是Union Find的一个简单实现:
class Node:
def __init__(self, key):
self.key = key
self.parent = self
self.size = 1
class UnionFind(dict):
def find(self, key):
node = self.get(key, None)
if node is None:
node = self[key] = Node(key)
else:
while node.parent != node:
# walk up & perform path compression
node.parent, node = node.parent.parent, node.parent
return node
def union(self, key_a, key_b):
node_a = self.find(key_a)
node_b = self.find(key_b)
if node_a != node_b: # disjoint? -> join!
if node_a.size < node_b.size:
node_a.parent = node_b
node_b.size += node_a.size
else:
node_b.parent = node_a
node_a.size += node_b.size
此演示的输出为:
[['i', 'e', 'a', 'u', 'o'], ['g', 'r', 'm', 'h'], ['k', 's', 'v']]
你的节点名有多长?假设它们被编码为整数,那么它们的数组只需要大约500 MB。我将使用pandas将文件读取为csv,将第一列设置为排序索引,并从头开始实现广度优先搜索。通过巧妙地使用loc,这可能会变得非常迅速。我正在使用pandas来读取文件。但节点名称是长度为10-20 asci值的字符串。我会用这些信息更新帖子。你有没有从边缘列表中搜索CCs的代码示例@Alexnet重要的信息是,你可以把所有的东西都放进记忆中。如果第一列是索引,我相信在while循环中使用df.loc[第二列]可以相对容易地实现广度优先搜索。如果我以后有时间,我会写一个原型。这太完美了,谢谢
data = """x d
c j
i e
f x
n z
a u
g r
w x
p l
u o
m g
k s
t q
y l
h m
n b
k v
e u
i o
r m
n c
x q
f q
j l
s v"""
results = find_components(data.splitlines(), 5)
print(results)
[['i', 'e', 'a', 'u', 'o'], ['g', 'r', 'm', 'h'], ['k', 's', 'v']]