Министерство Образования и Науки Российской Федерации
Федеральное Агентство по образованию
НОВОСИБИРСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
Кафедра Вычислительной техники
Лабораторная работа № 1
По дисциплине «Моделирование»
Тема: «Принципы имитационного моделирования»
Студенты:
Группа: АП-418
Вариант: 7
Преподаватель:
Новосибирск, 2007 г.
1. Цель лабораторной работы
- изучить принципы построения имитационных моделей: принцип и принцип особых состояний
средствами интегрированной статистической системы Statistica;
- приобрести навыки построения имитационных моделей на примере моделирования работы простейших систем.
2. Задание к работе
2.1. Рассчитать траекторию процесса Z(t), происходящего в дифференцирующем фильтре (рис. 1), в моменты времени t=1,2,…,N (
=0,01). Рассчитать значения производной детерминированной функции x(t) (в соответствии с вариантом, табл. 1), подаваемой на вход фильтра, используя принцип
(см. п. 3 пояснения к работе).
x(t) X`(t) Z(t)
![]() |
Рис. 1. Структурная схема дифференцирующего фильтра.
2.2. Рассчитать значения производной детерминированной функции x(t), подаваемой на вход фильтра, в моменты времени t=1,2,…,N, используя аналитическую формулу (аналитический метод). Построить графики исходной функции x(t) и производных x’(t), рассчитанных имитационным методом и аналитическим. Сопоставить результаты вычисления производных аналитическим и имитационным методами. Сделать выводы.
Вар. | X(t) | N | Z(0) |
7. | Sin2(t) | 1000 | 0,5 |
3. Пояснения к работе
Процесс, происходящий в фильтре (рис. 1), описывается дифференциальным уравнением:
(1)
, где:
K – коэффициент усиления;
х(t) – входной сигнал.
Доказано, что:
![]()
Преобразуем математическую модель фильтра (1) к виду, позволяющему применить принцип
. В простейшем случае достаточно уравнение (1) аппроксимировать конечно-разностным уравнением:
| , где |
|
|
Что соответствует итерационной формуле:
(2)
(3).
Задав начальное условие Z(t0)=Z0 можно построить траекторию процесса, происходящего в фильтре, с целью получения текущего значения производной любой детерминированной функции x(t), подаваемой на вход.
Результаты по первому заданию:
t | sin(t)^2 | y(t) | real | delta |
-0,5 | 0,229849 | -4,8368 | -0,84147 | 3,995329 |
-0,49 | 0,221489 | -0,83601 | -0,8305 | 0,005515 |
-0,48 | 0,21324 | -0,82487 | -0,81919 | 0,00568 |
-0,47 | 0,205106 | -0,8134 | -0,80756 | 0,005844 |
-0,46 | 0,19709 | -0,80161 | -0,7956 | 0,006005 |
-0,45 | 0,189195 | -0,78949 | -0,78333 | 0,006164 |
-0,44 | 0,181424 | -0,77706 | -0,77074 | 0,00632 |
-0,43 | 0,173781 | -0,76432 | -0,75784 | 0,006474 |

Задание ко второй части работы
Вычислительная система состоит из 2-х компьютеров. Из предварительного обследования получена информация, что интервал времени между двумя последовательными поступлениями заданий в вычислительную систему подчиняются равномерному закону распределения в некотором интервале. Требуется разработать программу на СИ++ имитирующую процесс работы такой системы для сотни задач. Рассчитать среднее время нахождения задания в очереди, вероятность простоя одного компьютера, вероятность простоя всей системы. Провести 1000 экспериментов.
Результаты работы по второму заданию
Листинг программы на СИ++
#include <stdlib. h>
#include <iostream. h>
#include <deque>
#include "vector. h"
static int uid = 0;
double CommonWaitTime = 0;
int CommonWaitTimes = 0;
class Task
{
public:
double StartTime;
double Duration;
int id;
Task()
{
StartTime = 0;
Duration = 0;
id = uid++;
};
double endTime()
{
return StartTime + Duration;
}
Task &operator = (Task &TT)
{
StartTime = TT. StartTime;
Duration = TT. Duration;
id = TT. id;
return (*this);
}
friend ostream& operator <<(ostream &out, Task &T)
{
out << "[" << T. id << ", " << T. StartTime << ", " << T. endTime() << "]";
return out;
}
};
// канал обработки
class Channel
{
public:
Task CurTask;
double CommonFreeTime;
double CommonFreeTimes;
Channel()
{
CommonFreeTime = 0;
CommonFreeTimes = 0;
};
Channel(Channel& CC)
{
CurTask = CC. CurTask;
CommonFreeTime = monFreeTime;
}
void freeINC(double delta)
{
CommonFreeTime += delta;
CommonFreeTimes++;
}
Channel &operator = (Channel &C)
{
this->CurTask = C. CurTask;
this->CommonFreeTime = monFreeTime;
return (*this);
}
};
Task GenTask(Task LastTask)
{
Task result;
result. Duration = rand() % 100 / 100.0 * 2 + 1;
result. StartTime = LastTask. StartTime + rand() % 100 / 100.0 * 8 + 1;
return result;
}
std::deque<Task> Q;
vector<Channel> C;
// subchannel data distributor (распределитель задач)
void SDD(Task NewTask)
{
// из всех свободных каналов обработки, выбираем тот, которому меньше всего надо ждать
if (NewTask. id!= -1)
Q. push_front(NewTask);
else
{
// если идёт разгрузка очереди
// то берём минимальное время конца из каналов
// как время следующей виртуальной задачи (как тек. время)
int imin = 0;
for (int i = 0; i < C. count; i++)
if (C[i].CurTask. endTime() < C[imin].CurTask. endTime())
imin = i;
NewTask. StartTime = C[imin].CurTask. endTime();
}
for (int i = 0; i < C. count; i++)
{
// если канал свободен для данной задачи
while (NewTask. StartTime >= C[i].CurTask. endTime())
{
if (Q. size() == 0)
return;
if (C[i].CurTask. endTime() > Q. back().StartTime)
{
CommonWaitTime += C[i].CurTask. endTime() - Q. back().StartTime;
CommonWaitTimes++;
Q. back().StartTime = C[i].CurTask. endTime();
C[i].CurTask= Q. back();
}
else
{
C[i].freeINC(Q. back().StartTime - C[i].CurTask. endTime());
C[i].CurTask = Q. back();
}
Q. pop_back();
}
}
}
void Experiment()
{
Task T0;
C. resize(2);
C. count = 2;
//CommonWaitTimes = 0;
for (int i = 0; (i < 10000) || (Q. size() > 0); i++) {
T0 = GenTask(T0);
if (i > 10000) {
T0.id = -1; // команда отработки всей очереди
}
cout << "QUEUE ( ";
for (int k = 0; k < Q. size(); k++)
cout << Q[k] << " ";
cout << ")\n";
cout << "SDD <-- (" << T0 << ")\n";
SDD(T0);
for (k = 0; k < C. count; k++)
cout << "C["<<k<<"] : (" << C[k].CurTask << ")\n";
cout << "QUEUE ( ";
for (k = 0; k < Q. size(); k++)
cout << Q[k] << " ";
cout << ")\n\n";
}
}
//
int main()
{
Experiment();
for (int k = 0; k < C. count; k++)
cout << "C["<<k<<"] : (" << C[k].CommonFreeTime / (double)C[k].CommonFreeTimes<< ")\n";
if (CommonWaitTimes > 0)
cout << "CommonWaitTime = " << CommonWaitTime / (double)CommonWaitTimes << "\n";
return 0;
}
Результаты работы программы
Среднее время простоя первого канала: 3,6689
Среднее время простоя второго канала: 44,3345
Среднее время ожидания задачи в очереди: 0,44
Вывод
Проведённые исследования подтверждают действенность метода имитационного моделирования. Полученные результаты работы программы действительно близки к точным, и из них видно, что второй компьютер загружен меньше, и среднее время простоя у него соответственно больше, чем у первого. Из-за того, что интервал поступления задач больше, чем интервал обработки, получилось что время ожидания задачи в очереди очень мало – почти ноль.



