Амкнутая система с неоднородными каналами: моделирование грузовых автоперевозок

Автор работы: Пользователь скрыл имя, 17 Июня 2014 в 23:16, курсовая работа

Краткое описание

При исследовании операций часто приходится сталкиваться с системами, предназначенными для многоразового использования при решении однотипных задач. Возникающие при этом процессы получили название процессов обслуживания, а системы – систем массового обслуживания (СМО). Каждая СМО состоит из определенного числа обслуживающих единиц (приборов, устройств, пунктов, станций), которые называются каналами обслуживания. Каналами могут быть линии связи, рабочие точки, вычислительные машины, продавцы и др. По числу каналов СМО подразделяют на одноканальные и многоканальные.
Заявки поступают в СМО обычно не регулярно, а случайно, образуя так называемый случайный поток заявок (требований). Обслуживание заявок также продолжается какое-то случайное время. Случайный характер потока заявок и времени обслуживания приводит к тому, что СМО оказывается загруженной неравномерно: в какие-то периоды времени скапливается очень большое количество заявок (они либо становятся в очередь, либо покидают СМО не обслуженными), в другие же периоды СМО работает с недогрузкой или простаивает.

Содержание

Введение3
Имитационное моделирование5
Нормальное распределение7
Экспоненциальное распределение7
Распределение Эрланга8
Описание системы9
Модельное время10
Классы и объекты10
Класс HeavyCar12
Класс Fuller13
Класс Emptier13
События и методы14
Листинг программы15
Результат35
Анализ результатов35
Список используемой литературы35

Прикрепленные файлы: 1 файл

курсач.docx

— 203.33 Кб (Скачать документ)

float ro_emptier=0;       //счетчик средней загрузки пункта  разгрузки

long int path_full=0L;    //счетчик  времени, проведенного самосвалами  в пути

//на разгрузку

long int path_empty=0L;   //счетчик  времени, проведенного самосвалами

//в пути на погрузку

long int take=0L;         //счетчик времени, проведенного  в пункте погрузки

long int give=0L;         //счетчик времени, проведенного  в пункте разгрузки

class HeavyCar

{

const static float direct_ave=22.0;

const static float direct_disp=3.0;

const static float back_ave=18.0;

const static float back_disp=3.0;

int id;                  //порядковый номер самосвала

enum states   state;                 //текущее состояние самосвала

int to_pfull;            //время до прибытия в пункт  разгрузки

int to_pempty;           //время до прибытия в пункт  погрузки

void *f;                 //указатель на пункт погрузки

void *e;                 //указатель на пункт разгрузки

public:

//Пункты погрузки и  разгрузки будут манипулировать  самосвалами

friend class Fuller;

friend class Emptier;

HeavyCar(int i);         //метод-конструктор

void putFuller(Fuller *f1);

void putEmptier(Emptier *e1);

void run();              //метод-диспетчер

void Print();

int State() { return(state); }

};

class Fuller

{

const static int volume=2;

const static float mu=0.25;

const static int rest=300;

float *perf;               //массив производительностей погрузчиков

int to_buldoser;           //время до завершения работы  бульдозера

int *to_full;              //массив времен до завершения  погрузки,

//-1 - в случае простоя

HeavyCar **serving;        //массив указателей на загружаемые  самосвалы

HeavyCar **queue;          //массив указателей на самосвалы, ждущие

//в очереди

int *to_rest;              //массив времен до завершения  отдыха,

//-1 в случае, если погрузчик  находится

//не в состоянии отдыха

int *isHeap;               //массив признаков того, готова  ли куча земли

//для погрузчика

public:

Fuller(HeavyCar **h);      //метод-конструктор

~Fuller();                 //метод-деструктор

void GroundReady();        //обработчик события: бульдозер  подготовил кучи

void Complete(int i);      //обработчик события: i-й погрузчик  завершил

//погрузку

void RestComplete(int i);  //обработчик  события: i-й погрузчик "отдохнул"

void Arrival(HeavyCar *h); //обработчик  события: прибыл самосвал h

int BestAvail();           //выбор наилучшего свободного  погрузчика

void Print();              //вывод на печать содержимого  объекта

int qLength();             //вычисление текущей длины очереди

int State(int i);          //вычисление состояния i-го погрузчика

int Busy();                //вычисление количества занятых  погрузчиков

void run();                //метод-диспетчер

};

class Emptier

{

const static int volume=1;

const static int border1=120;

const static int border2=480;

int *to_empty;             //массив времен до завершения разгрузки,

//-1 в случае простоя

HeavyCar **serving;        //массив указателей на разгружаемые  самосвалы

HeavyCar **queue;          //массив указателей на самосвалы, ждущие

//в очереди

public:

Emptier();                 //метод-конструктор

~Emptier();                //метод-деструктор

void Complete(int i); //обработчик  события: i-й самосвал завершил  разгрузку

void Arrival(HeavyCar *h); //обработчик  события: прибыл самосвал h

void Print();              //печать содержимого объекта

int qLength();

int Busy();

int FirstAvail();          //выбор первого по порядку  свободного

//разгрузчика

void run();                //метод-диспетчер

};

 

HeavyCar::HeavyCar(int i)

{

id=i;

state=Que_Fuller;          //первоначально все самосвалы  стоят в очереди

//на погрузку

to_pfull=-1;

to_pempty=-1;

}

void HeavyCar::putFuller(Fuller *f1)

{

f=f1;

}

void HeavyCar::putEmptier(Emptier *e1)

{

e=e1;

}

void HeavyCar::Print()

{

switch(state)

{

case Que_Fuller: printf("Самосвал %d находится в очереди на погрузку\n", id); break;

case Full: printf("Самосвал %d загружается\n", id); break;

case Full_Move: printf("Самосвал %d движется с грузом. Прибудет на разгрузку через %.1f минут\n", id, ((float)to_pfull)/60); break;

case Que_Emptier: printf("Самосвал %d находится в очереди на разгрузку\n", id); break;

case Empty: printf("Самосвал %d разгружается\n", id); break;

case Empty_Move: printf("Самосвал %d движется порожний. Прибудет на погрузку через %.1f минут\n", id, ((float)to_pempty)/60); break;

}

}

void HeavyCar::run()

{

if (state==3)                    //груженый самосвал находится  в пути

{

to_pfull--;

if (to_pfull==0)                //самосвал прибыл в пункт разгрузки

{

to_pfull=-1;

((Emptier*)e)->Arrival(this);  //сообщаем  об этом в пункт разгрузки

}

}

else if (state==Empty_Move)      //порожний самосвал находится  в пути

{

to_pempty--;

if (to_pempty==0)               //самосвал прибыл в пункт погрузки

{

to_pempty=-1;

((Fuller*)f)->Arrival(this);   //сообщаем  об этом пункту погрузки

}

}

else;                            //обработка других состояний  самосвала -

//в других классах

//Инкремент счетчика общего  времени пребывания самосвалов  в различных //состояниях

switch(state)

{

case Que_Fuller: take++; break;         //очередь на погрузку

case Full: take++; break;             //погрузка

case Full_Move: path_full++;  break;    //путь к пункту разгрузки

case Que_Emptier: give++; break;        //очередь на разгрузку

case Empty: give++;       break;      //разгрузка

case Empty_Move: path_empty++; break;   //путь к пункту погрузки

}

return;

}

Fuller::Fuller(HeavyCar **h)

//В начальном состоянии  все погрузчики простаивают, все  самосвалы ждут

//в очереди, бульдозеры  приступают к работе

{

int i;

to_buldoser=(int)(get_erlang(mu,volume,0.001)*60);

to_full=new int[volume];

to_rest=new int[volume];

perf=new float[volume];

isHeap= new int[volume];

serving=new HeavyCar *[volume];

queue=new HeavyCar *[S];

perf[0]=0.0714;   //производительность  первого погрузчика - 1/14 самосвала

//в минуту

perf[1]=0.0833;   //производительность  второго - 1/12 самосвала в минуту

for(i=0;i<volume;i++)

{

to_full[i]=-1;

to_rest[i]=-1;

isHeap[i]=0;

serving[i]=NULL;

}

for(i=0;i<S;i++)

queue[i]=h[i];

}

Fuller::~Fuller()

{

delete[] to_full;

delete[] perf;

delete[] isHeap;

delete[] to_rest;

delete [] serving;

delete [] queue;

}

void Fuller::Print()

{

int i;

if (to_buldoser>0) printf("Бульдозер работает. Подготовит фронт работ через %d минут\n", to_buldoser/60);

else printf("Бульдозер не  работает\n");

printf("В очереди на  погрузку - %d самосвалов\n", qLength());

for(i=0;i<S;i++)

{

if (!queue[i]) break;

printf("%d-й в очереди - самосвал № %d\n", i+1, queue[i]->id);

}

for(i=0;i<volume;i++)

{

switch(State(i))

{

case 1:

printf("%d-й погрузчик работает. Он обслуживает самосвал № %d. До окончания погрузки %d минут\n",i+1,serving[i]->id,to_full[i]/60);

case 2:

printf("%d-й погрузчик отдыхает. До окончания отдыха %d минут\n",i+1,to_rest[i]/60);

case 3:

printf("%d-й погрузчик простаивает.\n",i+1);

}

}

return;

}

int Fuller::State(int i)

//Вычисление состояния i-го  погрузчика

{

if (serving[i]!=NULL) return(1);   //работает

if (to_rest[i]>0) return(2);       //отдыхает после погрузки

return(3);                         //свободен

}

int Fuller::qLength()

{

int i;

for(i=0;i<S;i++)

if (queue[i]==NULL) return(i);

return(S);                         //все места в очереди заняты

}

int Fuller::BestAvail()

{

float max=0;

int k=-1;

for(int i=0;i<volume;i++)

{

//Нас интересуют только  погрузчики, которые свободны и  имеют //подготовленную кучу земли. Их них выбираем наилучший

if ((State(i)==3)&&(perf[i]>max)&&(isHeap[i]==1))

{

max=perf[i];

k=i;

}

}

return(k);

}

int Fuller::Busy()

{

int k=0;

for(int i=0;i<volume;i++)

if (State(i)==1) k++;

return(k);

}

void Fuller::GroundReady()

{

int i, k, mi, j;

//Возле каждого погрузчика появилась куча земли

for(i=0;i<volume;i++)

isHeap[i]=1;

to_buldoser=-1;                         //бульдозер прекращает работу

//На обслуживание поступает  количество самосвалов, равное значению  минимума //длины очереди и числа  погрузчиков

if (qLength()<volume) mi=qLength();

else mi=volume;

for(j=0;j<mi;j++)

{

k=BestAvail();                          //выбираем наилучший из доступных

//погрузчиков

if (k==-1) return;

to_full[k]=(int)(get_exp(perf[k])*60);  //разыгрываем  длительность погрузки

serving[k]=queue[0];                    //ставим на погрузку первый

//самосвал из очереди

queue[0]->state=Full;                 //переводим этот самосвал

//в состояние погрузки

for(i=0;i<(S-1);i++)                    //продвижение очереди

queue[i]=queue[i+1];

queue[S-1]=NULL;

}

}

void Fuller::Arrival(HeavyCar *h)        //в пункт погрузки прибыл пустой

//самосвал

{

int k, p;

k=BestAvail();                          //выбираем наилучший из доступных

//погрузчиков

if (k==-1)                              //такового нет, ставим самосвал

//в очередь

{

p=qLength();

queue[p]=h;

queue[p]->state=Que_Fuller;

}

else                           //ставим самосвал на обслуживание

{

to_full[k]=(int)(get_exp(perf[k])*60);

serving[k]=h;

serving[k]->state=Full;

}

}

void Fuller::Complete(int i)    //i-й погрузчик завершил погрузку

{

int j;

to_rest[i]=rest;               //i-й погрузчик приступил к отдыху

isHeap[i]=0;

to_full[i]=-1;                 //i-й погрузчик временно не  занимается

//погрузкой

serving[i]->state=Full_Move;   //изменяем  состояние загруженного самосвала

//Разыгрываем для загруженного  самосвала время в пути до  пункта разгрузки

serving[i]->to_pfull=(int)(get_normal(serving[i]->direct_ave,  serving[i] -> direct_disp,0.001)*60);

serving[i]=NULL;               //на i-м погрузчике самосвала нет

//Проверяем, все ли погрузчики  освободились

for(j=0;j<volume;j++)

if (isHeap[j]==1) break;

if (j==volume)                 //все освободились, запускаем бульдозер

to_buldoser=(int)(get_erlang(mu,volume,0.001)*60);

}

void Fuller::RestComplete(int i)

{

int k;

to_rest[i]=-1;                 //отдых завершен

if (qLength()==0) return;      //самосвалов нет, делать погрузчику  нечего

if (isHeap[i]==0) return;      //куча земли не готова, делать  погрузчику

//нечего

to_full[i]=(int)(get_exp(perf[i])*60);   //работа есть, разыгрываем время

//погрузки

serving[i]=queue[0];           //ставим на обслуживание первый  самосвал

//из очереди

queue[0]->state=Full;        //изменяем состояние этого самосвала

for(k=0;k<(S-1);k++)           //продвигаем очередь

queue[k]=queue[k+1];

queue[S-1]=NULL;

}

void Fuller::run()

{

if (to_buldoser>0) to_buldoser--;

if (to_buldoser==0) GroundReady();     //бульдозер завершил работу

for(int i=0;i<volume;i++)

{

if (to_full[i]>0) to_full[i]--;

if (to_full[i]==0) Complete(i);       //i-й погрузчик завершил работу

if (to_rest[i]>0) to_rest[i]--;

if (to_rest[i]==0) RestComplete(i);   //i-й погрузчик завершил отдых

}

fprintf(qu1,"%d\n", qLength());        //запись текущей длины очереди

//к погрузчику в файл  и пересчет

//средней длины очереди

//и коэффициента загрузки

//погрузчика

que1_ave=que1_ave*(1-1.0/(total+1))+((float)qLength())/(total+1);

ro_fuller=ro_fuller*(1-1.0/(total+1))+(((float)Busy())/volume)/(total+1);

if (to_buldoser>0) ro_buld++;          //инкремент счетчика загрузки

//бульдозера

}

Emptier::Emptier()

//В начальный момент  времени пункт разгрузки пуст

{

int i;

to_empty=new int[volume];

serving=new HeavyCar *[volume];

queue=new HeavyCar *[S];

for(i=0;i<volume;i++)

{

to_empty[i]=-1;

serving[i]=NULL;

}

for(i=0;i<S;i++)

queue[i]=NULL;

}

Emptier::~Emptier()

{

delete[] to_empty;

delete [] serving;

delete [] queue;

}

void Emptier::Print()

{

int i;

printf("В очереди на  разгрузку - %d самосвалов\n", qLength());

for(i=0;i<S;i++)

{

if (queue[i]==NULL) break;

printf("%d-й в очереди - самосвал № %d\n", i+1, queue[i]->id);

}

for(i=0;i<volume;i++)

{

if (to_empty[i]>0)

printf("%d-й разгрузчик работает. Он обслуживает самосвал № %d. До окончания погрузки %d минут\n",i+1,serving[i]->id,to_empty[i]/60);

else printf("%d-й разгрузчик  простаивает.\n",i+1);

}

return;

}

int Emptier::qLength()

{

int i;

for(i=0;i<S;i++)

if (queue[i]==NULL) return(i);

return(S);

}

int Emptier::Busy()

{

int k=0;

for(int i=0;i<volume;i++)

if (to_empty[i]>0) k++;

return(k);

}

int Emptier::FirstAvail()

{

for(int i=0;i<volume;i++)

if (to_empty[i]==-1) return(i);

return(-1);

}

 

void Emptier::Arrival(HeavyCar *h)   //прибытие самосвала

{

int k, p;

k=FirstAvail();                     //какой разгрузчик свободен?

if (k==-1)                          //свободного разгрузчика нет

{

p=qLength();

queue[p]=h;

queue[p]->state=Que_Emptier;

}

else                                //свободный разгрузчик есть

{

to_empty[k]=border1+rand()%(border2-border1+1);

serving[k]=h;

serving[k]->state=Empty;

}

}

void Emptier::Complete(int i)        //i-й разгрузчик завершил разгрузку

{

int j;

serving[i]->state=Empty_Move;       //меняем состояние разгруженного

//самосвала

//Вычисляем для него  время в пути до пункта погрузки

serving[i]->to_pempty=(int)(get_normal(serving[i]->back_ave, serving[i]->back_disp,0.001)*60);

if (qLength()==0)                   //очередь пуста

{

to_empty[i]=-1;

serving[i]=NULL;

}

else                                //очередь не пуста, ставим первый

//самосвал на разгрузку, меняем его

//состояние и продвигаем  очередь

{

to_empty[i]=border1+rand()%(border2-border1+1);

serving[i]=queue[0];

serving[i]->state=Empty;

for(j=0;j<(S-1);j++)

queue[j]=queue[j+1];

queue[S-1]=NULL;

}

}

void Emptier::run()

{

for(int i=0;i<volume;i++)

{

if (to_empty[i]>0) to_empty[i]--;

//Разгрузка завершена. Вызываем  метод-обработчик и делаем инкремент

//счетчика разгруженных  самосвалов

if (to_empty[i]==0) {

Complete(i);

completed++;

}

}

//Запись текущей длины  очереди в файл, пересчет средней  длины очереди

//и коэффициента загрузки  разгрузчика

fprintf(qu2,"%d\n", qLength());

que2_ave=que2_ave*(1-1.0/(total+1))+((float)qLength())/(total+1);

ro_emptier=ro_emptier*(1-1.0/(total+1))+(((float)Busy())/volume)/(total+1);

}

 

Функция main():

#define N 28800               //общая длительность моделирования

#include "cod.h"

int main()

{

  int i;

  HeavyCar **masCar;          //массив указателей на самосвалы  и выделение

                              //памяти для него

  masCar=new HeavyCar *[S];

  srand((unsigned)time(0));   //инициализация ГСЧ

//Открытие файлов для  сбора статистики по длинам  очередей

Информация о работе Амкнутая система с неоднородными каналами: моделирование грузовых автоперевозок