Javakurs/Übungsaufgaben/Gauß-Algorithmus/Musterloesung: Unterschied zwischen den Versionen
< Javakurs | Übungsaufgaben | Gauß-Algorithmus
(Die Seite wurde neu angelegt: „==Beispiel-Lösung== ===Ausgabe der Zwischenschritte sind möglich=== <code> →* @author Sebastian Peuser, c-line@mailbox.tu-berlin.de: public class G…“) |
K (fix alignment) |
||
Zeile 4: | Zeile 4: | ||
===Ausgabe der Zwischenschritte sind möglich=== | ===Ausgabe der Zwischenschritte sind möglich=== | ||
− | < | + | <pre> |
− | + | /* | |
− | + | * @author Sebastian Peuser <c-line AT mailbox.tu-berlin DOT de> | |
− | + | */ | |
− | + | public class Gauss { | |
− | + | public static void main(String[] args) { | |
− | + | double[][] matrix = { { 1, 1, 1 }, { 43, 0, 31 }, { 4, 0, 7 } }; | |
− | + | double[] vector = { 2, 4, 8 }; | |
− | + | ||
− | + | /* | |
− | + | * "true" oder "false" kann als dritter Parameter uebergeben werden. | |
− | + | * "true" -> Zwischenschritte werden auf der Konsole ausgegeben "false" | |
− | + | * -> nichts wird ausgegeben | |
− | + | */ | |
− | + | printVector(getSolution(matrix, vector, false)); | |
− | + | } | |
− | + | ||
− | + | /* | |
− | + | * Gauss-Jordan-Algorithmus nur fuer eindeutige Gleichungssysteme geeignet | |
− | + | * (andernfalls wird NULL zurueckgegeben) matrix[row][column] | |
− | + | */ | |
− | + | public static double[] getSolution(double[][] matrix, double[] vector, boolean printSteps) { | |
− | + | // Das Gleichungssystem hat keine eindeutige Loesung! | |
− | + | if (matrix.length < matrix[0].length) { | |
− | + | System.out.println("Gleichungssystem nicht eindeutig loesbar!"); | |
− | + | return null; | |
− | + | } | |
− | + | ||
− | + | // Merken der Spalte, welche eine Zahl ungleich null besitzt | |
− | + | int tmpColumn = -1; | |
− | + | ||
− | + | // Alle Zeilen durchgehen: Ziel der for-Schleife -> Matrix in | |
− | + | // Zeilenstufenform bringen! | |
− | + | // -> Alle Zahlen unterhalb der Diagonale sind null | |
− | + | for (int line = 0; line < matrix.length; line++) { | |
− | + | tmpColumn = -1; | |
− | + | ||
− | + | // Umformungsschritt 1: Finden einer Spalte mit einem Wert ungleich | |
− | + | // null | |
− | + | for (int column = 0; column < matrix[line].length; column++) { | |
− | + | for (int row = line; row < matrix.length; row++) { | |
− | + | if (matrix[row][column] != 0) { | |
− | + | tmpColumn = column; | |
− | + | break; | |
− | + | } | |
− | + | } | |
− | + | ||
− | + | // Abbruch, zahl ungleich null wurde gefunden | |
− | + | if (tmpColumn != -1) { | |
− | + | break; | |
− | + | } | |
− | + | } | |
− | + | ||
− | + | // NullZeile(n) entdeckt! | |
− | + | if (tmpColumn == -1) { | |
− | + | for (int row = line; row < matrix.length; row++) { | |
− | + | // Gleichungssystem hat keine Loesung! | |
− | + | if (vector[line] != 0) { | |
− | + | // Wenn die Zwischenschritte ausgegeben werden sollen | |
− | + | if (printSteps) { | |
− | + | printStep(matrix, vector); | |
− | + | } | |
− | + | ||
− | + | System.out.println("Gleichungssystem besitzt keine Loesung!"); | |
− | + | return null; | |
− | + | } | |
− | + | } | |
− | + | // Nullzeile(n) vorhanden -> Ist das System noch eindeutig | |
− | + | // loesbar? | |
− | + | if (matrix[0].length - 1 >= line) { | |
− | + | // Wenn die Zwischenschritte ausgegeben werden sollen | |
− | + | if (printSteps) { | |
− | + | printStep(matrix, vector); | |
− | + | } | |
− | + | ||
− | + | // System nicht eindeutig loesbar. | |
− | + | System.out.println("Gleichungssystem nicht eindeutig loesbar!"); | |
− | + | return null; | |
− | + | } | |
− | + | break; | |
− | + | } | |
− | + | ||
− | + | // Umformungsschritt 2: Die Zahl matrix[line][tmpColumn] soll | |
− | + | // UNgleich null sein | |
− | + | if (matrix[line][tmpColumn] == 0) { | |
− | + | for (int row = line + 1; row < matrix.length; row++) { | |
− | + | if (matrix[row][tmpColumn] != 0) { | |
− | + | // Wenn die Zwischenschritte ausgegeben werden sollen | |
− | + | if (printSteps) { | |
− | + | printStep(matrix, vector); | |
− | + | System.out.println("Zeile " + (line + 1) + " wird mit Zeile " + (row + 1) + " getauscht"); | |
− | + | } | |
− | + | ||
− | + | // Vertauschen von Zeilen -> matrix[line][tmpColumn] | |
− | + | // wird dann ungleich null | |
− | + | swapTwoLines(line, row, matrix, vector); | |
− | + | break; | |
− | + | } | |
− | + | } | |
− | + | } | |
− | + | ||
− | + | // Umformungsschritt 3: matrix[line][tmpColumn] soll gleich 1 sein. | |
− | + | if (matrix[line][tmpColumn] != 0) { | |
− | + | // Wenn die Zwischenschritte ausgegeben werden sollen | |
− | + | if (printSteps) { | |
− | + | printStep(matrix, vector); | |
− | + | System.out.println("Zeile " + (line + 1) + " wird durch " + matrix[line][tmpColumn] + " geteilt"); | |
− | + | } | |
− | + | ||
− | + | // Division der Zeile mit matrix[line][tmpColumn] | |
− | + | divideLine(line, matrix[line][tmpColumn], matrix, vector); | |
− | + | } | |
− | + | ||
− | + | // Wenn die Zwischenschritte ausgegeben werden sollen | |
− | + | if (printSteps) { | |
− | + | printStep(matrix, vector); | |
− | + | } | |
− | + | ||
− | + | // Umformungsschritt 4: Alle Zahlen unter matrix[line][tmpColumn] | |
− | + | // sollen null sein. | |
− | + | for (int row = line + 1; row < matrix.length; row++) { | |
− | + | // Wenn die Zwischenschritte ausgegeben werden sollen | |
− | + | if (printSteps) { | |
− | + | System.out.println("Zu Zeile " + (row + 1) + " wird subtrahiert: " + matrix[row][tmpColumn] + " * Zeile " + (line + 1)); | |
− | + | } | |
− | + | ||
− | + | // Subtraktion damit unter der Zahl im Umformungsschritt 3 nur | |
− | + | // nullen stehen | |
− | + | removeRowLeadingNumber(matrix[row][tmpColumn], line, row, matrix, vector); | |
− | + | } | |
− | + | } | |
− | + | ||
− | + | // Umformungsschritt 6: Matrix in Normalform bringen (Zahlen oberhalb | |
− | + | // der Diagonale werden ebenfalls zu null) | |
− | + | for (int column = matrix[0].length - 1; column > 0; column--) { | |
− | + | // Wenn die Zwischenschritte ausgegeben werden sollen | |
− | + | if (printSteps) { | |
− | + | printStep(matrix, vector); | |
− | + | } | |
− | + | ||
− | + | // Alle Werte oberhalb von "column" werden zu null | |
− | + | for (int row = column; row > 0; row--) { | |
− | + | // Wenn die Zwischenschritte ausgegeben werden sollen | |
− | + | if (printSteps) { | |
− | + | System.out.println("Zu Zeile " + (row) + " wird subtrahiert: " + matrix[row - 1][column] + " * Zeile " + (column + 1)); | |
− | + | } | |
− | + | ||
− | + | // Dazu wird Subtraktion angewandt | |
− | + | removeRowLeadingNumber(matrix[row - 1][column], column, row - 1, matrix, vector); | |
− | + | } | |
− | + | } | |
− | + | ||
− | + | // Wenn die Zwischenschritte ausgegeben werden sollen | |
− | + | if (printSteps) { | |
− | + | printStep(matrix, vector); | |
− | + | } | |
− | + | ||
− | + | // Unser ehemaliger Loesungsvektor ist jetzt zu unserem Zielvektor | |
− | + | // geworden :) | |
− | + | return vector; | |
− | + | } | |
− | + | ||
− | + | /* | |
− | + | * Hier werden einfach zwei Zeilen vertrauscht | |
− | + | */ | |
− | + | private static void swapTwoLines(int rowOne, int rowTwo, double[][] matrix, double[] vector) { | |
− | + | double[] tmpLine; | |
− | + | double tmpVar; | |
− | + | ||
− | + | tmpLine = matrix[rowOne]; | |
− | + | tmpVar = vector[rowOne]; | |
− | + | ||
− | + | matrix[rowOne] = matrix[rowTwo]; | |
− | + | vector[rowOne] = vector[rowTwo]; | |
− | + | ||
− | + | matrix[rowTwo] = tmpLine; | |
− | + | vector[rowTwo] = tmpVar; | |
− | + | } | |
− | + | ||
− | + | /* | |
− | + | * eine Zeile wird durch "div" geteilt. "div" darf nicht null sein | |
− | + | */ | |
− | + | private static void divideLine(int row, double div, double[][] matrix, double[] vector) { | |
− | + | for (int column = 0; column < matrix[row].length; column++) { | |
− | + | matrix[row][column] = matrix[row][column] / div; | |
− | + | } | |
− | + | vector[row] = vector[row] / div; | |
− | + | } | |
− | + | ||
− | + | /* | |
− | + | * Eine Zeile (row) wird mit einem entsprechendem vielfachen (factor) von | |
− | + | * einer anderen Zeile (rowRoot) subtrahiert. | |
− | + | */ | |
− | + | private static void removeRowLeadingNumber(double factor, int rowRoot, int row, double[][] matrix, double[] vector) { | |
− | + | for (int column = 0; column < matrix[row].length; column++) { | |
− | + | matrix[row][column] = matrix[row][column] - factor * matrix[rowRoot][column]; | |
− | + | } | |
− | + | vector[row] = vector[row] - factor * vector[rowRoot]; | |
− | + | } | |
− | + | ||
− | + | /* | |
− | + | * Ein Vector wird auf der Konsole ausgegeben (transponiert) | |
− | + | */ | |
− | + | public static void printVector(double[] vector) { | |
− | + | if (vector == null) { | |
− | + | return; | |
− | + | } | |
− | + | System.out.println(); | |
− | + | System.out.print("Loesungsvektor ist: ("); | |
− | + | for (int i = 0; i < vector.length; i++) { | |
− | + | if (i != 0) { | |
− | + | System.out.print(","); | |
− | + | } | |
− | + | System.out.print(vector[i]); | |
− | + | } | |
− | + | System.out.println(")^T"); | |
− | + | } | |
− | + | ||
− | + | /* | |
− | + | * Eine Matrix wird auf der Konsole ausgegeben matrix[row][column] | |
− | + | */ | |
− | + | public static void printMatrix(double[][] matrix) { | |
− | + | if (matrix == null) { | |
− | + | return; | |
− | + | } | |
− | + | for (int row = 0; row < matrix.length; row++) { | |
− | + | System.out.print("("); | |
− | + | for (int column = 0; column < matrix[row].length; column++) { | |
− | + | if (column != 0) { | |
− | + | System.out.print(","); | |
− | + | } | |
− | + | System.out.print(matrix[row][column]); | |
− | + | } | |
− | + | System.out.println(")"); | |
− | + | } | |
− | + | } | |
− | + | ||
− | + | /* | |
− | + | * Diese Methode zeigt die Zwischenschritte der Berechnung auf der Konsole | |
− | + | * an. Fuer die Aufgabe nicht weiter relevant (unbekannte Konzepte werden | |
− | + | * verwendet!) | |
− | + | */ | |
− | + | private static void printStep(double[][] matrix, double[] vector) { | |
− | + | System.out.println(); | |
− | + | ||
− | + | // Werte werden fuer die Ausgabe auf ein bestimmtes Format gebracht | |
− | + | // -> Damit die Ausgabe auch immer schick aussieht | |
− | + | java.text.DecimalFormat df = new java.text.DecimalFormat("0.00"); | |
− | + | for (int row = 0; row < matrix.length; row++) { | |
− | + | for (int column = 0; column < matrix[row].length; column++) { | |
− | + | if (matrix[row][column] >= 0) { | |
− | + | System.out.print("+"); | |
− | + | } | |
− | + | System.out.print(df.format(matrix[row][column]) + " "); | |
− | + | } | |
− | + | System.out.print("| "); | |
− | + | if (vector[row] >= 0) { | |
− | + | System.out.print("+"); | |
− | + | } | |
− | + | System.out.println(df.format(vector[row])); | |
− | + | } | |
− | + | } | |
− | + | } | |
− | + | </pre> | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | </ |
Aktuelle Version vom 4. März 2013, 18:39 Uhr
Beispiel-Lösung
Ausgabe der Zwischenschritte sind möglich
/* * @author Sebastian Peuser <c-line AT mailbox.tu-berlin DOT de> */ public class Gauss { public static void main(String[] args) { double[][] matrix = { { 1, 1, 1 }, { 43, 0, 31 }, { 4, 0, 7 } }; double[] vector = { 2, 4, 8 }; /* * "true" oder "false" kann als dritter Parameter uebergeben werden. * "true" -> Zwischenschritte werden auf der Konsole ausgegeben "false" * -> nichts wird ausgegeben */ printVector(getSolution(matrix, vector, false)); } /* * Gauss-Jordan-Algorithmus nur fuer eindeutige Gleichungssysteme geeignet * (andernfalls wird NULL zurueckgegeben) matrix[row][column] */ public static double[] getSolution(double[][] matrix, double[] vector, boolean printSteps) { // Das Gleichungssystem hat keine eindeutige Loesung! if (matrix.length < matrix[0].length) { System.out.println("Gleichungssystem nicht eindeutig loesbar!"); return null; } // Merken der Spalte, welche eine Zahl ungleich null besitzt int tmpColumn = -1; // Alle Zeilen durchgehen: Ziel der for-Schleife -> Matrix in // Zeilenstufenform bringen! // -> Alle Zahlen unterhalb der Diagonale sind null for (int line = 0; line < matrix.length; line++) { tmpColumn = -1; // Umformungsschritt 1: Finden einer Spalte mit einem Wert ungleich // null for (int column = 0; column < matrix[line].length; column++) { for (int row = line; row < matrix.length; row++) { if (matrix[row][column] != 0) { tmpColumn = column; break; } } // Abbruch, zahl ungleich null wurde gefunden if (tmpColumn != -1) { break; } } // NullZeile(n) entdeckt! if (tmpColumn == -1) { for (int row = line; row < matrix.length; row++) { // Gleichungssystem hat keine Loesung! if (vector[line] != 0) { // Wenn die Zwischenschritte ausgegeben werden sollen if (printSteps) { printStep(matrix, vector); } System.out.println("Gleichungssystem besitzt keine Loesung!"); return null; } } // Nullzeile(n) vorhanden -> Ist das System noch eindeutig // loesbar? if (matrix[0].length - 1 >= line) { // Wenn die Zwischenschritte ausgegeben werden sollen if (printSteps) { printStep(matrix, vector); } // System nicht eindeutig loesbar. System.out.println("Gleichungssystem nicht eindeutig loesbar!"); return null; } break; } // Umformungsschritt 2: Die Zahl matrix[line][tmpColumn] soll // UNgleich null sein if (matrix[line][tmpColumn] == 0) { for (int row = line + 1; row < matrix.length; row++) { if (matrix[row][tmpColumn] != 0) { // Wenn die Zwischenschritte ausgegeben werden sollen if (printSteps) { printStep(matrix, vector); System.out.println("Zeile " + (line + 1) + " wird mit Zeile " + (row + 1) + " getauscht"); } // Vertauschen von Zeilen -> matrix[line][tmpColumn] // wird dann ungleich null swapTwoLines(line, row, matrix, vector); break; } } } // Umformungsschritt 3: matrix[line][tmpColumn] soll gleich 1 sein. if (matrix[line][tmpColumn] != 0) { // Wenn die Zwischenschritte ausgegeben werden sollen if (printSteps) { printStep(matrix, vector); System.out.println("Zeile " + (line + 1) + " wird durch " + matrix[line][tmpColumn] + " geteilt"); } // Division der Zeile mit matrix[line][tmpColumn] divideLine(line, matrix[line][tmpColumn], matrix, vector); } // Wenn die Zwischenschritte ausgegeben werden sollen if (printSteps) { printStep(matrix, vector); } // Umformungsschritt 4: Alle Zahlen unter matrix[line][tmpColumn] // sollen null sein. for (int row = line + 1; row < matrix.length; row++) { // Wenn die Zwischenschritte ausgegeben werden sollen if (printSteps) { System.out.println("Zu Zeile " + (row + 1) + " wird subtrahiert: " + matrix[row][tmpColumn] + " * Zeile " + (line + 1)); } // Subtraktion damit unter der Zahl im Umformungsschritt 3 nur // nullen stehen removeRowLeadingNumber(matrix[row][tmpColumn], line, row, matrix, vector); } } // Umformungsschritt 6: Matrix in Normalform bringen (Zahlen oberhalb // der Diagonale werden ebenfalls zu null) for (int column = matrix[0].length - 1; column > 0; column--) { // Wenn die Zwischenschritte ausgegeben werden sollen if (printSteps) { printStep(matrix, vector); } // Alle Werte oberhalb von "column" werden zu null for (int row = column; row > 0; row--) { // Wenn die Zwischenschritte ausgegeben werden sollen if (printSteps) { System.out.println("Zu Zeile " + (row) + " wird subtrahiert: " + matrix[row - 1][column] + " * Zeile " + (column + 1)); } // Dazu wird Subtraktion angewandt removeRowLeadingNumber(matrix[row - 1][column], column, row - 1, matrix, vector); } } // Wenn die Zwischenschritte ausgegeben werden sollen if (printSteps) { printStep(matrix, vector); } // Unser ehemaliger Loesungsvektor ist jetzt zu unserem Zielvektor // geworden :) return vector; } /* * Hier werden einfach zwei Zeilen vertrauscht */ private static void swapTwoLines(int rowOne, int rowTwo, double[][] matrix, double[] vector) { double[] tmpLine; double tmpVar; tmpLine = matrix[rowOne]; tmpVar = vector[rowOne]; matrix[rowOne] = matrix[rowTwo]; vector[rowOne] = vector[rowTwo]; matrix[rowTwo] = tmpLine; vector[rowTwo] = tmpVar; } /* * eine Zeile wird durch "div" geteilt. "div" darf nicht null sein */ private static void divideLine(int row, double div, double[][] matrix, double[] vector) { for (int column = 0; column < matrix[row].length; column++) { matrix[row][column] = matrix[row][column] / div; } vector[row] = vector[row] / div; } /* * Eine Zeile (row) wird mit einem entsprechendem vielfachen (factor) von * einer anderen Zeile (rowRoot) subtrahiert. */ private static void removeRowLeadingNumber(double factor, int rowRoot, int row, double[][] matrix, double[] vector) { for (int column = 0; column < matrix[row].length; column++) { matrix[row][column] = matrix[row][column] - factor * matrix[rowRoot][column]; } vector[row] = vector[row] - factor * vector[rowRoot]; } /* * Ein Vector wird auf der Konsole ausgegeben (transponiert) */ public static void printVector(double[] vector) { if (vector == null) { return; } System.out.println(); System.out.print("Loesungsvektor ist: ("); for (int i = 0; i < vector.length; i++) { if (i != 0) { System.out.print(","); } System.out.print(vector[i]); } System.out.println(")^T"); } /* * Eine Matrix wird auf der Konsole ausgegeben matrix[row][column] */ public static void printMatrix(double[][] matrix) { if (matrix == null) { return; } for (int row = 0; row < matrix.length; row++) { System.out.print("("); for (int column = 0; column < matrix[row].length; column++) { if (column != 0) { System.out.print(","); } System.out.print(matrix[row][column]); } System.out.println(")"); } } /* * Diese Methode zeigt die Zwischenschritte der Berechnung auf der Konsole * an. Fuer die Aufgabe nicht weiter relevant (unbekannte Konzepte werden * verwendet!) */ private static void printStep(double[][] matrix, double[] vector) { System.out.println(); // Werte werden fuer die Ausgabe auf ein bestimmtes Format gebracht // -> Damit die Ausgabe auch immer schick aussieht java.text.DecimalFormat df = new java.text.DecimalFormat("0.00"); for (int row = 0; row < matrix.length; row++) { for (int column = 0; column < matrix[row].length; column++) { if (matrix[row][column] >= 0) { System.out.print("+"); } System.out.print(df.format(matrix[row][column]) + " "); } System.out.print("| "); if (vector[row] >= 0) { System.out.print("+"); } System.out.println(df.format(vector[row])); } } }