MAC2166 - Introdução à Computação

05/05/2014 - Aula 10

Matrizes

Matrizes são estruturas bidimensionais (tabelas) com m linhas por n colunas muito importantes na matemática, utilizadas por exemplo para a resolução de sistemas de equações e transformações lineares.

Em Python, uma matriz pode ser representada como uma lista de listas, onde elemento da lista contém uma linha da matriz, que por sua vez corresponde a uma lista com os elementos da coluna da matriz. Veja um exemplo abaixo:

In [1]:
linha0 = [1,10,100,1000]
linha1 = [2,20,200,2000]
linha2 = [3,30,300,3000]
matriz1 = [linha0,linha1,linha2]  # A matriz é uma lista de listas
print(matriz1)
matriz2 = [[1,10,100,1000],[2,20,200,2000],[3,30,300,3000]] # Outra forma de criar a matriz
print(matriz2)
matriz1 == matriz2
[[1, 10, 100, 1000], [2, 20, 200, 2000], [3, 30, 300, 3000]]
[[1, 10, 100, 1000], [2, 20, 200, 2000], [3, 30, 300, 3000]]

Out[1]:
True

Para acessar uma posição específica de uma matriz, usamos uma indexação dupla, ou seja, precisamos indicar o índice da linha onde a posição desejada se encontra e depois o índice da coluna (ou seja, o índice da posição desejada dentro dessa linha). Veja o exemplo a seguir:

In [2]:
matriz3 = [[1,10,100,1000],[2,20,200,2000],[3,30,300,3000]] # Outra forma de criar a matriz
print("O valor da posição na segunda linha da matriz, na quarta coluna, é:", matriz3[1][3])
O valor da posição na segunda linha da matriz, na quarta coluna, é: 2000

Exemplo: criando uma matriz A, de tamanho 5x5, com o valor 2 na posição [1][1] e zero nas demais posições

Considere o código abaixo como uma primeira tentativa de criar a matriz A:

In [3]:
linha_com_zeros = [0]*5
A = [ linha_com_zeros ] * 5
print(A)
A[1][1] = 2
print(A)
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
[[0, 2, 0, 0, 0], [0, 2, 0, 0, 0], [0, 2, 0, 0, 0], [0, 2, 0, 0, 0], [0, 2, 0, 0, 0]]

Essa primeira tentativa de criar a matriz A não foi bem sucedida. Em lugar de criar uma lista contendo 5 listas independentes de tamanho 5, acabamos criando uma lista contendo 5 referências para uma mesma lista. Com isso, ao alterar uma posição de uma das linhas de A, também alteramos a mesma posição de todas as demais linhas de A. Certamente, esse não é o modo correto de criar e inicializar uma matriz.
Note que o que foi feito acima equivale ao trecho de código (mais curto, mas igualmente semanticamente incorreto) abaixo:

In [4]:
A = [ [0] * 5 ] * 5
print(A)
A[1][1] = 2
print(A)
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
[[0, 2, 0, 0, 0], [0, 2, 0, 0, 0], [0, 2, 0, 0, 0], [0, 2, 0, 0, 0], [0, 2, 0, 0, 0]]

O código a seguir mostra a forma correta de se criar A. Note que precisamos usamos um laço (no caso, o for) para criar 5 listas contendo 5 elementos cada, sendo que cada uma delas foi adicionada à lista A, correspondendo a uma linha das linhas da matriz A.

In [5]:
A = []
for i in range(5):
   A.append( [0] * 5 )
A[1][1] = 2
print(A)
[[0, 0, 0, 0, 0], [0, 2, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]

Problema 19

Escreva um programa que lê n e uma matriz An x n, e verifica se A é simétrica.

In []:
n = int(input("Digite o número de linhas da matriz quadrada: "))
print("Digite os elementos da matriz de tamanho %dx%d:" %(m,n))
A = []
for i in range(m):
    A.append([])
    for j in range(n):
        elemento = input("Elemento da %da. linha, %da. coluna: " %(i+1,j+1))
        A[i].append(elemento)    
        
simetrica = True
i = 0
while simetrica and i < n:
    j = 0
    while simetrica and j < i:
        if A[i][j] != A[j][i]:
            simetrica = False
        j += 1
    i += 1

if simetrica:
    print("A matriz eh simetrica.")
else:
    print("A matriz nao eh simetrica.")

Problema 20

Escreva um programa que recebe duas matrizes Am x n e Bn x p e imprime a matriz Cm x p que é o produto de A por B.

In []:
def main():
    m = int(input("Digite o numero de linhas da matriz A: "))
    n = int(input("Digite o numero de colunas da matriz A: "))
    A = le_matriz(m,n)

    p = int(input("Digite o numero de colunas da matriz B: "))
    B = le_matriz(n,p)

    C = []
    for i in range(m):
        C.append([])
        for j in range(p):
            soma = 0
            for k in range(n):
                soma += A[i][k] * B[k][j]
            
            C[i].append(soma)
            
    print("O resultado da multiplicaçao de A por B e: ")
    imprime_matriz(C)        

        
def le_matriz(m, n):
    """
    (int, int) --> list
    
    Funçao que recebe como entrada um numero de linhas m
    e um numero de colunas n e entao le uma matriz de inteiros
    tamanho m x n, ou seja, uma lista contendo m listas
    com n elementos cada. A matriz lida eh devolvida como
    valor de retorno da funçao. 
    """

    print("Digite os elementos da matriz de tamanho %dx%d:" %(m,n))
    matriz = []
    for i in range(m):
        matriz.append([])
        for j in range(n):
            elemento = int(input("Elemento da %da. linha, %da. coluna: " %(i+1,j+1)))
            matriz[i].append(elemento)
            
    return matriz

def imprime_matriz(matriz):
    """
    (list) --> None

    Funçao que recebe uma matriz como entrada, ou seja uma
    lista de listas, e entao a imprime.
    A funçao nao tem nenhum valor de retorno.
    """
    
    for linha in matriz:
        for elemento in linha:
            print(elemento, end = " ")
        print()

#########################
main()

Problema Extra 1

Faça um programa que leia n e os elementos de uma matriz real An x n e verifica se a matriz A tem uma linha, coluna ou diagonal composta apenas por zeros.

In []:
def main():
    n = int(input("Digite o numero de linhas da matriz A: "))
    A = le_matriz(n,n)

    # Verifica se matriz tem linhas ou colunas compostas por zeros

    achou_linha_zeros = False
    achou_coluna_zeros = False
    i = 0
    while ((not achou_linha_zeros) or (not achou_coluna_zeros)) and i < n:
        linha_somente_zeros = True
        coluna_somente_zeros = True
        j = 0
        while (linha_somente_zeros or coluna_somente_zeros) and j < n:
            if A[i][j] != 0.0:
                linha_somente_zeros = False

            if A[j][i] != 0.0:
                coluna_somente_zeros = False

            j += 1
        i += 1

        if linha_somente_zeros:
            achou_linha_zeros = True
            
        if coluna_somente_zeros:
            achou_coluna_zeros = True

    if achou_linha_zeros:
        print("A matriz tem uma linha composta por zeros.")

    if achou_coluna_zeros:
        print("A matriz tem uma coluna composta por zeros.")

    # Verifica se as diagonais sao compostas por zeros
    i = 0
    diagonal1_somente_zeros = True
    diagonal2_somente_zeros = True
    while (diagonal1_somente_zeros or diagonal2_somente_zeros) and i < n:
        if A[i][i] != 0.0:
            diagonal1_somente_zeros = False
        if A[i][n-i-1] != 0.0:
            diagonal2_somente_zeros = False
        i += 1
            
    if diagonal1_somente_zeros or diagonal2_somente_zeros:
        print("A matriz tem uma diagonal composta por zeros.")

    
def le_matriz(m, n):
    """
    (int, int) --> list
    
    Funçao que recebe como entrada um numero de linhas m
    e um numero de colunas n e entao le uma matriz de reais 
    de tamanho m x n, ou seja, uma lista contendo m listas
    com n elementos cada. A matriz lida eh devolvida como
    valor de retorno da funçao. 
    """

    print("Digite os elementos da matriz de tamanho %dx%d:" %(m,n))
    matriz = []
    for i in range(m):
        matriz.append([])
        for j in range(n):
            elemento = float(input("Elemento da %da. linha, %da. coluna: " %(i+1,j+1)))
            matriz[i].append(elemento)
            
    return matriz

#########################
main()

Problema Extra 2

Um jogo de palavras cruzadas pode ser representado por uma matriz Am x n onde cada posição da matriz corresponde a um quadrado do jogo, sendo que 0 indica um quadrado branco e -1 indica um quadrado preto. Indicar na matriz as posições que são início de palavras horizontais e/ou verticais nos quadrados correspondentes (substituindo os zeros), considerando que uma palavra deve ter pelo menos duas letras. Para isso, numere consecutivamente tais posições.

Exemplo: Dada a matriz

0 -1 0 -1 -1 0 -1 0
0 0 0 0 -1 0 0 0
0 0 -1 -1 0 0 -1 0
-1 0 0 0 0 -1 0 0
0 0 -1 0 0 0 -1 -1
A saída deve ser:

1 -1 2 -1 -1 3 -1 4
5 6 0 0 -1 7 0 0
8 0 -1 -1 9 0 -1 0
-1 10 0 11 0 -1 12 0
13 0 -1 14 0 0 -1 -1
In []:
def main():
    m = int(input("Digite o número de linhas da matriz A: "))
    n = int(input("Digite o número de colunas da matriz A: "))

    # Vamos ler a matriz, colocando uma moldura de "-1" em torno dela,
    # para facilitar os calculos
    A = [[-1] * (n+2)]
    for i in range(1,m+1):
        A.append([-1])
        for j in range(1,n+1):
            elemento = int(input("Elemento da %da. linha, %da. coluna: " %(i,j)))
            A[i].append(elemento)
        A[i].append(-1)
    A.append([-1] * (n+2))

    print("A matriz lida é: ")
    imprime_matriz_sem_moldura(A)
        
    cont = 1
    for i in range(1,m+1):
        for j in range(1,n+1):
            if A[i][j] == 0 and ( (A[i][j-1] == -1 and A[i][j+1] == 0) \
                                  or (A[i-1][j] == -1 and A[i+1][j] == 0)):
                A[i][j] = cont
                cont += 1

    print("A matriz de resultado é:")
    imprime_matriz_sem_moldura(A)
    

def imprime_matriz_sem_moldura(matriz):    
    for i in range(1,len(matriz)-1):
        for j in range(1,len(matriz[i])-1):
            print("%2d" %matriz[i][j], end = " ")
        print()
        
#########################
main()

Tópicos vistos na Aula 10

Referências e outros materiais para estudo