Tutte和Thomassen有一个猜想(有限和无限图的平面性和二元性,1979)说这个
可以获得3连通图 从一个轮子通过成功地添加一个 边缘并将顶点分成两部分 至少相邻的顶点 三个使边缘连接起来 不包含在3个循环中。要是我们 应用更一般的分裂 操作(即,我们允许边缘 将两个新顶点连接起来 包含在3个循环中)然后我们可以 从K_4开始,我们只需要 分裂操作以便 生成所有3连通图。
我正在尝试使用iGraph和Python实现上一次声明的操作。
我想定义一个函数splitVertex(g,v),取一个图g和一个顶点v,然后在操作定义时以所有可能的方式拆分v。然后我想要一份所有这些新图表的清单,我会对它们做进一步的工作。
此时,我有以下函数创建两个新的顶点x和y,它们将是拆分后新创建的顶点。
def splitVertex(g,v):
numver = g.vcount()
g.add_vertices(2)
x = numver
y = numver+1
g.add_edges([(x,y)])
有人可以用一种很好的方式来帮我解决这个问题吗?我知道这会产生大量的数据,但没关系,我有充足的时间;)
编辑:当然这必须以某种方式控制,因为3连通图的数量是无限的,但这不是这个问题所关注的。
答案 0 :(得分:1)
您的拆分操作应该更复杂一些。您需要修改用于连接到v
的所有边缘,以便连接到x
或y
。
def splitVertex(g,v):
numver = g.vcount()
g.add_vertices(2)
x = numver
y = numver+1
g.add_edges([(x,y)])
neighbors = g.neighbors(v)
g.delete_vertices([v])
new_graphs = []
for (neighbors_of_x, neighbors_of_y) in set_split(neighbors):
if len(neighbors_of_x) < 2: continue
if len(neighbors_of_y) < 2: continue
g2 = g.copy()
g2.add_edges(map(lambda neighbor_of_x: [neighbor_of_x, x], neighbors_of_x))
g2.add_edges(map(lambda neighbor_of_y: [neighbor_of_y, y], neighbors_of_y))
new_graphs.add(g2)
return new_graphs
set_split
应该生成将neighbors
分成两组的所有可能方法。
然后,您需要为v
生成所有可能的选项,并将其应用于每个图表。
您可能会获得许多同构图。我想有一个更好的方法可以做到这一切,不能把它想到头顶。
答案 1 :(得分:0)
基于Keith's solution。这是完全未经测试的,但我想一般的想法是可以的。此版本生成拆分,而不是一次返回所有拆分。
from itertools import chain, combinations
def powerset(iterable):
"Returns all the possible subsets of the elements in a given iterable"
s = list(iterable)
return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
def partition(iterable):
"Returns all the possible ways to partition a set into two subsets"
s = set(iterable)
for s1 in powerset(s):
yield s1, s-s1
def split_vertex(graph, v1):
# Note that you only need one extra vertex, you can use v for the other
v2 = graph.vcount()
graph.add_vertices(1)
# Find the neighbors of v1
neis = set(graph.neighbors(v1))
# Delete all the edges incident on v1 - some of them will be re-added
g.delete_edges(g.incident(v1))
# Iterate over the powerset of neis to find all possible splits
for set1, set2 in partition(neis):
if len(set1) < 2 or len(set2) < 2:
continue
# Copy the original graph
g2 = g.copy()
# Add edges between v1 and members of set1
g2.add_edges([(v1, v3) for v3 in set1])
# Add edges between v2 and members of set2
g2.add_edges([(v2, v3) for v3 in set2])
# Return the result
yield g2