Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- п»ї#include <iostream>
- #include <fstream>
- #include <bitset>
- #include <string>
- #include <cmath>
- using namespace std;
- int lcg(int m = 0, int a = 0, int c = 0, int x = 0){
- static int M = m; // Статические инты для того, чтобы не посылать их в функцию каждый раз. Так они просто сохраняются после первого определения (72-ая строка)
- static int A = a;
- static int C = c;
- static int X = x;
- X = (A*X+C) % M; // Формула, по которой высчитывается следующий псевдорандомный элемент. Зависит от коэффициетнот a, c, m и от прошлого x.
- return X; // Возвращает новый псевдорандомный элемент
- }
- void distribution(int* arr_ran, int N, int m){
- // Нужно было как-то заисать данные в 2 столбика. Я придумал такой вариант, но каждый раз когда я открываю эту лабу, я уже не помню как именно я здесь это осуществил. Я к тому, что можно сказать, что после выполнения какой-то задачи я успешно забыл о том как я это сделал, как о чем-то уже ненужном
- ofstream out("data.txt");
- int size = 10; // Сколько коллонок в гистограмме
- int* distr = new int[size];
- distr[0]=m/(size); //=10
- for (int i=1; i<size; i++){ // Здесь создается массив чисел с шагом m/size, в данном случае 10.
- distr[i]=distr[i-1]+m/(size);
- }
- int* tmp = new int[size];
- for (int i = 0;i<size; i++) tmp[i]=0;
- for (int i=0; i<N; i++){
- for (int j=0; j<size; j++){
- if (arr_ran[i]<distr[j]){ //Сверяется каждый элемент последовательности с каждым шаком в гистограмме
- tmp[j]++;
- break;
- }
- }
- }
- int middle=m/size/2;
- for (int i=0; i<size; i++){
- out << distr[i]-middle << "\t" << tmp[i] << endl; // Для гистограммы нужно указать именно среднее значение по иксам.
- }
- }
- void test(int* arr_ran, int N){
- const int bits=8; // Кол-во бит для представления
- int Sum=0;
- for (int i=0; i<N; i++){
- bitset<bits> b{(arr_ran[i])};
- for (int i=bits-1; i>=0; i--){ //Здесь подсчитывается S n по всей последовательности
- Sum+=2*b[i]-1;
- }
- cout << b.to_string() << endl; // to_string переводит массив битов в сроковое представление
- }
- double Sum_obs = abs(Sum)/sqrt(N*bits); //S obs считает по формуле
- double P = erfc(Sum_obs/sqrt(2)); // erfc - функция ошибок, присутвует в библиотеке cmath C++
- cout << "P = " << P;
- if (P>0.01) cout << " Success" << endl;
- else
- {
- cout << " Failed" << endl;
- }
- }
- int main() {
- int N, a, c, x;
- int m;
- cout << "Linear Congruent Generator" << endl;
- cout << "Enter number of digits N, modulus m, multiplier a, increment c, start value X: " << endl;
- //cin >> N >> m >> a >> c >> x;
- N=100;
- m=100; // Будут генериться разные числа от 0 до 99 включительно.
- x=1;
- a=21; // 100 делится на такие простые числа: 2, 5. a=их произведению +1 = 11. Но так как если m нацело делится на 4, а a-1 следовательно тоже должно делится на 4, то умножаем 2*5*2 и только тогда +1.
- c=3; // У c и m не должно быть общих делителей
- // Попробуй изменить a на 20, или c на 4 например. (последовательность начнет повторятся до того, как в ней наберется m чисел).
- int* arr_ran = new int[N];
- lcg(m,a,c,x);
- for (int i=0; i<N; i++){
- int get_ran = lcg();
- cout << get_ran << " ";
- arr_ran[i]=get_ran;
- }
- cout << endl << endl;
- distribution(arr_ran, N, m);
- test(arr_ran, N);
- system("pause");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement