Algorithm 高效的子图散列算法?

Algorithm 高效的子图散列算法?,algorithm,hash,graph-algorithm,Algorithm,Hash,Graph Algorithm,对于给定图的子图(由节点和边组成)是否有散列算法?类似地,我所说的特定图是一个分子网络,对该网络的子图进行散列的目的是,看看给定一个不同的网络,是否有一个特定的子图与先前散列的子图相匹配 我不关心查找所有子图本身的运行时。我关心的是给定一个特定的散列子图和另一个子图,我是否能发现该子图是否是我在O(1)时间内见过的子图。如果您的图是非循环的(具有可变拆分级别的树), 可以在图形的每个顶点(节点)中保留一些值, 即“此子树的哈希” 计算子树哈希是一种简单的递归算法,如: // Initial va

对于给定图的子图(由节点和边组成)是否有散列算法?类似地,我所说的特定图是一个分子网络,对该网络的子图进行散列的目的是,看看给定一个不同的网络,是否有一个特定的子图与先前散列的子图相匹配

我不关心查找所有子图本身的运行时。我关心的是给定一个特定的散列子图和另一个子图,我是否能发现该子图是否是我在O(1)时间内见过的子图。

如果您的图是非循环的(具有可变拆分级别的树), 可以在图形的每个顶点(节点)中保留一些值, 即“此子树的哈希”

计算子树哈希是一种简单的递归算法,如:

// Initial value ~0 meaning "need to compute"
uint32_t subtree_hash(node *p) {
  for(int attempts = 0; p->hash == ~0; attempts++) {
    p->hash = compute_hash(p->value) + attempts;
    foreach node *child in (p->children) {
      p->hash = ((p->hash >> 7) | (p->hash << (32 - 7))) + subtree_hash(child);
  }
  return p->hash; // never ~0
}
//初始值~0表示“需要计算”
uint32\u t子树\u散列(节点*p){
对于(int尝试次数=0;p->hash==0;尝试次数++){
p->hash=compute_hash(p->value)+尝试;
foreach节点*子节点(p->children){
p->hash=((p->hash>>7)|(p->hash hash;//从不~0
}
如果图形是非循环的(具有可变拆分级别的树), 可以在图形的每个顶点(节点)中保留一些值, 即“此子树的哈希”

计算子树哈希是一种简单的递归算法,如:

// Initial value ~0 meaning "need to compute"
uint32_t subtree_hash(node *p) {
  for(int attempts = 0; p->hash == ~0; attempts++) {
    p->hash = compute_hash(p->value) + attempts;
    foreach node *child in (p->children) {
      p->hash = ((p->hash >> 7) | (p->hash << (32 - 7))) + subtree_hash(child);
  }
  return p->hash; // never ~0
}
//初始值~0表示“需要计算”
uint32\u t子树\u散列(节点*p){
对于(int尝试次数=0;p->hash==0;尝试次数++){
p->hash=compute_hash(p->value)+尝试;
foreach节点*子节点(p->children){
p->hash=((p->hash>>7)|(p->hash hash;//从不~0
}

假设顶点有整数ID,我只会按照定义的顺序(例如字典)散列子图中的边列表,使用通常用于散列整数对数组的任何散列算法。此列表中的边表示为具有固有顺序的顶点对,因此如果要表示的图形实际上具有无向边,则还需要按一定顺序排列每条边内的顶点对(例如,从最小值到最大值)。

假设顶点具有整数ID,我将按照定义的顺序(例如字典)散列子图中的边列表,使用通常用于散列整数对数组的任何散列算法。此列表中的边表示为具有固有顺序的顶点对,因此如果要表示的图形实际上具有无向边,则还需要按一定顺序排列每条边内的顶点对(例如,从最小值到最大值)。

对子图进行散列没有有效的算法,否则,图匹配将被称为多项式

由于分子图具有有界连通性,因此存在一些特定的算法


在谷歌上搜索“规范分子签名”我在网上发现了这一点

对子图进行散列没有有效的算法,否则图匹配将被认为是多项式的

由于分子图具有有界连通性,因此存在一些特定的算法


通过谷歌搜索“规范分子签名”我在网上找到了这个

如何定义子图?节点是相同的(身份),还是具有相同的值?编辑。子图由节点以及任何边(定向或无向)组成。散列子图如何工作?我怀疑这是否可行。如果你的散列方案有效,你可以简单地解决图同构。IIRC,图同构很难。我不是说不同标签的子图是同一个子图。我是说,给定特定命名的节点和边,两个子图s相同。但可能仍然不可能。如何定义子图?节点是否相同(标识),或它们是否具有相同的值?已编辑。子图由节点以及任何边(定向或无向)组成。散列子图如何工作?我怀疑这是否可行。如果你的散列方案有效,你可以简单地解决图同构。IIRC,图同构很难。我不是说不同标签的子图是同一个子图。我是说,给定特定命名的节点和边,两个子图这是一样的。但可能仍然不可能。我想您应该对所有子级的子树\u哈希进行异或运算,这样顺序就不重要了。在原始请求中,没有指定order matter或is not matter。因此,默认情况下,我假设-order is matter,因为在最简单的情况下(二叉树),您不能总是在不影响树结构的情况下更改lson rson。当然,如果顺序不重要,则需要禁用旋转,只需添加值。XOR不太好,因为,例如,如果两个子项具有相等的哈希值,则它们的值将与我们的结果交叉。如果使用加法,则会添加2倍的值。交叉掉只有特定和的最低位,但不是整个和。我认为您应该对所有子树的子树\u哈希进行异或运算,以便顺序不重要。在原始请求中,没有指定顺序重要或不重要。因此,默认情况下,我假设-顺序重要,因为在最简单的情况下(二叉树),您不能总是在不影响树结构的情况下更改lson rson。当然,如果顺序不重要,则需要禁用旋转,只需添加值。XOR不太好,因为,例如,如果两个子项具有相等的哈希值,则它们的值将与我们的结果交叉。如果使用加法,则会添加2倍的值。交叉掉只有特定和的最低位,而不是整个和。