networkx maximal_matching() 不return最大匹配
networkx maximal_matching() does not return maximum matching
我正在学习使用 networkx python 模块对二分图进行一些匹配。模块中有两个函数给出图的最大基数匹配:
nx.maximal_matching()
nx.bipartite.maxmum_matching()
请注意,虽然名称为 maximal_matching
,但它的文档确实声明它 "Find a maximal cardinality matching in the graph."
由于我的图是二分图,我假设这两个图会给出相同的结果,至少两者的边数相同。然而,我的代码似乎表明 nx.maximal_matching()
给出了错误的答案:正如 nx.bipartite.maxmum_matching()
所建议的那样,可能还有一个优势。
下面是我的工作代码:
import networkx as nx
from networkx import bipartite
def plotGraph(graph,ax,title):
pos=[(ii[1],ii[0]) for ii in graph.nodes()]
pos_dict=dict(zip(graph.nodes(),pos))
nx.draw(graph,pos=pos_dict,ax=ax,with_labels=True)
ax.set_title(title)
return
if __name__=='__main__':
#---------------Construct the graph---------------
g=nx.Graph()
edges=[
[(1,0), (0,0)],
[(1,0), (0,1)],
[(1,0), (0,2)],
[(1,1), (0,0)],
[(1,2), (0,2)],
[(1,2), (0,5)],
[(1,3), (0,2)],
[(1,3), (0,3)],
[(1,4), (0,3)],
[(1,5), (0,2)],
[(1,5), (0,4)],
[(1,5), (0,6)],
[(1,6), (0,1)],
[(1,6), (0,4)],
[(1,6), (0,6)]
]
for ii in edges:
g.add_node(ii[0],bipartite=0)
g.add_node(ii[1],bipartite=1)
g.add_edges_from(edges)
#---------------Use maximal_matching---------------
match=nx.maximal_matching(g)
g_match=nx.Graph()
for ii in match:
g_match.add_edge(ii[0],ii[1])
#----------Use bipartite.maximum_matching----------
match2=bipartite.maximum_matching(g)
g_match2=nx.Graph()
for kk,vv in match2.items():
g_match2.add_edge(kk,vv)
#-----------------------Plot-----------------------
import matplotlib.pyplot as plt
fig=plt.figure(figsize=(10,8))
ax1=fig.add_subplot(2,2,1)
plotGraph(g,ax1,'Graph')
ax2=fig.add_subplot(2,2,2)
plotGraph(g_match,ax2,'nx.maximal_matching()')
ax3=fig.add_subplot(2,2,3)
plotGraph(g_match2,ax3,'bipartite.maximum_matching()')
plt.show()
这是生成的图。如图所示,subplot-2 有 6 条边,而 3 有 7 条边。这是 networkx 实现中的错误还是我在这里做错了什么?
PS: 我的networkx是1.11版本
根据this bug report的回答,返回的匹配是最大匹配,而不是最大匹配。在他们的术语中(我不知道这有多常见)意味着它给出了局部最优而不是全局最优。
因此,对于 maximal_matching 返回的匹配,只能保证不能通过向该匹配添加边使其变大(同时仍然是匹配)。但是,不保证不存在多边的匹配。
networkx.maximal_matching
算法没有按照您想要的方式给出 最大基数 匹配。它实现了一个简单的贪心算法,其结果纯粹是在不能添加额外边的意义上是最大的。
它的对应项,对于您想要的全局最大基数匹配,是 networkx.max_weight_matching
用图论的说法,最大匹配和最大匹配是不同的(即使在二分图中也是如此)。正如 donkopotamus 所指出的,最大匹配仅意味着您不能向其添加更多边。最大匹配意味着没有匹配的边数超过它。这就是函数如此命名的原因。
也就是说,图论中没有最大基数匹配这样的东西。但不幸的是,文档使用了 "maximal cardinality matching" 这样的措辞。这很容易导致人们感到困惑;或者更糟的是误解了算法的目的。
我正在学习使用 networkx python 模块对二分图进行一些匹配。模块中有两个函数给出图的最大基数匹配:
nx.maximal_matching()
nx.bipartite.maxmum_matching()
请注意,虽然名称为 maximal_matching
,但它的文档确实声明它 "Find a maximal cardinality matching in the graph."
由于我的图是二分图,我假设这两个图会给出相同的结果,至少两者的边数相同。然而,我的代码似乎表明 nx.maximal_matching()
给出了错误的答案:正如 nx.bipartite.maxmum_matching()
所建议的那样,可能还有一个优势。
下面是我的工作代码:
import networkx as nx
from networkx import bipartite
def plotGraph(graph,ax,title):
pos=[(ii[1],ii[0]) for ii in graph.nodes()]
pos_dict=dict(zip(graph.nodes(),pos))
nx.draw(graph,pos=pos_dict,ax=ax,with_labels=True)
ax.set_title(title)
return
if __name__=='__main__':
#---------------Construct the graph---------------
g=nx.Graph()
edges=[
[(1,0), (0,0)],
[(1,0), (0,1)],
[(1,0), (0,2)],
[(1,1), (0,0)],
[(1,2), (0,2)],
[(1,2), (0,5)],
[(1,3), (0,2)],
[(1,3), (0,3)],
[(1,4), (0,3)],
[(1,5), (0,2)],
[(1,5), (0,4)],
[(1,5), (0,6)],
[(1,6), (0,1)],
[(1,6), (0,4)],
[(1,6), (0,6)]
]
for ii in edges:
g.add_node(ii[0],bipartite=0)
g.add_node(ii[1],bipartite=1)
g.add_edges_from(edges)
#---------------Use maximal_matching---------------
match=nx.maximal_matching(g)
g_match=nx.Graph()
for ii in match:
g_match.add_edge(ii[0],ii[1])
#----------Use bipartite.maximum_matching----------
match2=bipartite.maximum_matching(g)
g_match2=nx.Graph()
for kk,vv in match2.items():
g_match2.add_edge(kk,vv)
#-----------------------Plot-----------------------
import matplotlib.pyplot as plt
fig=plt.figure(figsize=(10,8))
ax1=fig.add_subplot(2,2,1)
plotGraph(g,ax1,'Graph')
ax2=fig.add_subplot(2,2,2)
plotGraph(g_match,ax2,'nx.maximal_matching()')
ax3=fig.add_subplot(2,2,3)
plotGraph(g_match2,ax3,'bipartite.maximum_matching()')
plt.show()
这是生成的图。如图所示,subplot-2 有 6 条边,而 3 有 7 条边。这是 networkx 实现中的错误还是我在这里做错了什么?
PS: 我的networkx是1.11版本
根据this bug report的回答,返回的匹配是最大匹配,而不是最大匹配。在他们的术语中(我不知道这有多常见)意味着它给出了局部最优而不是全局最优。
因此,对于 maximal_matching 返回的匹配,只能保证不能通过向该匹配添加边使其变大(同时仍然是匹配)。但是,不保证不存在多边的匹配。
networkx.maximal_matching
算法没有按照您想要的方式给出 最大基数 匹配。它实现了一个简单的贪心算法,其结果纯粹是在不能添加额外边的意义上是最大的。
它的对应项,对于您想要的全局最大基数匹配,是 networkx.max_weight_matching
用图论的说法,最大匹配和最大匹配是不同的(即使在二分图中也是如此)。正如 donkopotamus 所指出的,最大匹配仅意味着您不能向其添加更多边。最大匹配意味着没有匹配的边数超过它。这就是函数如此命名的原因。
也就是说,图论中没有最大基数匹配这样的东西。但不幸的是,文档使用了 "maximal cardinality matching" 这样的措辞。这很容易导致人们感到困惑;或者更糟的是误解了算法的目的。