Eliminacja gaussa, błędne wyniki


(Snes38) #1

Witam, od razu powiem że jestem bardzo początkujący jeśli chodzi o pisanie kodu c++, trzeba mi było napisać kod służący do wykonywania eliminacji gaussa, napisałem coś takiego prostego:

#include <iostream>

using namespace std;

int main()
{
    int n,k,j,i,p,s;
    cout << "Wprowadz liczbe rownan:" << endl;
    cin >> n;
    float a[n][n],b[n],x[n];

    for(i=1;n>i-1;i++){
            for(j=1;n>j-1;j++){
        cout << "rownanie "<<i<<" x"<<j << endl;
        cin >> a[i][j];}
    }
        cout << "Wprowadz wyrazy wolne:" << endl;
    for(i=1;n>i-1;i++){

        cout << "rownanie "<<i<< endl;
        cin >> b[i];
    }


    for(k=1;(k<=n-1)&&(a[k-1][k-1]!=0);k++){
        for(i=k+1;i<=n;i++){
            p=a[i-1][k-1]/a[k-1][k-1];
            for(j=k;j<=n;j++){
                a[i-1][j-1]-=p*a[k-1][j-1];

            }
            b[i-1]-=p*b[k-1];
        }

    }

   if(a[n-1][n-1]!=0){
    for(i=n;i>=1;i--){
        s=0;
            for(j=i+1;j<=n;j++){
            s+=a[i-1][j-1]*x[j-1];
        }
        x[i-1]=(b[i-1]-s)/a[i-1][i-1];
    }
}


      for(i=1;i<=n;i++){
       cout << "x"<<i<<"="<<x[i] << endl;
        }

    return 0;
}

Program coś tam oblicza lecz robi to źle, gdyż na końcu wychodzą jakieś nieskończoności i inne głupoty, czy ktoś byłby tak miły i doszukał się w tym kodzie co zrobiłem źle?


(Ryan) #2

Jakie kroki podjąłeś póki co, w celu zidentyfikowania i naprawienia problemu? Brak doświadczenia nie tłumaczy braku zapału, więc zakładam, że zapał jest i coś mimo wszystko próbowałeś zrobić.

Swoją drogą: ciekawe, że to drugi w tym tygodniu program do eliminacji Gaussa. ;>


(tomms) #3
int n,k,j,i,p,s;
    cout << "Wprowadz liczbe rownan:" << endl;
    cin >> n;
    float a[n][n],b[n],x[n];

W ten sposób nie tworzy się tablic dynamicznych w języku C++, to jest rozszerzenie kompilatora GCC.

Aby zadeklarować taką tablice to ‘n’ to musiałaby być stała czasu kompilacji (runtime constant) a to jest zmienna.

Jeśli dopiero uczysz się C++ to zastosuj std::vector<float> lub wskaźnik z alokacją pamięci poprzez ‘new’.

 

for(i=1;n>i-1;i++){
            for(j=1;n>j-1;j++){
        cout << "rownanie "<<i<<" x"<<j << endl;
        cin >> a[i][j];}
    }

Wychodzisz poza tablicę dodatkowo opuszczając pierwszy element, tablice w C++ indeksujemy od zera do ‘n-1’, czyli:

 

for(i=0; i < n ; i++){
            for(j=0 ; j < n ; j++){
    ...
    }

Podobny błąd masz w następnych pętlach.


(Ryan) #4

C99 definiuje VLA, więc nie jest to rozszerzenie GCC. Jest to natomiast brakujący w MSVC ficzer C99. :slight_smile:


(Snes38) #5

Porównywałem mój kod który odpowiadał za tą eliminację z działającym kodem, a okazało się że to przy wczytywaniu i wyświetlaniu danych był problem, natomiast nie widziałem na forum tematu ostatnio z eliminacją, gdybym znalazł to nie pisałbym swojego tematu, chyba że jakimś cudem przeoczyłem.

 

Dziękuję tomms za odpowiedź i wytłumaczenie co jest nie tak, poprawiłem te pętle i działa w porządku, jeszcze raz bardzo dziękuję :slight_smile: