/* Dreigl.java * Autor: Markus Raab * Datum: Freitag Okt 22 * Kategorie: Mathematik*/ /* Ein lineares inhomogenes Gleichungssystem von drei Gleichungen in * drei Unbekannten soll gelöst werden.*/ import eprog.EprogException; import eprog.EprogIO; class Dreigl { static private float [] feld; static private float [] ergebnis; /* Liest ein Array von Zahlen ein: * a11*x1 + a12*x2 + a13*x3 = b1 * a21*x1 + a22*x2 + a23*x3 = b2 * a31*x1 + a32*x2 + a33*x3 = b3 * * feld[0] *x1 + feld[1] *x2 + feld[2] *x3 = feld[3] * feld[4] *x1 + feld[5] *x2 + feld[6] *x3 = feld[7] * feld[8] *x1 + feld[9] *x2 + feld[10]*x3 = feld[11] * * Es werden also zwölf Ganzzahlen * (in Java auch unter Integer bekannt) * eingelesen.*/ static private void einlesen () { int i; int j; float temp; boolean c = false; try { for (i=0; i< 12; i++) { EprogException sizeError = new EprogException(); feld [i] = (float) EprogIO.readInt (); if (feld[i] > 20) throw sizeError; if (feld[i] < -20) throw sizeError; } } catch (EprogException e) { EprogIO.println ("?"); System.exit (0); // beende Programm } /* Division durch Null abfangen. * In der Diagonale müssen Werte ungleich * Null stehen! * Durch austauschen der Zeilen muss eine * Möglichkeit gefunden werden, sonst wird * FALSCHE EINGABE zurückgegeben.*/ /* Hier werden die 6 Möglichkeiten durchprobiert. * Es werden immer abwechselt die unteren zwei Zeilen * und dann die letzte und erste Zeile getauscht. * Damit werden alle Möglichkeiten durchprobiert! * * Diese Reihenfolge demonstriert wie der Code * funktioniert. * a,b,c sind jeweils eine Zeile. * a a b b c c * b -> c -> c -> a -> a -> b * c b a c b a */ for (i=1; i <= 6;i++) { // feld_ausgeben(); if (! (feld[0] == 0 || feld[5] == 0 || feld[10] == 0)) { c = true; break; // Lösung gefunden! } if (i%2 == 1) // Vertausche untere zwei Zeilen { for (j=4; j<8; j++) { // Vertausche j und j+4 temp = feld [j]; feld [j] = feld [j+4]; feld [j+4] = temp; } } else { // Vertausche oberstes und unterste Zeilen for (j=0; j<4; j++) { // Vertausche j und j+8 temp = feld [j]; feld [j] = feld [j+8]; feld [j+8] = temp; } } } if (! c) // konnte keine eindeutige Lösung finden! { EprogIO.println ("FALSCHE EINGABE"); System.exit (0); } } /* Diese Methode können Sie verwenden, um * das Beispiel besser zu verstehen. Es gibt * das ganze Feld schön formatiert aus. * * Diese Methode wurde öfters verwendet, * musste aber auskommentiert werden, um * die richtigen IO/Paare zu erzeugen.*/ static private void feld_ausgeben () { for (int i=0; i< 12; i++) { EprogIO.print (feld [i]); if (i%4 < 3) EprogIO.print ("*x" + i%4); if (i%4 == 2) EprogIO.print (" = "); if (i%4 < 2) EprogIO.print (" + "); if (i%4 == 3) EprogIO.println(); } EprogIO.println(); } static private void ergebnis_ausgeben() { for (int i=0; i< 3; i++) { EprogIO.printFixed (ergebnis[i]); if (i != 2) EprogIO.print (" "); } EprogIO.println(); } /* Es gibt verschiedene Wege, ein Gleichungssystem zu * berechnen eine davon ist das Gauss'sche * Eliminationsverfahren, das hier beschrieben werden soll: * * Bringen Sie zuerst die Matrix [a11..a33] in Halbdiagonalform, * das heißt, es sollen unter der Diagonale a11 a22 a33 nur noch * Nullen stehen. * In der Diagonale müssen Werte ungleich 0 stehen! * * Beispiel: * 1 2 3 4 * 2 2 4 5 | -(2/1)*Zeile1 * 1 -1 1 7 | -(1/1)*Zeile1 * * * 1 2 3 4 * 0 -2 -2 -3 * 0 -3 -2 3 | -(-3/-2)*Zeile2 * * * 1 2 3 4 * 0 -2 -2 -3 * 0 0 1 7.5 */ static private void halb_diagonal_form () { int i; /* Die einzelnen Zeilen werden um diesen Faktor * erweitert, damit man auf das Ergebnis kommt.*/ float faktor; // erster Schritt: -(2/1) * Zeile1 faktor = feld [4] / feld [0]; for (i=0; i< 4; i++) feld [i+4] -= faktor * feld [i]; // feld_ausgeben(); // zweiter Schritt: -(1/1) * Zeile1 faktor = feld [8] / feld [0]; for (i=0; i< 4; i++) feld [i+8] -= faktor * feld [i]; // feld_ausgeben(); // dritter Schritt: -(-3/-2) * Zeile2 faktor = feld [9] / feld [5]; for (i=0; i< 4; i++) feld [i+8] -= faktor * feld [i+4]; // feld_ausgeben(); } /* Wenn das Gleichungssystem auf die richtige Form gebracht * wurde, ist die Berechnung von x1, x2 und x3 * (in diesem Fall jetzt ergebnis[0], ergebnis[1] und * ergebnis[2]) ein Kinderspiel! * * feld[0] *x1 + feld[1] *x2 + feld[2] *x3 = feld[3] * feld[5] *x2 + feld[6] *x3 = feld[7] * feld[10] *x3 = feld[11] */ static private void berechnen () { /* Auch hier könnte noch eine division durch Null * auftreten, falls durch das bringen in die * Halbdiagonalform noch ein zusätlicher Wert * Null geworden ist? * * Richtig wäre ein erneuter Aufruf von Austauschen * der Zeilen und in halbdiagonale bringen, ist * so aber nicht gefordert.*/ if (feld[0] == 0 || feld[5] == 0 || feld[10] == 0) { EprogIO.println ("FALSCHE EINGABE"); System.exit (0); // beende Programm } /* x3 können wir direkt in der dritten Zeile * berechnen!*/ ergebnis[2] = feld [11] / feld [10]; /* x2 können wir mit verwendung von x3 in der * zweiten Zeile berechnen. Dazu feld[6] *x3 * subtrahieren und das ganze diviert durch feld[5] * um zu x2 zu gelangen.*/ ergebnis[1] = (feld [7] - feld [6] * ergebnis [2]) / feld[5]; /* Fast fertig berechnet, jetzt fehlt nur noch x1, * welches durch die erste Zeile berechnet werden kann. * Diesesmal den ganzen Ausdruck * (feld[1] * x2 + feld[2] * x3) * mit Subtraktion auf die rechte Seite bringen und * das Ganze durch feld[0] um auf x1 zu kommen!*/ ergebnis[0] = (feld[3] - (feld[1] * ergebnis[1] + feld[2] * ergebnis[2])) / feld [0]; } static public void main (String [] arg) { feld = new float [12]; ergebnis = new float [3]; einlesen (); // feld_ausgeben(); halb_diagonal_form(); berechnen(); ergebnis_ausgeben(); } };
Fr Jul 30 13:54:24 CEST 2021
patent_button.gif valid-html401.png elektra.jpg fsfe-logo.png valid-css.png vim.gif anybrowser.gif