|
Программа имитационного моделирования работы кассового зала написана на языке C с помощью среды разработки Borland C++ 3.1.
Блок-схема имитационного моделирования работы кассового зала
Исходный текст программы состоит из одного файла Kas1.c который содержит реализацию таких функций программы:
– float RND_DIG (void) - Функция возвращающая СЧ в диапазоне [0, 1];
– void massive (void) - Функция выделяющая память под массив времени обслуживания у каждой из касс;
– float _tau(void) - Функция возвращающая время обслуживания у кассы;
– float time_to(void) - Функция определяет время входа следующего клиента. Промежутки между входами распределены по закону Пуассона с параметром lambda;
– void inf (void) - Функция вывода информации пользователю.
РУКОВОДСТВО
пользовател
я
1. Программа имитационного моделирования работы банка расположена по следующему адресу:
A:\Kas1.exe
2. На запрос программы:
«Введите количество касс в кассовом зале ж\\д вокзала:»
Вводим предполагаемое (данное) количество касс обслуживающих клиентов.
3. На запрос программы:
«Введите параметр распределения Пуассона для определения времени между входами пассажиров в зал:»
Вводим lambda – Параметр распределения Пуассона
4. На запрос программы:
«Введите минимальную продолжительность обслуживания у касс»
Вводим tau_min – минимальную продолжительность обслуживания.
4. На запрос программы:
«Введите максимальную продолжительность обслуживания у касс»
Вводим tau_max – максимальную продолжительность обслуживания.
5. На запрос программы:
«Введите время моделирования работы зала(в ч.):»
Вводим hours - время моделирования работы зала.
6. На запрос программы:
«Введите математическое ожидание времени обслуживания у касс:»
Вводим MO - математическое ожидание.
7. На запрос программы:
«Введите среднеквадратическое отклонение времени обслуживания у касс:»
Вводим SKO - среднеквадратическое отклонение.
8. После просмотра результатов, нажмите любую клавишу для завершения работы.
5. Листинг программы
/* Включаемие модули*/
#include<stdio.h> // Функции потокового ввода - вывода
#include<conio.h> // Формирование экракна
#include<math.h> // Математические функции
#include<alloc.h> // Функции по работе с динам. памятью
//Прототипы функций
float RND_DIG( void ); // Ф-я генерирует случ. числа
void inf( void); // Ф-я сообщает о назн-ии программы
void massive( void ); // Ф-я выделяющая память под массив
float _tau( void ); // Расчет времени обсл-я клиента у кассы
float time_to ( void ); // Расчет времени входа пассажира в зал
//Объявление переменных
float
tau_min, // Мин. время обсл-я у касс
tau_max, // Макс. время обсл-я у касс
*tau, // Тек. время обсл-я у касс
current_time, // Тек. время
minutes, // Общ. время работы в минутах
lambda, // Пар-р закона распр-я Пуассона
enter_time_, // Время входа очередного пассажира
MO, // Мат. ожид-е времени обсл-я
SKO, // Среднекв. откл-е времени обсл-я у касс
t_free, // Общ. время простоя касс
t_free_av, // Ср. время простоя
serve_av, // Ср. % обслуж-я пассажиров
refuse_av, // Ср. % отказов в обсл-ии
N0=7836, // 1-й множитель для расчета случ. числа
NI=4792, // 2-й множитель для расчета случ. числа
N, // Прозведение N0 и NI
ND; // Средние 4 цифры из числа N
int
m, // Кол-во касс
i, // Тек. номер кассы
enter, // Кол-во вошедших
hours, // Время работы зала в часах
serve, // Кол-во обслуж-х пассажиров
refuse, // Кол-во необслуж-х пассажиров
stand, // Кол-во стоящих в очереди на момент обслуживания
INDPAS; // Флаг обслуживания пассажиров
// Главная функция программы
void main(void)
{
inf(); // cообщение о назначении программы
textcolor( 14 ); //установка цвета и фона
textbackground( 1 );
clrscr(); //очистка экрана
/* Прием данных от пользователя */
printf("\n████████████████████████████████████████████████████████████████████████████████");
for(i=1;i<=21;i++)
printf("█ █");
printf("████████████████████████████████████████████████████████████████████████████████");
gotoxy(10,7);
do
{
printf("\n█\tВведите количество касс в кассовом"
" зале ж\\д вокзала:");
scanf( "%d", &m );
}
while( (m<=0)||(m>=100) );
do
{
printf( "\n█\tВведите параметр распределения Пуассона для"
" определения" );
printf( "\n█\t\tвремени между входами пассажиров в зал:" );
scanf( "%f", &lambda );
}while( lambda<=0 );
clrscr();
//Вывод рамки
printf("\n████████████████████████████████████████████████████████████████████████████████");
for(i=1;i<=21;i++)
printf("█ █");
printf("████████████████████████████████████████████████████████████████████████████████");
gotoxy(5,3);
do
{
printf( "\n█\n█\tВведите минимальную продолжительность обслуживания " );
printf( "\n█\t\t\tу кассами:" );
scanf( "%f", &tau_min );
}while( tau_min<=0 );
do
{
printf( "\n█\tВведите максимальную продолжительность обслуживания " );
printf( "\n█\t\t\tу касс:" );
scanf( "%f", &tau_max );
}while( tau_max<=tau_min );
do
{
printf( "\n█\tВведите время моделирования работы зала(в ч.):" );
scanf( "%d", &hours );
}while( hours<=0 );
do
{
printf("\n█\tВведите математическое ожидание времени обслуживания");
printf( "\n█\t\tу касс:");
scanf( "%f", &MO );
}while( MO<=0 );
do
{
printf( "\n█\tВведите среднеквадратическое отклонение времени ");
printf( "\n█\tобслуживания у касс:");
scanf( "%f", &SKO );
}while( SKO<=0 );
massive(); // создание и обнуление массива
minutes=floor( hours*60 ); // переведем время работы в минуты
enter=0; // никто не входил
serve=0; // никого не обслужили
refuse=0; // никому не отказали
t_free=0; // кассы еще не простаивали
current_time=0; // начало отсчета времени с нуля
enter_time_=time_to(); // когда зайдет следующий
/* Цикл моделирования работы зала
for( current_time=0; current_time<=minutes; current_time++ )
{
/* Коррект-ка времени обсл-я у каждой кассы */
if( current_time )
for( i=1; i<=m ;i++)
if( tau[i] ) //Если касса занята, то уменьшим время обсл-я
tau[i]--; // в ней на 1 мин.
else // Если касса свободна, наращиваем общее время
t_free++; // простоя касс.
if( enter_time_<=current_time )
{
enter++; // Если входит пассажир, отмечаем это
enter_time_=time_to(); // Узнаем, когда зайдет следующий?
i=1; // Вошедший подходит к 1-й кассе
INDPAS=1; // Его еще не обслуживают
do
{
if( tau[i]<=0 ) //Если касса свободна, ставим пассажира на
{ //обсл-е и узнаем, сколько ему стоять у кассы
tau[i]=_tau();
INDPAS=0; //Укажем, что пассажира обслуживают
}
i++; // Подходим к следующей кассе
}while((i<=m) && (INDPAS==1));
if( INDPAS==1 ) // Если клиент не обслужен, отмечаем это
refuse++;
if( INDPAS==0) // Если клиент обслужен, отмечаем это
serve++;
}
}
stand=0; // Пока в очереди никто не стоит
i=1; // Начинаем с первой кассы
do
{
if( tau[i]>0 ) // Если время обсл-я не равно нулю, значит
stand++; // у кассы кто-то стоит
i++; // Смотрим у следующей кассы
}while( i<=m );
serve-=stand; // Корректируем кол-во обслуженных
t_free_av=(float)t_free/m; // Вычислим ср. время простоя
serve_av=(float)serve/enter; // Вычислим ср. % обслуженных
refuse_av=(float)refuse/enter; // Вычислим ср. % необслуженных
textcolor(1); // Установка параметров текста
textbackground(2);
clrscr();
_setcursortype( _NOCURSOR );
/*Вывод полученных результатов
//Вывод рамки
printf("\n████████████████████████████████████████████████████████████████████████████████");
for(i=1;i<=21;i++)
printf("█ █");
printf("████████████████████████████████████████████████████████████████████████████████");
gotoxy(3,3);
printf( "\n█\n█\t╔════════════════════════════════════════════════════════════╗ ");
printf(" \n█\t║ %d железнодорожных касс работало на протяжении: %d часов.",m,hours );
gotoxy(70,6);
printf("║");
printf(" \n█\t║ В зал зашло %d посетителей.", enter );
gotoxy(70,7);
printf("║");
printf(" \n█\t║");
gotoxy(70,8);
printf("║");
printf(" \n█\t║\n█\t║ Было обслужено %d человек(а).", serve);
gotoxy(70,9);
printf("║");
printf(" \n█\n█\t║ Ушли необслуженными %d человек(а).", refuse);
gotoxy(70,10);
printf("║");
printf(" \n█\n█\t║ В очереди осталось стоять %d человек(а). ", stand);
gotoxy(70,11);
printf("║");
printf(" \n█\n█\t║ Средний процент обслуживания пассажиров %.2f%%", serve_av*100);
gotoxy(70,12);
printf("║");
printf(" \n█\n█\t║ Средний процент отказов в обслуживании %.2f%%", refuse_av*100);
gotoxy(70,13);
printf("║");
printf(" \n█\n█\t║ Всего кассы простаивали: %.0fч. %.0f мин. ",floor( t_free/60 ),
t_free-floor( t_free/60 )*60 );
gotoxy(70,14);
printf("║");
printf(" \n█\n█\t║ Среднее время простоя 1 кассы: %.0fч. %.0f мин.",
floor( t_free_av/60 ), t_free_av-floor( t_free_av/60 )*60);
gotoxy(70,15);
printf("║");
gotoxy(70,16);
printf("║");
printf(" \n█\t╚════════════════════════════════════════════════════════════╝ ");
getch();
}
//Функция возвращающая СЧ в диапазоне от 0 до 1
float RND_DIG (void)
{
float
x; //СЧ в диапазоне от 0 до 1
N=(NI*N0);
ND=floor(N/100);
ND=(ND/10000-floor(ND/10000))*10000; // Отбросим первые 2 цифры
N0=NI;
NI=ND;
x=ND/9999;
return x;
}
//Ф-я выделяет память под массив времени обсл-я у каждой из касс
void massive( void )
{
int i;
tau=(float *)malloc( (m+1)*sizeof(float) );
/* Обнуление элементов массива */
for(i=1; i<=m; i++)
tau[i]=0;
}
// Ф-я возвр. время обсл-я у кассы
float _tau( void )
{
float
x, // Случайное число x
y, // Случайное число y
z, // Случайное число z
tau_; // Время обслуживания
// Проверка на четность
//---------------------
if( floor ( ( float )i/2 )==ceil( ( float )i/2 ) )
{
x=RND_DIG(); // Запрос случ. числа от ДСЧ
y=RND_DIG(); // Запрос случ. числа от ДСЧ
if( x>=.0001) // Если х не слишком маленькое, считаем z
z=sqrt( -2*log( x ) )*sin( 2*M_PI*y );
else
{
if( sin( 2*M_PI*y )<=0 )
z=0; // Если оба множителя слишком малы, то z=0
else
z=(float)minutes/2; //Если 2-й множ-ль нормальный, то
} //вел-на z равна половине времени работы зала.
tau_=MO+z*SKO; // Вычислим нормально распределенное время обсл-я
if( tau_<0 ) // Если время отрицательно, оно равно 1 мин.
tau_=1;
}
else
{
x=RND_DIG(); // Запрос случ. величины от ДСЧ
/* Вычислим равномерно распределенное время обсл-я */
//--------------------------------------------------
tau_=floor( tau_min+x*( tau_max-tau_min )+.5);
}
return floor( tau_+.5 ); //Выведем в место запроса
}
// Ф-я определяет время входа след-го клиента. Промежутки
// между входами распределены по закону Пуассона с пар-м lambda
// ============================================================
float time_to( void )
{
int
j; // Пар-р закона распр-я Пуассона
float
x, // Случ. вел-на
tau, // Время до входа
a, // Пар-р закона распр-я
n, // Половина общего времени работы
S; // Пар-р закона распр-я
n=floor( minutes/2+0.5 );
x=RND_DIG(); // Примем случ. число
tau=0;
j=0;
a=exp( (lambda * (-1)) ); // Расчет нач. знач-я пар-ра а
S=0;
do
{
if( S>=x && x<S+a ) // Проверка х на пренадл-ть промежутку [S ; S+a)
break;
tau++;
j++;
S+=a;
a*=lambda/j;
}
while( tau<=n );
return current_time+tau; // Возвратим время до входа след-го клиента
}