生成所有可能的3连接图
-
13-10-2019 - |
题
Tutte和Thomassen有一个猜想(有限和无限图的平面和二元性,1979年)说了这一点
可以通过巧妙地添加边缘并将顶点拆分到两个相邻的程度的顶点,至少三个,使得连接在一起的边缘不包含3个周期中的边缘,从而从轮子中获得了3个连接的图。如果我们采用更通用的分裂操作(即,我们允许将两个新顶点连接到3个周期中),那么我们可以从K_4开始,并且我们只需要分裂操作即可生成所有3 - 连接图。
我正在尝试使用python使用IGRAPH实施最后的陈述操作。
我想定义一个函数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个连接图的数量是无限的,但这不是这个问题所关注的。
解决方案
基于 基思的解决方案. 。这是完全未经测试的,但我想总体想法还可以。此版本会生成拆分,而不是一次返回所有这些版本。
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
其他提示
您的分裂操作应该更多地参与其中。您需要修改所有用于连接到的边缘 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
并将它们应用于每个图。
您可能会得到很多同构图。我想有一种更好的方法可以做到这一切,无法从我的头顶上想到它。
不隶属于 StackOverflow