Olá pessoal
Estou querendo fazer um método em java para calcular a determinante de uma matriz 2x2 / 3x3.
Antes de postar minha dúvida fiz várias buscas pelo google e pelo GUJ, mas não encontrei nada que me ajude.
O mais próximo que encontrei que me ajudou foi um algoritimo em português estruturado, mas que ao que parece está errado.
O algoritimo que achei é o seguinte:
Programa Determinante Matriz Quadrada Ordem ?n?
Programa DeterminanteMatrizN;
Inicio;
{ Definição de Variáveis e Tipos Globais }
Tipo Mat = Matriz[1..n,1..n] de Inteiros;
Mat: M;
Inteiro: Det, n, x, y;
{ Modulo para Calculo de Determinante de Matriz Quadrada de ordem N}
Modulo Determinante(Inteiro: Det, n; Matriz[1..n,1..n] de Inteiros: M; Inteiro: L, C;);
Inicio;
{ Definição de Variáveis Locais }
Tipo Mat = Matriz[1..n-1,1..n-1] de inteiros;
Tipo Vet = vetor[1..n] de inteiros;
Vet: D1, D2;
Mat: MA;
Inteiro: X1, X2, Y1, Y2, Det2, Cof;
Inteiro: Det1, Det2, x, y, z, w, n;
Escolha
Caso n = 1: { Determinante Matriz ordem 1}
Det ← M[1,1];
Caso n>1 e n<4: { Determinante Matriz ordem 2 ou 3}
Det1 ← 0;
Det2 ← 0;
Para x = 0 até n-1
D1[x+1] ← 1;
D2[x+1] ← 1;
Para y = 1 até n
z ← x + y;
Se ( z > n ) então { Se coluna > n }
z ← z ? n; { pega a partir da col 1 }
FimSe;
D1[x+1] ← D1[x+1] * M[y,z]; { Diagonal Principal }
w ← n ? z + 1;
D2[x+1] ← D2[x+1] * M[y,w]; { Diagonal Secundária }
FimPara;
Det1 ← Det1 + D1[x+1]; { Diagonal Principal }
Det2 ← Det2 + D2[x+1]; { Diagonal Secundária }
FimPara;
Det ← Det1 ? Det2;
Caso Contrário: { Determinante Matriz ordem > 3}
Se L > 0 então { Reduz a matriz ... }
X2 ← 0;
Para X1 = 1 até n
X2 ← X2 + 1;
Se X1 <> L então { ... tirando a linha L ... }
Y2 ← 0;
Para Y1 = 1 até n
Y2 ← Y2 + 1;
Se Y2 <> C então { ... e a coluna C ... }
MA[X2, Y2] ← M[X1,Y1];
FimSe;
FimPara;
FimSe;
FimPara;
d ← n ? 1; { ... e diminui a ordem da matriz. }
Senão { para a primeira vez }
MA ← M;
d ← n;
FimSe;
Det ← 0; { Calcula Determinante por Laplace }
Para X2= 1 até d
Determinante(Det2, d, MA, 1, X2); { Det. da matriz reduzida}
Cof ← POT(-1,1+X2) * Det2; { Calculo do Cofator }
Det ← Det + M[1,X2] * Cof; { Teorema de Laplace }
FimPara;
FimEscolha;
Fim;
{ Programa Principal, Carrega a Matriz e Calcula o Determinante }
{ Dimensão da matriz }
Leia(n);
{ Carrega a matriz }
Para x = 1 até n
Para y = 1 até n
Leia(M[x,y]);
FimPara;
FimPara;
{ Calcula Determinante }
Determinante(Det, n, M, 0, 0);
Escreve(?O Determinante é :?, Det);
Fim.
Mas ele dá erro ao executar, tanto com matriz 2x2 quanto 3x3. Dá erro de "index out of bounds".
Para matriz 2x2 eu consegui fazer, mas para 3x3 não consegui chegar a nenhuma conclusão.
Até tem um método que faz o calculo manualmente, mas não consigo pensar em uma lógica para transformá-lo em algo mais prático.
Segue o método de cálculo manual e o que eu tentei fazer que não deu certo:
public static float matrizCalculaDeterminanteManual(float[][] matriz)
throws Exception {
if (!ckMatrizQuadradaValido(matriz))
throw new Exception("Matriz de tamanho inválido");
float determinante = 0;
if (matriz.length == 2) {
determinante = (matriz[0][0] * matriz[1][1]) - (matriz[0][1] * matriz[1][0]);
} if (matriz.length == 3) {
float principal = (matriz[0][0] * matriz[1][1] * matriz[2][2]);
float secundaria = (matriz[2][0] * matriz[1][1] * matriz[0][2]);
principal += (matriz[0][1] * matriz[1][2] * matriz[2][0]);
secundaria += (matriz[2][1] * matriz[1][2] * matriz[0][0]);
principal += (matriz[0][2] * matriz[1][0] * matriz[2][1]);
secundaria += (matriz[2][2] * matriz[1][0] * matriz[0][1]);
determinante = principal - secundaria;
} else {
throw new Exception("Matrizez de ordem maior do que 3 não são suportadas por enquanto");
}
return determinante;
}
// ----------------------------------------------------------------------------------------------------------------------------------------------
public static float matrizCalculaDeterminante(float[][] matriz)
throws Exception {
if (!ckMatrizQuadradaValido(matriz))
throw new Exception("Matriz de tamanho inválido");
int ordem = matriz.length;
float determinante = 0;
float det1 = 1;
float det2 = 1;
float[] diagonalPrincipal = new float[ordem];
float[] diagonalSecundaria = new float[ordem];
switch (ordem) {
case 1: {
determinante = matriz[0][0];
break;
}
case 2: {
for (int coluna = 0; coluna < ordem; coluna++) {
diagonalPrincipal[coluna] = 1;
diagonalSecundaria[coluna] = 1;
for (int linhaPrincipal = 0; linhaPrincipal < ordem; linhaPrincipal++) {
int linhaSecundaria = (ordem-1) - linhaPrincipal;
if (linhaPrincipal == coluna)
diagonalPrincipal[coluna] = diagonalPrincipal[coluna] * matriz[linhaPrincipal][coluna]; // diagonal principal
if (linhaSecundaria == ((ordem-1)-coluna))
diagonalSecundaria[coluna] = diagonalSecundaria[coluna] * matriz[linhaSecundaria][coluna]; // diagonal secundaria
}
det1 = det1 * diagonalPrincipal[coluna]; // diagonal principal
det2 = det2 * diagonalSecundaria[coluna]; // diagonal secundaria
}
determinante = det1 - det2;
break;
}
case 3: {
for (int coluna = 0; coluna < ordem; coluna++) {
diagonalPrincipal[coluna] = 1;
diagonalSecundaria[coluna] = 1;
for (int linhaPrincipal = 0; linhaPrincipal < ordem; linhaPrincipal++) {
int linhaSecundaria = (ordem-1) - linhaPrincipal;
if (linhaPrincipal == coluna)
diagonalPrincipal[coluna] = diagonalPrincipal[coluna] * matriz[linhaPrincipal][coluna]; // diagonal principal
if (linhaSecundaria == ((ordem-1)-coluna))
diagonalSecundaria[coluna] = diagonalSecundaria[coluna] * matriz[linhaSecundaria][coluna]; // diagonal secundaria
}
det1 = det1 * diagonalPrincipal[coluna]; // diagonal principal
det2 = det2 * diagonalSecundaria[coluna]; // diagonal secundaria
}
determinante = det1 - det2;
break;
}
default: {// maior que 3
throw new Exception("Matrizez de ordem maior do que 3 não são suportadas por enquanto");
//break;
}
}
return determinante;
}