Lineare Gleichungssysteme lösen -> Problem

Status
Nicht offen für weitere Antworten.

Icarus

Neues Mitglied
Hallo,

ich versuche mich derzeit an einer eigenen Klasse zum lösen von linearen Gleichungssystemen der Form Ax=y, wobei A eine quadratische Matrix mit einer beliebigen Zeilen-/Spaltenanzahl n ist.

Mein Code führt auch zu den richtigen Ergebnissen, solange an den entscheidenden Stellen keine Nullen im Spiel sind.

(Anmerkung: Die Spalte ganz rechts repräsentiert den y Vektor)

(Konsolenausgabe) Matrix, die korrekt gelöst wird:

( 2.0 | 3.0 | 0.0 )
( 4.0 | 7.0 | 1.0 )

Ergebnis: [-1.5, 1.0]

(Konsolenausgabe) Matrix, bei der Probleme auftauchen:

( 0.0 | 2.0 | 1.0 )
( 2.0 | 1.0 | 1.0 )

Ergebnis: [NaN, 0.5]


Wie dieser Fehler zustande kommt ist mir klar: Es kommt zu einer Division von 0 / R (R: eine Reele Zahl), die bei einer "von Hand" ausgeführten Rechnung durch die richtige Sortierung der Zeilen verhindert würde.

Nur wie bringt man dem Computer bei, die Zeilen vorher korrekt zu sortieren?


Ich habe mich in dem Zusammenhang ein wenig durch das Web gegooglet und oft etwas von Pivotisierung und LR-Zerlegung gelesen, aber leider nicht wirklich verstanden, worum es dabei geht, bzw. wie es funktioniert. ???:L

Kennt jemmand vieleicht einen guten Link oder eine gute Erklärung?

Hoffe Ihr könnt mir weiterhelfen :)



Mein Code:

Code:
import java.util.*;

public class LGS 
{
	
	public static void main(String[] args) 
	{
//		LGS lTestLGS = new LGS( new double[][]{{2,3,0},{4,7,1}});
//		LGS lTestLGS = new LGS( new double[][]{{3,6,-2,-4},{3,2,1,0},{(double)3/2,5,-5,-9}});
		LGS lTestLGS = new LGS( new double[][]{{0,2,1},{2,1,1}});
		lTestLGS.printToConsole();
		System.out.print( Arrays.toString( lTestLGS.solve() ) );
	}
	
	private double lLGS[][];
	
	public LGS ( double pLGS[][] ) 
	{
		lLGS = pLGS;
		
	}
	
	public double[] solve( )
	{
		for( int i=0; i<lLGS.length-1; i++ )
		{
//			System.out.println("LGS Primary cursor is now in line " + i);
			for( int j=i+1; j<lLGS.length; j++ )
			{
//				System.out.println("LGS Secondary cursor is now in line " + j);
				double lFactor = lLGS[i][i] / lLGS[j][i];
				System.out.println("LGS Factor: " + lLGS[i][i] + " / " + lLGS[j][i] + " = " + lFactor);
				for( int k=i; k<lLGS[0].length; k++ )
				{
					System.out.print("LGS Calc: " + lLGS[j][k] + " * " + lFactor + " - " + lLGS[i][k] + " = " );
					lLGS[j][k] = lLGS[j][k] * lFactor - lLGS[i][k];
					System.out.print(lLGS[j][k] + "\r\n");
					
				}
				
//				this.printToConsole();
			}
		}
		
		double lSolutions[] = new double[lLGS.length];
		
		for( int i=lLGS[0].length-2; i>=0; i-- )
		{
			double lTemp = lLGS[i][lLGS[0].length-1];
			for( int j=lLGS[0].length-2; j>i; j--)
			{
//				System.out.print( lTemp );
				lTemp = lTemp - lLGS[i][j] * lSolutions[j];
//				System.out.print( " - " + lLGS[i][j] + " * " + lSolutions[j] + " = " + lTemp + "\r\n");
//				System.out.println("j " + j );
			}
//			System.out.println("i " + i );
			lSolutions[i] = lTemp / lLGS[i][i];
//			System.out.println( "LSG: " + lTemp + " / " + lLGS[i][i] + " = " + lSolutions[i] );
		}
		
		return lSolutions;
	
	}
	
	public void printToConsole()
	{
		String lOutput = new String();
		for( int i=0; i<lLGS.length; i++ )
		{
			lOutput = lOutput + "( ";
			for( int j=0; j<lLGS[i].length; j++ )
			{
				lOutput = lOutput + lLGS[i][j];
				if( j+1 <lLGS[i].length ) lOutput = lOutput + " | ";
			}
			lOutput = lOutput + " )\r\n";
		}
		System.out.println(lOutput);
	}
}
 

0x7F800000

Top Contributor
Das gehört eigentlich ins Mathematik-unterforum...

Die zeilen darfst du vertauschen wie du willst, von der Reihenfolge der Gleichungen ändert sich die Lösungsmenge des Gleichungssystems ja nicht. Deswegen darfst du in jeder Spalte nach einem pivot element !=0 suchen, und dieses pivot-element auf die diagonale verschieben.

Es könnte aber auch sein, dass du kein pivotelement !=0 findest, wenn etwa die gesamte Spalte von Anfang an 0 gewesen ist.

Was du dann machst, hängt davon ab, was du machen willst.
Wenn du nur eine Partikuläre Lösung finden willst, dann solltest du besser PA=LR zerlegung nehmen, das ist schneller. Für die Anschauung find ich folgende Animation ziemlich gut.

Kommt es dir auf die partikuläre Lösung nicht so sehr an, und willst du stattdessen den Kern von A haben, dann weiß ich gar nicht, was normalerweise gemacht wird. Ich habe zB folgende methode implementiert, die zusätzlich den Kern berechnet:

Klasse zum abspeichern von simplen double-matrizen:
Code:
package fastnumerics;

import numbertheory.ZMath;

public class Matrix implements Cloneable{
	
	public double[][] elements;
	
	public Matrix(int rows, int columns){
		if(rows<=0 || columns<=0){
			throw new IllegalArgumentException("number of rows and columns must be positive");		
		}
		elements=new double[rows][columns];
	}
	
	public Matrix(double[][] _elements){
		elements=_elements;
		
		if(rows()<=0 || columns()<=0){
			throw new IllegalArgumentException("number of rows and columns must be positive");
		}
	}
	
	public Matrix(int rows, int columns, double ... _elements){
		elements=new double[rows][columns];
		for(int r=0; r<rows; r++){
			for(int c=0; c<columns; c++){
				elements[r][c]=_elements[r*columns+c];
			}
		}
	}
	
	public int rows(){
		return elements.length;
	}
	
	public int columns(){
		return elements[0].length;
	}
	
	public Matrix transpose(){
		Matrix result=new Matrix(columns(),rows());
		for(int i=0; i<rows(); i++){
		for(int k=0; k<columns(); k++){
			result.elements[k][i]=elements[i][k];
		}
		}
		return result;
	}
	
	public String toString(){
		StringBuffer buffer=new StringBuffer();
		if(columns()>1){
			// write as matrix
			for(int r=0; r<rows(); r++){
				for(int c=0; c<columns(); c++){
					buffer.append(elements[r][c]+"\t");
				}
				buffer.append("\n");
			}
		}else{
			//write as column vector
			buffer.append("(");
			for(int r=0; r<rows(); r++){
				buffer.append(elements[r][0]+(r==rows()-1?"":"\t"));
			}
			buffer.append(")^T");
		}
		return buffer.toString();
	}
	
	public Matrix clone(){
		Matrix clone=new Matrix(rows(),columns());
		for(int r=0; r<rows(); r++){
		for(int c=0; c<columns(); c++){
			clone.elements[r][c]=elements[r][c];
		}
		}
		return clone;
	}
	
	public Matrix multiply(Matrix other){
		Matrix result=new Matrix(this.rows(),other.columns());
		for(int r=0; r<result.rows(); r++){
		for(int c=0; c<result.columns(); c++){
			for(int k=0; k<this.columns(); k++){
				result.elements[r][c]+=this.elements[r][k]*other.elements[k][c];
			}
		}
		}
		return result;
	}
	
	public Matrix add(Matrix other){
		Matrix result=new Matrix(this.rows(),this.columns());
		for(int r=0; r<result.rows(); r++){
		for(int c=0; c<result.columns(); c++){
			result.elements[r][c]=this.elements[r][c]+other.elements[r][c];
		}
		}
		return result;
	}
	
	public static Matrix getIdentity(int n){
		Matrix result=new Matrix(n,n);
		for(int r=0; r<result.rows(); r++){
		for(int c=0; c<result.columns(); c++){
			result.elements[r][c]=ZMath.kronekerDelta(r, c);
		}
		}
		return result;
	}
}

...und hier das eigentliche Gauß'sche Eliminationsverfahren:
Code:
package fastnumerics;
import java.util.*;

public class GaussianElimination {
	
	/**
	 * Solves Ax=b, returns particular solution, writes Kernel-basis into the list
	 * warning: this method completely wrecks the matrices A and b !
	 * 
	 * @param a			Matrix A 	
	 * @param b			multiple column vectors b_1,...,b_r combined to one Matrix b
	 * @param basis 	(output) reference to an empty collection of matrices, that is filled with basis vectors of the kernel
	 * 
	 * @return			particular solutions for Ax_1=b_1, ... , Ax_r=b_r combined to one single matrix x so that Ax=b
	 */
	public static Matrix gaussianEliminationWithSideEffects(Matrix a,Matrix b,Collection<Matrix> basis){
		
		// #{basis vectors}+#pivotElements= dim(Ker)+dim(Img) = dim(Source)=number of columns
		/*  from the one side, the array is filled with positions of pivot elements
		 *  from the other side, the array is filled with indices of columns, that have no pivot element
		 */
		int[] pivotPositions_basisVectors=new int[a.columns()];
		int rang=0;
		
		for(int row=0,column=0; row<a.rows() && column<a.columns(); row++,column++){
			//search for a row with a_i0 != 0, get the maximal
			double bestPivot=0; int bestPivotIndex=row;
			for(int pivotSearch=row; pivotSearch<a.rows(); pivotSearch++){
				if(Math.abs(a.elements[pivotSearch][column])>bestPivot){
					bestPivotIndex=pivotSearch;
					bestPivot=Math.abs(a.elements[pivotSearch][column]);
				}
			}
			if(bestPivot>0){
				//save position of the pivot element
				pivotPositions_basisVectors[row]=column;
				rang++;
				//swap row and bestPivotIndex
				double[] temp=a.elements[row];
				a.elements[row]=a.elements[bestPivotIndex];
				a.elements[bestPivotIndex]=temp;
				//also in b
				temp=b.elements[row];
				b.elements[row]=b.elements[bestPivotIndex];
				b.elements[bestPivotIndex]=temp;
				
				double f;
				//eliminate all elements (except for the current row) in the current column
				for(int eliminating=0; eliminating<a.rows(); eliminating++){
					if(eliminating==row) continue;
					f=-a.elements[eliminating][column]/a.elements[row][column];
					a.elements[eliminating][column]=0;
					for(int h=column+1; h<a.columns(); h++){
						a.elements[eliminating][h]+=a.elements[row][h]*f;
					}
					//same for b
					for(int h=0; h<b.columns(); h++){
						b.elements[eliminating][h]+=b.elements[row][h]*f;
					}
				}
				//normalize row
				f=1/a.elements[row][column];
				a.elements[row][column]=1;
				for(int h=column+1; h<a.columns(); h++){
					a.elements[row][h]*=f;
				}
				//same for b
				for(int h=0; h<b.columns(); h++){
					b.elements[row][h]*=f;
				}
			}else{
				//pivot != 0 not found
				//save the column, which later will be transformed into vector of the basis
				pivotPositions_basisVectors[a.columns()-1-column+rang]=column;
				//look at the next column, stay in the same row
				row--;
				continue;
			}
		}
		
		//create basis vectors
		for(int i=rang; i<a.columns(); i++){
			
			Matrix basisVector=new Matrix(a.columns(),1);
			int vectorIndex=pivotPositions_basisVectors[i];
			
			basisVector.elements[vectorIndex][0]=-1;
			for(int k=0; k<rang; k++){
				basisVector.elements[pivotPositions_basisVectors[k]][0]=a.elements[k][vectorIndex];
			}
			
			basis.add(basisVector);
		}
		
		//create particular solution
		Matrix particularSolution=new Matrix(a.columns(),b.columns());
		for(int bRow=0; bRow<rang; bRow++){
			particularSolution.elements[pivotPositions_basisVectors[bRow]]=b.elements[bRow];
		}
		
		//check that rang(b)<=rang(a)
		for(int bRow=rang; bRow<b.rows(); bRow++){
		for(int h=0; h<b.columns(); h++){
			if(b.elements[bRow][h]!=0){
				return null; //no solution
			}
		}
		}
		
		return particularSolution;
	}
	
	/**
	 * Does the same as gaussianEliminationWithSideEffects, but works with clones of A and b.
	 * @param a			Matrix A
	 * @param b			multiple column vectors combined to one Matrix
	 * @param basis		(output) empty collection of matrices, that is filled with basis vectors of the kernel of A
	 * @return			particular solution x so that Ax=b
	 */
	
	public static Matrix gaussianElimination(Matrix a, Matrix b, Collection<Matrix> basis){
		return gaussianEliminationWithSideEffects(a.clone(),b.clone(),basis);
	}
	
	public static void main(String[] args){
		
		//* 
		Matrix a=new Matrix(3,3, 2,2,0, 2,4,1, 0,2,1);
		Matrix b=new Matrix(3,1, 4,7,3);
		//*/
		
		Collection<Matrix> basis=new LinkedList<Matrix>();
		
		System.out.println(a);
		System.out.println(b);
		
		System.out.println("particular="+gaussianEliminationWithSideEffects(a,b,basis));
		System.out.println("basis=");
		for(Matrix m:basis){
			System.out.println(m);
		}
	}
}
Hier werden die Spalten nicht hinundherpermutiert, es gibt auch keine Permutationsmatrix P (gut, die gibt es bei der anderen implementierung eigentlich auch nicht)
Stattdessen werden die positionen der pivot-elemente und der Spalten, wo keine pivot-elemente zu finden waren, in einem array abgespeichert (in einem wohlbemerkt: weil die größe des Arrays vorher eindeutig durch die dimension des Urbildes bestimmt ist. Für mathematische Anschauung ist das etwas besser, zudem spart es speicherplatz, aber es ist vielleicht nicht so gut zu lesen)
Am ende wird aus den spalten mit pivot-elementen die spezielle Lösung zusammengebastelt.
Aus den Spalten ohne pivot-elemente wird der Kern zusammengebaut.

Es funzt ganz gut. Aber alleine aus dem code wirst du das wohl auch nicht nachvollziehen können, rechne lieber selbst ein wenig herum, bis du dir das alles klargemacht hast.


edit: Achso, zum testen solltest du noch das ZMath package rauswerfen, brauchst du eh nicht. kroneker-delta wirst du wohl selbst hinbekommen ;) oder schmeiß die methode, die das benötigt auch raus: für die gauß elimination braucht man das alles nicht.
 

Icarus

Neues Mitglied
Hallo Andrey,

entschuldige bitte, dass ich das falsche Forum gewählt habe. Ich dachte, das Mathematikforum sei für mathematische Fragen, welche nichts mit Programmierproblemen zu tun haben.

Danke für den Link und Deinen Code. :)

Werde beides morgen mal durcharbeiten in der Hoffnung, dass ich dann mein Problem gelöst bekomme! :###

Ansonsten wird man nochmal von mir hören :wink:
 

0x7F800000

Top Contributor
Icarus hat gesagt.:
Ich dachte, das Mathematikforum sei für mathematische Fragen, welche nichts mit Programmierproblemen zu tun haben.
Nee, dafür ist das eher ungeeignet. kein Latex, kein MathML... :?
Ist im Prinzip nicht soo wichtig, solangs nicht bei EE o.ä. landet :D
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
NoP-ay Lineare Rekurison gibAnzahl Java Basics - Anfänger-Themen 6
amelie123456 Lineare Suche / Binäre Suche Java Basics - Anfänger-Themen 2
S Lineare listen verkettung Java Basics - Anfänger-Themen 7
V_Fynn03 Beliebiges Element in einer Liste löschen (Java)(Lineare Datenstrukturen) Java Basics - Anfänger-Themen 9
V_Fynn03 Lineare Datenstrukturen Element löschen? Java Basics - Anfänger-Themen 2
S Java Lineare-Suche Zeitmessung Java Basics - Anfänger-Themen 5
S Java Lineare Suche Java Basics - Anfänger-Themen 1
A Was könnten typische Prüfungsaufgaben zum Thema lineare, verkettete Listen sein? Java Basics - Anfänger-Themen 5
B lineare und schlichte Rekursion Java Basics - Anfänger-Themen 1
A Lineare Rekursion Java Basics - Anfänger-Themen 6
R Klassen Die lineare Datenstruktur Queue Java Basics - Anfänger-Themen 3
N Array, lineare Suche, binäre Suche, Programm bleibt unerwartet stehen... Java Basics - Anfänger-Themen 6
L Einfache Lineare Suche Java Basics - Anfänger-Themen 7
S Lineare Gleichung lösen Java Basics - Anfänger-Themen 1
L Lineare Listen Java Basics - Anfänger-Themen 2
S Datentypen nicht lineare STATISCHE Datenstruktur? Java Basics - Anfänger-Themen 10
B lineare Gleichung programmieren Java Basics - Anfänger-Themen 2
P Lineare Suche im Array Java Basics - Anfänger-Themen 5
C Lineare Rekursion -> iterative Schleife Java Basics - Anfänger-Themen 3
B Lineare Suche Java Basics - Anfänger-Themen 5
B endrekursion und lineare rekursion Java Basics - Anfänger-Themen 4
U Lineare Suche in einem Array Java Basics - Anfänger-Themen 3
T Lineare Listen: sortiertes Einfügen Java Basics - Anfänger-Themen 6
M lineare Suche Java Basics - Anfänger-Themen 12
G verkettete lineare Liste Java Basics - Anfänger-Themen 2
D Lineare Kongruenz Java Basics - Anfänger-Themen 4
B Warum hat dieser einfache Algorithmus lineare Laufzeit? Java Basics - Anfänger-Themen 3
G Array - lineare Liste Java Basics - Anfänger-Themen 2
Chucky Lineare Listen Programm Verständnisproblem Java Basics - Anfänger-Themen 38
Alen123 Wie würdet ihr diese Aufgabenstellung lösen? Java Basics - Anfänger-Themen 18
S GUI-Programmierung Sudoku-Rätsel lösen Java Basics - Anfänger-Themen 1
L Symbo Rätsel lösen lassen Java Basics - Anfänger-Themen 3
J Array eintrag mit möglichst wenig code lösen Java Basics - Anfänger-Themen 16
T Rekursionsaufgabe lösen Java Basics - Anfänger-Themen 6
D Erste Schritte Lösen dieser Aufgabe, Hilfe! Java Basics - Anfänger-Themen 12
F Switch Case Problem mit Regex lösen? Java Basics - Anfänger-Themen 6
B Türme von Hanoi mit einer beliebigen aber gültigen Eingabe lösen Java Basics - Anfänger-Themen 5
N Denksportaufgabe durch Algorithmus lösen Java Basics - Anfänger-Themen 2
K Compiler-Fehler NullPointerException lösen Java Basics - Anfänger-Themen 16
B Wie könnte man mit Java diese Matheaufgabe lösen Java Basics - Anfänger-Themen 7
kilopack15 Sin(x) rekursiv lösen Java Basics - Anfänger-Themen 17
A instanceof-if-else-Anweisungen eleganter lösen Java Basics - Anfänger-Themen 5
N Von Kopf bis Fuss TestArrays lässt sich nicht lösen Java Basics - Anfänger-Themen 5
L NullPointerException lösen Java Basics - Anfänger-Themen 6
R Hanoi rekursiv lösen Problem Java Basics - Anfänger-Themen 1
A Sudoku mit Backtracking lösen Java Basics - Anfänger-Themen 3
C Gleichung mit Potenz mit einer Unbekannten lösen Java Basics - Anfänger-Themen 5
D Sudoku lösen mit Backtracking Java Basics - Anfänger-Themen 20
B Quadratische Gleichung mit JAVA lösen Java Basics - Anfänger-Themen 5
S Bisschen hilfe beim Sudoku Lösen benötigt Java Basics - Anfänger-Themen 7
I Fragen bzw. Aufgabe lösen Java Basics - Anfänger-Themen 4
C Differenz-Methode mit Array lösen Java Basics - Anfänger-Themen 14
M Sudoku Rekursiv lösen Java Basics - Anfänger-Themen 9
M Gibt es eine einfachere Variante diese Aufgabenstellung zu lösen? Java Basics - Anfänger-Themen 11
O Wie kann man das einfach lösen? (dynamisch viele Attribute) Java Basics - Anfänger-Themen 6
G methode lösen Java Basics - Anfänger-Themen 5
G Sudoku rekursiv lösen Java Basics - Anfänger-Themen 10
G (csv)Datei lesen FindBug findet mgl. NullPointer - wie lösen Java Basics - Anfänger-Themen 3
K Lösen einer Gleichung Java Basics - Anfänger-Themen 12
V wie kann man das lösen ? Java Basics - Anfänger-Themen 3
lumo lösen von: "Type safety"? Java Basics - Anfänger-Themen 4
J Mit welchem LayoutManager Problem lösen? Java Basics - Anfänger-Themen 2
A Übungsaufgabe lösen - Problem mit true und false Java Basics - Anfänger-Themen 6
J Lösen linearer Gleichungen Java Basics - Anfänger-Themen 3
N Ist dieses Problem mit Java zu lösen? Java Basics - Anfänger-Themen 7
P wait und notify oder wie soll ich es lösen Java Basics - Anfänger-Themen 2
H [req] wer kann mir helfen die aufgabe zu lösen? Java Basics - Anfänger-Themen 2
F Kann ein Problem bei Anweisungen nicht lösen Java Basics - Anfänger-Themen 4
G Aufgabe: Kann sie nicht lösen Java Basics - Anfänger-Themen 12
G quadratische Gleichung lösen Java Basics - Anfänger-Themen 2
I gleichung lösen Java Basics - Anfänger-Themen 4
S Gleichungssystem lösen Java Basics - Anfänger-Themen 6

Ähnliche Java Themen

Neue Themen


Oben