Resolução de Matriz NxM
Publicado por Karl Phillip 14/08/2004
[ Hits: 23.582 ]
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()
Afinador de Violão/guitarra em python e gtk.
Faça suas próprias atualizações de pacotes/programas no Void Linux e torne-se um Contribuidor
Como rodar o Folding@home no Linux
Criando um painel de controle (Dashboard) para seu servidor com o Homepage
O Abismo entre o Código e o Chão: Saltos Tecnológicos e a Exclusão Estrutural no Brasil
Instalar e Configurar a santíssima trindade (PAP) no Void Linux
Pisando no acelerador do Linux Mint: Kernel XanMod, zRAM e Ajustes de Swap
Como compilar kernel no Linux Mint
Lançamento do Brutal DOOM test 6
Consertando o erro no Brave de webgl
Solução para ter de volta as bordas e barra de títulos das janelas em zenity no Debian 13.x
Seno, Coseno, Tangente em CLIPPER (0)
Inserir uma URL num arquvo pelo Ubuntu (CLIPPER) (0)
VMWare Player não conecta na rede nem consigo intercambiar arquivos (1)









