Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <assert.h>
- #include <math.h>
- #include <map>
- #include <time.h>
- using namespace std;
- #define d 0.85
- #define MAX_ITER 1000
- #define EPSILON 0.0000001
- #define ZERO 1e-12 // stała przybliżenia zera
- void setXY(map<int, map<int, double>> &macierz_sasiedztwa, int x, int y, double val)
- {
- if (fabs(val) >= ZERO)
- macierz_sasiedztwa[x][y]= val;
- }
- double getXY(map<int, map<int, double>> &macierz_sasiedztwa, int x, int y)
- {
- if ((macierz_sasiedztwa.find(x) != macierz_sasiedztwa.end())
- && (macierz_sasiedztwa[x].find(y) != macierz_sasiedztwa[x].end()) )
- {
- return macierz_sasiedztwa[x][y];
- }
- else
- return 0;
- }
- double getXYRazyMacierzDiag(vector <double> &ilosc, map<int, map<int, double>> &macierz_sasiedztwa, int x, int y)
- {
- if (y>=ilosc.size())
- return getXY(macierz_sasiedztwa, x, y);
- double ret = 0;
- if ((macierz_sasiedztwa.find(x) != macierz_sasiedztwa.end())
- && (macierz_sasiedztwa[x].find(y) != macierz_sasiedztwa[x].end()) )
- {
- // jezeli jest polaczenie
- ret = ret - macierz_sasiedztwa[x][y];
- ret = ret * (double)d/(double)ilosc[y];
- ret = ret + (x==y ? 1.0 : 0.0);
- // return -(double)macierz_sasiedztwa[x][y] * (double)d/(double)ilosc[y] + x==y;
- }
- else
- {
- if (!(ilosc[x] > 0))
- {
- //return double(0.0-(1.0 * d/(double)ilosc.size()) + x==y);
- ret = ret - (1.0 * d/(double)ilosc.size());
- ret = ret + (double)x==y;
- }
- else
- //return double(0.0 + x==y);
- ret = (double)x==y;
- }
- return ret;
- }
- void setXYRazyMacierzDiag(vector <double> &ilosc, map<int, map<int, double>> &macierz_sasiedztwa, int x, int y, double val)
- {
- if (fabs(val) < ZERO)
- return;
- if (y>=ilosc.size())
- {
- setXY(macierz_sasiedztwa, x, y, val);
- return;
- }
- double set;
- // jezeli jest polaczenie
- //ret = ret - macierz_sasiedztwa[x][y];
- //ret = ret * (double)d/(double)ilosc[y];
- //ret = ret + (x==y ? 1.0 : 0.0);
- set = val;
- set = set - (x==y ? 1.0 : 0.0);
- set = set / ((double)d/(double)ilosc[y]);
- macierz_sasiedztwa[x][y] = -set;
- }
- // sprawdzanie
- bool sprawdz_zbieznosc(vector <vector<double>> in)
- {
- assert( in.size() == in[0].size());
- // ||C|| W
- double max = 0;
- for(int i=0; i<in.size(); i++)
- {
- double sum = 0;
- for(int j=0; j<in.size(); j++)
- {
- sum += abs( in[i][j] );
- }
- if (sum > max)
- max = sum;
- }
- if (max < 1)
- return true;
- // ||C|| K
- max = 0;
- for(int i=0; i<in.size(); i++)
- {
- double sum = 0;
- for(int j=0; j<in.size(); j++)
- {
- sum += abs( in[j][i] );
- }
- if (sum > max)
- max = sum;
- }
- if (max < 1)
- return true;
- // ||C|| F
- double sum_sum = 0;
- for(int i=0; i<in.size(); i++)
- {
- double sum = 0;
- for(int j=0; j<in.size(); j++)
- {
- sum += abs( in[j][i]*in[j][i] );
- }
- sum_sum + sum;
- }
- if (sqrt(sum_sum) < 1)
- return true;
- return false;
- }
- void odwroc_macierz(vector<vector<double>> &a)
- {
- int i,j,k,n=a.size();
- double d_tmp;
- // rozszerzenie o macierz diagonalna
- for(i=0;i<n;i++)
- {
- for(j=0;j<n;j++)
- {
- if(j==i)
- a[i].push_back( 1 );
- else
- a[i].push_back( 0 );
- }
- }
- /************** partial pivoting **************/
- for(i=n-1;i>0;i--)
- {
- if(a[i-1][0]<a[i][0])
- {
- for(j=0;j<n*2;j++)
- {
- d_tmp=a[i][j];
- a[i][j]=a[i-1][j];
- a[i-1][j]=d_tmp;
- }
- }
- }
- /********** reducing to diagonal matrix ***********/
- for(i=0;i<n;i++)
- {
- for(j=0;j<n;j++)
- if(j!=i)
- {
- d_tmp=a[j][i]/a[i][i];
- for(k=0;k<n*2;k++)
- a[j][k]-=a[i][k]*d_tmp;
- }
- }
- /************** reducing to unit matrix *************/
- for(i=0;i<n;i++)
- {
- d_tmp=a[i][i];
- for(j=0;j<n*2;j++)
- a[i][j]=a[i][j]/d_tmp;
- }
- for(i=0;i<n;i++)
- {
- for(j=0;j<n;j++)
- a[i].erase( a[i].begin() );
- }
- }
- void odejmij_macierz(vector<vector<double>> &A, vector<vector<double>> &B)
- {
- assert(A.size() == B.size());
- assert(A[0].size() == B[0].size());
- for(int i=0; i<A.size(); i++)
- {
- for(int j=0; j<A[0].size(); j++)
- {
- A[i][j] -= B[i][j];
- }
- }
- }
- void pomnoz_macierz(vector<vector<double>> &A, vector<vector<double>> &B)
- {
- for(int i = 0; i < A.size(); i++)
- {
- for(int j = 0; j < B[0].size(); j++)
- {
- double s = 0;
- for(int k = 0; k < A[0].size(); k++)
- s += A[i][k] * B[k][j];
- A[i][j] = s;
- }
- }
- }
- int Gauss_Seidel(map<int, map<int, double>> &A, vector<double> &B, vector<double> &X, vector <double> &ilosc)
- {
- // macierz kwadratowa musi byc
- //assert(A.size() == A[0].size());
- //assert(A.size() == B.size());
- // Calculate D^-1
- for (map<int, map<int, double>>::iterator it=A.begin(); it!=A.end(); ++it)
- {
- for(map<int, double>::iterator it2=it->second.begin(); it2!=it->second.end(); ++it2)
- {
- if (it->first == it2->first)
- setXYRazyMacierzDiag(ilosc, A, it->first, it2->first, 1.0 / getXYRazyMacierzDiag(ilosc, A, it->first, it2->first));
- }
- }
- // Calculate D^-1 * b
- for (map<int, map<int, double>>::iterator it=A.begin(); it!=A.end(); ++it)
- {
- int i = it->first;
- B[i] *= getXYRazyMacierzDiag(ilosc, A, i, i);
- }
- //Calculate D^-1 * L
- //Calculate D^-1 * U
- for (map<int, map<int, double>>::iterator it=A.begin(); it!=A.end(); ++it)
- {
- for(map<int, double>::iterator it2=it->second.begin(); it2!=it->second.end(); ++it2)
- {
- int i = it->first;
- int j = it2->first;
- if (j == i)
- continue;
- //A[i][j] *= A[i][i];
- setXYRazyMacierzDiag(ilosc, A, i, j, getXYRazyMacierzDiag(ilosc, A, i, j) * getXYRazyMacierzDiag(ilosc, A, i, i) );
- }
- }
- // iteracje
- int k;
- for (k=0; k<MAX_ITER; k++)
- {
- double maxXiDiff = 0, maxXi = 0;
- double X2;
- //for (int i=0; i<A.size(); i++)
- for (map<int, map<int, double>>::iterator it=A.begin(); it!=A.end(); ++it)
- {
- int i = it->first;
- X2 = B[i];
- // x = D^-1*b -
- for(map<int, double>::iterator it2=it->second.begin(); it2!=it->second.end(); ++it2)
- {
- int j = it2->first;
- if (j == i)
- continue;
- //X2 -= A[i][j]*X[j]; // - D^-1*L * x
- X2 -= getXYRazyMacierzDiag(ilosc, A, i, j)*X[j]; // - D^-1*L * x
- }
- if ( abs( X2 - X[i] ) > maxXiDiff)
- maxXiDiff=abs( X2 - X[i] );
- if ( abs( X2 ) > maxXi )
- maxXi = abs( X2 );
- X[i] = X2;
- }
- double eps = maxXiDiff / maxXi;
- if ( !( EPSILON < eps) )
- break;
- }
- return k;
- }
- int CarlGustavJakobJacobi(vector<vector<double>> &A, vector<double> &B, vector<double> &X)
- {
- // macierz kwadratowa musi byc
- assert(A.size() == A[0].size());
- assert(A.size() == B.size());
- // wyznaczenie macierzy N = D^-1
- vector<double> N;
- for (int i=0; i<A.size(); i++)
- {
- N.push_back( 1.0/A[i][i] );
- }
- // kryt zbieznosci wedlug wykladu
- // wyznaczenie macierzy M = -N (L + U)
- vector<vector<double>> M;
- for (int i=0; i<A.size(); i++)
- {
- M.push_back( vector<double>() );
- for (int j=0; j<A.size(); j++)
- {
- if (i == j)
- {
- M[i].push_back( 0 );
- }
- else
- {
- M[i].push_back ( -(A[i][j] * N[i]) );
- }
- }
- }
- assert( sprawdz_zbieznosc(M) );
- vector<double> X2 = X;
- int k; // ilosc iteracji
- for (k=0; k<MAX_ITER; k++)
- {
- double maxXiDiff = 0, maxXi = 0;
- for (int i=0; i<A.size(); i++)
- {
- X2[i] = N[i]*B[i];
- for (int j=0; j<A.size(); j++)
- {
- X2[i] += M[i][j]*X[j];
- }
- if ( abs( X2[i] - X[i] ) > maxXiDiff)
- maxXiDiff = abs( X2[i] - X[i] );
- if ( abs( X2[i] ) > maxXi )
- maxXi = abs( X2[i] );
- }
- X = X2;
- double eps = maxXiDiff / maxXi;
- if ( !( EPSILON < eps) )
- break;
- }
- return k;
- }
- void generuj_wektor_poczatkowy( vector<double> &X, int size)
- {
- for (int i=0; i<size; i++)
- {
- X.push_back( 0.0 );
- }
- }
- void PR_dodaj_kolumne(int n, vector<double> &B)
- {
- for(int i=0; i<n; i++)
- {
- B.push_back( (1.0-d) / double(n) );
- }
- }
- void PR_pomnoz_razy_macierz_diagonalna_i_dodaj_krawedzie_do_wszystkich_pustych
- (vector<double> &ilosc, map<int, map<int, double>> &sasiedztwo)
- {
- for(int i=0; i<ilosc.size(); i++)
- {
- // dodanie krawedzi do wszystkich
- if (!(ilosc[i] > 0))
- {
- ilosc[i] = ilosc.size()-1;
- for (int j=0; j<ilosc.size(); j++)
- {
- if (i==j)
- continue;
- sasiedztwo[j][i] = 1;
- }
- }
- //for(int j=0; j<sasiedztwo[i].size(); j++)
- for(map<int, map<int, double>>::iterator it=sasiedztwo.begin(); it!=sasiedztwo.end(); ++it)
- {
- if (it->second.find(i) != it->second.end() )
- it->second[i] *= d/ilosc[i];
- }
- }
- }
- void PR_I_odj_macierz(map<int, map<int, double>> &sasiedztwo, int n)
- {
- for (map<int, map<int, double>>::iterator it=sasiedztwo.begin(); it!=sasiedztwo.end(); ++it)
- {
- for(map<int, double>::iterator it2=it->second.begin(); it2!=it->second.end(); ++it2)
- {
- double val = 0 - getXY(sasiedztwo, it->first, it2->first);
- val += it->first==it2->first;
- setXY(sasiedztwo, it->first, it2->first, val);
- }
- }
- for(int i=0; i<n; i++)
- {
- if (getXY(sasiedztwo, i, i) == 0)
- setXY(sasiedztwo, i, i, 1);
- }
- }
- bool PR_wczytaj(map<int, int> &backNodes, vector <double> &ilosc, map<int, map<int, double> > &macierz_sasiedztwa)
- {
- int currId = 0;
- int src, dst;
- int count = 0;
- map<int, int> Nodes;
- while (!cin.eof())
- {
- cin >> src >> dst;
- if (cin.eof() || src == -1)
- break;
- // mapy id
- if (Nodes.find(src) == Nodes.end())
- {
- Nodes[src] = currId;
- backNodes[currId] = src;
- currId++;
- }
- if (Nodes.find(dst) == Nodes.end())
- {
- Nodes[dst] = currId;
- backNodes[currId] = dst;
- currId++;
- }
- /* powiekszanie wektorow*/
- if (Nodes[src] > count)
- count = Nodes[src];
- if (Nodes[dst] > count)
- count = Nodes[dst];
- while(ilosc.size() <= count)
- ilosc.push_back( 0 );
- // ustawienie macierzy
- ilosc[Nodes[src]]++;
- macierz_sasiedztwa[Nodes[dst]][Nodes[src]] = 1;
- }
- return true;
- }
- #define PAGE_RANK
- int main()
- {
- map<int, map<int, double> > A;
- vector<double> B;
- vector<double> X;
- #ifndef PAGE_RANK
- int n;
- cin >> n;
- // wczytywanie macierzy
- for(int i=0; i<n; i++)
- {
- double tmp;
- for(int j=0; j<n; j++)
- {
- cin >> tmp;
- A[i][j] = tmp;
- }
- cin >> tmp;
- B.push_back(tmp);
- }
- generuj_wektor_poczatkowy(X, n);
- #endif
- #ifdef PAGE_RANK
- vector<double> ilosc;
- map<int, int> Nodes;
- PR_wczytaj(Nodes, ilosc, A);
- /*PR_pomnoz_razy_macierz_diagonalna_i_dodaj_krawedzie_do_wszystkich_pustych(ilosc, A);
- PR_I_odj_macierz(A, ilosc.size() );*/
- PR_dodaj_kolumne(ilosc.size(), B);
- generuj_wektor_poczatkowy(X, ilosc.size() );
- #endif
- time_t now; time(&now);
- int iter = Gauss_Seidel(A, B, X, ilosc);
- time_t seconds = time(NULL) - now;
- cout << "Gauss_Seidel: liczba iteracji: " << iter << endl;
- cout << "Czas [s]: " << seconds << endl;
- double sum = 0;
- for(int i=0; i<X.size(); i++)
- {
- //#ifndef PAGE_RANK
- cout << "x" << i << "= " << X[i] << endl;
- //#endif
- sum += X[i];
- }
- cout << "Suma: " << sum << endl;
- X.clear();
- generuj_wektor_poczatkowy(X, ilosc.size() );
- time(&now);
- /*iter = CarlGustavJakobJacobi(A, B, X);*/
- seconds = time(NULL) - now;
- cout << "CarlGustavJakobJacobi: liczba iteracji: " << iter << endl;
- cout << "Czas [s]: " << seconds << endl;
- sum = 0;
- for(int i=0; i<X.size(); i++)
- {
- #ifndef PAGE_RANK
- cout << "x" << i << "= " << X[i] << endl;
- #endif
- sum += X[i];
- }
- cout << "Suma: " << sum << endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement