Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » Rätselecke » Gleichungssystem lösen

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
02.07.2003, 15:47 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


So da wir ja nun wissen wie man eine Determinante einer Matrix bestimmt, kann man ganz leicht ein lineares Gleichungssystem lösen.

zu schreiben ist folgende Funktion:

C++:
double* glSys(double*m,int n,double*v);


m ist die Matrix die die Koeffizienten der Variablen des Gleichungssystems enthält.
n ist die breite und höhe der matrix.
v ist der vektor der mit den bedinungung die für die Gleichungen gelten sollen

Beispiel: nehmen wir folgendes Gleichungssystem:
6*x1 + 2*x2 -1*x3 = 9
9*x1 + 1*x2 - 3.5*x3 = 20.5
3*x1 + 2*x2 - 4*x3 = 8

Man kann dies z.b. mit Hilfe von Determinanten lösen:
x1=det(A1)/det(A);
Ihr könnt die Funktion aus dieser Aufgabe verwenden:

6 2 -1 9 2 -1
wobei A= 9 1 3.5 und A1 = 20.5 1 3.5
3 2 4 8 2 4

ma muss also nur die Zahlen der Spalte dessen, Variable man errechnen möchte durch die Zahlen des "Bedingungsvektors" (in diesem Falle (9, 20.5 ,8)) ersetzten.


returnvalue der funktion soll der Lösungsvektor sein.

Die Matrix die übergeben wird soll immer quadratisch sein, das heisst das Gleichungssystem ist niemals überbestimmt und auch nicht unterbestimmt.
Sollten hierbei eine Redundante Zeile eingefügt worden sein, was dann hiesse das das gleichungssystem doch unterbestimmt wäre soll NULL zurückgeliefert werden an sonsten halt der Lösungsvektor.
Das Gleichungssystem hat genau eine eindeutige Lösung wenn die Determinante von m ungleich 0 ist.

Dies hier könnt ihr zum testen nehmen:

C++:
int main(){
int i,n=3;

double *matrix=new double[n*n];
double *b=new double[n];
double *vektor;

matrix[0]=6;
matrix[1]=2;
matrix[2]=-1;

matrix[3]=9;
matrix[4]=1;
matrix[5]=3.5;

matrix[6]=3;
matrix[7]=2;
matrix[8]=4;

b[0]=9;
b[1]=20.5;
b[2]=8;

if( (vektor=glSys(matrix,n,b))==NULL) printf("Nicht eindeutig lösbar\n");
else for(int i=0;i<n;i++) printf("x%d=%f\t",i+1,vektor[i]);
printf("\n");
}

delete [] matrix;
delete [] b;
if(vektor!=NULL) delete [] vektor;




Wenn ihr als Lösung x1=2 x2=-1 und x3=1 rausbekommt habt ihrs warhscheinlich richtig gemacht.

Viel Spass


Bearbeitung von Pablo:

URL war nicht aktuell.


--
...fleißig wie zwei Weißbrote

Dieser Post wurde am 02.05.2004 um 18:56 Uhr von Pablo editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
04.07.2003, 09:12 Uhr
daredevil
Speicherteufel



C++:
#include "stdio.h"

double det(double*m,int n){
double*h,r=m[0]*m[3]-m[1]*m[2], loes;
int i,j,k,x=n-1,b=1;
if(n-2){
    r=0;
    for(i=-1;++i<n;b=-b){
        h=new double[x*x];
        for(j=0;j<x;j++)
            for(k=0;k<x;k++)
                h[k+j*n-j]=m[(k<i?0:1)+n+k+j*n];
        r+=b*m[ i ]*det(h,x);
        delete[]h;
    }
}
return r;
}

double* Gleich(double*m, int n, double*v)
{
double oben, unten;
double *speicher=new double[n*n];
double *loes=new double[n];
int i, j, k;

unten=det(m, n);

printf("unten ist %.2lf\n", unten);

for(i=0; i<(n*n); i++)
speicher[i]=m[i];

for(k=0; k<n; k++)
for(i=0, j=0; i<(n*n); i+=n, j++)
{
    speicher[i]=v[j];
oben=det(speicher, n);
printf("oben ist %.2lf\n", oben);

loes[i]=oben/unten;    
}    


return loes;

}

int main(){
double *matrix=new double[3*3];
double *beding=new double[3];
double *loes=new double[3];
int i;

//erste Zeile
matrix[0]=6;
matrix[1]=2;
matrix[2]=-1;
//zweite Zeile
matrix[3]=9;
matrix[4]=1;
matrix[5]=3.5;

matrix[6]=3;
matrix[7]=2;
matrix[8]=4;

beding[0]=9;
beding[0]=20.5;
beding[0]=8;

loes=Gleich(matrix,3, beding);

for(i=0; i<3; i++)
    printf("x%d ist gleich: %.2f\n",i, loes[i]);


delete [] matrix;
return 0;
}




Kannst du mir sagen was da nicht stimmt?
--
tschüss,
DareDevil
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
04.07.2003, 09:53 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


Hi,
den Fehler in deiner Funktion hab ich noch nicht gefunden.
Aber auf jeden Fall ist die hier ein ärgerliches Fehlerchen unterlaufen.
So einer der leider öfter kommt wenn man copy und paste verwendet


C++:
beding[0]=9;
beding[0]=20.5;
beding[0]=8;



muss natürlich so heissen


C++:
beding[0]=9;
beding[1]=20.5;
beding[2]=8;


--
...fleißig wie zwei Weißbrote

Dieser Post wurde am 04.07.2003 um 09:54 Uhr von Heiko editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
04.07.2003, 10:05 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


falsch an deiner funktion ist das du die determinante "oben" zu früh ausrechnest, bevor du den kompletten vektor kopiert hast.

und für die folgenden werte musste du erst wieder die alte matrix herstellen und nur immer die erforderliche spalte austauschen, an sonsten stehen ja in der vorspalte noch die vorher überschriebenen werte, die an dieser Stelle dann falsch wären.

Gruss Heiko
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
04.07.2003, 10:07 Uhr
daredevil
Speicherteufel


uups...
bin schreibfaul. habs ausgebessert, aber es kommen immer noch falsche werte raus.

danke für die hilfe.
--
tschüss,
DareDevil
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
04.07.2003, 10:39 Uhr
daredevil
Speicherteufel


juhuu!

es klappt!


C++:
#include "stdio.h"

double det(double*m,int n){
double*h,r=m[0]*m[3]-m[1]*m[2], loes;
int i,j,k,x=n-1,b=1;
if(n-2){
    r=0;
    for(i=-1;++i<n;b=-b){
        h=new double[x*x];
        for(j=0;j<x;j++)
            for(k=0;k<x;k++)
                h[k+j*n-j]=m[(k<i?0:1)+n+k+j*n];
        r+=b*m[ i ]*det(h,x);
        delete[]h;
    }
}
return r;
}

double* Gleich(double*m, int n, double*v)
{
double oben, unten;
double *speicher=new double[n*n];
double *loes=new double[n];
int i, j, k, z;

unten=det(m, n);

for(k=0; k<n; k++)
{
for(z=0; z<(n*n); z++)
speicher[z]=m[z];

for(i=0, j=0; i<(n*n); i+=n, j++)
speicher[j*n+k]=v[j];

oben=det(speicher, n);
loes[k]=oben/unten;    
}    

delete [] speicher;
return loes;
}

int main(){
double *matrix=new double[3*3];
double *beding=new double[3];
double *loes=new double[3];
int i;

//erste Zeile
matrix[0]=6;
matrix[1]=2;
matrix[2]=-1;
//zweite Zeile
matrix[3]=9;
matrix[4]=1;
matrix[5]=3.5;

matrix[6]=3;
matrix[7]=2;
matrix[8]=4;

beding[0]=9;
beding[1]=20.5;
beding[2]=8;

loes=Gleich(matrix,3, beding);

for(i=0; i<3; i++)
    printf("x%d ist gleich: %.2f\n",i, loes[i]);

delete [] beding;
delete [] loes;
delete [] matrix;
return 0;
}




wie gesagt, optimierung ist nicht meine sache...
--
tschüss,
DareDevil

Dieser Post wurde am 04.07.2003 um 10:40 Uhr von daredevil editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
04.07.2003, 10:53 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


Jupp funzt.
Hast du gut gemacht.
ein bisschen was zu meckern hab ich allerdings noch.
Es fehlt das der Null zurückliefert, wenn det=0;
sonst bekommst du nen Absturz falls das mal passiert.
Ausserdem allokierst du hier speicher

C++:
double *loes=new double[3];



dem pointer loes weisst du aber an dieser stelle was neues zu

C++:
loes=Gleich(matrix,3, beding);



das heisst du hast dann noch reste in deinem speicher stehen die du nicht mehr weg bekommst. Besser wäre nicht zu allokieren sondern nur den pointer zu definieren weil die funktion das ja schon für dich übernimmt.
Vielleicht solltest du dich ja Speicherteufel nennen.

so genug gelabert hier ist meine, natürlich kürzere Lösung

C++:
double* glSys(double*m,int n,double*v){
int i=-1,j,k;
double a=det(m,n),*r=NULL,*h;
    if(a!=0){
        r=new double[n];
        while(++i<n){
            h=new double[n*n];
            for(j=0;j<n;j++)for(k=0;k<n;k++)h[k+j*n]=i-k?m[k+j*n]:v[j];
            r[i]=det(h,n)/a;
            delete[]h;
        }
    }
return r;
}


--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
04.07.2003, 11:05 Uhr
daredevil
Speicherteufel





C++:
#include "stdio.h"

double det(double*m,int n){
double*h,r=m[0]*m[3]-m[1]*m[2], loes;
int i,j,k,x=n-1,b=1;
if(n-2){
    r=0;
    for(i=-1;++i<n;b=-b){
        h=new double[x*x];
        for(j=0;j<x;j++)
            for(k=0;k<x;k++)
                h[k+j*n-j]=m[(k<i?0:1)+n+k+j*n];
        r+=b*m[ i ]*det(h,x);
        delete[]h;
    }
}
return r;
}

double* Gleich(double*m, int n, double*v)
{
double oben, unten;
double *speicher=new double[n*n];
double *loes=new double[n];
int i, j, k, z;

unten=det(m, n);
if(unten==0)
{
//Fehlerbehandlung
}

for(k=0; k<n; k++)
{
for(z=0; z<(n*n); z++)
speicher[z]=m[z];

for(i=0, j=0; i<(n*n); i+=n, j++)
speicher[j*n+k]=v[j];

oben=det(speicher, n);
loes[k]=oben/unten;    
}    

delete [] speicher;
return loes;
}

int main(){
double *matrix=new double[3*3];
double *beding=new double[3];
double *loes;
int i;

//erste Zeile
matrix[0]=6;
matrix[1]=2;
matrix[2]=-1;
//zweite Zeile
matrix[3]=9;
matrix[4]=1;
matrix[5]=3.5;

matrix[6]=3;
matrix[7]=2;
matrix[8]=4;

beding[0]=9;
beding[1]=20.5;
beding[2]=8;

loes=Gleich(matrix,3, beding);

for(i=0; i<3; i++)
    printf("x%d ist gleich: %.2f\n",i, loes[ i ]);

delete [] beding;
delete [] loes;
delete [] matrix;
return 0;
}




so besser?
--
tschüss,
DareDevil
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
04.07.2003, 11:08 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


Ja ja,war ja schon akzeptiert.
Ich meinte das auch einfacher
so:

C++:
if(unten==0) return NULL;


--
...fleißig wie zwei Weißbrote

Dieser Post wurde am 04.07.2003 um 11:09 Uhr von Heiko editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
04.07.2003, 11:14 Uhr
daredevil
Speicherteufel



so jetzt hab ich 2 von deinen rätseln gelöst...
jetzt hab ich blut geleckt und lust auf noch eins...
--
tschüss,
DareDevil
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ Rätselecke ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: