Skocz do zawartości
soulburner

[c++] Metoda Eliminacji Gauss'a I... Problem

Rekomendowane odpowiedzi

Witam!

 

Muszę opanować rozwiązywanie układów równań metodą eliminacji Gauss'a. Posiadam wzór algorytmu z pewnej książki "Metody numeryczne" - niestety, więcej nic o niej nie wiem, bo mam tylko ksero kilku stron ;)

 

Idąc krok po kroku i spoglądając w program znajomego (który zapewne został żywcem ściągnięty z netu ;) prawdopodobnie stąd), udało sprowadzić się macierz do postaci trójkątnej.

 

Problem zaczyna się jednak podczas próby obliczenia rozwiązania, czyli "iksów".

 

Najpierw może pokażę co siedzi w książce:

Dołączona grafika

 

A teraz czas na kod, który na tej podstawie wymęczyłem (siedzi w nim pełno głupawych cout'ów, które pomocne są przy sprawdzeniu, w której pętli się program wywalił):

 

#include <iostream>#include <iomanip>#include <fstream>#include <cmath>using namespace std;int main(int argc, char *argv[]){  ifstream fin;  ofstream fout;    double tabA[100][101]; //macierz  double x[100]; //rozwiazania (iksy)  int n=0;	//ilosc rownan  int i=0;  int p=0;  int j=0;      fin.open("in.txt");  fin >> n;	for(i = 0; i < n; i++)	  for(j = 0; j <= n; j++)		fin >> tabA[i][j];  fin.close();    cout <<"Odczytano plik z danymi\n\n";    cout << "Wczytana macierz:" << endl;  for(int i=0;i<n;i++)  {	for(int j=0;j<n;j++)	{	  cout << tabA[i][j] << "\t";	}	cout << " = " << tabA[i][n] <<"\t";	cout << endl;  }      cout <<"\nTest: macierz w punkcie a11 ma wartosc "<< tabA[0][0]<<endl;//-----------------------------------------------------------------------  //sprowadzenie do postaci trojkatnej  cout <<"\nSprowadzanie macierzy do postaci trojkatnej:\n ";  for (p=0; p<=n-1; p++)  {	cout << "1...";	for (i=p+1; i<=n-1; i++)	{	  cout << "2...";  	  for (j=p+1; j<=n; j++)	  {		cout << "3...";				tabA[i][j] = tabA[i][j] - (tabA[i][p] / tabA[p][p]) * tabA[p][j];	  }	tabA[i][p]=0;	}  }    //x[n]=  //----------------------------------------------------------------------    cout << "\nMacierz po przeksztalceniu:" << endl;  for(int i=0;i<n;i++)  {	for(int j=0;j<n;j++)	{	  cout << tabA[i][j] << "  ";	}	cout << " = " << tabA[i][n] <<"  ";	cout << endl;  }      //------------------------------------------------------------------  cout <<"\nRozwiazywanie ukladu trojkatnego: \n ";  /*rozwiazywanie ukladu trojkatnego - to tutaj dzieje się... no własnie, chyba niewiele, skoro 'iksy' wychodza zerowe :/ */  for (i=n-1; i>=0; i--)  {	cout << "1...";	double w=0;	for (p=i+1; p<=1; p++)	{	  cout << "2...";	  w = w + tabA[i][p]*x[p];	}	cout << "1e...";	x[i] = (tabA[i][n+1] - w) / tabA[i][i];  }  //------------------------------------------------------------------       //wyswietlenie rozwiazania    cout <<"\nROZWIAZANIE:\n";  for (i=0; i<=n-1; i++)  {	cout << "x["<<i+1<<"] = "<< x[i] << endl;  }    system("pause >nul");  return EXIT_SUCCESS;}

Bardzo proszę o wykazanie błędu i sugestie poprawienia. Gotowe fragmenty kodu też mile widziane, ale z komentarzem :P

Edytowane przez soulburner

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Ok, sam sobie odpisuję, nie znaczy to jednak, że wszystko już gra ;)

 

Rzecz pierwsza - pominąłem w algorytmie częśc x[n]=..., po pierwszych pętlach.

Rzecz druga - niewiele to jednak dało, bo ostatnia pętla rozwiązująca iksy działa i tak sama ;)

 

Dodam może zawartość pliku źródłowego, skąd pobierane są dane (in.txt):

34 2 -1 72 2 1 91 -1 1 4

Jest jednak pewien problem - otóż liczby w wynikach są zaokrąglane do całości, podczas gdy rozwiązując zadanie na piechotę, otrzymujemy wyniki typu x3 = 2.8, podczas gdy program zaokrągla to do 3.

 

Co popełniłem tu źle?

 

Pomóżcie, towarzysze, zaliczenie jutro mam po 11:00 :P

 

#include <iostream>#include <iomanip>#include <fstream>#include <cmath>using namespace std;int main(int argc, char *argv[]){  ifstream fin;  ofstream fout;    double tabA[100][101]; //macierz  double x[100]; //rozwiazania (iksy)  int n=0;	//ilosc rownan  int i=0;  int p=0;  int j=0;      fin.open("in.txt");  fin >> n;	for(i = 0; i < n; i++)	  for(j = 0; j <= n; j++)		fin >> tabA[i][j];  fin.close();    cout <<"Odczytano plik z danymi\n\n";    cout << "Wczytana macierz:" << endl;  for(int i=0;i<n;i++)  {	for(int j=0;j<n;j++)	{	  cout << tabA[i][j] << "\t";	}	cout << " = " << tabA[i][n] <<"\t";	cout << endl;  }      cout <<"\nTest: macierz w punkcie a11 ma wartosc "<< tabA[0][0]<<endl;//------------------------------------------------------------------------------    //sprowadzenie do postaci trojkatnej  cout <<"\nSprowadzanie macierzy do postaci trojkatnej:\n ";  for (p=0; p<=n-1; p++)  {	cout << "1...";	for (i=p+1; i<=n-1; i++)	{	  cout << "2...";  	  for (j=p+1; j<=n; j++)	  {		cout << "3...";				tabA[i][j] = tabA[i][j] - (tabA[i][p] / tabA[p][p]) * tabA[p][j];	  }	tabA[i][p]=0;	}  }  cout << "zakonczono\n";  x[n-1] = tabA[n-1][n] / tabA[n-1][n-1];  cout <<"//developer - po operacji x[n-1] wyszlo, ze ostatni x = "<<x[n-1]<<endl;//------------------------------------------------------------------------------    cout << "\nMacierz po przeksztalceniu:" << endl;  for(int i=0;i<n;i++)  {	for(int j=0;j<n;j++)	{	  cout << tabA[i][j] << "\t";	}	cout << " = " << tabA[i][n] <<"\t";	cout << endl;  }      //---------------------------------------------------------------------  cout <<"\nRozwiazywanie ukladu trojkatnego: \n ";  //rozwiazywanie ukladu trojkatnego  for (i=n-1; i>=0; i--)  {	cout << "1...";	double w=0;	for (p=i+1; p<n; p++)	//for (p=n-1; p>=i; p--)	{	  cout << "2...";	  w = w + tabA[i][p] * x[p];	  //cout <<"\n>>"<<x[p]<<endl;	}	cout << "1e...";	x[i] = (tabA[i][n] - w) / tabA[i][i];  }  //---------------------------------------------------------------------  cout<<"zakonczono";     //wyswietlenie rozwiazania    cout <<"\nROZWIAZANIE:\n";  for (i=0; i<n; i++)												 //i<=n-1  {	cout << "x["<<i+1<<"] = "<< x[i] << endl;  }    system("pause >nul");  return EXIT_SUCCESS;}
Edytowane przez soulburner

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

Ładowanie


×
×
  • Dodaj nową pozycję...