我有一个数学问题,我试图用Python解决。
我有一个尺寸为n x n的2D交互或design structure矩阵M.非对角线元素E_ij或E_ji对应于i和j之间的交互或依赖性水平,如下所示(n = 4,注意E_ij不一定等于E_ji):
array([[1. , 0.84329654, 0.20122157, 0.77170836],
[0.13859503, 1. , 0.60849155, 0.75713354],
[0.08269742, 0.2694153 , 1. , 0.81393679],
[0.89496009, 0.32028813, 0.0307102 , 1. ]])
我想找到一个包含元素k< n,最小化这种非对角线值。换句话说,我想在M中找到最接近对角矩阵的子集矩阵K.在子集矩阵K中,行索引应该与列索引相同,但不一定是连续的。
因此,对于上面给出的数组的例子,如果k = 2,那么我们总共有6个可能的子矩阵(例如4选择2),而对我来说最优的子矩阵将是(i = 0) ,j = 2):
[[1. 0.20122157]
[0.08269742 1. ]]
现在,我的解决方案是蛮力,所以对于大的值(n选择k,它变得非常慢。这是我到目前为止的解决方案:
import numpy as np
from itertools import combinations
from operator import itemgetter
n = matrix.shape[0] # size of original matrix
k = 2
sub = combinations(range(0, n), k)
sub = list(sub) # list of all possible index combinations
# populate all possible sub-matrices
sub_matrices = []
for comb_idxs in sub:
sub_val = matrix[np.ix_(comb_idxs, comb_idxs)]
sub_matrices.append(sub_val)
# make an off-diagonal mask
inv_eye = np.ones([k, k])
np.fill_diagonal(inv_eye, 0)
# apply mask to sub-matrices and sum their off-diagonal values
off_diag_sub_matrices = sub_matrices*inv_eye
off_diag_sum = np.sum(np.sum(off_diag_sub_matrices, axis=1), axis=1)
# find the index of the sub-matrix with minimal off-diagonal sum
min_idx = min(enumerate(off_diag_sum), key=itemgetter(1))[0]
关于如何提高此算法效率的任何想法?