应用场景:
提示:这里简述项目相关背景:
现有一个记录了网络节点信息的txt文本,文本中的数据类型都是整数,每一行前两个数字代表这两个节点之间存在连边,即文本前两列表示该网络中的节点连边。现在需要计算这个网络矩阵的特征值和特征向量。
正常状况下的代码:
import numpy as np
#将txt内容转换成矩阵
data = np.loadtxt('E:/za7za8/AB.txt')
matrix = np.array(data)
#计算特征值和特征向量
eigenvalues, eigenvectors = np.linalg.eig(matrix)
#选择最大特征值和对应的特征向量
max_eigenvalue_index = np.argmax(eigenvalues)
max_eigenvalue = eigenvalues[max_eigenvalue_index]
max_eigenvector = eigenvectors[:, max_eigenvalue_index]
print("矩阵的特征值:", eigenvalues)
print("矩阵的特征向量:", eigenvectors)
print("最大特征值:", max_eigenvalue)
print("对应的特征向量:", max_eigenvector)
有时候用array可能会报错,于是升级版代码:
import numpy as np
# 加载txt文件并转换为二维数组
data = np.loadtxt('AB.txt', delimiter=' ')
# 创建零矩阵
n = int(data.max() + 1) # 节点数为最大节点值加1
matrix = np.zeros((n, n))
# 设置连边值
for row in data:
node1, node2 = row
int_node1 = int(node1)
int_node2 = int(node2)
matrix[int_node1, int_node2] = 1
matrix[int_node2, int_node1] = 1 # 如果网络是无向的,可以设置对称的连边值
#计算矩阵的特征值绝对值
eigenvalues = np.abs(np.linalg.eigvals(matrix))
#找到特征值绝对值中的最大值
max_abs_eigenvalue = np.max(eigenvalues)
print("矩阵特征值绝对值的最大值:", max_abs_eigenvalue)
问题描述
提示:这里描述项目中遇到的问题:
问题1:数字与数字之间的空格个数不确定,且该txt中有不止两列数字。
解决代码:
import numpy as np
#将txt文件并转换为二维数组,这步很容易报错
data = np.loadtxt('your/path', delimiter=None, usecols=(0, 1),dtype=int)
#创建零矩阵
n = int(data.max() + 1) # 节点数为最大节点值加1
matrix = np.zeros((n, n))
# 设置连边值
for row in data:
node1, node2 = row
int_node1 = int(node1)
int_node2 = int(node2)
matrix[int_node2, int_node1] = 1
#如果是无向图则再加一行matrix[int_node1, int_node2] = 1
#计算矩阵的特征值绝对值
eigenvalues = np.abs(np.linalg.eigvals(matrix))
#找到特征值绝对值中的最大值
max_abs_eigenvalue = np.max(eigenvalues)
print("矩阵的特征值绝对值的最大值:",max_abs_eigenvalue)
问题2:矩阵节点数过大,内存小算不出来
方案一:
import numpy as np
from scipy.sparse import lil_matrix
from scipy.sparse.linalg import eigsh
#加载txt文件并转换为二维数组
data = np.loadtxt('AB.txt', delimiter=None, usecols=(0, 1), dtype=int)
#获取节点数和创建稀疏矩阵
n = np.max(data) + 1 # 节点数为最大节点值加1
matrix = lil_matrix((n, n))
#设置连边值
for row in data:
node1, node2 = row
matrix[node1, node2] = 1
matrix[node2, node1] = 1 # 如果网络是无向的,可以设置对称的连边值
#计算矩阵的特征值绝对值
eigenvalues, _ = eigsh(matrix, k=1, which='LM')
#找到特征值绝对值中的最大值
max_abs_eigenvalue = np.abs(eigenvalues[0])
print("矩阵特征值绝对值的最大值:", max_abs_eigenvalue)
方案二:
import numpy as np
from scipy.sparse import coo_matrix
from scipy.sparse.linalg import eigsh
# 逐行读取txt文件并构建稀疏矩阵
rows = []
cols = []
with open('AB.txt', 'r') as file:
for line in file:
data = line.strip().split()
node1, node2 = int(data[0]), int(data[1])
rows.append(node1)
cols.append(node2)
rows.append(node2)
cols.append(node1)
# 获取节点数和创建稀疏矩阵
n = max(max(rows), max(cols)) + 1 # 节点数为最大节点值加1
matrix = coo_matrix((np.ones(len(rows)), (rows, cols)), shape=(n, n))
# 计算矩阵的特征值绝对值
eigenvalues, _ = eigsh(matrix, k=1, which='LM')
# 找到特征值绝对值中的最大值
max_abs_eigenvalue = np.abs(eigenvalues[0])
print("矩阵特征值绝对值的最大值:", max_abs_eigenvalue)
方案三:
import numpy as np
from scipy.sparse import coo_matrix
from scipy.sparse.linalg import eigsh, LinearOperator
from scipy.sparse.linalg.eigen.arpack import ArpackNoConvergence
#逐行读取txt文件并构建稀疏矩阵
rows = []
cols = []
with open('AB.txt', 'r') as file:
for line in file:
data = line.strip().split()
node1, node2 = int(data[0]), int(data[1])
rows.append(node1)
cols.append(node2)
rows.append(node2)
cols.append(node1)
#获取节点数和创建稀疏矩阵
n = max(max(rows), max(cols)) + 1 # 节点数为最大节点值加1
matrix = coo_matrix((np.ones(len(rows)), (rows, cols)), shape=(n, n))
#定义线性算子
def matvec(x):
return matrix.dot(x)
linear_operator = LinearOperator((n, n), matvec)
#计算矩阵的特征值绝对值
try:
eigenvalues, _ = eigsh(linear_operator, k=1, which='LM', maxiter=1000)
except ArpackNoConvergence:
eigenvalues = np.array([np.nan])
#找到特征值绝对值中的最大值
max_abs_eigenvalue = np.abs(eigenvalues[0])
print("矩阵特征值绝对值的最大值:", max_abs_eigenvalue)
最后,如果还是算不出来,考虑对矩阵进行归一化(不确定特征值是否不变,仅仅记录)
import numpy as np
from scipy.sparse import coo_matrix
from scipy.sparse.linalg import eigsh
#逐行读取txt文件并构建稀疏矩阵
rows = []
cols = []
with open('E:/WR.txt', 'r') as file:
for line in file:
data = line.strip().split()
node1, node2 = int(data[0]), int(data[1])
rows.append(node1)
cols.append(node2)
rows.append(node2)
cols.append(node1)
#获取节点数和创建稀疏矩阵
n = max(max(rows), max(cols)) + 1 # 节点数为最大节点值加1
matrix = coo_matrix((np.ones(len(rows)), (rows, cols)), shape=(n, n))
#归一化缩放节点数值
normalized_matrix = matrix / np.max(matrix)
#计算归一化后矩阵的特征值绝对值
eigenvalues, _ = eigsh(normalized_matrix, k=1, which='LM')
#找到特征值绝对值中的最大值
max_abs_eigenvalue = np.abs(eigenvalues[0])
print("矩阵特征值绝对值的最大值:", max_abs_eigenvalue)