МІНІСТЕРСТВО ОСВІТИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”
КАФЕДРА ПРОГРАМНОГО ЗАБЕЗПЕЧЕННЯ
Звіт
До лабораторної роботи № 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;
}
}
}
Результат виконання завдання:
Висновок: в даній роботі я навчився одержувати послідовності псевдовипадкових квазірівномірно розподілених чисел запропонованими методами та перевірка їх на рівномірність за допомогою гістограми та за непрямими ознаками. Також я перевірив кожну із згенерованих послідовностей на незалежність методом, основаним на обчисленні кореляційного моменту, та гіпотезу про стохастичність послідовностей.