Resolução de Matriz NxM
Publicado por Karl Phillip 14/08/2004
[ Hits: 23.131 ]
Esse código escrito em Python resolve uma matriz NxM pelo método Gauss-Jacobi e quando possível aplica Regressão/Eliminação (somente se todos os elementos da diagonal inferior forem igual a 0).
É um programa matemático para resolver problemas de Programação Linear (Pesquisa Operacional). Gostaria de agradecer a Aloysio de Paiva Figueiro pelo suporte durante todo o desenvolvimento do programa.
#!/usr/bin/env python # >> Desenvolvido em Python (LPOO) *Windows*: http://www.cygwin.com/setup.exe # >> http://www.python.org *GNU/Linux*: http://www.python.org/download/ # - Le uma matriz NxM do teclado # - Aplica o metodo Gauss-Jacobi # - Aplica o Regrecao/Eliminacao # # Universidade do Oeste de Santa Catarina - UNOESC / Videira # Disciplina: Pesquisa Operacional # Academico: Karl Phillip Buhr from __future__ import division ##Para as divisoes retornarem floating points import sys ##Importa modulo Padrao class InvalidSizeError(Exception): """Excessao pra levantar caso as linhas da matriz tenham tamanho diferente""" pass def printM(m): ##printM() imprime uma matriz na tela """Imprime a matriz""" for j in m: for elem in j: print "%3d" % elem, print "" print "" def readM(): ##readM() le uma matriz NxM do teclado """Le matriz do teclado""" matriz = [] ## Lista vazia para conter a matriz lastsize = 0 ## Guarda o tamanho da ultima linha lida.. ##..para comparar com a seguinte print ">> Entre com a MATRIZ: (linha em branco para terminar):" while 1: r = sys.stdin.readline() ## Le uma linha da entrada padrao if r.strip(): ## Come newlines/espacos em branco nos extremos l = r.split() ## Parte uma string nos espacos em branco.. ##.. '1 2 32 1 2' --> ['1', '2', '32', '1', '2'] s = len(l) ## s = tamanho de l if lastsize and s != lastsize: ## Se o tamanho da linha for diferente da anterior raise InvalidSizeError, "As linhas devem ter todas o mesmo numero de colunas." matriz.append([float(elem) for elem in l]) ## Converte os elementos da linha pra inteiros.. ##.. e coloca na matriz lastsize = s ## Linha atual vira linha anterior... retoma o loop else: break ## Linha vazia: sai do loop return matriz ## retorna a matriz ##### Inicio da funcao que aplica os metodos ###### def jacobi_reg(mat, ErroR, MaX): COLUNAS = 0 numIT = 1 switchh = False ##### Aplica o metodo Gauss-Jacobi ###### LINHAS = len(mat) ## numero de linhas for C in mat[0]: COLUNAS += 1 ## numero de colunas print ">> Dimensao da Matriz: [%d][%d]\n" %(LINHAS, COLUNAS) ## Imprime numero de Linhas X Colunas if ((COLUNAS - LINHAS) != 1): print ">> *** Existem mais linhas do que colunas ***\n" sys.exit(1) ###### Primeira iteracao ###### B = list(zip(*mat)[-1]) ## B[] Vetor que guarda a ultima coluna da matriz X0 = [B[i]/mat[i][i] for i in xrange(LINHAS)] ## Guarda o result de X[i]= b1/a11 , X[i]=b2/a22 etc.. X1 = list(X0) ## X1(atual) = X0(anterior) ###### Segunda iteracao em diante.. ###### numIT += 1 while not switchh: sup = 0 div = 0 for i in xrange(LINHAS): X1[i] = B[i] for j in xrange(COLUNAS-1): if ( i != j): X1[i]= (X1[i] - (mat[i][j] * X0[j])) X1[i] = (1/mat[i][i] * X1[i]) aux = X1[i] - X0[i] if (aux < 0) : aux = aux * -1 aux2 = X1[i] if (aux2 < 0): aux2 = aux2 * -1 if (aux > sup): sup = aux if (aux2 > div): div = aux2 X0 = list(X1) if (sup / div) <= ErroR: switchh = True numIT += 1 if int(numIT) > int(MaX): print ">> **Impossivel** encontrar resultado em %s *iteracoes*.\n" % MaX sys.exit(0) printM(mat) ## Imprime MAT my_cont = 0 print "*** GauSS-JaCoBi ***" for i in X0: ## Imprime X, resultados de gauss-jacobi print "X%d = %f" % ((my_cont+1), i) my_cont += 1 print "\n>> Numero de iteracoes: %d " % numIT print ">> Valor do erro: %s" % ErroR ####### Fim do Gauss-Jacobi ######### ####### Inicio da Regrecao ######### print "\n\n*** ReGreSSaO/eLiMiNaCAo ***" for a in xrange(1, LINHAS): ## Checar a a triangular inferior esta zerada, for b in xrange(0, COLUNAS): ## se nao estiver nao calcula regressao/elim if (int(a) != int(b)): if (int(mat[a][b]) != 0): print ">> **Impossivel** calcular com triangular inferior *diferente de 0*\n" sys.exit(0) elif (int(a) == int(b)): break switchh = False i = LINHAS-1 j = i B[j] = B[j] / mat[i][j] i -= 1 j = i t = 0 numIT = 1 COLUNAS -= 1 while not (switchh): div = 0 numIT += 1 for t in xrange(j+1, COLUNAS): div = div + (mat[i][t] * B[t]) B[j] = (B[j] - div) / mat[i][j] if int(i) == 0: switchh = True i -= 1 j = i my_cont = 0 for i in B: ## Imprime B, vetor que guarda resultados da regressao/elim print "B%d = %f" % ((my_cont+1), i) my_cont += 1 ####### Fim da Regressao ######### def main(): erro = raw_input("\n>> Defina o ERRO: ") ## Guarda o ERRO definido pelo usuario maxx = raw_input(">> MAX iteracoes: ") ## Guarda o MAX de iteracoes if int(maxx) <= 0: print "\n>> *** Maximo de iteracoes tem que ser > 0 ***\n" sys.exit(0) matriz = readM() ## Chama readM() e guarda o resultado em "matriz" #matriz = [1, 0, 0, 0, 2], [0, 4, 0, 0, 15], [0, 0, 10, 0, 10], [0, 0, 0, 1, 1] #matriz = [1, 0, 0, 2], [0, 5, 0, 15], [0, 0, 10, 10] print "\n************************************************" jacobi_reg(matriz, erro, maxx) ## Chama gauss_jacobi() com paremetros print "\n-=*********************************************=-" if __name__ == '__main__': main()
Script para fazer o Scroll Lock funcionar no Linux
Gerador de cartão de crédito com Tkinter
Enviar mensagem ao usuário trabalhando com as opções do php.ini
Meu Fork do Plugin de Integração do CVS para o KDevelop
Compartilhando a tela do Computador no Celular via Deskreen
Como Configurar um Túnel SSH Reverso para Acessar Sua Máquina Local a Partir de uma Máquina Remota
Configuração para desligamento automatizado de Computadores em um Ambiente Comercial
Compartilhamento de Rede com samba em modo Público/Anônimo de forma simples, rápido e fácil
Cups: Mapear/listar todas as impressoras de outro Servidor CUPS de forma rápida e fácil
Criando uma VPC na AWS via CLI
De volta para o futuro - ou melhor, para o presente (24)
Comandos no NixOS não funcionam (0)
Plasma 6 com partes em inglês (0)