Nadesłany przez Marian, 14 marca 2011 13:58
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
gs_1_c.cpp:
// Metoda Gaussa-Seidela // www.algorytm.org #include <iostream> using namespace std; #include <math.h> #define eps 0.000001 #define iteracje 200 int main() { int n, i, j, k, stop; float dzielnik; float norma1, norma2; float **A, **U, **L, **D, **I, *B, *B2, *x, *x2; bool koniec; // rozmiar macierzy cout << "Podaj rozmiar macierzy: "; cin >> n; // macierz glowna A = new float * [n]; // macierz dolnotrojkatna L = new float * [n]; // macierz gornotrojkatna U = new float * [n]; // przekatna D = new float * [n]; // macierz jednostkowa I = new float * [n]; // tworzenie tablicy tablic - macierzy kwadratowych for (i = 0; i < n; i++) { A[i] = new float[n]; L[i] = new float[n]; U[i] = new float[n]; D[i] = new float[n]; I[i] = new float[n]; } // stworzenie wektora wyrazow wonych i wektora wyników B = new float [n]; B2 = new float [n]; x = new float [n]; x2 = new float [n]; // wczytanie elementow rownan i wyzerowanie pozostalych macierzy for (i = 0; i < n; i++) for (j = 0; j < n; j++) { cout << "Podaj element macierzy[" << i << "][" << j << "]: "; cin >> A[i][j]; L[i][j] = 0; U[i][j] = 0; D[i][j] = 0; I[i][j] = 0; } for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { // utworzenie macierzy dolnotrojkatnej if (i > j) L[i][j] = A[i][j]; // utworzenie macierzy gornotrojkatnej else if (i < j) U[i][j] = A[i][j]; else { // wczytanie wyrazow wolnych cout << "Podaj " << i << " wyraz wolny: "; cin >> B[i]; // utworzenie macierzy z przekatnej macierzy glownej D[i][i] = A[i][i]; // jedynki na przekatnej I[i][i] = 1; } } } // wyznaczenie p = min{||-(L+D)^-1 * N||:||-(L+D)^-1 * N||} // obliczenie D + L (wynik w L) for (i = 0; i < n; i++) L[i][i] = D[i][i]; // obliczenie (D + L)^-1 (wynik w I) for (i = 0; i < n; i++) { dzielnik = L[i][i]; for (j = 0; j < n; j++) { L[i][j] /= dzielnik; I[i][j] /= dzielnik; } for (k = 0; k < n; k++) { if (k == i) continue; dzielnik = L[k][i]; for (j = 0; j < n; j++) { L[k][j] -= (L[i][j]*dzielnik); I[k][j] -= (I[i][j]*dzielnik); } } } // obliczenie (L + D)^-1 * N (wynik w L) for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { L[i][j] = 0; for (k = 0; k < n; k++) L[i][j] += (I[i][k]*U[k][j]); } } // obliczenie -(L+D)^-1 * N for (i = 0; i < n; i++) for (j = 0; j < n; j++) L[i][j] *= (-1); // norma "jeden" norma1 = 0; for (i = 0; i < n; i++) { dzielnik = 0; for (j = 0; j < n; j++) dzielnik += fabs(L[j][i]); if (dzielnik > norma1) norma1 = dzielnik; } // norma "nieskonczonosc" norma2 = 0; for (i = 0; i < n; i++) { dzielnik = 0; for (j = 0; j < n; j++) dzielnik += fabs(L[i][j]); if (dzielnik > norma2) norma2 = dzielnik; } // p = min(norma1, norma2) if (norma1 > norma2) norma1 = norma2; // ciag nie jest zbiezny do rozwiazania ukladu rownan if (norma1 >= 1) norma1 = 0.5; // inicjalizacja wektora wynikow for (i = 0; i < n; i++) x[i] = 0; koniec = true; stop = iteracje; do { // przepisanie x - aktualnych wynikow do x2 - wynikow z poprzedniej iteracji for (i = 0; i < n; i++) x2[i] = x[i]; // wykonanie kolejnej iteracji for (i = 0; i < n; i++) { B2[i] = B[i]; for (int j = 0; j < i; j++) B2[i] -= (A[i][j]*x[j]); for (int j = i + 1; j < n; j++) B2[i] -= A[i][j] * x2[j]; x[i] = B2[i]/A[i][i]; } // sprawdzenie warunku zakonczenia: ||x(k)-x(k-1)|| <= epsilon for (i = 0; i < n; i++) { if (fabs(x[i] - x2[i]) > eps) { koniec = true; break; } else koniec = false; } stop--; } while (koniec && stop > 0); // wyswietlenie wyniku cout << "WYNIK:\n"; for (i = 0; i < n; i++) cout << x[i] << " "; cout << endl; return 0; }