我有一個稀疏三角矩陣,我需要將其提升到 2 次方。問題是,其中一個要求是將矩陣存盤為嵌套字典(我需要創建一個 python 實作),因此 numpy 的標準函式不適用。(我知道這種存盤矩陣的方式可能有點矯枉過正,但這是針對大學課程的)
下面是我如何實作矩陣本身的創建(這里很少與稀疏等效):
def __init__(self, *matrix):
self.rare_values = dict()
if len(matrix) > 0:
for i, line in enumerate(matrix):
if i == 0:
self.n = line
continue
value = line[0]
i = line[1]
j = line[2]
if j > i:
i = line[2]
j = line[1]
if i in self.rare_values.keys():
if j in self.rare_values[i].keys():
self.rare_values[i][j] = value
else:
dict_column = {j: value}
self.rare_values[i].update(dict_column)
else:
dict_line = {i: {j: value}}
self.rare_values.update(dict_line)
我的問題是,是否有可能實作一種演算法來將這樣的矩陣提升到 2 次方?如果是這樣,如果你能提供一個偽代碼或極簡主義的解釋來說明我將如何去做,我將不勝感激。
謝謝!
uj5u.com熱心網友回復:
您提供的代碼可以顯著簡化為:
class Sparse:
def __init__(self, n=None, *matrix):
self.rare_values = dict()
self.n = n
for line in matrix:
value, *indices = line
c,r = sorted(indices)
# Personally, here I would have instead used
# r,c = sorted(indices, reverse=True)
# as (r,c) order seems more common, but it's no big deal.
self.rare_values.setdefault(r, {})[c] = value
這會產生與您的方法相同的結構__init__,只是更清楚(IMO)。
從那里開始,對每個值進行平方就像迭代dict-of-dicts一樣簡單,例如使用嵌套的for回圈迭代.items():
def square(self):
for (r,row) in self.rare_values.items():
for (c,val) in row.items():
self.rare_values[r][c] = val ** 2
例子:
class Sparse:
def __init__(self, n=None, *matrix):
self.rare_values = dict()
self.n = n
for line in matrix:
value, *indices = line
c,r = sorted(indices)
self.rare_values.setdefault(r, {})[c] = value
def square(self):
for (r,row) in self.rare_values.items():
for (c,val) in row.items():
self.rare_values[r][c] = val ** 2
s = Sparse(3, (0,0,0), (2,1,1), (4,0,2), (6,2,3), (8,0,4))
print(s.rare_values) # {0: {0: 0}, 1: {1: 2}, 2: {0: 4}, 3: {2: 6}, 4: {0: 8}}
s.square()
print(s.rare_values) # {0: {0: 0}, 1: {1: 4}, 2: {0: 16}, 3: {2: 36}, 4: {0: 64}}
評論的跟進
The following example shows how you might raise the matrix to a power (not the element-wise operation I showed above).
Note this code changes some things from your version and my original version. It accepts items in (r,c,v) order and doesn't attempt to "normalize" the indices like you do to force a triangular matrix.
If you want that behavior you'll have to edit this version to re-add that back.
class Sparse:
def __init__(self, n=None, entries=None):
self.matrix = dict()
self.n = n
for (r,c,v) in (entries or []):
self.set(r, c, v)
def set(self, r, c, v):
self.matrix.setdefault(r, {})[c] = v
def get(self, r, c):
return self.matrix.get(r, {}).get(c, 0)
def square_matrix(self):
result = Sparse(self.n)
for r in range(self.n):
for c in range(self.n):
val = sum(self.get(r,i) * self.get(i,c) for i in range(self.n))
result.set(r, c, val)
return result
sparse = Sparse(2, [
(0,0,1), (0,1,2),
(1,0,3), (1,1,4),
])
print(sparse.matrix) # {0: {0: 1, 1: 2}, 1: {0: 3, 1: 4}}
# = [[1 2]
# [3 4]]
result = sparse.square_matrix()
print(result.matrix) # {0: {0: 7, 1: 10}, 1: {0: 15, 1: 22}}
# = [[ 7 10]
# [15 20]]
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/453478.html
