域用户组成员 导出_导出子图同构(induced subgraph isomorphism)问题

和图
的导出子图有哪些同构的问题可以看成一个约束满足问题(CSP)
,CSP的详细定义见:约束规划,约束传播和CSP问题

导出子图同构问题的形式化

简单地说,图

中的嵌入(embedding)
满足

(1)

,

(2)

,

(3)

,

的某个导出子图的同构(把条件3去掉就是子图同构)

标准形式的导出子图同构问题

的每个结点
都对应一个变量
,因此可以定义双射
变量集

每个结点

的嵌入一定是
中的结点
,因此变量
对应的域为
域集

由条件(1)知,有约束条件

由条件(2)知,对

,有约束条件

由条件(3)知,对

,有约束条件

综合以上3种约束,有约束集

使用求解器求解同构问题

我们已经把导出子图同构对应的CSP问题

表示成了标准形式,因此可以使用求解器进行求解

OR-tools是谷歌开源的运筹学求解器库,详细介绍见:使用谷歌的OR-Tools求解鸡兔同笼

networkx是python的一个图算法库,详细介绍见:python常用代码的第12和13节

以下代码使用OR-tools和networkx求解导出子图同构问题:

import networkx as nx
from ortools.sat.python import cp_model
from itertools import combinations
def var_from_domain(model, name, domain):
    "initialize a variable with integer domain defined by domain"
    domain = cp_model.Domain.FromIntervals([[i] for i in domain])
    val = model.NewIntVarFromDomain(domain, name)
    return val

# 五角星
G=nx.Graph([(1,3),(1,4),(2,4),(2,5),(3,5)])
# 五边形
S=nx.Graph([(1,2),(2,3),(3,4),(4,5),(5,1)])

model = cp_model.CpModel()

D = list(G.nodes)
X = {i:var_from_domain(model, "X("+str(i)+")", D) for i in S.nodes}

# 约束:嵌入 S -> subgraph of G
model.AddAllDifferent([X[i] for i in S.nodes])
E_G = list(G.edges) + [e[::-1] for e in G.edges]
for v1, v2 in combinations(S.nodes,2):
    if (v1,v2) in S.edges:
        model.AddAllowedAssignments((X[v1],X[v2]), E_G)
    else:
        model.AddForbiddenAssignments((X[v1],X[v2]), E_G)

solver = cp_model.CpSolver()
status = solver.Solve(model)
if status == cp_model.FEASIBLE:
    print("有嵌入:")
    for v, x in X.items():
        print('f(%s)=%i' % (v, solver.Value(x)))
else:
    print("不存在导出子图同构")

你可能感兴趣的:(域用户组成员,导出)