Автор работы: Пользователь скрыл имя, 17 Июня 2014 в 23:16, курсовая работа
При исследовании операций часто приходится сталкиваться с системами, предназначенными для многоразового использования при решении однотипных задач. Возникающие при этом процессы получили название процессов обслуживания, а системы – систем массового обслуживания (СМО). Каждая СМО состоит из определенного числа обслуживающих единиц (приборов, устройств, пунктов, станций), которые называются каналами обслуживания. Каналами могут быть линии связи, рабочие точки, вычислительные машины, продавцы и др. По числу каналов СМО подразделяют на одноканальные и многоканальные.
Заявки поступают в СМО обычно не регулярно, а случайно, образуя так называемый случайный поток заявок (требований). Обслуживание заявок также продолжается какое-то случайное время. Случайный характер потока заявок и времени обслуживания приводит к тому, что СМО оказывается загруженной неравномерно: в какие-то периоды времени скапливается очень большое количество заявок (они либо становятся в очередь, либо покидают СМО не обслуженными), в другие же периоды СМО работает с недогрузкой или простаивает.
Введение3
Имитационное моделирование5
Нормальное распределение7
Экспоненциальное распределение7
Распределение Эрланга8
Описание системы9
Модельное время10
Классы и объекты10
Класс HeavyCar12
Класс Fuller13
Класс Emptier13
События и методы14
Листинг программы15
Результат35
Анализ результатов35
Список используемой литературы35
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
находится в очереди на
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(
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,
case 2:
printf("%d-й погрузчик
case 3:
printf("%d-й погрузчик
}
}
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)&
{
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[
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[
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)(
serving[i]=NULL; //на i-м погрузчике самосвала нет
//Проверяем, все ли погрузчики освободились
for(j=0;j<volume;j++)
if (isHeap[j]==1) break;
if (j==volume) //все освободились, запускаем бульдозер
to_buldoser=(int)(get_erlang(
}
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[
//погрузки
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/(
ro_fuller=ro_fuller*(1-1.0/(
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,
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()%(
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)(
if (qLength()==0)
{
to_empty[i]=-1;
serving[i]=NULL;
}
else
//самосвал на разгрузку, меняем его
//состояние и продвигаем очередь
{
to_empty[i]=border1+rand()%(
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/(
ro_emptier=ro_emptier*(1-1.0/(
}
Функция main():
#define N 28800
//общая длительность
#include "cod.h"
int main()
{
int i;
HeavyCar **masCar;
//массив указателей на
//памяти для него
masCar=new HeavyCar *[S];
srand((unsigned)time(0)); //инициализация ГСЧ
//Открытие файлов для сбора статистики по длинам очередей
Информация о работе Амкнутая система с неоднородными каналами: моделирование грузовых автоперевозок