肝了几天终于把这个算法肝出来了,其实不太高明,而且算法时间复杂度高,但是目前想不到其他办法了,最后出来的代码很简单,但是之前尝试了很多种可能时间复杂度底的方法都行不通,不能将邻接矩阵标准化,最后只得放弃,用这个简单但是算起来很慢的算法。主要是之前做的那些失败的尝试花费了很多时间。
做一个图的项目,想要从邻接矩阵这里获得位置信息,但是可能相同的图结构会给不同的位置编码,因此了解到同构图的概念,去学习了一下,但是主要的提出的计算同构图的方法都是不是基于邻接矩阵的,如果我要直接用他们的算法的话还需要处理我的邻接矩阵,鉴于本人水平有限,所以还是打算从邻接矩阵入手。参考的文献在文件夹: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('=====================================')