其他分享
首页 > 其他分享> > 图的同构问题

图的同构问题

作者:互联网

图的同构问题

引用知网论文[1]张海龙. 图的同构问题算法研究[D].华中科技大学,2007.中基于矩阵变换的同构算法的步骤。用python编写代码实现。这里只是简单判断图是否同构,不涉及映射关系。代码涉及的行间异或矩阵、行间同或矩阵、同型矩阵等自己去参考这个论文。代码由于只是简单翻译算法步骤,相信读起来很困难,如果先去看看这个论文再来看代码就非常容易看懂了。本人是python初学者,有一些代码写的也是很弱智,请见谅。
来源上面已经说明

'''
    图的同构
    A  B  是否同构
    步骤:
        结点数目相同? 没意义
        度数相同?
        对B全排列 A与全排列的子集逐一匹配
        匹配则同构 若均不满足 则不同构
        时间复杂度 全排列 n! 吓死人的
        根据百度 从 图的同构问题算法研究_张海龙这一论文中找到一种解法
        时间复杂度O(n^3)空间复杂度O(n^2)
        无向图G=(V,E),G1=(V1,E1)设邻接矩阵为A 同型矩阵为AA,行间同或矩阵为RA,行间异或矩阵为RX
        步骤:
        求出同型矩阵AA
        根据同或异或距离计算方法求出RA,RX
        以G的RX为参照,对RX的每一行,搜索G1的RX的所有行,找到一个匹配,若无匹配则不同构,若匹配则下一步骤
        判断在A,RX中是否存在同样匹配,若存在则调整相应行列,转上一步骤,若不成立则不同构
        所所有行存在行行交换,则继续寻找顶点之间的一一关系。
        以下根据论文中的以此算法做实例3.3图同构的实例应用分析 写出对应的代码
'''
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
def getAA(A): #获取同型矩阵
    RES=np.full((len(A), len(A)), 0)
    for i in range(len(A)):
        for j in range(len(A)):
            if(A[i][j]>0):
                RES[i][j]=1
    return RES
def getRA(A,AA):#获取行间同或矩阵为RA
    RX = np.full((len(A), len(A)), 0)
    for i in range(len(A)):
        for j in range(len(A)):
            if(i==j):
                RX[i][j]=AA[i][j]
            else:
                res=0
                for k in range(len(A)):
                    res += (A[i][k] + A[j][k])*((AA[i][k]^AA[j][k])^1)
                RX[i][j] = res
    return RX
def getRX(A,AA):#获取行间异或矩阵为RA
    RX=np.full((len(A),len(A)),0)
    for i in range(len(A)):
        for j in range(len(A)):
            if (i == j):
                RX[i][j] = AA[i][j]
            else:
                res = 0
                for k in range(len(A)):
                    res += (A[i][k] + A[j][k])*(AA[i][k]^AA[j][k])
                RX[i][j] = res
    return RX
if __name__ == '__main__':
    A=np.array([
        [1,2,1,1,1],
        [2,0,3,1,1],
        [1,3,0,2,2],
        [1,1,2,0,1],
        [1,1,2,1,0]
    ])#测试邻接矩阵01
    AA=getAA(A)#获取同型矩阵
    RA=getRA(A,AA)#获取行间同或矩阵为RA
    RX=getRX(A,AA)#获取行间异或矩阵为RA
    A1=np.array([
        [0,2,1,1,1],
        [2,0,1,2,3],
        [1,1,1,1,2],
        [1,2,1,0,1],
        [1,3,2,1,0]
    ])#测试邻接矩阵02
    AA1=getAA(A1)#获取同型矩阵
    RA1=getRA(A1,AA1)#获取行间同或矩阵为RA
    RX1=getRX(A1,AA1)#获取行间异或矩阵为RA
    flag=0#判断同不同构
    aid=np.full((len(A),len(A)),0)#复制A邻接矩阵 这个只是用来与结果比对 没什么其他作用了
    for i in range(len(A)):
        for j in range(len(A)):
            aid[i][j]=A[i][j]
    for i in range(len(RX1)):
        # print("RX1:",RX1[i])
        # temp=[]#测试用的
        index=-1
        for j in range(len(RX)):
            if(set(RX[j]) == set(RX1[i])):
                # temp=RX[j]#测试用的
                index=j #找到匹配的行了 记录用于下一步骤
                break#找到了就没必要找接下去了 
        if(index!=-1):#也就是找到匹配行
            # print("temp:",temp)#测试用的
            if(set(RA[index]) != set(RA1[i]) or set(A[index]) != set(A1[i])): #还要判断相对应的行间同或矩阵、行间异或矩阵是否也存在同样的匹配
                flag=1
                print("非同构!")
                break
            #若成立才交换 否则直接退出
            print("交换行{1} {0}".format(index + 1, i + 1))
            #以下都是同样的操作 交换对应矩阵的行和列 先交换行 再交换列
            for k in range(len(RX)):
                RX[index][k], RX[i][k] = RX[i][k], RX[index][k]
            for k in range(len(RX)):
                RX[k][index], RX[k][i] = RX[k][i], RX[k][index]
            for k in range(len(RX)):
                RA[index][k],RA[i][k]=RA[i][k],RA[index][k]
            for k in range(len(RX)):
                RA[k][index],RA[k][i]=RA[k][i],RA[k][index]
            for k in range(len(RX)):
                A[index][k],A[i][k]=A[i][k],A[index][k]
            for k in range(len(RX)):
                A[k][index],A[k][i]=A[k][i],A[k][index]
        else:
            print("非同构!")
            break
    if(flag==0):
        print("同构!")
        print("起始矩阵:\n",aid)
        print("变换后的矩阵:\n",A)
        print("与另外一个矩阵A1:\n{0}一致".format(A1))

复杂度就不详细计算了。
时间复杂度:O(n^3),n表示结点个数。
空间复杂度:O(n^2),涉及邻接矩阵。

改算法设计是本人的算法课实验作业,本人实在想不出好的方法,才从知网上找相关思路,翻译成代码完成作业的,别学。

标签:index,同构,矩阵,RX,len,问题,range,RA
来源: https://blog.csdn.net/moucle_man/article/details/121515346