【问题标题】:Creating symmetric matrix indexes-values in Python在 Python 中创建对称矩阵索引值
【发布时间】:2018-09-17 09:12:36
【问题描述】:

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

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】:

此处输入的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

【讨论】:

  • 这对我来说效果很好,但需要时间。有没有办法达到同样的目的。也许以使用更多内存为代价。在某些情况下,我使用具有大量内存的较小矩阵工作....谢谢
  • @user58925:该算法仅访问 CSR 输入的每个条目一次,直接创建所需的输出结构,并仅分配所需数量的列表。我不确定它是否可以更快,即使获得使用更多内存的许可。
  • 如果可以的话,还有一个问题。我看到使用 sym 函数会占用大量内存。我的印象是,使矩阵对称需要最多两倍于原始矩阵的内存(因为上三角形已经包括对角线)。但是使用sym,矩阵占用的内存增加了4倍以上。你知道为什么会这样吗?可能是因为 Python 列表使用 append 分配了额外的空间。有没有办法避免这个问题?
猜你喜欢
  • 2013-11-18
  • 2011-01-06
  • 1970-01-01
  • 1970-01-01
  • 2021-06-29
  • 1970-01-01
  • 1970-01-01
  • 2014-06-17
  • 1970-01-01
相关资源
最近更新 更多