Facebook
From Insensitive Teal, 7 Years ago, written in C++.
Embed
Download Paste or View Raw
Hits: 272
  1. #include <iostream>
  2. #include <random>
  3. #include <cmath>
  4. #include <fstream>
  5. using namespace std;
  6.  
  7. void vfun_ReadDatas(int &iXmax, int &iN, int &iX0);
  8. void vfun_LCG(const int &iXmax, int &iX0, const int &iN, int *iPrimeNumbersTab);
  9. int ifun_SetC(int &iModule);
  10. int ifun_Random(int iFirst, const int iLast);
  11. bool bfun_NWD(int iA, int iB);
  12. void vfun_SaveToFile(const string sName, int iValue);
  13. void vfun_RandomizeLCG(const int &iModule, const int &iA, const int &iIncrease, const int &iX0, const int &iN);
  14. int *ifun_MakeTab(const int iSize);
  15. int ifun_CountPrime(int iValue);
  16. int *ifun_PrimeNumbers(int iValue);
  17. bool bfun_CheckWithTheory(int iA, int *iPrimeNumbersTab, int iModule);
  18. int ifun_SetA(int iModule, int *iPrimeNumbersTab);
  19.  
  20. int main() {
  21.         int iXmax, iN, iX0;
  22.         vfun_ReadDatas(iXmax, iN, iX0);
  23.         vfun_LCG(iXmax, iX0, iN, iPrimeNumbersTab);
  24.  
  25.         return 0;
  26. }
  27.  
  28.  
  29. /**
  30. * Funckja pobierająca dane do generatora
  31. * @param iXmax xmax
  32. * @param iN liczba wyrazów
  33. * @param iX0 ziarno
  34. */
  35. void vfun_ReadDatas(int &iXmax, int &iN, int &iX0)      {
  36.         cin >> iXmax >> iN >> iX0;
  37.  
  38.         while (iN < 0 || iXmax < 0 || iX0 < 0 || iX0 >= iXmax) {
  39.                 cout << "!" << endl;
  40.                 cin >> iXmax >> iN >> iX0;
  41.         }
  42. }
  43.  
  44. /**
  45. * Zbieranie danych do generatora losujący metodą liniową
  46. * @param iXmax xmax
  47. * @param iX0 ziarno
  48. * @param iN liczba wyrazów
  49. */
  50. void vfun_LCG(const int &iXmax, int &iX0, const int &iN, int *iPrimeNumbersTab) {
  51.         int iModule = iXmax + 1;
  52.         int iC = ifun_SetC(iModule);
  53.         ifun_PrimeNumbers(iModule);
  54.         int iMultiplier = ifun_SetA(iModule, iPrimeNumbersTab);
  55.         vfun_RandomizeLCG(iModule, iMultiplier, iC, iX0, iN);
  56. }
  57.  
  58. /**
  59. * Wyznaczanie przyrostu c
  60. * @param iModule moduł m
  61. * @return wartosc przyrostu c
  62. */
  63. int ifun_SetC(int &iModule) {
  64.         int iIncrease = ifun_Random(1, iModule);
  65.  
  66.         while (bfun_NWD(iModule, iIncrease)) {
  67.                 iIncrease = ifun_Random(1, iModule);
  68.         }
  69.  
  70.         return iIncrease;
  71. }
  72.  
  73. /**
  74. * Losowanie liczby
  75. * @param iFirst wyraz od ktorego losujemy
  76. * @param iLast wyraz do ktorego losujemy
  77. * @return dist(rd) wylosowana liczba
  78. */
  79. int ifun_Random(int iFirst, const int iLast) {
  80.         random_device rd;
  81.         uniform_int_distribution<int>dist(iFirst, iLast - 1);
  82.         return dist(rd);
  83. }
  84.  
  85. /**
  86. * Najwiekszy wspolny dzielnik
  87. * @param iA liczba pierwsza
  88. * @param iB liczba druga
  89. * @return false gdy NWD=1
  90. * @return true gdy NWD!=1
  91. */
  92. bool bfun_NWD(int iA, int iB) {
  93.         do {
  94.                 if (iA > iB) {
  95.                         iA = iA - iB;
  96.                 }
  97.                 else {
  98.                         iB = iB - iA;
  99.                 }
  100.         } while (iA != iB);
  101.  
  102.         if (iA == 1) {
  103.                 return false;
  104.         }
  105.         else {
  106.                 return true;
  107.         }
  108. }
  109.  
  110. /**
  111. * Zapisywanie do pliku
  112. * @param sName nazwa pliku
  113. * @param iValue wartość x ze wzoru
  114. */
  115. void vfun_SaveToFile(const string sName, int iValue) {
  116.         ofstream fsFile;
  117.         fsFile.open(sName, ios::app);
  118.         fsFile << iValue << endl;
  119.         fsFile.close();
  120. }
  121.  
  122. /**
  123. * Podstawienie wartości do wzoru głównego
  124. * iModule moduł m
  125. * iA mnożnik a
  126. * iIncrease przyrost c
  127. * iX0 ziarno x0
  128. * iN liczba wyrazów
  129. */
  130. void vfun_RandomizeLCG(const int &iModule, const int &iA, const int &iIncrease, const int &iX0, const int &iN) {
  131.         int x = iX0;
  132.  
  133.         for (int i = 0; i < iN; i++) {
  134.                 x = (iA * x + iIncrease) % iModule;
  135.                 vfun_SaveToFile("Wyniki.txt", x);
  136.         }
  137. }
  138.  
  139. /**
  140. * Proba tworzenia tablicy
  141. * @param iSize rozmiar
  142. * @return iTab tablica jeśli udało się stworzyć
  143. */
  144. int *ifun_MakeTab(const int iSize) {
  145.         int *iTab;
  146.  
  147.         try {
  148.                 iTab = new int[iSize];
  149.         }
  150.         catch (bad_alloc &bad) {
  151.                 cout << "!";
  152.                 exit(EXIT_FAILURE);
  153.         }
  154.  
  155.         return iTab;
  156. }
  157.  
  158. /**
  159. * Zlicza czynniki pierwsze liczby
  160. * @param iValue liczba sprawdzana
  161. * @return iCont liczba pierwszych
  162. */
  163. int ifun_CountPrime(int iValue) {
  164.         int iK = 2, iCount = 0;
  165.        
  166.         while (iValue>1) {
  167.                 while (iValue%iK == 0){
  168.                         iCount++;
  169.                         iValue /= iK;
  170.                 }
  171.                 iK++;
  172.         }
  173.        
  174.         return iCount;
  175. }
  176.  
  177. /**
  178. * Wypelnia tablice dzielnikami pierwszymi liczby
  179. * @param iValue liczba
  180. * @return iPrimeNumbersTab wypelniona tablica
  181. */
  182. int *ifun_PrimeNumbers(int iValue) {
  183.         int iSize = ifun_CountPrime(iValue);
  184.         int *iPrimeNumbersTab = ifun_MakeTab(iSize);
  185.         int g = sqrt(iValue);
  186.  
  187.         for (int i = 2, j=0; i <= g; i++) {
  188.                 while (iValue % i == 0)
  189.                 {
  190.                         iPrimeNumbersTab[j] = i;
  191.                         iValue /= i;
  192.                         j++;
  193.                 }
  194.         }
  195.         return iPrimeNumbersTab;
  196. }
  197.  
  198. /**
  199. * Sprawdza z teorią
  200. * @param iA podstawa do potegowania
  201. * @param iPrimeNumbersTab tablica dzielnikow ktore sa pierwsze
  202. * @param iValue moduł m
  203. * @return true zgodne ze wszystkim
  204. * @return false jesli sie nie zgadza
  205. */
  206. bool bfun_CheckWithTheory(int iA, int *iPrimeNumbersTab, int iModule)
  207. {
  208.         int b = iA - 1;
  209.         int iSize = ifun_CountPrime(iModule);
  210.         for (int i = 0; i < iSize; i++)
  211.         {
  212.                 if (b % iPrimeNumbersTab[i] != 0)
  213.                 {
  214.                         return false;
  215.                 }
  216.         }
  217.         if (iModule % 4 == 0)
  218.         {
  219.                 if (b % 4 == 0)
  220.                 {
  221.                         return true;
  222.                 }
  223.                 else
  224.                 {
  225.                         return false;
  226.                 }
  227.         }
  228. }
  229.  
  230. /*
  231. * Szuka a do wzoru glownego
  232. * @param iModule wartosc m
  233. * @param iPrimeNumbersTab tablica zeby sprawdzic z teorią
  234. * @return iA znalezione a
  235. */
  236. int ifun_SetA(int iModule, int *iPrimeNumbersTab) {
  237.         int iA, iLambda, iMaksLambda = 0, iCount = 0;
  238.         int *iTabA = ifun_MakeTab(100);
  239.        
  240.         for (int i = 0; i < 100; i++) {
  241.                 iTabA[i] = 0;
  242.         }
  243.  
  244.         for (iA = 2, iLambda = 1; iA < iModule; iA++, iLambda++) {
  245.                 int iPowAandLambda = pow(iA, iLambda);
  246.        
  247.                 while (bfun_NWD(iA, iModule) == false) {       
  248.                         while (iPowAandLambda % iModule == 1) {
  249.                                 if (iLambda > iMaksLambda) {           
  250.                                         for (int i = 0; i < 100; i++) {
  251.                                                 iTabA[i] = 0;
  252.                                         }
  253.  
  254.                                         iCount = 1;                                    
  255.                                         iMaksLambda = iLambda;
  256.                                         iTabA[iCount] = iA;
  257.                                 }
  258.                                 if (iLambda == iMaksLambda) {
  259.                                         iCount++;
  260.                                         iTabA[iCount] = iA;
  261.                                 }
  262.                         }
  263.                 }
  264.         }
  265.  
  266.         for (int i = 0; i < iCount; i++) {
  267.                 if (bfun_CheckWithTheory(iA, iPrimeNumbersTab, iModule) == true) {
  268.                         iA = iTabA[i];
  269.                 }
  270.                 else {
  271.                         iA = iTabA[iCount];
  272.                 }
  273.         }
  274.         return iA;
  275. }