Python 彩色同构图的Hash函数
我有一个无向彩色(相邻节点有不同的颜色)图,我需要计算一个散列,这样,如果两个图同构,它们有相同的散列(该图也是平面的,我不知道它是否能产生一些差异) 我的数据结构如下:Python 彩色同构图的Hash函数,python,graph,hash,isomorphism,Python,Graph,Hash,Isomorphism,我有一个无向彩色(相邻节点有不同的颜色)图,我需要计算一个散列,这样,如果两个图同构,它们有相同的散列(该图也是平面的,我不知道它是否能产生一些差异) 我的数据结构如下: class Node: def __init__(self, id, color): self.id = id # int self.color = color # string self.adjacentNodes = set() id属性用于程序逻辑,因此在比较图形
class Node:
def __init__(self, id, color):
self.id = id # int
self.color = color # string
self.adjacentNodes = set()
id
属性用于程序逻辑,因此在比较图形时不应将其考虑在内
我的想法是对图中的节点进行排序,然后从第一个节点开始探索相邻节点,以生成图的树。
然后,我从树中生成一个唯一的字符串(实际上,我是在探索过程中生成该字符串的)。
所以,我想做的是,找到一种图的规范化
说明
我首先按度排序节点,然后按颜色属性名称升序排序。
我使用第一个节点,开始使用深度优先搜索搜索相邻节点,并以相同的方式对它们进行排序。
我跟踪已访问的节点,以避免扩展旧节点
我的字符串是这样生成的:使用深度优先搜索,每次我到达一个新节点时,我都会将以下内容附加到图形字符串中:
- 节点颜色
- 节点度
- 已访问节点列表中的索引
# actually this function return the unique string associated with the graph
# that will be hashed with the function hash() in a second moment
def new_hash(graph, queue=[]): # graph: list of Node
if not queue: # first call: find the root of the tree
graph.sort(key = lambda x: (len(x.adjacentNodes), x.color), reverse=True)
groups = itertools.groupby(graph, key = lambda x: (len(x.adjacentNodes), x.color))
roots = []
result_hash = ''
for _, group in groups:
roots = [x for x in group]
break # I just need the first (the candidates roots)
temp_hashes = []
for node in roots:
temp_queue = [node.id]
temp_hash = node.color + str(len(node.adjacentNodes)) + str(temp_queue.index(node.id))
temp_hash += new_hash(list(node.adjacentNodes), temp_queue)
temp_hashes.append((node, temp_hash, temp_queue))
temp_hashes.sort(key = lambda x: x[1], reverse=True)
queue = temp_hashes[0][2]
result_hash += temp_hashes[0][1]
result_hash += new_hash(list(temp_hashes[0][0].adjacentNodes), queue=queue)
else:
graph.sort(key = lambda x: (len(x.adjacentNodes), x.color), reverse=True)
groups = itertools.groupby(graph, key = lambda x: (len(x.adjacentNodes), x.color))
grouped_nodes = []
result_hash = ''
for _, group in groups:
grouped_nodes.append([x for x in group])
for group in grouped_nodes:
while len(group) > 0:
temp_hashes = []
for node in group:
if node.id in queue:
temp_hash = node.color + str(len(node.adjacentNodes)) + str(queue.index(node.id))
temp_hashes.append((node, temp_hash, queue))
else:
temp_queue = queue[:]
temp_queue.append(node.id)
temp_hash = node.color + str(len(node.adjacentNodes)) + str(temp_queue.index(node.id))
temp_hash += new_hash(list(node.adjacentNodes), queue=temp_queue)
temp_hashes.append((node, temp_hash, temp_queue))
temp_hashes.sort(key = lambda x: x[1], reverse=True)
queue = temp_hashes[0][2]
result_hash += temp_hashes[0][1]
group.remove(temp_hashes[0][0])
return result_hash
问题
因此,我有两个问题:
- 我的算法真的有效吗(我的意思是,它似乎有效,但我没有任何数学证明)
- 是否有更快的算法(复杂性更低)来计算散列
hash
,它实际上也不是散列。无论如何,我认为我正在做的是一个图的规范化。我试图找到一种规范形式,使我能够始终以相同的方式探索树,以生成正确的字符串标识符。@Code学徒我查阅了论文。它们很有趣,但不要明确地谈论等轴对称,我认为这并不能解决我的问题。