C++ Code für LGS?
Ich möchte mit einen C++-Programm alle LGS lösen können (endlich, unendlich und keine Lösungen). Ich habe auch einen Code. Endlich viele und keine Lösungen kann er recht gut (bisher), aber unendlich viele Lösungen kann er nicht anzeigen lassen (soll dann auch t einführen, nicht einfach einen Wert einsetzen).
Wo liegt der Fehler?
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
// Funktion zur Berechnung des Determinanten einer Matrix
double determinant(vector<vector<double>>& matrix, int n) {
double det = 0;
if (n == 1) {
return matrix[0][0];
}
if (n == 2) {
return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0];
}
for (int i = 0; i < n; i++) {
vector<vector<double>> subMatrix(n - 1, vector<double>(n - 1));
for (int j = 1; j < n; j++) {
for (int k = 0; k < n; k++) {
if (k < i) {
subMatrix[j - 1][k] = matrix[j][k];
}
else if (k > i) {
subMatrix[j - 1][k - 1] = matrix[j][k];
}
}
}
det += pow(-1, i) * matrix[0][i] * determinant(subMatrix, n - 1);
}
return det;
}
// Funktion zur Durchführung der Gauss-Jordan-Elimination
void gaussJordan(vector<vector<double>>& matrix, vector<double>& constants) {
int n = matrix.size();
for (int i = 0; i < n; i++) {
int maxIndex = i;
for (int j = i + 1; j < n; j++) {
if (abs(matrix[j][i]) > abs(matrix[maxIndex][i])) {
maxIndex = j;
}
}
if (maxIndex != i) {
swap(matrix[maxIndex], matrix[i]);
swap(constants[i], constants[maxIndex]); // Korrektur hier
}
double factor = matrix[i][i];
for (int j = i; j < n; j++) {
matrix[i][j] /= factor;
}
constants[i] /= factor;
for (int j = 0; j < n; j++) {
if (j != i) {
double factor = matrix[j][i];
for (int k = i; k < n; k++) {
matrix[j][k] -= factor * matrix[i][k];
}
constants[j] -= factor * constants[i];
}
}
}
}
// Funktion zur Überprüfung der Invertierbarkeit und zur Lösung des LGS
vector<double> solveLinearSystem(vector<vector<double>>& matrix, vector<double>& constants) {
int n = matrix.size();
double det = determinant(matrix, n);
// Überprüfung auf unendlich viele Lösungen
bool allZero = true;
for (double constant : constants) {
if (constant != 0) {
allZero = false;
break;
}
}
if (det == 0) {
if (allZero) {
cout << "Das LGS hat unendlich viele Lösungen." << endl;
return {}; // Leerer Vektor, da unendlich viele Lösungen existieren
}
else {
cout << "Das LGS hat keine Lösung." << endl;
return {}; // Leerer Vektor, da keine Lösung existiert
}
}
// Anwendung der Gauss-Jordan-Elimination
gaussJordan(matrix, constants);
vector<double> solution(n);
for (int i = 0; i < n; i++) {
solution[i] = constants[i];
}
return solution;
}
int main() {
vector<vector<double>> matrix = {
{ 1, -3, 5 },
{ 2, -5, 12 },
{ 3, -11, 11 }
};
vector<double> constants = { 2, 1, 12 };
vector<double> solution = solveLinearSystem(matrix, constants);
if (!solution.empty()) {
cout << "Die Lösung des LGS ist: ";
for (int i = 0; i < solution.size(); i++) {
cout << "x" << i + 1 << " = " << solution[i] << ", ";
}
cout << endl;
}
else {
cout << "Das LGS hat keine Lösung." << endl;
}
return 0;
}
1 Antwort
if (det == 0) {
if (allZero) {
cout << "Das LGS hat unendlich viele Lösungen." << endl;
return {}; // Leerer Vektor, da unendlich viele Lösungen existieren
}
else {
cout << "Das LGS hat keine Lösung." << endl;
return {}; // Leerer Vektor, da keine Lösung existiert
}
}
In dem Code hier wird nur überprüft, ob die Determinante 0 ist und ob der Vektor auf der rechten Seite 0 ist. Wenn im Falle, dass die Determinante 0 ist, die rechte Seite nicht der Nullvektor ist, bedeutet das nicht, dass es keine Lösung gibt.
Gegenbeispiel:
1x +1 y = 1
0x + 0y = 0
Hier gibt es unendlich viele Lösungen. Wenn man die Einträge auf der rechten Seite vertauscht, gibt es keine Lösung:
1x +1 y = 0
0x + 0y = 1
Bei größeren Matrizen steigt auch der Aufwand, die Determinante zu berechnen.
Darum würde ich die Überprüfung der Determinante und des Vektors streichen und direkt den Gauß-Algorithmus durchführen.
Zudem könnte man auch nichtquadratische Matrizen beachten.
Meine Lösung:#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
// Funktion zur Durchführung der Gauss-Jordan-Elimination
bool gaussJordan(vector<vector<double>>& matrix, vector<double>& constants) {
int n = matrix.size(); // Anzahl der Zeilen
int m = matrix[0].size(); // Anzahl der Spalten
int k = 0; // Pivotspalte
for (int i = 0; i < n; i++) {
while(k < m){ // suche Pivotelement != 0
// suche in Spalte k
int maxIndex = i;
for (int j = i + 1; j < n; j++) {
if (abs(matrix[j][k]) > abs(matrix[maxIndex][k])) {
maxIndex = j;
}
}
if (maxIndex != i) {
swap(matrix[maxIndex], matrix[i]);
swap(constants[i], constants[maxIndex]); // Korrektur hier
}
if(matrix[i][k] != 0){
break;
}
// Falls alle Elemente = 0, durchsuche nächste Spalte
k++;
}
if(k == m){
if(constants[i] == 0)
continue;
else return false;
}
double factor = matrix[i][k];
for (int j = k; j < m; j++) {
matrix[i][j] /= factor;
}
constants[i] /= factor;
for (int j = 0; j < n; j++) {
if (j != i) {
double factor = matrix[j][k];
for (int l = k; l < m; l++) {
matrix[j][l] -= factor * matrix[i][l];
}
constants[j] -= factor * constants[i];
}
}
}
return true;
}
int main() {
vector<vector<double>> matrix = {
{ 1, -3, 5, 5},
{ 2, -5, 12, 12},
{ 3, -11, 11, 11 }
};
vector<double> constants = { 2, 1, 12 };
bool hasSolution = gaussJordan(matrix, constants);
if(!hasSolution){
cout << "Das LGS hat keine Lösung." << endl;
return 0;
}
int n = matrix.size();
int m = matrix[0].size();
cout << "Die Lösung des LGS ist:" << endl;
for(int i = 0; i < n; i++){ // zeilenweise
bool isZero = true;
for(int j = 0; j < m; j++){
if(matrix[i][j] != 0){
if(isZero){
isZero = false;
cout << "x" << j + 1 << " = " << constants[i];
}
else{
cout << ((matrix[i][j] < 0) ? " + " : " - ");
if(abs(matrix[i][j]) != 1)
cout << abs(matrix[i][j]);
cout << "x" << j + 1;
}
}
}
cout << endl;
}
return 0;
}
Ach man, klappt nicht. Wie würdest du es schreiben?