CCF CSP 矩阵运算 python暴力

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 dd而不是 n ∗ n n*n nn,减少了空间开销。模拟测试满分通过,可时间复杂度并没有降低。想要降低时间复杂度,还是得优化矩阵乘法。

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)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值