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