[英]Generating all possible 3-connected graphs
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連通圖的數量是無限的,因此必須以某種方式進行控制,但這不是此問題所關注的。
您的拆分操作應該更加復雜。 您需要修改用於連接到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
生成所有可能的選擇,並將它們應用於每個圖形。
您可能會得到很多同構圖。 我想有一種更好的方法來完成所有這些工作,無法想到。
基於Keith的解決方案 。 這是完全未經測試的,但我想總體思路還可以。 此版本生成拆分,而不是一次返回所有拆分。
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.