在Python中创建对称矩阵索引值

问题描述 投票:1回答:1

我有一个矩阵的上三角的列和值列表,我想将其转换为对称矩阵。例如,我有

UpperTriangle = [[[0, 5], [6.0, 4.0]],
                 [[1, 3], [9.0, 6.0]],
                 [[2, 4, 6], [9.0, 6.0, 6.0]],
                 [[3], [4.0]],
                 [[4, 6], [4.0, 4.0]],
                 [[5], [2.6666666666666665]],
                 [[6], [4.0]]]

我想把它转换成

Symmetric = [[[0, 5], [6.0, 4.0]],
             [[1, 3], [9.0, 6.0]],
             [[2, 4, 6], [9.0, 6.0, 6.0]],
             [[1, 3], [6.0, 4.0]],
             [[2, 4, 6], [6.0, 4.0, 4.0]],
             [[0, 5], [4.0, 2.6666666666666665]],
             [[2, 4, 6], [6.0, 4.0, 4.0]]]

第一个列表与矩阵的第一行有关,列表中的第一个列给出了列索引,第二个列表给出了与列索引有关的值。第二个列表与第二行有关,依此类推。在上面的示例中(row = 0,column = 0)的值为6.0,(row = 0,column = 5)的值为4.0,(row = 1,column = 1)的值为9.0,(row = 1,column = 3)有价值6.0。

一种方法是创建一个numpy矩阵,然后使用以下内容创建一个对称矩阵。

W = np.maximum( A, A.transpose() )

但这是不可行的,因为实际问题涉及具有350,000行和列的矩阵,构建一个numpy矩阵A占用太多内存并且转换它需要花费太多时间。

在不诉诸于构建numpy矩阵(使用Python 2.7)的情况下,将UpperTriangle转换为Symmetric的最快Python方法是什么? (在合理的记忆范围内)。

问题出现在使用IBM的Cplex Python API的情况下,您需要插入对称矩阵来设置二次方。

import cplex
my_prob = cplex.Cplex()
my_prob.objective.set_quadratic(Symmetric)
my_prob.solve()
python list matrix cplex
1个回答
1
投票

这里输入的CSR非常方便。在考虑每一行时,您当然要了解对称矩阵的一列。当您到达每一行时,您已经知道从其上三角形形式中省略的所有列的内容。您甚至可以按照它们在该行中出现的顺序了解这些值!

这只是一个简单的编程问题:

def sym(up):        # alters 'up' in place
  pfx=[([],[]) for _ in up]  # to be added to each row
  for r,((cc,vv),(pc,pv)) in enumerate(zip(up,pfx)):
    for c,v in zip(cc,vv):
      if c>r:       # store off-diagonal for later row
        cr,cv=pfx[c]
        cr.append(r); cv.append(v)
    cc[:0]=pc; vv[:0]=pv     # prepend to preserve order
© www.soinside.com 2019 - 2024. All rights reserved.