Pergunta

Eu estou olhando para criar uma matriz 2-D de inteiros com simétrica endereçamento (isto é, matriz [2,3] e a matriz [3,2] irá devolver o mesmo valor) no pitão. Os inteiros terá adição e subtração feito sobre eles, e ser usadas para comparações lógicas. Minha idéia inicial era criar o inteiro objetos na frente e tentar preencher uma lista de listas com alguns python equivalente de ponteiros. Eu não tenho certeza de como fazê-lo, no entanto. Qual é a melhor maneira de implementar isso, e eu deveria estar usando listas ou outra estrutura de dados?

Foi útil?

Solução

A maneira mais simples e mais limpa é usar apenas um dicionário com tuplas ordenadas como chaves. As tuplas corresponder com o seu índice de matriz. __getitem__ Override e __setitem__ para acessar o dicionário por tuplas ordenadas; aqui está uma classe de exemplo:

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)

E, em seguida, usá-lo como este:

>>> 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)

Outras dicas

Golub e Van Loan de "Matrix Computations" livro descreve um esquema de endereçamento viável:

Você arruma os dados em um vetor e acesso da seguinte forma, assumindo i> = j:

a_ij = A.vec((j-1)n - j(j-1)/2 + i)    

Você é provavelmente melhor fora de usar uma matriz numpy praça cheia. Sim, desperdiça metade da memória que armazena valores redundantes, mas rolando sua própria matriz simétrica em Python vai perder ainda mais memória e CPU por armazenar e processar os inteiros como objetos Python.

Você só precisa armazenar o triângulo inferior da matriz. Tipicamente, isto é feito com um n (n + 1) / 2 lista comprimento. Você vai precisar sobrecarregar o método __getitem__ para interpretar o que os meios de entrada.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top