Главная      Учебники - Экономика     Лекции по экономической теории - часть 4

 

поиск по сайту            

 

 

 

 

 

 

 

 

 

содержание   ..  492  493  494   ..

 

 

Имитационное моделирование на основании предварительно установленных зависимостей

Имитационное моделирование на основании предварительно установленных зависимостей



2. ПРОГРАММНОЕ РЕШЕНИЕ

Программа имитационного моделирования работы кассового зала написана на языке 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; // Возвратим время до входа след-го клиента

}