Симметрично адресуемая матрица
-
07-07-2019 - |
Вопрос
Я ищу создание двумерной матрицы целых чисел с симметричной адресацией (то есть матрица [2,3] и матрица [3,2] будут возвращать одно и то же значение) в Python. Целые числа будут иметь сложение и вычитание, и будут использоваться для логических сравнений. Моя первоначальная идея состояла в том, чтобы создать целочисленные объекты заранее и попытаться заполнить список списков некоторым эквивалентом Python указателей. Я не уверен, как это сделать, хотя. Каков наилучший способ реализовать это, и я должен использовать списки или другую структуру данных?
Решение
Более простой и понятный способ - просто использовать словарь с отсортированными кортежами в качестве ключей. Кортежи соответствуют вашему матричному индексу. Переопределите __ getitem __
и __ setitem __
для доступа к словарю по отсортированным кортежам; вот пример класса:
class Matrix(dict):
def __getitem__(self, index):
return super(Matrix, self).__getitem__(tuple(sorted(index)))
def __setitem__(self, index, value):
return super(Matrix, self).__setitem__(tuple(sorted(index)), value)
А затем используйте это так:
>>> matrix = Matrix()
>>> matrix[2,3] = 1066
>>> print matrix
{(2, 3): 1066}
>>> matrix[2,3]
1066
>>> matrix[3,2]
1066
>>> matrix[1,1]
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "z.py", line 3, in __getitem__
return super(Matrix, self).__getitem__(tuple(sorted(index)))
KeyError: (1, 1)
Другие советы
«Матричные вычисления» Голуба и Ван Лоана; Книга описывает возможную схему адресации:
Вы упаковываете данные в вектор и получаете доступ следующим образом, предполагая, что i > = j:
a_ij = A.vec((j-1)n - j(j-1)/2 + i)
Скорее всего, вам лучше использовать матрицу с полными квадратами. Да, он тратит впустую половину памяти, сохраняя избыточные значения, но сворачивание вашей собственной симметричной матрицы в Python приведет к потере еще больше памяти и ЦП, сохраняя и обрабатывая целые числа как объекты Python. Р>
Вам нужно только сохранить нижний треугольник матрицы. Обычно это делается с одним списком длины n (n + 1) / 2. Вам потребуется перегрузить метод __ getitem __
, чтобы интерпретировать, что означает эта запись.