- •Содержание
- •Введение
- •1 Постановка задачи оптимизации закупки топлива авиакомпанией
- •1.1 Качественное описание задачи
- •1.2 Концептуальная модель задачи
- •1.3 Математическая постановка задачи
- •2 Алгоритмизация решения задачи оптимизации закупки топлива авиакомпанией
- •2.1 Методы нахождения опорного и оптимального решения транспортной задачи
- •2.2 Описание венгерского метода нахождения оптимального плана
- •2.3 Описание алгоритма нахождения опорного плана методом северо-западного угла
- •2.4 Описание алгоритма нахождения оптимального плана распределительным методом
- •2.5 Проектирование сценария диалога
- •2.6 Описание структур данных
- •2.7 Описание программной системы «Оптимизация закупки топлива авиакомпанией»
- •2.8 Структурная схема сценария диалога и описание его программной реализации
- •2.9 Структурная схема алгоритмов метода северо-западного угла и распределительного и описание их программной реализации
- •2.10 Структурная схема алгоритмов ведения файловых архивов, графического представления результатов и их программная реализация
- •3. Численные эксперименты
- •3.1 Ручная реализация метода северо-западного угла и распределительного
- •3.2 Ручная реализация венгерского метода
- •3.3 Машинные эксперименты с программной системой
- •3.4 Качественная интерпретация полученных результатов
- •Заключение
2.8 Структурная схема сценария диалога и описание его программной реализации
Структурная схема сценария диалога представлена на рисунке 2.1
Диалог в программе формируется через обработку программных исключений. При возникновении исключения программа определяет тип ошибки, формируется лог ошибки и отправляется на поле вывода. После отправления вычисления прекращаются и программа возвращается в этап ввода данных, в котором пользователь может скорректировать свои данные.
При успешном завершении процесса вычислений на поле вывода подаётся результат.
2.9 Структурная схема алгоритмов метода северо-западного угла и распределительного и описание их программной реализации
Структурная схема алгоритмов метода северо-западного угла и распределительного представлены в приложениях А и В соответственно.
Описание подпрограмм системы представлено в таблице 2.2
Таблица 2.2
Имя |
Тип |
Параметры |
Назначение |
Назначение параметров |
Содерж. Под-прог- рамы |
numof1 |
bool |
Double[][] f, Int x Int y |
Показывает. Находится ли в строке и столбце элемена менее одного базисного |
f – матрица базисности x, y - координаты |
- |
equal |
void |
ref Double[][] a, Double[][] b |
a=b поэлементно |
a, b – матрицы. |
- |
circleOfEnumerizing |
bool |
ref double[][] f, int Circle-Length, int curi, int curj, ref List<Point> c |
Ищет цикл пересчёта |
f – матр. базис., circle-Length - № шага, curi, curj –координаты тек. элем. цикла, List<Point> c – контейнер цикла
|
equal |
Выполнение вычислений начинается с инициализацией массивов a, b и матрицы c. Матрицы x и f обнуляются.
Этап нахождения опорного плана проходит согласно алгоритму. При этом значение переменных фиксируется в матрице x, а факт их базисности – в матрице f. Количество базисных переменных также фиксируется
Этап приведения плана производится следующим образом:
Сначала формируется значение переменной quanOfVar, которое показывает, скольких базисных переменных не хватает построенному плану до невырожденного. Если это значение равно нулю, то происходит переход к нахождению оптимального решения. Иначе для каждого свободного элемента (f[i][j]=0) проверяется нахождение в его строке и столбце не более одного элемента. Этот факт сохраняется в переменной is1r1c и вычисляется с помощью функции numof1. Если значение is1r1c ложно, то поиск кандидата на базисную переменную продолжается. Иначе клетка становится базисной (f[i][j]=1), quanOfVar декрементируется и поиск прерывается. Если quanOfVar не равна нулю, то производится поиск положения для следующей базисной переменной. В противном случае производится переход на этап поиска оптимального плана.
Этап поиска оптимального плана организуется как цикл с постусловием, внутри которого находится счётчик прохода по матрице (один счётчик внутри другого). Их работу регулирует два флага: isopt – контролирует выход из цикла при оптимальном решении, isNegative – контролирует прерывание счётчика при нахождении цикла пересчёта с отрицательной ценой (При вхождении в цикл isopt=1, isNegative=0). Работа внутри цикла организуется следующим образом:
Сначала происходит построение цикла пересчёта для свободного элемента. Оно организуется с помощью рекурсивной функции circleOfEnumerizing, работа которой состоит из режима прямой и обратной прогонки. На каждом шаге этапа прямой прогонки происходит последовательное сканирование строки/столбца (зависит от чётности шага) на наличие незанятого базисного элемента (в локальной матрице f: f[i][j]=1) или начального элемента цикла (в локальной матрице f: f[i][j]=2). Если он находится, то производится переход на следующий шаг, базисный элемент «занимается» (в локальной матрице f: f[i][j]=3), производится дальнейший поиск. Если на данном шаге не было найдено незанятой базисной переменной, производится откат на шаг назад и производится дальнейший поиск на этап, к которому был произведён откат, элемент освобождается, относительно которого производился поиск, освобождается (в локальной матрице f: f[i][j]=1). Если на чётном этапе не ранее четвёртого находится начальный элемент цикла (свободный элемент, от которого ищется цикл), то цикл замыкается и производится обратная прогонка, на которой координаты элементов цикла заносятся в список circle.
Затем производится нахождение цены цикла, которая находится как разность суммы чётных (массивы в С начинаются с 0 элемента) и нечётных элементов. Если цена цикла неотрицательна (isNegative=0), то происходит поиск и расчёт цикла пересчёта следующего элемента. Если же элемент был последним, то план х объявляется оптимальным (isopt=1), производится расчёт стоимости, и происходит вывод плана и его стоимости наряду с количеством произведённых итераций (входов в цикл с постусловием) и количеством посчитанных циклов пересчёта (входов в счётчик). Если же цена цикла отрицательна (isNegative=1), то расчёт циклов пересчёта прекращается и производится переход по циклу. Для этого ищется минимальное значение матрицы х, принадлежащее одному из нечётных значений списка circle. Затем из значений х нечётных значений цикла вычитается и к значениям х чётных значений прибавляется данный минимум, причём один из обнулившихся в результате перехода нечётных элементов обозначается в матрице f как свободный, а элемент, относительно которого цикл считался, становится базисным. Затем для модифицированного плана производится повторный расчёт циклов пересчёта с первого свободного элемента данного плана (повторный вход в цикл с постусловием, т.к. isopt=0)
