Министерство Образования и Науки Российской Федерации

Федеральное Агентство по образованию

НОВОСИБИРСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ

Кафедра Вычислительной техники

Лабораторная работа № 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

Вывод

Проведённые исследования подтверждают действенность метода имитационного моделирования. Полученные результаты работы программы действительно близки к точным, и из них видно, что второй компьютер загружен меньше, и среднее время простоя у него соответственно больше, чем у первого. Из-за того, что интервал поступления задач больше, чем интервал обработки, получилось что время ожидания задачи в очереди очень мало – почти ноль.