子图同构算法

  • 如何判定子图同构
  • 定义
  • 判定方法
  • Ullmann算法
  • 1.Ullmann算法的定义
  • 2.Ullmann算法实现
  • 伪代码:
  • 步骤:
  • 判断同构的代码


如何判定子图同构

定义

有个Gα和Gβ, Gα有pa个点,qa条边,Gβ有pb个点,qb条边。A是Gα的邻接矩阵,相应的B是Gβ的邻接矩阵。Gα中的每一个边和点在Gβ中也有相对应的边和点。那么如何判断同构呢。

判定方法

设A是子图,B是原图。那么有一个A的点到B的点的映射。这个映射的模式叫做M。M是pa行,pb列的。M有一个性质就是每行只有一个1,每列至多一个1。这个就是一个A中的点到B中的点的一个映射。我们定义一个C = [cij] = M(MB)T。如果在图A中i和j有边能推导出图C中i和j有边。那为什么是对的呢。因为M是映射,MB就是把B中被映射的点按照顺序抽出来在和B点对应。 M中第i行j列为1的意义是A的第i个点对应,B的第j个点。MB中第i行j列为1的意义是现在A的第i个点对应到的点到B的第j个点有一条边。把这个矩阵转置在乘以M。C就是B中和A对应的点和在B中的边全部抽出来组成的图。

那么如果aij = 1能推导出cij = 1。A就是B的一个子图的同构。

Ullmann算法

1.Ullmann算法的定义

对于图的同构问题,Ullmann 算法是一个简单的图同构算法,它采取的手段就是利用枚举找到子图同构。
这个算法的目的就是 对于一个给定的图Q,要找出在图G当中的和图Q同构的所有的子图。

2.Ullmann算法实现

伪代码:

同构图神经网络模型GAT计算图谱相似度 图的同构算法_知识图谱

步骤:

Step 1 :

建立矩阵同构图神经网络模型GAT计算图谱相似度 图的同构算法_同构图神经网络模型GAT计算图谱相似度_02。 使得同构图神经网络模型GAT计算图谱相似度 图的同构算法_i++_03,如果

Q中第同构图神经网络模型GAT计算图谱相似度 图的同构算法_同构图神经网络模型GAT计算图谱相似度_04-个顶点与同构图神经网络模型GAT计算图谱相似度 图的同构算法_知识图谱_05中第同构图神经网络模型GAT计算图谱相似度 图的同构算法_同构图神经网络模型GAT计算图谱相似度_06-个顶点有相同的标签;

Q中第同构图神经网络模型GAT计算图谱相似度 图的同构算法_同构图神经网络模型GAT计算图谱相似度_04-个顶点的度小于等于同构图神经网络模型GAT计算图谱相似度 图的同构算法_知识图谱_05中第同构图神经网络模型GAT计算图谱相似度 图的同构算法_同构图神经网络模型GAT计算图谱相似度_06-个顶点的度;

同构图神经网络模型GAT计算图谱相似度 图的同构算法_图论_10

Step 2. 从矩阵同构图神经网络模型GAT计算图谱相似度 图的同构算法_同构图神经网络模型GAT计算图谱相似度_02生成矩阵同构图神经网络模型GAT计算图谱相似度 图的同构算法_i++_12. 即对同构图神经网络模型GAT计算图谱相似度 图的同构算法_同构图神经网络模型GAT计算图谱相似度_02进行逐行检查,将部分不为0的元素变成0,使得矩阵同构图神经网络模型GAT计算图谱相似度 图的同构算法_i++_12满足每行有且仅有一个元素为1,每列最多只有一个元素不为0.(最大深度为同构图神经网络模型GAT计算图谱相似度 图的同构算法_知识图谱_15.)

同构图神经网络模型GAT计算图谱相似度 图的同构算法_算法_16

Step 3 按照以下规则判断矩阵同构图神经网络模型GAT计算图谱相似度 图的同构算法_i++_12是否满足条件:
MC=M′(M′⋅MB)T, ∀i∀j:(MA[i][j]=1)⇒(MC[i][j]=1).

Step 4 迭代以上步骤,列出所有可能的矩阵同构图神经网络模型GAT计算图谱相似度 图的同构算法_i++_12.

判断同构的代码

需要输入两个图,以及映射图M,执行step3的步骤

#include<bits/stdc++.h>
using namespace std;
//typedef long long int ll;
const int maxn = 1e5+10;
class Matrix{
   public:
            int **cont;
            //int **du;
            int a, b;
   public:
       Matrix(){
          cont = 0;
          //du = 0;
          a = b = 0;
      }
      Matrix(int a, int b){
          this->a = a;
          this->b = b;
          cont = new int*[a];
          //du = new int*[a];
          for (int i = 0; i < a; i++){
              cont[i] = new int[b];
             // du[i] = new int[b];
              for (int j = 0; j < b; j++){
                  cont[i][j] = 0;
                  //du[i][j] = 0 ;
              }
          }
      }
      Matrix(int *x, int a, int b){
          this->a = a;
          this->b = b;
          cont = new int*[a];
          for (int i = 0; i < a; i++){
              cont[i] = new int[b];
              for (int j = 0; j < b; j++){
                  cont[i][j] = x[i*a + j];
                  //cout<<cont[i][j]<<" ";
              }
              //cout<<endl;
          }
      }
     Matrix(const Matrix& x){
          if (x.isNULL()){
              cont = 0;
              a = b = 0;
          }
          else{
              //x.print();
              a = x.a; b = x.b;
              //cout<<x.a<<" "<<x.b<<endl;
              cont = new int*[a];
              for (int i = 0; i < a; i++){
                  cont[i] = new int[b];
                  for (int j = 0; j < b; j++){
                      cont[i][j] = x.cont[i][j];
                      //cout<<x.cont[i][j]<<" ";
                  }
                  //cout<<endl;
              }
          }
      }
      ~Matrix(){
          for (int i = 0; i < b; i++){
              delete[] cont[i];
          }
          delete cont;
      }
      Matrix Muiltply(Matrix y){
          if (isNULL() || y.isNULL() || b != y.a){
              return Matrix();
          }
          Matrix z(a, y.b);
          for (int i = 0; i < a; i++){
              for (int j = 0; j < y.b; j++){
                  for (int k = 0; k < b; k++){
                      z.cont[i][j] += cont[i][k] * y.cont[k][j];
                  }
              }
          }
          return z;
      }
      //布尔矩阵乘法
    Matrix boolMuiltply(Matrix y){
          if (isNULL() || y.isNULL() || b != y.a){
              return Matrix();
          }
          Matrix z(a, y.b);
          for (int i = 0; i < a; i++){
              for (int j = 0; j < y.b; j++){
                  for (int k = 0; k < b; k++){
                      z.cont[i][j] += cont[i][k] * y.cont[k][j];
                  }
                  if(z.cont[i][j] > 0){
                      z.cont[i][j] = 1;
                 }
              }
          }
          return z;
    }
     bool isNULL() const{
        if (cont == 0){
            return true;
         }
        else{
            return false;
         }
     }
    bool isequal(Matrix& y){
        if(a == y.a && b == y.b){
             for (int i = 0; i < a; i++){
                 for (int j = 0; j < a; j++){
                     if(cont[i][j] != y.cont[i][j]){
                         return false;
                    }
                 }
            }
            return true;
         } else{
             return false;
         }
     }
     //转置
    Matrix Trans(){
        Matrix x(b,a);
        for (int i = 0; i < a; i++){
            for (int j = 0; j < b; j++){
                 x.cont[j][i] = cont[i][j];
            }
         }
         return x;
     }
    bool iscontent(const Matrix &A)const{
        if(a == A.a && b == A.b){
             for (int i = 1; i <= a; i++){
                for (int j = 1; j <= b; j++){
                    if(A.cont[i][j] == 1 && cont[i][j] == 0){
                        return 0;
                     }
                }
             }
             return 1;
         }
         return 0;
     }
     void print(){
         if (isNULL()){
             printf("NULL\n");
        }
         for (int i = 0; i < a; i++){
             for (int j = 0; j < b; j++){
                 cout << cont[i][j] << " ";
             }
             cout << std::endl;
         }
     }
};
int main(){
     typedef Matrix Map;
     typedef Matrix T;
     //A为子图,B为原图,M为映射关系
     Map A,B;T M;
     //根据公式判断
     Map x = M.boolMuiltply(M.boolMuiltply(B).Trans());
     x.iscontent(A);
}