Python 生成所有可能的3连通图

Python 生成所有可能的3连通图,python,algorithm,graph,graph-theory,igraph,Python,Algorithm,Graph,Graph Theory,Igraph,有一个由Tutte和Thomassen(有限和无限图的平面性和对偶性,1979)提出的猜想是这样的 可以得到一个3连通图 通过成功地添加 边并将顶点拆分为两个 至少度的相邻顶点 三个这样的边缘连接他们 不包含在3个循环中。如果我们 应用更一般的拆分 操作(即,我们允许边缘 将两个新的顶点合并为 包含在3个循环中)然后我们可以 从K4开始,我们只需要 拆分操作,以便 生成所有3连通图 我正在尝试使用带有Python的iGraph实现最后一个声明的操作 我想定义一个函数splitVertex(g,v

有一个由Tutte和Thomassen(有限和无限图的平面性和对偶性,1979)提出的猜想是这样的

可以得到一个3连通图 通过成功地添加 边并将顶点拆分为两个 至少度的相邻顶点 三个这样的边缘连接他们 不包含在3个循环中。如果我们 应用更一般的拆分 操作(即,我们允许边缘 将两个新的顶点合并为 包含在3个循环中)然后我们可以 从K4开始,我们只需要 拆分操作,以便 生成所有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-连通图的数量是无限的,但这不是这个问题所关心的。

您的拆分操作应该更复杂一些。您需要修改用于连接到
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
def拆分顶点(g,v):
numver=g.vcount()
g、 添加_顶点(2)
x=numver
y=numver+1
g、 添加_边([(x,y)])
邻居=g.邻居(v)
g、 删除_顶点([v])
新的_图=[]
对于集合分割(邻域)中的(邻域x的邻域,邻域y的邻域):
如果len(_x的邻域_)<2:继续
如果len(y的邻域)小于2:继续
g2=g.copy()
g2.添加_边(映射(lambda邻居_of_x:[邻居_of_x,x],邻居_of_x))
g2.添加_边(映射(lambda neighbor_of_y:[neighbor_of_y,y],neighbor_of_y))
新增_图。添加(g2)
返回新的_图
其中,
set\u split
应生成将
邻居
拆分为两个集合的所有可能方式

然后,您需要为
v
生成所有可能的选择,并将它们应用于每个图形

你可能会得到很多同构图。我想有一个更好的方法来完成这一切,我想不出有什么好办法。

基于。这是完全未经测试的,但我想总的想法是可以的。此版本生成拆分,而不是一次返回所有拆分

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
来自itertools导入链,组合
def动力装置(iterable):
“返回给定iterable中元素的所有可能子集”
s=列表(iterable)
返回链。从_iterable(范围(len(s)+1)内r的组合(s,r))
def分区(iterable):
“返回将集合划分为两个子集的所有可能方法”
s=设定值(iterable)
对于动力装置中的s1:
屈服s1,s-s1
def split_顶点(图形,v1):
#请注意,您只需要一个额外的顶点,其他顶点可以使用v
v2=graph.vcount()
图.添加顶点(1)
#找到v1的邻居
neis=集合(图形邻域(v1))
#删除v1上的所有边-其中一些边将被重新添加
g、 删除_边(例如事件(v1))
#迭代neis的powerset以查找所有可能的拆分
对于分区(neis)中的set1和set2:
如果len(set1)<2或len(set2)<2:
持续
#复制原始图形
g2=g.copy()
#在v1和集合1的成员之间添加边
g2.添加_边([(v1,v3)表示集合1中的v3])
#在v2和集合2的成员之间添加边
g2.添加_边([(v2,v3)表示集合2中的v3])
#返回结果
产量g2

你听起来好像认为3连通图的数目是有限的,但实际上不是,所以你不能生成所有的。证明:取两个3连通图,在它们之间添加3条合适的边,就得到了一个新的3连通图。重复ad infinum。@THC4k:好的,是的;但是对于给定的具有n个节点的3连通图,如何生成所有3连通n+1节点的子体呢?我一直在纸上画草图,我也有点挠头!我不认为3-连通图的数目是有限的,但是n个顶点上的3-连通图的数目肯定是有限的。这能从K_4生成5个顶点上的轮图吗?K_4是一个三次图,邻域数始终为3,在这种情况下,分区将始终导致某些集合小于2,这将导致函数不返回任何内容。