CCF CSP 矩阵运算 python暴力
numpy
不能用numpy,要自己造轮子。我试过了,用numpy无法通过。
1.按矩阵运算的方式暴力写代码
运行超时,只能拿70分。印象中在《算法导论》中看到过矩阵乘法的绝妙算法,可惜没太记住。
代码如下:
def zeros(m, n): #返回整型的m*n全零矩阵
output = [[] for i in range(m)]
for i in range(m):
for j in range(n):
output[i].append(0)
return output
def matirx_mul_Q_KT(mat1, mat2, n, d):
result = zeros(n, n)
for i in range(n):
for j in range(n):
temp = 0
for k in range(d):
temp += mat1[j][k]*mat2[k][i]
result[j][i] = temp
return result
def matrix_mul_V(mat1, mat2, n, d):
result = zeros(n, d)
for i in range(n):
for j in range(d):
temp = 0
for k in range(n):
temp += mat1[i][k]*mat2[k][j]
result[i][j] = temp
return result
def matrix_T(mat, n, d): #转置函数
result = zeros(d, n)
for i in range(n):
for j in range(d):
result[j][i] = mat[i][j]
return result
def matrix_dot_mul(num, mat, n): #点乘函数
for i in range(n):
for j in range(n):
mat[i][j] *= num[i]
return mat
n, d = map(int, input().split())
matQ = [list(map(int, input().split())) for i in range(n)]
matK = [list(map(int, input().split())) for i in range(n)]
matV = [list(map(int, input().split())) for i in range(n)]
matW = list(map(int, input().split()))
matK = matrix_T(matK, n, d)
matQmatKT = matirx_mul_Q_KT(matQ, matK, n, d)
matQmatKT = matrix_dot_mul(matW, matQmatKT, n)
result = matrix_mul_V(matQmatKT, matV, n, d)
for i in range(n):
output = ' '.join(str(x) for x in result[i])
print(output)
2.根据矩阵乘法结合律改变计算顺序
先算 K T × V K^T \times V KT×V,这样矩阵大小就是 d ∗ d d*d d∗d而不是 n ∗ n n*n n∗n,减少了空间开销。模拟测试满分通过,可时间复杂度并没有降低。想要降低时间复杂度,还是得优化矩阵乘法。
def zeros(m, n):
output = [[] for i in range(m)]
for i in range(m):
for j in range(n):
output[i].append(0)
return output
def matirx_mul(mat1, mat2, n, d):
result = zeros(n, n)
for i in range(n):
for j in range(n):
temp = 0
for k in range(d):
temp += mat1[j][k]*mat2[k][i]
result[j][i] = temp
return result
def matrix_mul_Q(mat1, mat2, n, d):
result = zeros(n, d)
for i in range(n):
for j in range(d):
temp = 0
for k in range(d):
temp += mat1[i][k]*mat2[k][j]
result[i][j] = temp
return result
def matrix_T(mat, n, d):
result = zeros(d, n)
for i in range(n):
for j in range(d):
result[j][i] = mat[i][j]
return result
def matrix_dot_mul(num, mat, n, d):
for i in range(n):
for j in range(d):
mat[i][j] *= num[i]
return mat
n, d = map(int, input().split())
matQ = [list(map(int, input().split())) for i in range(n)]
matK = [list(map(int, input().split())) for i in range(n)]
matV = [list(map(int, input().split())) for i in range(n)]
matW = list(map(int, input().split()))
matK = matrix_T(matK, n, d)
matKmatV = matirx_mul(matK, matV, d, n)
matQmatKmatV = matrix_mul_Q(matQ, matKmatV, n, d)
result = matrix_dot_mul(matW, matQmatKmatV, n, d)
for i in range(n):
output = ' '.join(str(x) for x in result[i])
print(output)