在最接近类似对角线的交互矩阵中找到子矩阵K.

时间:2018-03-05 12:12:09

标签: python matrix algebra

我有一个数学问题,我试图用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]

关于如何提高此算法效率的任何想法?

0 个答案:

没有答案