algorytm.org

Implementacja w C/C++

Baza Wiedzy
wersja offline serwisu przeznaczona na urządzenia z systemem Android
Darowizny
darowiznaWspomóż rozwój serwisu
Nagłówki RSS
Artykuły
Implementacje
Komentarze
Forum
Bookmarki






Sonda
Implementacji w jakim języku programowania poszukujesz?

Metoda Gaussa - Seidela - Implementacja w C/C++
Ocena użytkownikóww: *****  / 10
SłabyŚwietny
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;
}
Komentarze
photo
-21 # Kaśka 2012-03-28 20:57
Jeśli c++, to cmath, a nie math.h -.-
Odpowiedz | Odpowiedz z cytatem | Cytować
photo
+3 # Gawron 2015-04-19 18:06
naprawde uwazasz, ze to najwiekszy problem w tym kodzie?
Odpowiedz | Odpowiedz z cytatem | Cytować
Dodaj komentarz