Моделирование работы системы и определение ее оптимальной структуры

 

ФГОУ СПО «Волгоградский технологический коледж»












Курсовой проект


Моделирование работы порта



Разработчик А.И. Сухинин

Рук. проекта А.А. Теткин


Введение


Описание реальных отношений между экономическими объектами и производственными процессами наиболее рационально и в полной мере осуществляется с помощью моделей имитационного типа.

Термин имитационное моделирование означает, что речь идет о моделях с помощью, которых нельзя вычислить или предсказать результат и поэтому с их помощью проводиться вычислительный эксперимент при заданных исходных данных. Метод имитационного моделирования дает возможность широкого использования математического аппарата и вычислительной техники для исследования хода экономических и производственных процессов . Таким образом, сущность имитационного моделирования состоит в том, что с помощью ЭВМ воспроизводится поведение исследуемой системы, а исследователь, управляя ходом процесса и анализируя получаемые результаты, делает выводы о ее свойствах и качестве поведения. Поэтому под имитацией следует понимать численный метод проведения на ЭВМ экспериментов с алгоритмами, описывающими поведение системы и определения интересующих нас функциональных характеристик. Имитационное моделирование является экспериментальной и прикладной методологией, имеющей целью:

·эти теории для предсказания будущего поведения системы, т.е. тех воздействий, которые могут быть вызваны изменениями в системе или изменениями способов ее функционирования.

Целью данной курсовой работы является разработка имитационной модели очереди с разнотипными заявками т.е модели работы порта. Основой для разработки модели в данной курсовой работе является метод имитационного моделирования. Так же курсовая работа предполагает создание программы на языке C++, обеспечивающей ввод исходной информации, ее обработку, реализацию алгоритма имитации процесса и выдачу необходимой информации.

1. Имитационное моделирование


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

Имитационное моделирование - это метод исследования, при котором изучаемая система заменяется моделью, с достаточной точностью описывающей реальную систему и с ней проводятся эксперименты с целью получения информации об этой системе. Экспериментирование с моделью называют имитацией (имитация - это постижение сути явления, не прибегая к экспериментам на реальном объекте).

Имитационное моделирование - это частный случай математического моделирования. Существует класс объектов, для которых по различным причинам не разработаны аналитические модели, либо не разработаны методы решения полученной модели. В этом случае математическая модель заменяется имитатором или имитационной моделью.

Имитационным моделированием иногда называют получение частных численных решений сформулированной задачи на основе аналитических решений или с помощью численных методов.

Имитационная модель - логико-математическое описание объекта, которое может быть использовано для экспериментирования на компьютере в целях проектирования, анализа и оценки функционирования объекта.

Возникновение теории управления запасами можно связать с работами Ф.Эджуорта и Ф. Харриса, появившимися в конце XIX - начале XX вв., в которых исследовалась простая оптимизационная модель определении экономичного размера партии поставки для складской системы с постоянным равномерным расходом и периодическим поступлением хранимого продукта.

Запасами называется любой ресурс на складе, который используется для удовлетворения будущих нужд. Примерами запасов могут служить полуфабрикаты, готовые изделия, материалы, различные товары, а также такие специфические товары, как денежная наличность, находящаяся в хранилище. Большинство организаций имеют примерно один тип системы планирования и контроля запасов. В банке используются методы контроля за количеством наличности, в больнице применяются методы контроля поставки различных медицинских препаратов.

К имитационному моделированию прибегают, когда:

·дорого или невозможно экспериментировать на реальном объекте;

·невозможно построить аналитическую модель: в системе есть время, причинные связи, последствие, нелинейности, стохастические (случайные) переменные;

·необходимо сымитировать поведение системы во времени.

Цель имитационного моделирования состоит в воспроизведении поведения исследуемой системы на основе результатов анализа наиболее существенных взаимосвязей между ее элементами или другими словами - разработке симулятора (англ. simulation modeling) исследуемой предметной области для проведения различных экспериментов.

Имитационное моделирование позволяет имитировать поведение системы во времени. Причём плюсом является то, что временем в модели можно управлять: замедлять в случае с быстропротекающими процессами и ускорять для моделирования систем с медленной изменчивостью. Можно имитировать поведение тех объектов, реальные эксперименты с которыми дороги, невозможны или опасны. С наступлением эпохи персональных компьютеров производство сложных и уникальных изделий, как правило, сопровождается компьютерным трёхмерным имитационным моделированием.

2. Теория массового обслуживания


Предметом теории массового обслуживания является количественная сторона процессов, связанных с массовым обслуживанием.

Целью теории является разработка математических методов отыскания основных характеристик процессов массового обслуживания, для оценки качества функционирования обслуживающей системы.

Последовательность событий условно обозначим потоком. Поток, состоящий из требований на обслуживание, будет являться потоком требований.

Поток требований, нуждающихся в обслуживании и поступающих в обслуживающую систему, называется входящим потоком. Поток требований, покидающих обслуживающую систему, называется выходящим потоком.

Задачей теории массового обслуживания является отыскание функциональных зависимостей величин, характеризующих качество функционирования обслуживающей системы, от характеристик входящего потока, параметров, характеризующих возможности одного обслуживающего аппарата, и способов организации всей обслуживающей системы в целом. Качество функционирования системы существенно зависит от того, как организовано управление процессом обслуживания, поэтому задача отыскания количественных характеристик организации управления является очень важной.

В области промышленного производства приходится очень часто сталкиваться с задачами массового обслуживания. Так, например, массовое обслуживание имеет место при обеспечении заводами-поставщиками и фабриками предприятий-потребителей и торговой сети своей продукцией. Обеспечение производства сырьем также носит характер массового обслуживания.

Организация взаимодействия между цехами в пределах предприятия представляет собой пример задач того же типа, только на более низкой ступени. В масштабах цеха теория массового обслуживания начинается со снабжения цеха сырьем и заканчивается организацией обслуживания и ремонта станков.

Большое количество проблем, связанных с массовым обслуживанием, должно быть решено при производственном планировании. В этом случае затраты усилий на детальное изучение количественной стороны процессов планирования даст большой экономический эффект и позволит более глубоко проникнуться в природу этих процессов.

Немалую пользу может оказать теория массового обслуживания на стадии технического проектирования. При проектировании весьма важным является вопрос о загруженности оборудования. Так, еще в процессе технического проектирования необходимо определить нужное количество оборудования и его мощность исходя из объемов работ, которые должны выполняться при помощи этого оборудования. При решении этой задачи необходимо учитывать такие случайные факторы, как время обслуживания, выход из строя отдельных устройств за счет поломок и время, требуемое для их устранения, а также ряд факторов, от которых будет зависеть эксплуатация этого проектируемого оборудования.

Использование методов теории может помочь также при осуществлении выбора лучшего, наиболее экономичного проекта из нескольких возможных.

Теория массового обслуживания поможет правильно организовать производство с целью наибольшего удовлетворения потребителей продукцией предприятия, являющейся выходящим потоком. Выяснение приоритетов потребителей должно осуществляться маркетинговыми службами с помощью анкетирования и опросов.

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


3. Описание системы


В африканском порту танкеры загружаются сырой нефтью, которую затем морским путем доставляют по назначению. Мощности порта позволяют загружать на более трех танкеров одновременно. Танкеры, прибывающие в порт через каждые 11 ± 7 ч, относятся к трем различным типам. Относительная частота появления танкеров данного типа и время, требуемое на их погрузку, приведены в табл. 1. Относительную частоту следует понимать как вероятность того, что прибывший танкер относится к данному типу.


Таблица 1. Характеристики типов танкеров

ТипОтносительная частотаВремя погрузки, ч10,2518 ±220,5524 ±330,2036 ± 4

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

Судовладелец предлагает дирекции порта заключить контракт на перевозку нефти в Великобританию и обеспечить выполнение условий контракта с помощью 5 танкеров особого, четвертого типа, для погрузки которых требуется 21 ± 3 ч. После погрузки танкер отчаливает и следует в Великобританию, там разгружается и затем снова возвращается в африканский порт для погрузки. Время цикла обращения танкера, включая время разгрузки, составляет 240 ± 24 ч. Фактором, осложняющим перевозку нефти, являются штормы, которым подвергается порт. Интервал времени между штормами распределен экспоненциально с математическим ожиданием 48 ч, причем шторм продолжается 4 ± 2 ч. Во время шторма буксир не работает.

Перед заключением контракта руководство порта решило определить влияние, которое окажут пять дополнительных танкеров на функционирование порта. Выводы предлагается сделать по результатам имитации работы порта в течение одного года (8760 ч) при условии заключения предлагаемого контракта Оцениваемые величины - время пребывания в порту дополнительных танкеров и уже работающих танкеров трех типов.


3.1 Модельное время


За единицу модельного времени примем 1 мин, чтобы не связывать себя маловероятным предположением, что все события занимают промежутки времени, кратные одному часу. Интервал времени между штормами будем генерировать так


(int)(get_exp(mu)*60)


где mu = 1/48 = 0,021. Для генерации равномерного рас- пределения (для интервалов между прибытиями танкеров, времени погрузки и цикла обращения) будем использовать функцию getuniform( ), которая разыгрывает абсолютное значение отклонения от среднего, а затем с вероятностью 0,5 прибавляет его к среднему либо вычитает из него. Этот способ позволяет уменьшить в два раза значение делителя при взятии остатка, а значит, снизить ошибку, возникающую из-за того, что 32 768 не делится нацело на этот делитель.


3.2 Классы и объекты


Продолжаем наращивать арсенал приемов, используемых для объектного представления динамических систем. Рассмотрим особенности поставленной задачи:

·Буксир имеет две разных очереди на обслуживание - на причаливание и на отчаливание. Заявки из очереди на отчаливание обслуживаются только в том случае, если очередь на причаливание пуста.

·Система соединяет в себе свойства как открытой, так и замкнутой. Количество заявок первых трех типов является переменной неограниченной величиной, так как они поступают из внешнего входного потока и, будучи обслуженными, покидают систему, после чего их дальнейшая судьба не отслеживается. Количество же заявок дополнительного, четвертого типа является постоянным, каждая из них периодически возвращается на обслуживание в систему, и за ними нужно продолжать следить в промежутках между периодами обслуживания (путешествие из Африки в Великобританию на разгрузку нефти и обратно). В связи с этим заявки первых трех типов будем называть неименованными, а заявки четвертого типа - именованными.

Три типа неименованных заявок, разумеется, можно описать одним классом, так как они различаются только значениями своих неизменяемых полей данных - частотой встречаемости и временем обслуживания. Так как неименованные заявки постоянно находятся под контролем некоторого обслуживающего устройства - буксира или порта, - метод run( ) для них не нужен, их постоянко будут «вести» другие объекты, а после выхода из порта они как объекты перестают существовать. В противоположность этому именованные заявки после выхода из порта пускаются «в самостоятельное плавание», продолжая существовать в качестве полноправных объектов системы. В это время они сами должны следить за собой и в конце концов зафиксировать момент следующего прибытия на погрузку. Очень показательна разница между механизмами фиксации прибытия неименованных и именованных заявок. Неименованные заявки поступают из случайного входного потока, поэтому время их прибытия разыгрывается с помощью ГСЧ, а само событие инициируется принимающей стороной - буксиром.

Прибытие же именованной заявки буксиром не разыгрывается - она сама дает знать о прибытии в порт, посылая буксиру соответствующее сообщение.

Указанные различия в поведении говорят о том, что неименованные и именованные заявки одним классом представлять нельзя, так как эти различия являються существенными. Для отображения поведения именованной заявки нам понадо-бятся и дополнительные поля данных, идополнительные методы. Но и описывать их совершенно разными классами тоже нехорошо. Дело в том, что после причаливания как те, так и другие заявки будут находиться в общей очереди на погрузку. Но если в очереди будут заявки разных классов, какой же тогда класс подставлять в шаблон в качестве значения параметра, коим как раз и является имя класса? Получается, что и один класс, и два разных класса - неудовлетворительные решения.

Ответ приходит сам собой - конечно же, следует применить наследование. Внимательное изучение того, что происходит в системе и что нужно отразить в программе, позволяет сделать вывод, что все поля данных и методы неименованных заявок покрываются именованными, последние же расширяются некоторым множеством дополнительных полей и методов, например run( ), а некоторые ме- тоды переопределяются (например, count()). Поэтому базовым классом будет класс неименованных заявок, а производным от него расширенный класс именованных заявок. Проблема с «разнотипностью элементов» списка тоже решается наилучшим образом. Напомним, что в качестве данных в элементе списка выступает не сам объект, а указатель на него, поэтому в качестве параметра шаблона можно задать имя базового класса - неименованных заявок.

По принципу подстановки указатель на объект производного класса является и указателем на объект базового класса, поэтому указатель на именованную заявку - объект производного класса - можно смело заносить в элемент списка.

Конкретизируем рассуждения, перечислив поля базового класса Tanker и производного класса Tanker4.


3.2.1 Класс Tanker

Неизменяемые поля данных:

·уникальный идентификатор объекта; можно назначить равным текущему значению счетчика прибытий;

·тип танкера (1, 2 или 3);

·среднее значение времени обслуживания на погрузке;

·максимальное отклонение от среднего значения.

Изменяемые поля данных:

·Время, проведенное в системе на текущий момент, начиная от постановки в очередь к буксиру на причаливание;

·код текущего состояния (1 - в очереди на причаливание, штормит; 2 - в очереди на причаливание, шторма нет, 3 - причаливание; 4 - в очереди на погрузку; 5 - погрузка; 6 - в очереди на отчаливание, штомит; 7 в очередина отчаливание, шторма нет; 8 - отчаливание).


3.2.2 Производный класс Tanker4

Неизменяемые поля данных:

·среднее значение времени в пути на разгрузку и обратно (14 400 мин);

·максимальное отклонение от среднего значения (1440 мин);

·связь с объектом Буксир для посылки ему сообщения о своем прибытии.

Изменяемые поля данных:

·добавляется еще одно возможное значение кода текущего состояния: 9 - в пути на разгрузку или обратно;

·время до прибьргия на причаливание; поле данных имеет смысл лишь для состояния 9.

По аналогии с предыдущими задачами буксир и порт должны быть объявлены «друзьями» танкера. Интересный нюанс заключается в том, что дружественность нужно отдельно объявить и в производном классе Тапкег4, так как по правилам С++ она не наследуется.

Довольно много полей данных приходится вводить для класса Буксир (Tug). Это связано с тем, что буксир является связующим звеном между танкерами и портом, а кроме того следует учитывать еще и влияние штормов.


3.2.3 Класс Tug

Неизменяемые поля данных:

·среднее значение интервала времени между прибытиями танкеров первых трех типов (660 мин);

·максимальное отклонение от среднего значения (420 мин);

·длительность причаливания и отчаливания (60 мин);

·средняя продолжительность шторма (240 мин);

·максимальное отклонение от среднего значения (120 мин);

·параметр экспоненциального распределения для интервала времени между штормами (0,021);

·указатель на объект класса Port для взаимодействия с ним.
Изменяемые поля данных:
·время до следующего прибытия танкера одного из трех типов;

·время до окончания причаливания;

·время до окончания отчаливания;

·очередь танкеров на причаливание;

·очередь танкеров на отчаливание;

·причаливающий (отчаливающий) танкер;

·текущая длина очереди на причаливание (вычисляемое поле);

·текущая длина очереди на отчаливание (вычисляемое поле);

·время до начала следующего шторма;

·время до окончания шторма.


3.2.4 Класс Port

Класс Port моделируется как обычный многоканальный узел обслуживания с общей очередью.

Неизменяемые поля:

·количество терминалов для погрузки (3);

·указатель на объект класса Tug.

Изменяемые поля:

·очередь танкеров на погрузку;

·массив указателей на обслуживаемые в данный момент танкеры;

·массив значений времени, оставшегося до окончания погрузки на каждом из терминалов;

·текущая длина очереди (вычисляемое поле).


3.3 События и методы


Танкеры выполняют в системе роль заявок, поэтому они не имеют моделирующих методов - все события, происходящие с ними, принимаются и обрабатываются объектами-серверами. Для буксира можно выделить следующие события и связанные с ними методы:

1.Начало шторма. Метод не имеет параметров.

2.Окончание шторма. Метод не имеет параметров.

3.Прибытие танкера четвертого типа на причаливание. Метод имеет параметр - указатель на прибывший танкер.

4.Прибытие танкера одного из первых трех типов на причаливание. Метод не имеет параметров.

5.Один из танкеров закончил погрузку и требует отчаливания. Метод имеет параметр - указатель на танкер.

6.Окончание отчаливания. Метод не имеет параметров, так как отчаливший танкер доступен через поле данных самого буксира.

.Окончание причаливания. Метод не имеет параметров, так как причаливший танкер доступен через поле данных самого буксира.

Коротко остановимся на особенностях некоторых методов. Методы 3 и 4 описывают одно и то же событие, но их алгоритмические реализации различаются по причине уже упоминавшегося существования различий между именованными и неименованными заявками. В методе 4 необходимо создать новый временный объект базового класса Tanker и разыграть время до прибытия следующего танкера. В методе 3 этого делать не нужно, так как прибывший объект уже существует в системе и доступ к нему мы получаем через передаваемый параметр. Эти два метода могут иметь одно название, что допускается правилами С++, так как их сигнатуры различаются. Конечно, методы 3 и 4 можно было бы объединить и в один, передавая в одном из случаев NULL-указатель и осуществляя внутри соответствующую проверку параметра. Но такой подход скрывал бы принципиальные различия между обработкой двух вариантов прибытия танкеров, которые здесь, наоборот, хотелось бы подчеркнуть. В методе 5 в качестве параметра может быть передан указатель на танкер любого типа - как указатель на объект базового класса. Отметим, что финальной частью методов 2, 6 и 7 является одно и то же действие - выбор в одной из очередей первого танкера и постановка его на обслуживание. Этот общий фрагмент кода для исключения повторений удобно выделить в отдельный метод, который мы назвали choice.

Для объекта Port событий всего два:

·прибытие очередного танкера. Метод имеет один параметр - указатель на прибывший танкер - и вызывается буксиром из метода 7;

·завершение погрузки. Метод имеет один параметр - номер терминала, который завершил погрузку, - и вызывает метод 5 для буксира.

4. Программная реализация алгоритма


При создания имитационной модели очереди с разнотипными заявками (работа порта) был выбран язык программирования C++ и написана программа на этом языке, позволяющая в полной мере отразить функционирование системы.

алгоритм имитация заявка порт модель

Листинг программы файл 6.h. Описание протоколов классов


#include<cstdio>

#include<cstdlib>

#include<ctime>

#include<cmath>namespace std;

#include "List.h"

#include "random.h"*q_tugIn; //файл для сбора статистики о длине очереди

//на причаливание*q_tugOut; //файл для сбора статистики о длине очереди

//на отчаливание*q_loading; //файл для сбора статистики о длине очереди

//на погрузку*sojourn; //файл для сбора статистики о времени пребывания

//в портуq_tugInAve=0; //переменная для подсчета средней длины очереди

//на причаливаниеq_tugOutAve=0; //переменная для подсчета средней длины очереди

//на отчаливаниеq_loadAve=0; //переменная для подсчета средней длины очереди

//на погрузкуsoj_Ave=0; //переменная для подсчета среднего времени

//пребывания на погрузкеsoj1_Ave=0; //переменная для подсчета среднего времени

//пребывания на погрузке для танкеров первых

//трех типовsoj2_Ave=0; //переменная для подсчета среднего времени

//пребывания на погрузке для танкеров

//четвертого типаint ro_tug=0L; //переменная для подсчета загрузки буксираro_port=0; //переменная для подсчета загрузки портаint entered=0L; //счетчик общего числа поступленийint completed=0L; //счетчик отчаливших танкеровint completed1=0L; //счетчик отчаливших танкеров первых трех типовint completed2=0L; //счетчик отчаливших танкеров четвертого типаint total; //счетчик тактов модельного времени

//базовый классTanker{:int id; //идентификатор танкераtype; //номер типаmedian; //среднее время погрузкиoffset; //максимальное отклонениеminutes; //текущее время пребывания на погрузкеstate; //текущее состояниеclass Tug;class Port;(); //конструктор

//Метод Print() удобно объявить виртуальным, например, для обхода любой из //очередей и распечатки ее содержимого, так как в очереди могут находиться //танкеры любого типаvoid Print();

};

//Производный классTanker4: public Tanker{static int median_path=14400; //14400 минут=240 часов - среднее

//время обращения танкера четвертого

//типаstatic int offset_path=1440; //24 часа - максимальное отклонение

//от среднего для времени обращения

//танкера четвертого типаto_arrival; //время до прибытия пустого танкера на причаливание*t; //связь с буксиром:class Tug;class Port;(int i);putTug(Tug *a);run();//диспетчерvoid Print();

};

//Класс БуксирTug{static int arr_median=660; //660 минут=11 часов - среднее время между //прибытиями танкеров первых трех типовstatic int arr_offset=420; //7 часов - максимальное отклонение

//от среднего для интервалов между

//прибытиями танкеров первых трех типовstatic int time_path=60; //1 час - длительность причаливания

//и отчаливанияstatic int storm_median=240; //4 часа - средняя длительность штормаstatic int storm_offset=120; //2 часа - максимальное отклонение

//от среднего для длительности штормаstatic int storm_mu=21; //1/48, где 48 часов - средняя

//длительность "бесштормового"

//интервала времениto_arrival; //время до прибытия танкера типов 1,2,3to_in; //время до окончания причаливанияto_out; //время до окончания отчаливания<Tanker> *queue_in; //очередь на причаливание<Tanker> *queue_out; //очередь на отчаливание*serving; //обслуживаемый танкерque_inLength; //длина очереди на причаливаниеque_outLength; //длина очереди на отчаливаниеto_sStart; //время до начала штормаto_sEnd; //время до окончания шторма*p; //указатель на порт:();stormStart(); //начало штормаstormEnd(); //окончание штормаArrival_Sea(Tanker4 *t); //прибытие танкера четвертого типаArrival_Sea(); //прибытие танкера типов 1,2,3Arrival_coast(Tanker *t); //танкер требует отчаливанияDeparture(); //окончание отчаливанияArrival(); //окончание причаливанияrun(); //диспетчерputPort(Port *a);choice(); //выбор танкера для обслуживанияPrint();

};

//Класс ПортPort{static int volume=3;<Tanker> *queue; //очередь на погрузку**serving; //загружаемые танкеры*to_serve; //время до окончания погрузкиq_length; //длина очереди*t; //указатель на буксир:();

~Port();Arrival(Tanker *a); //прибытие танкераComplete(int i); //завершение погрузкиputTug(Tug *a);Print();FirstAvail();Busy();run(); //диспетчер

};::Tanker(){r;=entered;=0;

//Разыгрывание типа танкера=rand()%100+1;(r>=25) type=1;if (r<=55) type=2;type=3;(type){1: median=1080; offset=120; break;2: median=1440; offset=180; break;3: median=2160; offset=240; break;

}

}Tanker::Print(){(state){1: printf("Танкер № %ld типа %d находится в очереди на причаливание. Штормит\n", id, type); break;2: printf("Танкер № %ld типа %d находится в очереди на причаливание. Шторма нет\n", id, type); break;3: printf("Танкер № %ld типа %d причаливает\n", id, type); break;4: printf("Танкер № %ld типа %d находится в порту в очереди на погрузку\n", id, type); break;5: printf("Танкер № %ld типа %d грузится в порту\n", id, type); break;6: printf("Танкер № %ld типа %d находится в очереди на отчаливание. Штормит\n", id, type); break;7: printf("Танкер № %ld типа %d находится в очереди на отчаливание. Шторма нет\n", id, type); break;8: printf("Танкер № %ld типа %d отчаливает\n", id, type); break;

}

}

//Начальное состояние танкера четвертого типа - 9::Tanker4(int i){=i;=0;=9;=4;_arrival=get_uniform(median_path, offset_path);=1260;=180;

}Tanker4::putTug(Tug *a){=a;

}Tanker4::Print(){(state){1: printf("Танкер № %ld типа %d находится в очереди на причаливание. Штормит\n", id, type); break;2: printf("Танкер № %ld типа %d находится в очереди на причаливание. Шторма нет\n", id, type); break;3: printf("Танкер № %ld типа %d причаливает\n", id, type); break;4: printf("Танкер № %ld типа %d находится в порту в очереди на погрузку\n", id, type); break;5: printf("Танкер № %ld типа %d грузится в порту\n", id, type); break;6: printf("Танкер № %ld типа %d находится в очереди на отчаливание. Штормит\n", id, type); break;7: printf("Танкер № %ld типа %d находится в очереди на отчаливание. Шторма нет\n", id, type); break;8: printf("Танкер № %ld типа %d отчаливает\n", id, type); break;9: printf("Танкер № %ld типа %d находится в пути\n", id, type); break;

}

}Tanker4::run()

{(state==9) to_arrival--;

//Танкер прибыл из Великобритании и сообщает об этом буксиру(to_arrival==0) ((Tug*)t)->Arrival_Sea(this);

}

//В начальном состоянии буксир свободен, очереди пусты::Tug(){_arrival=get_uniform(arr_median, arr_offset);=NULL;_in=-1;_out=-1;_in=NULL;_out=NULL;_inLength=0;_outLength=0;_sStart=(int)(get_exp((float)(storm_mu/1000))*60);(to_sStart==0) to_sStart=1;_sEnd=-1;

}Tug::choice(){

//Очередь на причаливание не пуста, ей - приоритет(que_inLength>0){_in=time_path;_inLength--;=queue_in->Data(); //голову очереди - на обслуживание_in=queue_in->Next(); //продвижение очереди

}

//Заявок на причаливание нет, а на отчаливание - естьif (que_outLength>0){_out=time_path;_outLength--;=queue_out->Data();_out=queue_out->Next();

};

}

Tug::stormStart(){_sStart=-1;_sEnd=get_uniform(storm_median, storm_offset);

}

Tug::stormEnd(){_sEnd=-1;_sStart=(int)(get_exp((float)(storm_mu/1000))*60);(to_sStart==0) to_sStart=1;();

}Tug::Arrival_Sea() //прибытие танкера типов 1,2,3

{_arrival=get_uniform(arr_median, arr_offset);++;*ptr=new Tanker(); //создаем новый танкер

//Шторма нет, буксир свободен, танкер сразу идет на причаливание((to_sEnd==-1)&&(serving==NULL)){=ptr;_in=time_path;>state=3;;

}

//Танкер ставится в очередь_inLength++;<Tanker> *ptr1=new ListNode<Tanker>(ptr, NULL);(queue_in==NULL) queue_in=ptr1;ListAdd<Tanker>(queue_in, ptr1);

//Назначение танкеру номера состояния в зависимости от наличия шторма(to_sEnd>0) ptr->state=1;ptr->state=2;;

}Tug::Arrival_Sea(Tanker4 *t){++;>to_arrival=-1;((to_sEnd==-1)&&(serving==NULL)){=t;_in=time_path;>state=3;;

}_inLength++;<Tanker> *ptr1=new ListNode<Tanker>(t, NULL);(queue_in==NULL) queue_in=ptr1;ListAdd<Tanker>(queue_in, ptr1);(to_sEnd>0) t->state=1;t->state=2;;

}Tug::Arrival_coast(Tanker *t) //прибытие танкера на отчаливание

{((to_sEnd==-1)&&(serving==NULL)) //шторма нет, буксир свободен

{=t;_out=time_path;>state=8;;

}_outLength++;<Tanker> *ptr1=new ListNode<Tanker>(t, NULL);(queue_out==NULL) queue_out=ptr1;ListAdd<Tanker>(queue_out, ptr1);(to_sEnd>0) t->state=6;t->state=7;;

}Tug::Departure(){_out=-1;

//Фиксация времени пребывания в порту отбывающего танкера(sojourn,"%.3f\n", (float)serving->minutes/60);++;

//Пересчет среднего времени пребывания_Ave=soj_Ave*(1-1.0/completed)+(float)(serving->minutes)/completed;

//Отбывает танкер типов 1,2,3(serving->type<4){++;_Ave=soj1_Ave*(1-1.0/completed1)+(float)(serving->minutes)/completed1;

//Объект для неименованной заявки удаляется из системыserving;

}//отбывает танкер четвертого типа

{++;_Ave=soj2_Ave*(1-1.0/completed2)+(float)(serving->minutes)/completed2;>state=9;

//Отправляем танкер четвертого типа в Великобританию

((Tanker4*)serving)->to_arrival=get_uniform(((Tanker4*)serving)->median_path, ((Tanker4*)serving)->offset_path);

//Сброс времени пребывания в порту>minutes=0;

}=NULL;

//Пока отчаливали, начался шторм. Буксир отдыхает(to_sEnd>0) return;

//Шторма нет. Выбираем следующий танкер на обслуживание();

}Tug::Arrival() {_in=-1;

//Сообщаем в порт о прибытии танкера на погрузку

((Port*)p)->Arrival(serving);=NULL;

//Пока причаливали, начался шторм. Буксир отдыхает(to_sEnd>0) return;();

}Tug::run(){k;(to_sStart>0) to_sStart--;(to_sStart==0) stormStart();(to_sEnd>0) to_sEnd--;(to_sEnd==0) stormEnd();(to_arrival>0) to_arrival--;(to_arrival==0) Arrival_Sea();(to_in>0) to_in--;(to_in==0) Arrival();(to_out>0) to_out--;(to_out==0) Departure(); <Tanker> *ptr=queue_in;

//Инкремент времени пребывания для всех танкеров, которые в данный момент //контролирует буксир(ptr!=NULL) {>Data()->minutes++;=ptr->Next();

}=queue_out;(ptr!=NULL){>Data()->minutes++;=ptr->Next();

}(serving!=NULL) serving->minutes++;

//Запись статистики - один раз в час((total+1)%60==0){=(total+1)/60;(q_tugIn,"%d\n", que_inLength);_tugInAve=q_tugInAve*(1-1.0/k)+((float)que_inLength)/k;(q_tugOut,"%d\n", que_outLength);_tugOutAve=q_tugOutAve*(1-1.0/k)+((float)que_outLength)/k;

}(serving!=NULL) ro_tug++;

}Tug::putPort(Port *a){=a;

}

Tug::Print(){(to_sStart==-1)("Буксир не работает из-за шторма\n");if (to_in>0)("Буксир помогает причалить танкеру типа %d\n", serving->type);if (to_out>0)("Буксир помогает отчалить танкеру типа %d\n", serving->type);("Буксир простаивает, так как некого обслуживать\n");

}

//Конструктор для класса Port::Port(){i;=NULL;=new Tanker *[volume];_serve=new int[volume];(i=0;i<volume;i++) {[i]=NULL;_serve[i]=-1;

}_length=0;

}

//Деструктор для класса Port::~Port(){[] to_serve;[] serving;

}

Port::Arrival(Tanker *t){i;

//Проверяем, есть ли свободный терминал=FirstAvail();(i!=-1) //есть, стразу ставим танкер на погрузку

{[i]=t;_serve[i]=get_uniform(t->median, t->offset);[i]->state=5;

}//нет, ставим танкер в очередь

{_length++;<Tanker> *ptr=new ListNode<Tanker>(t, NULL);(queue==NULL) queue=ptr;ListAdd<Tanker>(queue, ptr);>state=4;

}

}

Port::Complete(int i){

//Отправляем загруженный танкер к буксиру

((Tug*)t)->Arrival_coast(serving[i]);_serve[i]=-1;[i]=NULL;(queue==NULL) return;

//Очередь не пуста, ставим на освободившийся терминал новый танкер[i]=queue->Data();_serve[i]=get_uniform(serving[i]->median, serving[i]->offset);[i]->state=5;=queue->Next();_length--;

}

Port::run(){k;

//Проверка завершения обслуживания и инкремент времени пребывания для всех //танкеров, находящихся под контролем порта(int i=0;i<volume;i++) {(to_serve[i]>0) { serving[i]->minutes++; to_serve[i]--; }(to_serve[i]==0) Complete(i);

}<Tanker> *ptr=queue;(ptr!=NULL){>Data()->minutes++;=ptr->Next();

}

//Запись статистики - 1 раз в час((total+1)%60==0){=(total+1)/60;(q_loading,"%d\n", q_length);_loadAve=q_loadAve*(1-1.0/k)+((float)q_length)/k;_port=ro_port*(1-1.0/k)+((float)Busy())/(k*volume);

}

}

Port::Print(){("В очереди на погрузку находятся %d танкеров\n", q_length);("Заняты погрузкой %d терминалов\n", Busy());(int i=0;i<volume;i++)("%d-й терминал обслуживает танкер типа %d\n", i+1, serving[i]->type);

}

Port::FirstAvail(){(int i=0;i<volume;i++)(serving[i]==NULL) return(i);(-1);

}

Port::Busy() //вычисление текущего количества занятых терминалов

{k=0;(int i=0;i<volume;i++)(serving[i]!=NULL) k++;(k);

}

Port::putTug(Tug *a){=a;

}

Листинг программы файл random.h


#include<cstdio>

#include<cmath>

#include<cstdlib>get_exp(float mu) {

//генератор случайных чисел, распределенных

//экспоненциальноr_num; float root, right;_num=rand(); //получение случайного целогочисла=((float)r_num)/(RAND_MAX+1); //проекция на интервал (0;1)=-log(1-right)/mu; //вычисление значения обратной функции(root);

}

get_uniform(int a, int b){ //Генерация равномерно распределенной величины a+bx, y;=rand()%(b+1);=rand()%2;(y==0) return(a-x);(a+x);

}

get_triangle(float A, float B, float C){r_num; float root, right;_num=rand(); //получение случайного целого

//числа=((float)r_num)/(RAND_MAX+1); //проекция на интервал (0;1).

//Константа RAND_MAX=32767 (215-1) определена в cstdlib(right<(C-A)/(B-A)) root=A+sqrt(right*(B-A)*(C-A));root=B-sqrt((1-right)*(B-A)*(B-C));(root);

}

get_pareto(float A, float B){r_num; float root, right;_num=rand(); //получение случайного целого числа=(float)r_num/RAND_MAX+1; //проекция на интервал (0;1)=A/(pow(1-right, (float) 1.0/B)); //вычисление значения обратной функции(root);

}


Листинг программы файл List.h


template <class Type> //это постоянная «заставка»

//к класам и функциям

//c парметризированным типомListNode {:<Type> *next; //указатель на следующий элемент списка*data; //указатель на данные хранящиеся в элементе списка:(Type *d, ListNode<Type> *n); //конструктор

~ListNode(); //деструктор*Data(); //метод для чтения данных<Type> *Next(); //метод для чтения указателя

//на следующий элементPutNext(ListNode<Type> *n); //метод для записи указателя

//на следующий элементPrint(); //печать содержимого элемента списка

};<class Type><Type>::ListNode(Type *d, ListNode<Type> *n) : next(n), data(d){

}<class Type><Type>::~ListNode(){data;

}<class Type>*ListNode<Type>::Data(){data;

}<class Type><Type> *ListNode<Type>::Next(){next;

}<class Type>ListNode<Type>::PutNext(ListNode<Type> *n){=n;

}<class Type>ListNode<Type>::Print(){>Print(); //предпологается наличие метода Print() для класса

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

}

//Описание класса-шаблона завершено, далее идут функции-шаблона, работающие

//не с отдельным элементом, а со всеми списком

<class Type>ListAdd(ListNode<Type> *head, ListNode<Type> *li) {

//добавление нового элемента li в хвост списка с головой head<Type> *old, *v;

//ищем внешний хвост списка(v=head; v!=NULL; v=v->Next())=v;>PutNext(li); //добавляем в след за найденым хвостом новый элемент списка

}<class Type><Type> *ListDelete(ListNode<Type> *head, ListNode<Type> *li) {

//удаление элемента li из списка с голоыой head

//функция возвращает указатель на голову нового списка

//int j;<Type> *old, *o1;(li==head){

//удаляемый элемент может быть головой списка

//в этом случае голова у списка меняется=head->Next();li;o1;

}

//Удаляемый элемент не являеться головой списка. Голова остаеться прежняя(ListNode<Type>* v=head; v!=li; v=v->Next())

//поиск элемента предшедствующего удаляемому=v;=li->Next();>PutNext(o1);

//предшествующий элеиент теперь «видит» элемент стоящий в списке вслед

//за удаленнымli;head;

}

//печать всех элементов списка с головой head<class Type>ListPrint(ListNode<Type> *head){(ListNode<Type>* v=head; v!=NULL; v=v->Next())>Print(); //подсчет количества элементов в списке с головой head

}<class Type>ListCount(ListNode<Type> *head){i; i=0;(ListNode<Type>* v=head; v!=NULL; v=v->Next()){>Print();++;

}i;

}


Листинг программы функция main()


#include "stdafx.h"

#include "iostream"

#define N 525600 //количество минут в году

#define M 5 //количество танкеров четвертого типа

#define _CRT_SECURE_NO_WARNINGS

#include "6.h"main(){i;**mas;

//Создание объектов Буксир и Портport;tug;

//Настройка их взаимодействия.putTug(&tug);.putPort(&port);=new Tanker4 *[M];;_tugIn=fopen("q_tugIn", "wt");_tugOut=fopen("q_tugOut", "wt");_loading=fopen("q_loading", "wt");=fopen("sojourn", "wt");((unsigned)time(0));

//Инициализация танкеров четвертого типа и настройка их взаимодействия

//с буксиром(i=0;i<M;i++) {[i]=new Tanker4(i+1);[i]->putTug(&tug);

}

//Основной цикл моделирования(total=0L;total<N;total++){.run();.run();(i=0;i<M;i++)[i]->run();

}[] mas;

//Закрытие файлов сбора статистики(sojourn);(q_tugIn); fclose(q_tugOut); fclose(q_loading);(LC_ALL, "Russian");

//Вывод на печать результатов эксперимента<< "Всего поступлений танкеров " << entered << endl;<< "Завершили цикл обслуживания в порту " << completed << endl;<< "Из них танкеров типов 1,2,3 - " << completed1 << endl;<< "Из них танкеров четвертого типа " << completed2 << endl;<< "Средняя длина очереди на причаливание " << q_tugInAve << endl;<< "Средняя длина очереди на отчаливание " << q_tugOutAve << endl;<< "Средняя длина очереди на погрузку " << q_loadAve << endl;<< "Среднее время пребывания на погрузке " << soj_Ave/60 << endl;<< "Среднее время пребывания на погрузке для танкеров типов 1,2,3 - " << soj1_Ave/60 << endl;<< "Среднее время пребывания на погрузке для танкеров четвертого типа - " << soj2_Ave/60 << endl;<< "Коэффициент загрузки буксира - " << ((float)ro_tug)/total << endl;<< "Коэффициент загрузки порта - " << ro_port << endl;

_gettch();

}


5. Анализ результатов работы программы


При отсутствии танкеров четвертого типа моделирование дает следующие результаты:


Рис. 1. Снимок работы программы с отстсутствием танкеров 4-ого типа


·всего поступлений в систему - 790 танкеров;

·из них обслужено - 789 танкеров;

·средняя длина очереди на причаливание - 0,004 танкера;

·средняя длина очереди на отчаливание - 0,005 танкера;

·средняя длина очереди на погрузку - 0,012 танкера;

·среднее время пребывания на погрузке - 21,8 часа;

·коэффициент загрузки буксира - 0,18;

·коэффициент загрузки порта - 0,59.

Мы видим, что неиспользованные ресурсы системы довольно велики, и, видимо, контракт заключить стоит. Убедимся в этом. При добавлении пяти танкеров четвертого типа получаем:

·всего поступлений в систему - 946;

·из них завершили обслуживание - 944;

·из них танкеров типов 1, 2, 3 - 784;

·танкеров типа 4 - 160;

·средняя длина очереди на причаливание - 0,027;

·средняя длина очереди на отчаливание - 0,035;

·средняя длина очереди на погрузку - 0,16;

·среднее время пребывания на погрузке (для всех танкеров) - 23,68 ч;

·среднее время пребывания на погрузке для танкеров типов 1, 2, 3 - 23,23 ч;

·среднее время пребывания на погрузке для танкеров типа 4 - 25,88 ч;

·коэффициент загрузки буксира - 0,22;

·коэффициент загрузки порта - 0,72.


Рис. 2. Снимок работы программы с пятью танкерами 4-ого типа


Показатели выросли, но остались в пределах нормы, перегрузок нигде не возникло.

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

Из графика, приведенного на рис. 3, видно, что среднее время пребывания танкеров в порту Тср увеличивается довольно медленно, пока М не превосходит 15. Далее T ср начинает увеличиваться стремительно и быстро выходит за разумные пределы. Следовательно, заключать контракт на обслуживание более 15 танкеров нецелесообразно.


Рис. 3. Зависимость среднего времени пребывания в порту от количества танкеров четвертого типа

Рис. 4. Зависимость коэффициента загрузки буксира от количества танкров четвертого типа


Рис. 5. Зависимость коэффициента загрузки порта от количества танкеров четвертого типа

Из графика на рис. 3 можно сделать еще один вывод. Время обслуживания танкера буксиром фиксировано и равно 2 ч, что составляет в общем-то небольшую долю для значения Тср. Значит, потенциальным узким местом системы является погрузка в порту, где танкеры проводят все оставшееся время. Этот вывод подтверждают графики, изображенные на рис. 4 и 5.

Так, из графика, приведенного на рис. 4, видно, что загрузка буксира при увеличении М стремится асимптотически к некоторой не очень большой величине, равной приблизительно 0,3. А вот порт с ростом М быстро оказывается перегруженным, его загрузка стремится к единице.


Заключение


В результате выполнения курсовой работы были достигнуты следующие результаты:

·изучены метод имитационного моделирования экономических объектов;

·получены навыки проведения численных экспериментов на имитационных моделях экономических систем;

·приобретен опыт проведения анализа по результатам данных экспериментов на имитационной модели;


Список использованной литературы


1.Труб И. И. «Объектно-ориентированное моделирование на С++»: Учебный курс.-СПб.:Питер, 2006.-411с.:ил.

2.Варфоломеев В.И. «Алгоритмическое моделирование элементов экономических систем». - М.: Финансы и статистика, 2000г.

.Клейнрок Л. «Теория массового обслуживания.»-М.: Машиностроение,1979.-432 с.

4.Прицкер А. «Введение в имитационное моделирование»-М.: Мир,1987.-644с.

.Емельянов А.А.,Власова Е.А., «Имитационное моделирование экономических процессов» - М. Финансы и статистика,2002.

6.Дубров А.М., Лагоша Б.А., Хрусталев Е.Ю. Моделирование рискованных ситуаций в экономике и бизнесе. -М.: Финансы и статистика, 2004. -224 с.

7.Князевская Н.В., Князевский В.С. Принятие рискованных решений в экономике и бизнесе. -М.: Контур, 1998. -160 с.

.Кремер Н.Ш. Исследование операций в экономике. -М.: Банки и биржи, 2003. -407 с.

9.Шикин Е.В. Математические методы и модели в управлении. -М.: Финансы и статистика, 2002. -430 с.


ФГОУ СПО «Волгоградский технологический коледж» Курсовой проект Моделирование работы порта

Больше работ по теме:

КОНТАКТНЫЙ EMAIL: [email protected]

Скачать реферат © 2017 | Пользовательское соглашение

Скачать      Реферат

ПРОФЕССИОНАЛЬНАЯ ПОМОЩЬ СТУДЕНТАМ