Prethodna tema :: Sljedeća tema |
Autor/ica |
Poruka |
markotron Forumaš(ica)
Pridružen/a: 26. 10. 2008. (12:07:29) Postovi: (95)16
Spol:
Lokacija: Umag
|
Postano: 16:57 ned, 7. 6. 2009 Naslov: |
|
|
Evo pokusao sam napravit program koji rjesava sustave linearnih jednadžbi. Nadam se da ispavno radi.. Provjeravao sam ali je provjerat dosta tesko za vece sustave pa ne znam.. Ako itko primjeti bug neka slobodno javi.. Odlucio sam ga stavit na forum jer mozda ce nekad nekom zatrebati :)
Upustva: Kopirajte kod u dev-cpp ili bilo sta slicno ili kako god hocete ga skompajlirajte. U istom folderu napravite dokument sustav.txt i u njega napisite prosirenu matricu (ako je sustav homogen, matrica MORA imati u zadnjem stupcu sve nule). U prvi red morate upisati koliko matrica ima redaka, odnosno stupaca. primejer
/* sustav.txt */
3 4
1 3 2 0
2 3 4 0
4 3 2 0
evo koda (malo je ruzan, ali koliko god se trudio ne mogu napisati estetski lijep kod):(
[code:1]
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
typedef struct {
int nep, jedn; //broj nepoznanica i broj jednadzba
double **Ap; //Proširena matrica sustava
} sustav;
typedef struct {
int solve, dimO, rang; //rjesivost sustava, dimenizaj potprostora rjesenja, rang Ap matrice9
double *part; //partikularno rjesenje sustava
double **omega; //baza za potprostor rjesenja
} rjesenje;
void iscitaj ( sustav s, rjesenje* r )
{
int i, j=0, b=0, k=0, br=0;
r->omega = (double**)malloc( r->dimO * sizeof(double*) );
for ( i = 0; i < r->dimO; ++i )
r->omega[i] = (double*)calloc( s.nep-1, sizeof(double) );
r->part = (double*)calloc( s.nep-1, sizeof(double) );
i = 0;
while ( i < s.jedn && j < s.nep-1 )
{
if ( !s.Ap[i][j] )
{
for ( k=0; k < s.nep-1 && k < s.jedn; ++k )
r->omega[b][k] = -s.Ap[k][j];
r->omega[b][j] = 1;
r->part[br++] = 0;
j++, b++;
continue;
}
r->part[br] = s.Ap[br][s.nep-1];
i++, j++, br++;
}
}
int zamjeni_retke ( sustav s, int j ) //obicna swap funkcija koja zamjenjuje retke cim naidje
{ //na neki element u j-tom stupcu razlicit od nule
int i, k;
if ( s.Ap[j][j] ) return TRUE;
for ( i = j+1; i < s.jedn; ++i )
if ( s.Ap[i][j] )
{
int tmp;
for ( k = 0; k < s.nep; ++k )
{
tmp = s.Ap[i][k];
s.Ap[i][k] = s.Ap[j][k];
s.Ap[j][k] = tmp;
}
return TRUE;
}
return FALSE;
}
void ponisti_stupac ( sustav s, int i, int j ) //Gaussova metoda eliminacije
{
int k, l;
for ( k = s.nep-1; k >= j; --k ) //treba ponistiti j-ti stupac sa elementom u i-tom retku.
s.Ap[i][k] /= s.Ap[i][j]; //djelimo sa elementom na poziciji i-j da dobijemo jedinicu.
for ( l = 0; l < s.jedn; ++l )
if ( l != j )
for ( k = s.nep-1; k >= j; --k )
s.Ap[l][k] = s.Ap[i][k] * -s.Ap[l][j]
+ s.Ap[l][k];
}
rjesenje rijesi_sustav ( sustav s )
{
rjesenje r;
r.solve = TRUE;
int i, j=0, k=TRUE, rang = 0; //sredjujemo sustav (matricu Ap) kako bi iz nje mogli iscitati rjesenja
for ( i = 0; i < s.jedn && j < s.nep; ++i )
{
if ( !(s.Ap[i][j]) )
k = zamjeni_retke( s, i );
if ( k || s.Ap[i][j] )
{
if ( j == s.nep-1 )
{
r.solve = FALSE;
break; // ako mjenjamo zadnji stupac =>
} // prosirana metrica nije istog ranga kao i matrica sustava.
ponisti_stupac ( s, i, j ); // Sustav nije rjesiv. (Kronecker-Capelli)
rang++;
}
else i--;
j++;
}
r.dimO = s.nep - rang - 1;
r.rang = rang;
if ( r.solve )
iscitaj( s, &r );
return r;
}
int main ( void )
{
int n, m, i, j;
double **matrica;
FILE *fp;
sustav s;
rjesenje r;
fp = fopen( "sustav.txt", "r" );
fscanf (fp, "%d%d", &n, &m );
if ( n < 2 || m < 3 )
{
printf ( "Matrica mora biti reda minimalno 3 x 2\n " );
system ( "PAUSE" );
exit ( 1 );
}
matrica = (double**)malloc( n*sizeof(double*) );
for ( i = 0; i < n; ++i )
matrica[i] = (double*)malloc( m*sizeof(double) );
for ( i = 0; i < n; ++i )
for ( j = 0; j < m; ++j )
fscanf (fp, "%lg", &matrica[i][j] );
fclose( fp );
s.nep = m;
s.jedn = n;
s.Ap = matrica;
r = rijesi_sustav ( s );
/****** ISPIS ******/
if ( !r.solve )
printf ( "Sustav nije rjesiv!\n\n" );
if ( r.solve )
{
printf( "Radi jednostavnosti su stupci ispisani kao uredjene n-torke.\n\n" );
printf( "(Partikularno) rjesenje (C_0): \n\n" );
printf ( "( " );
for ( i = 0; i < s.nep-1; ++i )
printf ( "%10.5f", r.part[i] );
printf ( " )\n\n" );
if ( r.dimO )
printf( "Prostor rjesenja: \n\n" );
for ( i = 0; i < r.dimO; ++i )
{
printf ( "( " );
for ( j = 0; j < s.nep-1; ++j )
printf ( "%10.5f", r.omega[i][j] );
printf ( " )\n" );
}
}
printf ( "\n\nDobivena matrica: \n\n" );
for ( i = 0; i < n; ++i )
{
for ( j = 0; j < m; ++j )
printf ( "%10.5f", matrica[i][j] );
printf ( "\n" );
}
/*oslobadjanje memorije*/
for ( i = 0; i < n; ++i )
free( matrica[i] );
free ( matrica );
for ( i = 0; i < r.dimO; ++i )
free ( r.omega[i] );
free ( r.omega );
free ( r.part );
system ( "PAUSE" );
return 0;
}
[/code:1]
Pozdrav
[size=9][color=#999999]Added after 11 minutes:[/color][/size]
Primjetio sam da lagano šteka.. valjda cu to ispravit sto prije...
[size=9][color=#999999]Added after 21 minutes:[/color][/size]
funkcija zamjeni retke ne radi kako treba... ah...
Evo pokusao sam napravit program koji rjesava sustave linearnih jednadžbi. Nadam se da ispavno radi.. Provjeravao sam ali je provjerat dosta tesko za vece sustave pa ne znam.. Ako itko primjeti bug neka slobodno javi.. Odlucio sam ga stavit na forum jer mozda ce nekad nekom zatrebati
Upustva: Kopirajte kod u dev-cpp ili bilo sta slicno ili kako god hocete ga skompajlirajte. U istom folderu napravite dokument sustav.txt i u njega napisite prosirenu matricu (ako je sustav homogen, matrica MORA imati u zadnjem stupcu sve nule). U prvi red morate upisati koliko matrica ima redaka, odnosno stupaca. primejer
/* sustav.txt */
3 4
1 3 2 0
2 3 4 0
4 3 2 0
evo koda (malo je ruzan, ali koliko god se trudio ne mogu napisati estetski lijep kod)
Kod: |
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
typedef struct {
int nep, jedn; //broj nepoznanica i broj jednadzba
double **Ap; //Proširena matrica sustava
} sustav;
typedef struct {
int solve, dimO, rang; //rjesivost sustava, dimenizaj potprostora rjesenja, rang Ap matrice9
double *part; //partikularno rjesenje sustava
double **omega; //baza za potprostor rjesenja
} rjesenje;
void iscitaj ( sustav s, rjesenje* r )
{
int i, j=0, b=0, k=0, br=0;
r->omega = (double**)malloc( r->dimO * sizeof(double*) );
for ( i = 0; i < r->dimO; ++i )
r->omega[i] = (double*)calloc( s.nep-1, sizeof(double) );
r->part = (double*)calloc( s.nep-1, sizeof(double) );
i = 0;
while ( i < s.jedn && j < s.nep-1 )
{
if ( !s.Ap[i][j] )
{
for ( k=0; k < s.nep-1 && k < s.jedn; ++k )
r->omega[b][k] = -s.Ap[k][j];
r->omega[b][j] = 1;
r->part[br++] = 0;
j++, b++;
continue;
}
r->part[br] = s.Ap[br][s.nep-1];
i++, j++, br++;
}
}
int zamjeni_retke ( sustav s, int j ) //obicna swap funkcija koja zamjenjuje retke cim naidje
{ //na neki element u j-tom stupcu razlicit od nule
int i, k;
if ( s.Ap[j][j] ) return TRUE;
for ( i = j+1; i < s.jedn; ++i )
if ( s.Ap[i][j] )
{
int tmp;
for ( k = 0; k < s.nep; ++k )
{
tmp = s.Ap[i][k];
s.Ap[i][k] = s.Ap[j][k];
s.Ap[j][k] = tmp;
}
return TRUE;
}
return FALSE;
}
void ponisti_stupac ( sustav s, int i, int j ) //Gaussova metoda eliminacije
{
int k, l;
for ( k = s.nep-1; k >= j; --k ) //treba ponistiti j-ti stupac sa elementom u i-tom retku.
s.Ap[i][k] /= s.Ap[i][j]; //djelimo sa elementom na poziciji i-j da dobijemo jedinicu.
for ( l = 0; l < s.jedn; ++l )
if ( l != j )
for ( k = s.nep-1; k >= j; --k )
s.Ap[l][k] = s.Ap[i][k] * -s.Ap[l][j]
+ s.Ap[l][k];
}
rjesenje rijesi_sustav ( sustav s )
{
rjesenje r;
r.solve = TRUE;
int i, j=0, k=TRUE, rang = 0; //sredjujemo sustav (matricu Ap) kako bi iz nje mogli iscitati rjesenja
for ( i = 0; i < s.jedn && j < s.nep; ++i )
{
if ( !(s.Ap[i][j]) )
k = zamjeni_retke( s, i );
if ( k || s.Ap[i][j] )
{
if ( j == s.nep-1 )
{
r.solve = FALSE;
break; // ako mjenjamo zadnji stupac =>
} // prosirana metrica nije istog ranga kao i matrica sustava.
ponisti_stupac ( s, i, j ); // Sustav nije rjesiv. (Kronecker-Capelli)
rang++;
}
else i--;
j++;
}
r.dimO = s.nep - rang - 1;
r.rang = rang;
if ( r.solve )
iscitaj( s, &r );
return r;
}
int main ( void )
{
int n, m, i, j;
double **matrica;
FILE *fp;
sustav s;
rjesenje r;
fp = fopen( "sustav.txt", "r" );
fscanf (fp, "%d%d", &n, &m );
if ( n < 2 || m < 3 )
{
printf ( "Matrica mora biti reda minimalno 3 x 2\n " );
system ( "PAUSE" );
exit ( 1 );
}
matrica = (double**)malloc( n*sizeof(double*) );
for ( i = 0; i < n; ++i )
matrica[i] = (double*)malloc( m*sizeof(double) );
for ( i = 0; i < n; ++i )
for ( j = 0; j < m; ++j )
fscanf (fp, "%lg", &matrica[i][j] );
fclose( fp );
s.nep = m;
s.jedn = n;
s.Ap = matrica;
r = rijesi_sustav ( s );
/****** ISPIS ******/
if ( !r.solve )
printf ( "Sustav nije rjesiv!\n\n" );
if ( r.solve )
{
printf( "Radi jednostavnosti su stupci ispisani kao uredjene n-torke.\n\n" );
printf( "(Partikularno) rjesenje (C_0): \n\n" );
printf ( "( " );
for ( i = 0; i < s.nep-1; ++i )
printf ( "%10.5f", r.part[i] );
printf ( " )\n\n" );
if ( r.dimO )
printf( "Prostor rjesenja: \n\n" );
for ( i = 0; i < r.dimO; ++i )
{
printf ( "( " );
for ( j = 0; j < s.nep-1; ++j )
printf ( "%10.5f", r.omega[i][j] );
printf ( " )\n" );
}
}
printf ( "\n\nDobivena matrica: \n\n" );
for ( i = 0; i < n; ++i )
{
for ( j = 0; j < m; ++j )
printf ( "%10.5f", matrica[i][j] );
printf ( "\n" );
}
/*oslobadjanje memorije*/
for ( i = 0; i < n; ++i )
free( matrica[i] );
free ( matrica );
for ( i = 0; i < r.dimO; ++i )
free ( r.omega[i] );
free ( r.omega );
free ( r.part );
system ( "PAUSE" );
return 0;
}
|
Pozdrav
Added after 11 minutes:
Primjetio sam da lagano šteka.. valjda cu to ispravit sto prije...
Added after 21 minutes:
funkcija zamjeni retke ne radi kako treba... ah...
_________________ reductio ad absurdum
|
|
[Vrh] |
|
Luuka Forumaš(ica)
Pridružen/a: 13. 02. 2007. (20:34:54) Postovi: (925)16
Spol:
Lokacija: Hakuna Matata
|
|
[Vrh] |
|
Gino Forumaš(ica)
Pridružen/a: 11. 09. 2008. (10:54:06) Postovi: (370)16
Lokacija: Pula
|
Postano: 17:29 ned, 7. 6. 2009 Naslov: |
|
|
kad smo vec kod linearne
bio sam radio prog za racunat determinantu (matrica nad realnim poljem)
dobio sam dojam da program daje rjesenje tocno do na predznak
[code:1]#include <stdio.h>
#include <stdlib.h>
typedef double tipPodatka;
void ucitajMatricu(tipPodatka **matrica, int brojRedaka, int brojStupaca){
int i,j;
for(i=0;i<brojRedaka;i++)
for(j=0;j<brojStupaca;j++)
scanf(" %lg",&matrica[i][j]); // typedef !!!
}
void ispisiMatricu(tipPodatka **matrica, int brojRedaka, int brojStupaca){
int i,j;
printf("\n\n");
for(i=0;i<brojRedaka;i++){
for(j=0;j<brojStupaca;j++)
printf("%10.2g",matrica[i][j]); //typedef !!!
printf("\n\n");
}
}
void zamjenaRedaka(tipPodatka **matrica, int prviRed, int drugiRed, int kolikoStupaca){
int i;
tipPodatka tmp;
for(i=0;i<kolikoStupaca;i++){
tmp=matrica[prviRed][i];
matrica[prviRed][i]=matrica[drugiRed][i];
matrica[drugiRed][i]=tmp;
}
}
void ponistavanje(double **matrica, int prviRed, int drugiRed, double koeficijent, int brojStupaca){
// prvi red pomnozen sa koeficijentom dodajemo drugom redu
int i;
for(i=0;i<brojStupaca;i++)
matrica[drugiRed][i]+=matrica[prviRed][i]*koeficijent;
}
int pozicija(double **matrica, int stupac, int brojRedaka){
// u kojem retku se nalazi ne nul element
int i;
for(i=stupac;i<brojRedaka;i++)
if(matrica[i][stupac]!=0) return i;
return -1;
}
double gauss(double **matrica, int redMatrice){
int i,j,kolikoZamjena=1,di;
for(i=0;i<redMatrice-1;i++){
di=pozicija(matrica,i,redMatrice);
if(di==-1) return 0;
if(di!=i){
zamjenaRedaka(matrica,i,di,redMatrice);
kolikoZamjena*=-1;
}
for(j=i+1;j<redMatrice;j++)
ponistavanje(matrica,i,j,-matrica[j][i]/matrica[i][i],redMatrice);
}
double determinanta=1;
for(i=0;i<redMatrice;i++) determinanta*=matrica[i][i];
determinanta*=kolikoZamjena;
return determinanta;
}
int main(){
int n,i;
double **matrica,determinanta;
scanf("%d",&n);
matrica=(tipPodatka**) malloc (n*sizeof(tipPodatka*));
if(matrica==NULL) exit(1);
for(i=0;i<n;i++){
matrica[i]=(tipPodatka*) malloc (n*sizeof(tipPodatka));
if(matrica[i]==NULL) exit(1);
}
ucitajMatricu(matrica,n,n);
determinanta=gauss(matrica,n);
ispisiMatricu(matrica,n,n);
for(i=0;i<n;i++) free(matrica[i]);
free(matrica);
printf("%g\n",determinanta);
//system("pause");
}
[/code:1]
npr za matricu
1 0 0 0 2
0 1 3 2 1
4 2 3 1 5
1 0 0 0 1
2 0 1 0 1
vrati 3, a trebalo bi -3
pa ako netko zna u cemu je problem
kad smo vec kod linearne
bio sam radio prog za racunat determinantu (matrica nad realnim poljem)
dobio sam dojam da program daje rjesenje tocno do na predznak
Kod: | #include <stdio.h>
#include <stdlib.h>
typedef double tipPodatka;
void ucitajMatricu(tipPodatka **matrica, int brojRedaka, int brojStupaca){
int i,j;
for(i=0;i<brojRedaka;i++)
for(j=0;j<brojStupaca;j++)
scanf(" %lg",&matrica[i][j]); // typedef !!!
}
void ispisiMatricu(tipPodatka **matrica, int brojRedaka, int brojStupaca){
int i,j;
printf("\n\n");
for(i=0;i<brojRedaka;i++){
for(j=0;j<brojStupaca;j++)
printf("%10.2g",matrica[i][j]); //typedef !!!
printf("\n\n");
}
}
void zamjenaRedaka(tipPodatka **matrica, int prviRed, int drugiRed, int kolikoStupaca){
int i;
tipPodatka tmp;
for(i=0;i<kolikoStupaca;i++){
tmp=matrica[prviRed][i];
matrica[prviRed][i]=matrica[drugiRed][i];
matrica[drugiRed][i]=tmp;
}
}
void ponistavanje(double **matrica, int prviRed, int drugiRed, double koeficijent, int brojStupaca){
// prvi red pomnozen sa koeficijentom dodajemo drugom redu
int i;
for(i=0;i<brojStupaca;i++)
matrica[drugiRed][i]+=matrica[prviRed][i]*koeficijent;
}
int pozicija(double **matrica, int stupac, int brojRedaka){
// u kojem retku se nalazi ne nul element
int i;
for(i=stupac;i<brojRedaka;i++)
if(matrica[i][stupac]!=0) return i;
return -1;
}
double gauss(double **matrica, int redMatrice){
int i,j,kolikoZamjena=1,di;
for(i=0;i<redMatrice-1;i++){
di=pozicija(matrica,i,redMatrice);
if(di==-1) return 0;
if(di!=i){
zamjenaRedaka(matrica,i,di,redMatrice);
kolikoZamjena*=-1;
}
for(j=i+1;j<redMatrice;j++)
ponistavanje(matrica,i,j,-matrica[j][i]/matrica[i][i],redMatrice);
}
double determinanta=1;
for(i=0;i<redMatrice;i++) determinanta*=matrica[i][i];
determinanta*=kolikoZamjena;
return determinanta;
}
int main(){
int n,i;
double **matrica,determinanta;
scanf("%d",&n);
matrica=(tipPodatka**) malloc (n*sizeof(tipPodatka*));
if(matrica==NULL) exit(1);
for(i=0;i<n;i++){
matrica[i]=(tipPodatka*) malloc (n*sizeof(tipPodatka));
if(matrica[i]==NULL) exit(1);
}
ucitajMatricu(matrica,n,n);
determinanta=gauss(matrica,n);
ispisiMatricu(matrica,n,n);
for(i=0;i<n;i++) free(matrica[i]);
free(matrica);
printf("%g\n",determinanta);
//system("pause");
}
|
npr za matricu
1 0 0 0 2
0 1 3 2 1
4 2 3 1 5
1 0 0 0 1
2 0 1 0 1
vrati 3, a trebalo bi -3
pa ako netko zna u cemu je problem
_________________ Mario Berljafa
|
|
[Vrh] |
|
Cobs Forumaš(ica)
Pridružen/a: 21. 01. 2008. (13:32:15) Postovi: (206)16
Spol:
Lokacija: Geto
|
Postano: 19:34 ned, 7. 6. 2009 Naslov: |
|
|
[quote="Gino"]
double gauss(double **matrica, int redMatrice){
...
for(i=0;i<redMatrice-1;i++){
di=pozicija(matrica,i,redMatrice);
if(di==-1) return 0;
if(di!=i){
zamjenaRedaka(matrica,i,di,redMatrice);
kolikoZamjena*=-1;
}
...
return determinanta;
}
[/quote]
ne znam tocno u cem je problem, al ti ovaj dio ( kolkoZamjena ) 5 puta mjenja predznak ( na kraju je -1 ) pa u umnošku s determinantom ispisane matrice 3 je dobar rezultat... a s obzirom da nisam provjeravo algoritam ni iso rucno rjesavat matricu... jel treba 5 puta determinanta mjenjat predznak ( zamjena redova ) ili ne ? ili si mozda zaboravio da se s tim jos mnozi? tu negdje bi trebo biti problem...
Gino (napisa): |
double gauss(double **matrica, int redMatrice){
...
for(i=0;i<redMatrice-1;i++){
di=pozicija(matrica,i,redMatrice);
if(di==-1) return 0;
if(di!=i){
zamjenaRedaka(matrica,i,di,redMatrice);
kolikoZamjena*=-1;
}
...
return determinanta;
}
|
ne znam tocno u cem je problem, al ti ovaj dio ( kolkoZamjena ) 5 puta mjenja predznak ( na kraju je -1 ) pa u umnošku s determinantom ispisane matrice 3 je dobar rezultat... a s obzirom da nisam provjeravo algoritam ni iso rucno rjesavat matricu... jel treba 5 puta determinanta mjenjat predznak ( zamjena redova ) ili ne ? ili si mozda zaboravio da se s tim jos mnozi? tu negdje bi trebo biti problem...
|
|
[Vrh] |
|
Gino Forumaš(ica)
Pridružen/a: 11. 09. 2008. (10:54:06) Postovi: (370)16
Lokacija: Pula
|
|
[Vrh] |
|
matmih Forumaš(ica)
Pridružen/a: 07. 12. 2006. (22:57:42) Postovi: (1A4)16
Spol:
Lokacija: {Zg, De , Ri}
|
|
[Vrh] |
|
Gino Forumaš(ica)
Pridružen/a: 11. 09. 2008. (10:54:06) Postovi: (370)16
Lokacija: Pula
|
|
[Vrh] |
|
|