МІНІСТЕРСТВО ОСВІТИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”
КАФЕДРА ПРОГРАМНОГО ЗАБЕЗПЕЧЕННЯ
Звіт
До лабораторної роботи № 1
На тему: “ Формування вхідних потоків і контролю їх якості для комп’ютерного моделювання складних систем статистичними методами”
З дисципліни : "Моделювання програмного забезпечення"
Мета роботи: одержання послідовностей псевдовипадкових квазірівномірно розподілених чисел запропонованими методами та перевірка їх якості.
Завдання:
Одержати послідовності псевдовипадкових квазірівномірно розподілених чисел при заданих параметрах для кожного з нижчевказаних способів:
методу серединних квадратів;
мультиплікативного методу;
 за допомогою вбудованих функцій із програмного забезпечення 		комп’ютера.
Кожну з генерованих послідовностей перевірити на рівномірність двома методами:
за гістограмою;
за непрямими ознаками.
Кожну з генерованих послідовностей провірити на незалежність методом, основаним на обчисленні кореляційного моменту.
Перевірити одержані послідовності на стохастичність.
Код програми
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Lab1_MPZ
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private static int t = 1;
        private static int count = 20;
        #region Метод серединних квадратів
        private void Count1Button_Click(object sender, EventArgs e)
        {
            List<double> mas = new List<double>();
            Gistograma1.Refresh();
            try
            {
                Output1.Clear();
                double X1 = double.Parse(Input1.Text);
                int N = int.Parse(Input2.Text);
                int length = X1.ToString().Length - 2;
                if (length % 2 == 1) length++;
                StringBuilder sb = new StringBuilder();
                string format = "{0:F" + length * 2 + "} ";
                string format_small = "{0:F" + length + "} ";
                sb.AppendFormat(format_small, X1);
                double Xi = X1;
                for (int i = 1; i < N; i++)
                {
                    try
                    {
                        string tmp;
                        Xi = Xi * Xi;
                        tmp = string.Format(format, Xi);
                        Xi = double.Parse("0," + tmp.Substring(length / 2 + 2, length));
                        //if (Xi == 0) Xi = X1;
                        mas.Add(Xi);
                        sb.AppendFormat(format_small, Xi);
                    }
                    catch
                    {
                    }
                }
                Output1.Text = sb.ToString();
            }
            catch (System.FormatException exc)
            {
                MessageBox.Show("Помилка при введенi даних для методу серединних квадратiв");
            }
            #region вивід гістограми
            int[] sections = new int[count];
            for (int i = 0; i < mas.Count; i++)
            {
                sections[(int)(mas[i] / (1.0 / count))]++;
            }
            int line_width = (int)((Gistograma1.Width - count + 1) / count);
            Graphics gr = Graphics.FromHwnd(Gistograma1.Handle);
            for (int i = 0; i < count; i++)
            {
                gr.DrawLine(new Pen(Color.Red, line_width), new Point(10 + (line_width + 1) * i, 110), new Point(10 + (line_width + 1) * i, 110 - ((int)((double)sections[i] / (double)sections.Max() * 100))));
            }
            gr.Dispose();
            #endregion // кінець виводу гісторгами
            #region перевірка за непрямими ознаками
            Graphic1.Refresh();
            gr = Graphics.FromHwnd(Graphic1.Handle);
            int dot_count = mas.Count-1;
            for (int i = 0; i < dot_count; i += 2)
            {
                gr.FillRectangle(Brushes.Red, (int)Math.Ceiling(mas[i] * 100), (int)Math.Floor(mas[i + 1] * 100), 1, 1);
            }
            gr.Dispose();
            #endregion //кінець перевірки за непрямими ознаками
            #region обчислення кореляційного моменту
            int NN = mas.Count;
            double SXi = 0, SXit = 0, SXiXit = 0, SXi2 = 0, SXit2 = 0;
            for (int i = 0; i < NN - t; i++)
            {
                SXi += mas[i];
                SXit += mas[i + t];
                SXiXit += mas[i] * mas[i + t];
                SXi2 += mas[i] * mas[i];
                SXit2 += mas[i + t] * mas[i + t];
            }
            double DXi, DXit;
            DXi = 1.0 / (NN - t) * SXi2 - 1.0 / ((NN - t) * (NN - t)) * SXi * SXi;
            DXit = 1.0 / (NN - t) * SXit2 - 1.0 / ((NN - t) * (NN - t)) * SXit * SXit;
            double Pt;
            Pt = (1.0 / (NN - t) * SXiXit - (1.0) / ((NN - t) * (NN - t)) * SXi * SXit) / Math.Sqrt(DXi * DXit);
            Korelyation1.Text = Pt.ToString();
            double B = 1.0 / NN;
            double rhs = (1.0 - B) * Math.Sqrt(1.0 / NN);
            if (Math.Abs(Pt) <= rhs) Independent1.Text = "Послідовність кореляційно незалежна";
            else Independent1.Text = "Послідовність залежна";
            #endregion // кінець обчислення кореляційного моменту
            #region Перевірка на стохастичність
            double hi2 = 0;
            int d = 5;  // кількість підінтервалів
            double[] mas1 = new double[d];
            double[] p = new double[d];
            double cnt = 0;
            int a = 0;
            double dl = 1.0 / d;
            for (double j = 0; j < 1; j += dl)
            {
                cnt = 0;
                for (int i = 0; i < mas.Count; i++)
                {
                    if (mas[i] > j && mas[i] <= (j + dl))
                        cnt++;
                }
                mas1[a] = cnt;
                p[a] = mas1[a] / NN;
                a++;
            }
            for (int i = 0; i < d; i++)
                if (p[i] != 0)
                    hi2 = hi2 + Math.Pow((mas1[i] - NN * p[i]), 2) / (NN * p[i]);
            Pirson1.Text = hi2.ToString();
            double hia2 = 0.352; // критична точка розподілу про різні значимості 0,95 і 3 ступеням свободи
            if (hi2 >= hia2)
                Stohastuchnistj1.Text = "Гіпотеза про стохастичність не вірна";
            else
                Stohastuchnistj1.Text = "Гіпотеза про стохастичність вірна з рівнем значимості 0,95";
            #endregion
        }
        #endregion
        #region Мультиплікативний Метод
        private void Count2Button_Click(object sender, EventArgs e)
        {
            List<double> mas = new List<double>();
            Gistograma2.Refresh();
            try
            {
                Output2.Clear();
                
                int X1 = int.Parse(Input3.Text);
                int N = int.Parse(Input5.Text);
                int L = int.Parse(Input4.Text);
                int length = X1.ToString().Length;
                int M = (int)Math.Pow(10, length);
                StringBuilder sb = new StringBuilder();
                string format = "{0:F4} ";
                
                int Xi = X1;
                for (int i = 0; i < N; i++)
                {
                    try
                    {
                        Xi = (Xi * L) % M;
                        mas.Add((double)Xi / (double)M);
                        sb.AppendFormat(format, mas[i]);
                    }
                    catch
                    {
                    }
                }
                Output2.Text = sb.ToString();
            }
            catch(System.FormatException exc)
            {
                MessageBox.Show("Помилка при введені даних для мультиплiкативного методу");
            }
            #region вивід гістограми
            int[] sections = new int[count];
            
            
            for (int i = 0; i < mas.Count; i++)
            {
                sections[(int)(mas[i] / (1.0/count))]++;
            }
            int line_width = (int)((Gistograma2.Width-count+1)/count);
            
            Graphics gr = Graphics.FromHwnd(Gistograma2.Handle);
            for (int i = 0; i < count; i++)
            {
                gr.DrawLine(new Pen(Color.Green, line_width), new Point(10 + (line_width + 1) * i, 110), new Point(10 + (line_width+1) * i, 110-((int)((double)sections[i] / (double)sections.Max() * 100))));
            }
            
            gr.Dispose();
            #endregion // кінець виводу гісторгами
            #region перевірка за непрямими ознаками
            Graphic2.Refresh();
            gr = Graphics.FromHwnd(Graphic2.Handle);
            int dot_count = mas.Count-1;
            for (int i = 0; i < dot_count; i += 2)
            {
               gr.FillRectangle(Brushes.Red, (int)Math.Ceiling(mas[i]*100), (int)Math.Floor(mas[i + 1]*100), 1, 1);
            }
            gr.Dispose();
            #endregion //кінець перевірки за непрямими ознаками
            #region обчислення кореляційного моменту
            int NN = mas.Count;
            double SXi = 0, SXit = 0, SXiXit = 0, SXi2 = 0, SXit2 = 0;
            for (int i = 0; i < NN - t; i++)
            {
                SXi += mas[i];
                SXit += mas[i + t];
                SXiXit += mas[i] * mas[i + t];
                SXi2 += mas[i] * mas[i];
                SXit2 += mas[i + t] * mas[i + t];
            }
            double DXi, DXit;
            DXi = 1.0 / (NN - t) * SXi2 - 1.0 / ((NN - t) * (NN - t)) * SXi * SXi;
            DXit = 1.0 / (NN - t) * SXit2 - 1.0 / ((NN - t) * (NN - t)) * SXit * SXit;
            double Pt;
            Pt = (1.0 / (NN - t) * SXiXit - (1.0) / ((NN - t) * (NN - t)) * SXi * SXit) / Math.Sqrt(DXi * DXit);
            Korelyation2.Text = Pt.ToString();
            double B = 1.0 / NN;
            double rhs = (1.0 - B) * Math.Sqrt(1.0 / NN);
            if (Math.Abs(Pt) <= rhs) Independent2.Text = "Послідовність кореляційно незалежна";
            else Independent2.Text = "Послідовність залежна";
            #endregion // кінець обчислення кореляційного моменту
            #region Перевірка на стохастичність
            double hi2 = 0;
            int d = 5;  // кількість підінтервалів
            double[] mas1 = new double[d];
            double[] p = new double[d];
            double cnt = 0;
            int a = 0;
            double dl = 1.0 / d;
            for (double j = 0; j < 1; j += dl)
            {
                cnt = 0;
                for (int i = 0; i < mas.Count; i++)
                {
                    if (mas[i] > j && mas[i] <= (j + dl))
                        cnt++;
                }
                mas1[a] = cnt;
                p[a] = mas1[a] / NN;
                a++;
            }
            for (int i = 0; i < d; i++)
                if (p[i] != 0)
                    hi2 = hi2 + Math.Pow((mas1[i] - NN * p[i]), 2) / (NN * p[i]);
            Pirson2.Text = hi2.ToString();
            double hia2 = 0.352; // критична точка розподілу про різні значимості 0,95 і 3 ступеням свободи
            if (hi2 >= hia2)
                Stohastuchnistj2.Text = "Гіпотеза про стохастичність не вірна";
            else
                Stohastuchnistj2.Text = "Гіпотеза про стохастичність вірна з рівнем значимості 0,95";
            #endregion
        }
        #endregion
        #region Метод стандартними засобами
        private void Count3Button_Click(object sender, EventArgs e)
        {
            List<double> mas = new List<double>();
            Gistograma3.Refresh();
            try
            {
                int N = int.Parse(Input6.Text);
                Random rand = new Random();
                StringBuilder sb = new StringBuilder();
                string format = "{0:F4} ";
                for (int i = 0; i < N; i++)
                {
                    mas.Add((double)rand.Next() / int.MaxValue);
                    sb.AppendFormat(format, mas[i]);
                }
                Output3.Text = sb.ToString();
            }
            catch(System.FormatException exc)
            {
                MessageBox.Show("Помилка при введені даних для генерації стандартними засобами");
            }
            #region вивід гістограми
            int[] sections = new int[count];
            for (int i = 0; i < mas.Count; i++)
            {
                sections[(int)(mas[i] / (1.0 / count))]++;
            }
            int line_width = (int)((Gistograma3.Width - count + 1) / count);
            Graphics gr = Graphics.FromHwnd(Gistograma3.Handle);
            for (int i = 0; i < count; i++)
            {
                gr.DrawLine(new Pen(Color.Blue, line_width), new Point(10 + (line_width + 1) * i, 110), new Point(10 + (line_width + 1) * i, 110 - ((int)((double)sections[i] / (double)sections.Max() * 100))));
            }
            gr.Dispose();
            #endregion // кінець виводу гісторгами
            #region перевірка за непрямими ознаками
            Graphic3.Refresh();
            gr = Graphics.FromHwnd(Graphic3.Handle);
            int dot_count = mas.Count -1;// 2;
            for (int i = 0; i < dot_count; i += 2)
            {
                gr.FillRectangle(Brushes.Red, (int)Math.Ceiling(mas[i] * 100), (int)Math.Floor(mas[i + 1] * 100), 1, 1);
            }
            gr.Dispose();
            #endregion //кінець перевірки за непрямими ознаками
            #region обчислення кореляційного моменту
            int NN = mas.Count;
            double SXi = 0, SXit = 0, SXiXit = 0, SXi2 = 0, SXit2 = 0;
            for (int i = 0; i < NN - t; i++)
            {
                SXi += mas[i];
                SXit += mas[i + t];
                SXiXit += mas[i] * mas[i + t];
                SXi2 += mas[i] * mas[i];
                SXit2 += mas[i + t] * mas[i + t];
            }
            double DXi, DXit;
            DXi = 1.0 / (NN - t) * SXi2 - 1.0 / ((NN - t) * (NN - t)) * SXi * SXi;
            DXit = 1.0 / (NN - t) * SXit2 - 1.0 / ((NN - t) * (NN - t)) * SXit * SXit;
            double Pt;
            Pt = (1.0 / (NN - t) * SXiXit - (1.0) / ((NN - t) * (NN - t)) * SXi * SXit) / Math.Sqrt(DXi * DXit);
            Korelyation3.Text = Pt.ToString();
            double B = 1.0 / NN;
            double rhs = (1.0 - B) * Math.Sqrt(1.0 / NN);
            if (Math.Abs(Pt) <= rhs) Independent3.Text = "Послідовність кореляційно незалежна";
            else Independent3.Text = "Послідовність залежна";
            #endregion // кінець обчислення кореляційного моменту
            #region Перевірка на стохастичність
            double hi2=0;
            int d = 5;  // кількість підінтервалів
            double[] mas1 = new double[d];
            double[] p = new double[d];
            double cnt = 0;
            int a=0;
            double dl = 1.0/d;
            for (double j = 0; j < 1; j += dl)
                    {
                    cnt = 0;
                    for (int i=0; i<mas.Count; i++)
                            {
                            if ( mas[i] > j && mas[i] <= (j + dl))
                                cnt++;
                            }
                    mas1[a]=cnt;
                    p[a]=mas1[a]/NN;
                    a++;
                    }
            for (int i=0; i<d; i++)
                    if(p[i] != 0)
                        hi2 = hi2 + Math.Pow((mas1[i]-NN*p[i]),2)/(NN*p[i]);
            Pirson3.Text = string.Format("{0:F8}",hi2.ToString());
            double hia2 = 0.352; // критична точка розподілу при рівні значимості 0,95 і 3 ступеням свободи
            if (hi2 >= hia2)
                Stohastuchnistj3.Text = "Гіпотеза про стохастичність не вірна";
            else
                Stohastuchnistj3.Text = "Гіпотеза про стохастичність вірна з рівнем значимості 0,95";
            #endregion
        }
        #endregion
        private void Input2_Leave(object sender, EventArgs e)
        {
            Input5.Text = Input2.Text;
            Input6.Text = Input2.Text;
        }
    }
}
Результат виконання завдання:
Висновок: в даній роботі я навчився одержувати послідовності псевдовипадкових квазірівномірно розподілених чисел запропонованими методами та перевірка їх на рівномірність за допомогою гістограми та за непрямими ознаками. Також я перевірив кожну із згенерованих послідовностей на незалежність методом, основаним на обчисленні кореляційного моменту, та гіпотезу про стохастичність послідовностей.