一种同构图算法——标准化邻接矩阵算法实现

交换邻接矩阵的行列,标准化邻接矩阵

背景

肝了几天终于把这个算法肝出来了,其实不太高明,而且算法时间复杂度高,但是目前想不到其他办法了,最后出来的代码很简单,但是之前尝试了很多种可能时间复杂度底的方法都行不通,不能将邻接矩阵标准化,最后只得放弃,用这个简单但是算起来很慢的算法。主要是之前做的那些失败的尝试花费了很多时间。

正文

需求

做一个图的项目,想要从邻接矩阵这里获得位置信息,但是可能相同的图结构会给不同的位置编码,因此了解到同构图的概念,去学习了一下,但是主要的提出的计算同构图的方法都是不是基于邻接矩阵的,如果我要直接用他们的算法的话还需要处理我的邻接矩阵,鉴于本人水平有限,所以还是打算从邻接矩阵入手。参考的文献在文件夹:E:\桌面大包\计算机\Graphormer学习 中。

算法讲解

很简单,就是先按度从小到大排列好,然后穷举所有的度相同的排列,这些得到的矩阵做一个排序,选第一个就认为是原邻接矩阵的标准化。
这里需要提到的是有学者发论文,提出过一种标准化邻接矩阵的方法,但是我复现了他的思路并不能标准化邻接矩阵。

代码实现

import torch
import random
import copy
import math

import torch
import numpy as np
import scipy.sparse as sp

from collections import defaultdict
from ast import literal_eval

from itertools import combinations, permutations
import itertools

from functools import reduce

def norm(a):
    #     print('a:\n',a)
    order = a.sum(-1).sort().indices
    b = a[order]
    c = b[:,order]

    #     print('c:\n',c)

    list1 = list(c.sum(-1).numpy())
    set1 = list(set(list1))

    degree_id_dict = {i: [] for i in set1}

    for target in set1:
        for index, nums in enumerate(list1):
            if nums == target:
                degree_id_dict[target].append(index)
    #         degree_id_dict[target] = torch.tensor(degree_id_dict[target])
    degree_id_dict_ = copy.deepcopy(degree_id_dict)

    iterings = [list(permutations(degree_id_dict[i], len(degree_id_dict[i]))) for i in degree_id_dict]  # 打乱index的顺序,所有排列组合做成迭代器

    all_order_lists = fn(iterings)

    c2_list = []
    for all_order_list in all_order_lists:
    #     print(all_order_list)
        c1 = c[list(all_order_list)]
        c2 = c1[:,list(all_order_list)]
    #     print(c)
        c2_list.append(c2.numpy().tolist())


    c2_list_sorted = sorted(c2_list)
    c_min = torch.tensor(c2_list_sorted[0])
    
    return c_min
    
fn = lambda x, code=',': reduce(lambda x, y: [i+j for i in x for j in y], x)
# 直接调用fn(lists, code)

text:


# 创建邻接矩阵
def make_AM(size = 12, numof1 = 30):
    a = torch.zeros(size,size).int()

    for m in range(numof1):
        i,j = random.sample(range(size),2)
    #     x = random.randint(0,9)
        a[i,j] = a[j,i]=1
    return a

# 交换行列,制作同构图
def make_homo_G(a):
    assert a.shape[0] == a.shape[1]
    
    size = a.shape[0]
    order = random.sample(range(size),size)
    b = a[order]
    c = b[:,order]
    return c

for i in range(128):
    homo1 = make_AM(size = 9, numof1 = 20)
    homo2 = make_homo_G(homo1)
#     print(homo1.numpy().tolist())
#     print(homo2.numpy().tolist())
#    print(homo1.sum(-1))
#    print(homo2.sum(-1))
    o1 = (norm(homo1))
    o2 = (norm(homo2))
#     print(o1)
#     print(o2)
    print((o1 != o2).sum())
#     print('=====================================')
上一篇:MySQL基础练习


下一篇:MySQL经典练习题(一)