我有一个节点图,这些节点可能是项目的潜在重复项,我正在尝试找到所有可能的匹配组合。如果连接了两个节点,则意味着它们可能是同一项目,但是没有一个节点可以匹配超过一次。
例如,如果我使用以下简单图形:
T = nx.Graph()
T.add_edge('A','B')
T.add_edge('A','C')
T.add_edge('B','D')
T.add_edge('D','A')
在此示例中,我的输出可能是:
[{A:B},{A:C,B:D},{A:D}]
如何创建唯一组合列表?一些图有约20个节点,因此无法通过所有组合进行强行使用。
答案 0 :(得分:1)
似乎您正在寻找的是找到G的匹配项,即没有两个边共享同一顶点的边集合。
特别是,您正在寻找G的最大匹配项。
Networkx提供功能maximal_matching。您可以扩展此功能以获得所有最大匹配。
一种实现方法可能是以下方法。您从部分匹配的列表开始,每个匹配由一条边组成。然后将每个部分匹配扩展到最大匹配,即直到不能扩展为更大基数的匹配为止。
如果可以使用边缘(u,v)将部分匹配的 m 扩展为更大的一个,则 m'= m∪{(u ,v)} 添加到部分匹配列表中。否则,将 m 添加到最大匹配项列表中。
以下代码可以通过多种方式进行改进以提高效率。一种方法是在添加到部分匹配列表之前进行检查。实际上,该列表将包含表示同一项的部分匹配项(即[{i,j},{u,v}]和[{u,v},{i,j}]))。
import networkx as nx
import itertools
def all_maximal_matchings(T):
maximal_matchings = []
partial_matchings = [{(u,v)} for (u,v) in T.edges()]
while partial_matchings:
# get current partial matching
m = partial_matchings.pop()
nodes_m = set(itertools.chain(*m))
extended = False
for (u,v) in T.edges():
if u not in nodes_m and v not in nodes_m:
extended = True
# copy m, extend it and add it to the list of partial matchings
m_extended = set(m)
m_extended.add((u,v))
partial_matchings.append(m_extended)
if not extended and m not in maximal_matchings:
maximal_matchings.append(m)
return maximal_matchings
T = nx.Graph()
T.add_edge('A','B')
T.add_edge('A','C')
T.add_edge('B','D')
T.add_edge('D','A')
print(all_maximal_matchings(T))