gpt4 book ai didi

algorithm - 如何部分比较两个图

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:38:38 28 4
gpt4 key购买 nike

例如,这两个图被认为是完美的部分匹配:

0 - 1

1 - 2

2 - 3

3 - 0

0 - 1

1 - 2

这两个被认为是不匹配

0 - 1

1 - 2

2 - 3

3 - 0

0 - 1

1 - 2

2 - 0

数字不必匹配,只要这些节点之间的关系能够完美匹配即可。

最佳答案

这是子图同构问题:http://en.wikipedia.org/wiki/Subgraph_isomorphism_problem

由于 Ullmann,文章中提到了一种算法。

乌尔曼算法是深度优先搜索的扩展。深度优先搜索将像这样工作:

def search(graph,subgraph,assignments):
i=len(assignments)

# Make sure that every edge between assigned vertices in the subgraph is also an
# edge in the graph.
for edge in subgraph.edges:
if edge.first<i and edge.second<i:
if not graph.has_edge(assignments[edge.first],assignments[edge.second]):
return False

# If all the vertices in the subgraph are assigned, then we are done.
if i==subgraph.n_vertices:
return True

# Otherwise, go through all the possible assignments for the next vertex of
# the subgraph and try it.
for j in possible_assignments[i]:
if j not in assignments:
assignments.append(j)
if search(graph,subgraph,assignments):
# This worked, so we've found an isomorphism.
return True
assignments.pop()

def find_isomorphism(graph,subgraph):
assignments=[]
if search(graph,subgraph,assignments):
return assignments
return None

对于基本算法,possible_assignments[i] = range(0,graph.n_vertices)。也就是说,所有的顶点都是可能的。

Ullmann 通过缩小可能性来扩展这个基本算法:

def update_possible_assignments(graph,subgraph,possible_assignments):
any_changes=True
while any_changes:
any_changes = False
for i in range(0,len(subgraph.n_vertices)):
for j in possible_assignments[i]:
for x in subgraph.adjacencies(i):
match=False
for y in range(0,len(graph.n_vertices)):
if y in possible_assignments[x] and graph.has_edge(j,y):
match=True
if not match:
possible_assignments[i].remove(j)
any_changes = True

这个想法是,如果子图的节点 i 可能与图的节点 j 匹配,那么对于子图中与节点 i 相邻的每个节点 x,必须有可能找到相邻的节点 y到图中的节点 j。这个过程的帮助可能比最初显而易见的要大,因为每次我们消除一个可能的分配时,这可能会导致其他可能的分配被消除,因为它们是相互依赖的。

那么最终的算法是:

def search(graph,subgraph,assignments,possible_assignments):
update_possible_assignments(graph,subgraph,possible_assignments)

i=len(assignments)

# Make sure that every edge between assigned vertices in the subgraph is also an
# edge in the graph.
for edge in subgraph.edges:
if edge.first<i and edge.second<i:
if not graph.has_edge(assignments[edge.first],assignments[edge.second]):
return False

# If all the vertices in the subgraph are assigned, then we are done.
if i==subgraph.n_vertices:
return True

for j in possible_assignments[i]:
if j not in assignments:
assignments.append(j)

# Create a new set of possible assignments, where graph node j is the only
# possibility for the assignment of subgraph node i.
new_possible_assignments = deep_copy(possible_assignments)
new_possible_assignments[i] = [j]

if search(graph,subgraph,assignments,new_possible_assignments):
return True

assignments.pop()
possible_assignments[i].remove(j)
update_possible_assignments(graph,subgraph,possible_assignments)

def find_isomorphism(graph,subgraph):
assignments=[]
possible_assignments = [[True]*graph.n_vertices for i in range(subgraph.n_vertices)]
if search(graph,subgraph,assignments,possible_assignments):
return assignments
return None

关于algorithm - 如何部分比较两个图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13537716/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com