O algoritmo de eliminação de Gauss é uma técnica fundamental para resolver sistemas de equações lineares. Neste artigo, implementamos uma versão em C++ que lida com coeficientes reais e identifica casos de solução única, infinitas soluções ou nenhuma solução.
Descrição do Problema
Dado um sistema com n equações e n variáveis, os coeficientes são números reais. O objetivo é encontrar a solução ou determinar se o sistema é inconsistnete ou indeterminado.
- Entrada: Primeira linha com o número n. As próximas n linhas contêm n+1 números reais (coeficeintes e o termo constante).
- Saída: Se solução única, imprimir cada variável com duas casas decimais. Se infinitas soluções, exibir "Infinite group solutions". Se sem solução, exibir "No solution".
- Restrições: 1 ≤ n ≤ 100, todos os valores com até duas casas decimais e módulo ≤ 100.
Exemplo
Entrada:
3
1.00 2.00 -1.00 -6.00
2.00 1.00 -3.00 -9.00
-1.00 -1.00 2.00 7.00
Saída:
1.00
-2.00
3.00
Estratégia de Implementação
A abordagem segue o método de eliminação de Gauss com pivotamento parcial:
- Para cada coluna c, encontrar o pivô com o maior valor absoluto entre as linhas não processadas.
- Trocar a linha atual pela linha do pivô.
- Normalizar a linha do pivô para que o primeiro elemneto se torne 1.
- Eliminar os coeficientes abaixo do pivô na mesma coluna.
- Ao final, obter uma matriz triangular superior e realizar a substituição reversa.
Observações Importantes:
- Devido à precisão finita dos números de ponto flutuante, usa-se um epsilon (1e-6) para verificar se um valor é essencialmente zero.
- Se o maior pivô em uma coluna for menor que o epsilon, pula-se a coluna (a linha atual não avança), o que indica possíveis variáveis livres.
- Após a eliminação direta, verifica-se inconsistência: se uma linha tiver todos os coeficientes das variáveis iguais a zero, mas o termo constante for diferente de zero, o sistema não tem solução.
- Se houver linhas completamente nulas, o sistema possui infinitas soluções.
Código
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
const int SIZE = 105;
const double EPS = 1e-6;
double mat[SIZE][SIZE];
int n;
int gaussElimination() {
int row = 1, col;
for (col = 1; col <= n; ++col) {
int maxRow = row;
for (int i = row; i <= n; ++i) {
if (fabs(mat[i][col]) > fabs(mat[maxRow][col]))
maxRow = i;
}
if (fabs(mat[maxRow][col]) < EPS) continue;
if (maxRow != row) {
for (int j = col; j <= n + 1; ++j)
swap(mat[maxRow][j], mat[row][j]);
}
for (int j = n + 1; j >= col; --j)
mat[row][j] /= mat[row][col];
for (int i = row + 1; i <= n; ++i) {
if (fabs(mat[i][col]) > EPS) {
double factor = mat[i][col];
for (int j = n + 1; j >= col; --j)
mat[i][j] -= factor * mat[row][j];
}
}
row++;
}
if (row <= n) {
for (int i = row; i <= n; ++i) {
if (fabs(mat[i][n + 1]) > EPS)
return 1; // Sem solução
}
return 2; // Infinitas soluções
}
for (int i = n; i >= 1; --i) {
for (int j = i - 1; j >= 1; --j) {
mat[j][n + 1] -= mat[j][i] * mat[i][n + 1];
}
}
return 0; // Solução única
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n + 1; ++j)
cin >> mat[i][j];
int result = gaussElimination();
cout << fixed << setprecision(2);
if (result == 0) {
for (int i = 1; i <= n; ++i)
cout << mat[i][n + 1] << '\n';
} else if (result == 1) {
cout << "No solution\n";
} else {
cout << "Infinite group solutions\n";
}
return 0;
}
O código primeiro realiza a eliminação progressiva, transformando a matriz aumentada em uma forma triangular superior. Em seguida, verifica a consistência e, se necessário, executa a substituição reversa para obter a solução final.