А так же транспортная задача линейного программирования

advertisement
Министерство образования и науки Российской Федерации
Федеральное государственное бюджетное образовательное
учреждение высшего профессионального образования
ТОМСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ СИСТЕМ УПРАВЛЕНИЯ И
РАДИОЭЛЕКТРОНИКИ (ТУСУР)
Факультет систем управления
Кафедра автоматизированных систем управления
(АСУ)
ОТЧЕТ
по производственной практике
Транспортная задача линейного программирования
Выполнил студент гр.
_________ И.Н Альков
«____»_____________2014 г
Руководитель практики
Руководитель практики
от предприятия
от университета
доцент каф. АСУ, к.т.н.
доцент каф. АСУ, к.т.н.
___________ А.Я. Суханов
_____________ А.В. Афонасенко
«____»_____________2014 г
«____»_____________2014 г
2014 г.
2
Министерство образования и науки Российской Федерации
Федеральное государственное бюджетное образовательное
учреждение высшего профессионального образования
ТОМСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ СИСТЕМ УПРАВЛЕНИЯ И
РАДИОЭЛЕКТРОНИКИ
Кафедра автоматизированных систем управления
(АСУ)
Задание
на производственную практику
Студенту гр. 431
Альков И.Н.
Тема работы: Транспортная задача линейного программирования
Индивидуальное задание: Реализация ПО для транспортной задачи
Время прохождения практики: с 23.06.2014 по 16.07.2014
Руководитель практики от
предприятия,
доцент каф. АСУ, к.т.н.
___________ Суханов А.Я.
Руководитель практики от
университета, доц., к.т.н.
_____________ Афонасенко А.В.
2014 г.
3
Оглавление
Введение. ................................................................................................................................................. 4
2. Техническое задание. .............................................................................................................................. 6
2.1. Основание для разработки. ............................................................................................................. 6
2.2. Назначение разработки. .................................................................................................................. 6
2.3. Требования к функциональным характеристикам. ....................................................................... 6
2.4. Требования к надёжности ............................................................................................................... 7
3. Основная часть. ....................................................................................................................................... 8
3.1. Аналитический обзор. ...................................................................................................................... 8
3.1. Обоснование выбранных программных средств. .......................................................................10
3.2. Теоретическая часть. ......................................................................................................................10
3.3. Описание математического аппарата. .........................................................................................13
3.3.1 Модели транспортной задачи .................................................................................................13
3.3.2 Определение оптимального и опорного плана транспортной задачи ...............................15
3.3.3 Методы определения первоначального опорного плана ....................................................16
3.3.3.1 Метод Северо-Западного угла .............................................................................................16
3.3.3.2 Метод минимального элемента ..........................................................................................18
3.3.3.3 Метод аппроксимации Фогеля.............................................................................................19
3.3.3.4 Метод двойного предпочтения. ..........................................................................................21
3.3.4 Методы определения оптимального плана ..........................................................................23
3.3.4.1 Венгерский метод ..................................................................................................................23
3.3.4.2 Метод потенциалов ..............................................................................................................24
3.4. Программа и тестирование. ..........................................................................................................24
4. Заключение. .......................................................................................................................................29
5. Список литературы. ...........................................................................................................................30
Приложение А........................................................................................................................................31
Приложение Б. .......................................................................................................................................44
4
Введение.
Под названием “транспортная задача” объединяется широкий круг задач с единой
математической моделью. Классическая транспортная задача – это задача о наиболее экономном плане перевозок однородного продукта или взаимозаменяемых продуктов из
пунктов производства в пункты потребления, встречается чаще всего в практических приложениях линейного программирования. Линейное программирование является одним из
разделов математического программирования – области математики, разрабатывающей
теорию и численные методы решения многомерных задач с ограничениями.
Огромное количество возможных вариантов перевозок затрудняет получение достаточно экономного плана эмпирическим или экспертным путем. Применение математических методов и вычислительных в планировании перевозок дает большой экономический эффект. Транспортные задачи могут быть решены симплексным методом однако
матрица системы ограничений транспортной задачи настолько своеобразна, что для ее
решения разработаны специальные методы. Эти методы, как и симплексный метод, позволяют найти начальное опорное решение, а затем, улучшая его получить оптимальное
решение.
В зависимости от способа представления условий транспортной задачи она может
быть представлена в сетевой (схематичной) или матричной (табличной) форме. Транспортная задача может также решаться с ограничениями и без ограничений.
Т.е. актуальность выбранной тематики заключается в том, что к задачам транспортного типа сводятся многие другие задачи линейного программирования – задачи о
назначениях, сетевые, календарного планирования.
А так же транспортная задача линейного программирования получила в настоящее
время широкое распространение в теоретических обработках и практическом применении
на транспорте и в промышленности. Особенно, важное значение она имеет в деле рационализации постановок важнейших видов промышленной и сельскохозяйственной продукции, а также оптимального планирования грузопотоков и работы различных видов транспорта. Что и является её предметной областью.
5
Целю, данной работы является освоение математической постановки транспортной
задачи линейного программирования и её решения через некоторые методы.
На основе проведенного анализа, которые приведены в разделе «Аналитический
обзор», делаем вывод, что достоинства аналогов программ транспортной задачи является
их эффективность в функциональном плане, однако их же недостатком.
Слишком громоздкий набор функционала заставляет долго обучаться на данном
продукте для эффективной и полноценной работе на нём. И как следствие необходимость
обучение персонала, что является ещё одной затратной единицей.
Наш продукт будет более интуитивно понятен пользователю, а так же для более
быстрого обучения он сможет смотреть результаты решения его задачи в виде графов, что
позволяет графически понятно понять эффективность его решения.
Это позволит снять затраты на обучения сотрудников, поскольку они смогут самостоятельно разобраться в работе приложения.
6
2. Техническое задание.
2.1. Основание для разработки.
Задание для проведения производственной практики, выдано кафедрой АСУ ТУСУ 02.07.2014. Наименование темы разработки – «Транспортная задача линейного программирования».
2.2. Назначение разработки.
Главная функция транспортной задачи – показывать оптимальное решение логических задач с использованием наиболее подходящих методов. При использовании одного из этих методов необходимо заполнить таблицу, начиная с левой верней клетки и с
максимально большего числа. После чего предполагается либо полностью вызов груза,
либо заполнение доступных маршрутов.
Важной особенностью стоит признать наличие исходного кода программы, который можно изменять под свои требования. Конечно, для этого необходимо обладать определёнными познаниями в языке C#, на основе которого разработана Транспортная задача.
Вторая функция транспортной задачи – предоставить пользователю удобный
для восприятия вид решения, т.е. вывести на экран граф, который отображает решение.
2.3. Требования к функциональным характеристикам.
1) Построение транспортной таблицы.
2) Проверка задачи на закрытость.
3) Составление опорного плана.
4) Проверка опорного плана на вырожденность.
5) Вычисление потенциалов для плана перевозки.
6) Проверка опорного плана на оптимальность.
7) Перераспределение поставок.
8) Если оптимальное решение найдено, переходим к п. 9, если нет – к п. 5.
9) Вычисление общих затрат на перевозку груза.
10) Построение графа перевозок.
7
2.4. Требования к надёжности
Программа должна обрабатывать ошибочные действия пользователя и сообщать
ему об этом. Программа должна обеспечивать контроль входной и выходной информации.
8
3. Основная часть.
3.1. Аналитический обзор.
Под названием «транспортная задача» объединяется широкий круг задач с единой
математической моделью. Данные задачи относятся к задачам линейного программирования и могут быть решены симплексным методом.
В ведение было упомянуто о методах, как и симплексный метод, которые позволяют найти начальное опорное решение для транспортной задачи, а затем, улучшая его,
получить оптимальное решение.
Транспортная задача является частным типом задачи линейного программирования и формулируется следующим образом. Имеется m пунктов отправления (или пунктов
производства) Аi …, Аm, в которых сосредоточены запасы однородных продуктов в количестве a1, ..., аm единиц. Имеется n пунктов назначения (или пунктов потребления) В1, ...,
Вm, потребность которых в указанных продуктах составляет b1, ..., bn единиц. Известны
также транспортные расходы Сij, связанные с перевозкой единицы продукта из пункта Ai в
пункт Вj, i
1, …, m; j
1, ..., n. Предположим, что
,
т. е. общий объем производства равен общему объему потребления. Требуется составить такой план перевозок (откуда, куда и сколько единиц продукта везти), чтобы удовлетворить спрос всех пунктов потребления за счет реализации всего продукта, произведенного всеми пунктами производства, при минимальной общей стоимости всех перевозок.
Приведенная формулировка транспортной задачи называется замкнутой транспортной моделью. Формализуем эту задачу.
Пусть хij - количество единиц продукта, поставляемого из пункта Аi в пункт Вj.
Подлежащие минимизации суммарные затраты на перевозку продуктов из всех пунктов
производства во все пункты потребления выражаются формулой:
9
Суммарное количество продукта, направляемого из каждого пункта отправления
во все пункты назначения, должно быть равно запасу продукта в данном пункте. Формально это означает, что
,i
1, …, m
Суммарное количество груза, доставляемого в каждый пункт назначения из всех
пунктов отправления, должно быть равно потребности. Это условие полного удовлетворения спроса:
,j
1, …, n
Объемы перевозок - неотрицательные числа, так как перевозки из пунктов потребления в пункты производства исключены:
xij
0, i
1, ..., m; j
1, …,n
Существует несколько распространенных методов для составления опорного решения транспортной задачи: «Метод Северо-Западного угла», «Метод минимального элемента», «Аппроксимация Фогеля», «Метод двойного предпочтения».
Далее опорный план обрабатывается методом потенциалов для составления плана
перевозки и в конце осуществляется построение графа перевозок.
Аналогами является транспортная программа «Trans Trade». Программа для автоматизации транспортных предприятий, а также любых отделов транспортной логистики,
чья деятельность, таки или иначе, связана с решением транспортных задач и осуществлением перевозок.
Многопользовательская транспортная программа с гибкой настройкой прав и
полномочий, предназначенная для решения транспортных задач
10
Типы лицензий транспортной программы:
Лицензия
Рабочих мест
Техподдержка
Срок действия
Стоимость
ИП
1
6 мес.
неограничен
5000 р.
Дуэт
2
6 мес.
неограничен
6600 р.
Трио
3
6 мес.
неограничен
7200 р.
Команда
5
1 год
неограничен
8800 р.
Коллектив
10
1 год
неограничен
12200 р.
Бизнес-круг
15
2 года
неограничен
18600 р.
Корпоративная
неограниченно
2 года
неограничен
32800 р.
3.1. Обоснование выбранных программных средств.
3.2. Теоретическая часть.
Транспортная задача является частным типом задачи линейного программирования и формулируется следующим образом. Имеется m пунктов отправления (или пунктов
производства) Аi …, Аm, в которых сосредоточены запасы однородных продуктов в количестве a1, ..., аm единиц. Имеется n пунктов назначения (или пунктов потребления) В1, ...,
Вm, потребность которых в указанных продуктах составляет b1, ..., bn единиц. Известны
11
также транспортные расходы Сij, связанные с перевозкой единицы продукта из пункта Ai в
пункт Вj, i
1, …, m; j
1, ..., n. Предположим, что
т. е. общий объем производства равен общему объему потребления. Требуется составить такой план перевозок (откуда, куда и сколько единиц продукта везти), чтобы удовлетворить спрос всех пунктов потребления за счет реализации всего продукта, произведенного всеми пунктами производства, при минимальной общей стоимости всех перевозок. Приведенная формулировка транспортной задачи называется замкнутой транспортной моделью. Формализуем эту задачу.
Пусть хij - количество единиц продукта, поставляемого из пункта А i в пункт Вj.
Подлежащие минимизации суммарные затраты на перевозку продуктов из всех пунктов
производства во все пункты потребления выражаются формулой:
(1)
Суммарное количество продукта, направляемого из каждого пункта отправления
во все пункты назначения, должно быть равно запасу продукта в данном пункте. Формально это означает, что
,i
1, …, m
(2)
Суммарное количество груза, доставляемого в каждый пункт назначения из всех
пунктов отправления, должно быть равно потребности. Это условие полного удовлетворения спроса:
,j
1, …, n
(3)
Объемы перевозок - неотрицательные числа, так как перевозки из пунктов потребления в пункты производства исключены:
xij
0, i
1, ..., m; j
1, ..., n (4)
Транспортная задача сводится, таким образом, к минимизации суммарных затрат
при выполнении условий полного удовлетворения спроса и равенства вывозимого количества продукта запасам его в пунктах отправления.
Определение 1.
Всякое неотрицательное решение системы линейных уравнений
12
1, …, n
,j
и
определяемое матрицей X=(xij)(i
,i
1, …, m,
1, …, m; j
1, ..., n), называется планом
транспортной задачи.
Определение 2.
План X*=(x*ij)(i
1, …, m; j
1, ..., n), при котором функция
принимает свое минимальное значение, называется оптимальным планом
транспортной задачи.
Обычно исходные данные записываются в виде таблицы 1.
Таблица 1.
Пункты отправ-
Пункты назначения
За-
ления
пасы
A1
В1
…
Bj
…
Bn
А1
C11
…
C1j
…
C1n
a1
X11
X1j
X1n
…
…
…
…
…
…
…
Ai
Ci1
…
Cij
…
Cin
ai
Xi1
Xij
Xin
…
…
…
…
…
…
…
Am
Cm1
…
Cmj
…
Cmn
am
Xm1
Потребности
b1
Xmj
…
bj
Xmn
…
Очевидно, общее наличие груза у поставщиков равно
bn
, а общая потребность
в грузе в пунктах назначения равна единице. Если общая потребность в грузе в пунктах
назначения равна запасу груза в пунктах отправления, т.е.
,
(5)
то модель такой транспортной задачи называется закрытой.
13
В ряде случаев не требуется, чтобы весь произведенный продукт в каждом пункте
производства был реализован. В таких случаях баланс производства и потребления может
быть нарушен:
,i
1, ..., m.
Введение этого условия приводит к открытой транспортной модели.
Теорема 1.
Любая транспортная задача, у которой суммарный объем запасов совпадает с
суммарным объемом потребностей, имеет решение.
3.3. Описание математического аппарата.
3.3.1 Модели транспортной задачи
3.3.1.1 Закрытая модель транспортной задачи
Для доказательства теоремы необходимо показать, что при заданных условиях
существует хотя бы один план задачи и линейная функция на множестве планов ограничена.
Доказательство. Пусть
=M>0 .
Тогда величины xij = aibj /M (i = 1,2,3, ... m; j = 1,2,3, ..., n)
яв-
ляются планом, так как они удовлетворяют системе ограничений
(2)и(3).
Действительно, подставляя значения в (2) и (3) , находим
= ai ,
= bj .
Выберем из значений Cij наибольшее C¢ = max Cij и заменим в линейной функции ( 1 ) все коэффициенты на C¢ тогда, учитывая ( 2 ) , получим
,
14
Выберем из значений Cij наименьшее C¢¢=min Cij и заменим в линейной функции
все коэффициенты на C¢¢ ; тогда, учитывая ( 2 ) имеем
Объединяя два последних неравенства в одно двойное , окончательно получаем
C¢¢M ? Z ? C¢ M,
т. е. линейная функция ограничена на множестве планов транспортной задачи.
3.3.1.2 Открытая модель транспортной задачи
Транспортная задача, в которой суммарные запасы и потребности не совпада-
ют, т. е. не выполняется условие
, называется открытой. Для открытой моде-
ли может быть два случая:
a) суммарные запасы превышают суммарные потребности
;
b) суммарные потребности превышают суммарные запасы
.
Линейная функция одинакова в обоих случаях, изменяется только вид системы
ограничений.
Найти минимальное значение линейной функции
при ограничениях
,
i = 1, 2, ..., m,
,
j = 1, 2, ..., n;
,
i = 1, 2, ..., m,
(случай а)
(случай б)
15
,
j = 1, 2, ..., n,
xij ³ 0 (i = 1, 2, ..., m;
j = 1, 2, ..., n).
Открытая модель решается приведением к закрытой модели.
В случае (а), когда суммарные запасы превышают суммарные потребности, вво-
дится фиктивный потребитель Bn+1, потребности которого bn+1 =
. В случае
(б), когда суммарные потребности превышают суммарные запасы, вводится фиктивный
поставщик Am+1, запасы которого am+1=
.
Стоимость перевозки единицы груза как фиктивного потребителя, так и стоимость перевозки единицы груза от фиктивного поставщика полагают равными нулю, так
как груз в обоих случаях не перевозится.
После преобразований задача принимает вид закрытой модели и решается обычном способом. При равных стоимостях перевозки единицы груза от поставщиков к фиктивному потребителю затраты на перевозку груза реальным потребителям минимальны, а
фиктивному потребителю будет направлен груз от наименее выгодных поставщиков. То
же самое получаем и в отношении фиктивного поставщика.
Прежде чем решать какую-нибудь транспортную задачу, необходимо сначала
проверить, к какой модели она принадлежит, и только после этого составить таблицу для
ее решения.
3.3.2 Определение оптимального и опорного плана транспортной задачи
Как и при решении задачи линейного программирования, симплексным методом,
определение оптимального плана транспортной задачи начинают с нахождения какогонибудь ее опорного плана.
Число переменных Xij в транспортной задаче с m пунктами отправления и n пунктами назначения равно nm, а число уравнений в системах (2) и (3) равно n+m. Так как мы
предполагаем, что выполняется условие (5), то число линейно независимых уравнений
равно n+m-1 отличных от нуля неизвестных.
16
Если в опорном плане число отличных от нуля компонентов равно в точности
n+m-1, то план является не выраженным, а если меньше - то выраженным.
Для определения опорного плана существует несколько методов. Три из них - метод северно-западного угла, метод минимального элемента и метод аппроксимации Фогеля - рассмотрены ниже.
При составлении первоначального опорного плана методом северо-западного угла
стоимость перевозки единицы не учитывается, поэтому построенный план далек от оптимального, получение которого связано с большим объемом вычислительных работ. Обычно рассмотренный метод используется при вычислениях с помощью ЭВМ.
Как и для всякой задачи линейного программирования, оптимальный план транспортной задачи является и опорным планом.
Для определения оптимального плана транспортной задачи можно использовать
изложенные выше методы. Однако ввиду исключительной практической важности этой
задачи и специфики ее ограничений [каждое неизвестное входит лишь в два уравнения
системы (2) и (3) и коэффициенты при неизвестных равны единице] для определения оптимального плана транспортной задачи разработаны специальные методы. Два из них метод потенциалов и Венгерский метод - рассматриваются ниже.
3.3.3 Методы определения первоначального опорного плана
3.3.3.1 Метод Северо-Западного угла
При этом методе на каждом шаге построения первого опорного плана заполняется
левая верхняя клетка (северо-западный угол) оставшейся части таблицы. При таком методе заполнение таблицы начинается с клетки неизвестного x11 и заканчивается в клетке неизвестного xmn , т. е. идет как бы по диагонали таблицы перевозок (приложение 3).
Заполнение таблицы начинается с ее северо-западного угла, т. е. клетки с неизвестным x11 . Первая база A1 может полностью удовлетворить потребность первого заказчика B1 (a1  300, b1  170, a1  b1 ) . Полагая x11  170 , вписываем это значение в клетку x11
и исключаем из рассмотрения первый столбец. На базе A1 остается измененный запас
17
a' 130 . В оставшейся новой таблице с тремя строками A1 , A2 , A3 и четырьмя столбцами
B2 , B3 , B4 , B5 ; северо-западным углом будет клетка для неизвестного x12 . Первая база с запасом a'1  130 может полностью удовлетворить потребность второго заказчика B2
(a'1  130, b2  110, a'1  b2 ) . Полагаем x12  110 , вписываем это значение в клетку x12 и исключаем из рассмотрения второй столбец. На базе A1 остается новый остаток (запас)
a' '1  20 . В оставшейся новой таблице с тремя строками A1 , A2 , A3 и тремя столбцами
B3 , B4 , B5 северо-западным углом будет клетка для неизвестного x13 . Теперь третий заказчик B3 может принять весь запас с базы A1 (a' '1  20, b3  100, a' '1  b3 ) . Полагаем x13  20 ,
вписываем это значение в клетку x13 и исключаем из рассмотрения первую строку. У заказчика из B3 осталась еще не удовлетворенной потребность b'3  80 .
Теперь переходим к заполнению клетки для неизвестного x 23 и т.д.
Через шесть шагов у нас останется одна база A3 с запасом груза (остатком от
предыдущего шага) a'3  200 и один пункт B5 с потребностью b5  200 . Соответственно
этому имеется одна свободная клетка, которую и заполняем, положив x35  200 . План составлен. Базис образован неизвестными x11 , x12 , x13 , x23 , x24 , x34 , x35 . Правильность составленного плана легко проверить, подсчитав суммы чисел, стоящих в заполненных клетках
по строкам и столбцам1.
Общий объем перевозок в тонно-километрах для этого плана составит
18
S1  70 170  50 110  15  20  40  80  60  70  11 50  25  200  30650 .
3.3.3.2 Метод минимального элемента
Суть метода заключается в том, что из всей таблицы стоимостей выбирают
наименьшую и в клетку, которая ей соответствует, помещают меньшее из чисел
и
.
Затем из рассмотрения исключают либо строку, соответствующую поставщику, запасы
которого полностью израсходованы, либо столбец, соответствующий потребителю, потребности которого полностью удовлетворены, либо и строку и столбец, если израсходованы запасы поставщика и удовлетворены потребности потребителя. Из оставшейся части
таблицы стоимостей снова выбирают наименьшую стоимость, и процесс распределения
запасов продолжают, пока все запасы не будут распределены, а потребности удовлетворены.
Пример
Составить первоначальный опорный план методом минимального элемента для
транспортной задачи вида:
2
3
4
15
11 6
10 1
8
9
3
3
4
1
2
21
10 20 10
Решение:
Задача сбалансирована.
Строим первоначальный опорный план методом минимального элемента.
1.
Выясним минимальную стоимость перевозок.
перевозка будет осуществляться с пункта производства
и
она
та
ления
составит
максимально
возможное
Первая
в пункт потребления
число
единиц
продук-
:. В этом случае, потребности пункта потреббудут удовлетворены полностью. Значит, стоимости столбца 2 можно
больше не рассматривать, так как перевозки
мальную стоимость перевозок (без учета столбца № 2).
.Выясним мини-
19
Вторая и третья перевозки будут осуществляться с
2.
пункта производства
вят
и
в пункт потребления
максимально
возможное
:
и
число
,
соответственно и состаединиц
продукта
;
3.
Четвертая перевозка осуществляется с пункта
4.
ния
, т.к.
(без учета первого, второго столбца и четвертой стро-
ки).
.
5.
, т.к.
Пятая перевозка осуществляется с пункта
т.к.
в пункт потребления
(без учета первого, второго столбца, третьей и четвертой стро-
ки).
6.
в пункт потребле-
.
Шестая перевозка осуществляется с пункта
в пункт потребления
(без учета первого, второго столбца, первой, третьей и четвертой стро-
ки).
Опорный план имеет вид;
10 5
0
0
1
0
0
3
0
0
11 10
3.3.3.3 Метод аппроксимации Фогеля
При определении опорного плана транспортной задачи методом аппроксимации
Фогеля находят разность по всем столбцам и по всем строкам между двумя записанными
в них минимальными тарифами. Эти разности записывают в специально отведенных для
этого строке и столбце в таблице условий задачи. Среди указанных разностей выбирают
20
минимальную. В строке (или в столбце), которой данная разность соответствует, определяют минимальная стоимость.
Если минимальная стоимость одинакова для нескольких клеток столбца (строки),
то для заполнения выбирают ту клетку, которая расположена в столбце (строке), соответствующем наибольшей разности между двумя минимальными стоимостями, находящимися в данном столбце (строке).
Пример
Найти методом аппроксимации Фогеля первоначальный опорный план транспортной задачи:
(Здесь мы перенесли потребности в верхнюю строку для удобства построения
плана). Рассмотрим задачу, приведенную для методов северо-западного угла и минимального элемента
Решение:
10 20 10
2
3
4 15 1
7
0
8
1
6
11
1
1
1
4
4
-
5
-
-
1
-
10
0
0
8
9
33
3
0
0
4
1
2 21 1
0
1
2
9
2
2
1
2
2
2
2
2
2
2
-
2
-
-
2
-
-
-
Опорный план имеет вид:
7 0
8
0 1
0
21
3 0
0
0 19 2
3.3.3.4 Метод двойного предпочтения.
В случае больших размерностей, эффективен способ определения первоначального опорного плана с помощью метода двойного предпочтения.
В каждом столбце отмечают знаком клетку с наименьшей стоимостью. Затем тоже проделывают в каждой строке. В результате некоторые клетки имеют двойную отметку. В них находится минимальная стоимость как по столбцу, так и по строке. В эти клетки
помещают максимально возможные объемы перевозок, каждый раз исключая и рассмотрения соответствующие столбцы или строки. Затем распределяют перевозки по клеткам с
единичной отметкой. Остальные перевозки распределяют по наименьшей стоимости.
Пример
10
20 10
2**
3
4
15
11
6* 10
1
8
9
3
4
1* 2* 21
3*
1. Заполняем клетки с двойным предпочтением :
10 20 10
10
15
0
1
0
3
22
0
21
2. Заполняем клетки с простым предпочтением, начиная с наименьшей стоимости.
10 20 10
10
0
15
0
0
1
0
0
3
3
0
20
1
21
3. Заполняем оставшиеся пустыми клетки.
10 20 10
10
0
5
15
0
0
1
1
0
0
3
3
0
20
1
21
Это опорный план составленный методом двойного предпочтения.
23
3.3.4 Методы определения оптимального плана
3.3.4.1 Венгерский метод
Идея метода была высказана венгерским математиком Эгервари и состоит в следующем. Строится начальный план перевозок, не удовлетворяющий в общем случае всем
условиям задачи (из некоторых пунктов производства не весь продукт вывозится, потребность части пунктов потребления не полностью удовлетворена). Далее осуществляется
переход к новому плану, более близкому к оптимальному. Последовательное применение
этого приема за конечное число итераций приводит к решению задачи.
Алгоритм венгерского метода состоит из подготовительного этапа и из конечного
числа итераций. На подготовительном этапе строится матрица X0 (xij[0])m,n, элементы
которой неотрицательны и удовлетворяют неравенствам:
, i 1, …, m;
, j 1, …, m.
Если эти условия являются равенствами, то матрица Хo - решение транспортной
задачи. Если среди условий имеются неравенства, то осуществляется переход к первой
итерации. На k-й итерации строится матрица Хk (xij[0])m,n. Близость этой матрицы к решению задачи характеризует число Dk — суммарная невязка матрицы Хk:
.
В результате первой итерации строится матрица Хl, состоящая из неотрицательных элементов. При этом Dl D0. Если Dl 0, то Хl - оптимальное решение задачи. Если Dl
0, то переходят к следующей итерации. Они проводятся до тех пор, пока Dk при некотором k не станет равным нулю. Соответствующая матрица Хk является решением транспортной задачи.
Венгерский метод наиболее эффективен при решении транспортных задач с целочисленными объемами производства и потребления. В этом случае число итераций не
превышает величины D0/2 (D0 - суммарная невязка подготовительного этапа).
Достоинством венгерского метода является возможность оценивать близость результата каждой из итераций к оптимальному плану перевозок. Это позволяет контролировать процесс вычислений и прекратить его при достижении определенных точностных
показателей. Данное свойство существенно для задач большой размерности.
24
3.3.4.2 Метод потенциалов
Метод потенциалов является модификацией симплекс-метода решения задачи линейного программирования применительно к транспортной задаче. Он позволяет, отправляясь от некоторого допустимого решения, получить оптимальное решение за конечное
число итераций. Общая схема отдельной итерации такова. По допустимому решению
каждому пункту задачи сопоставляется число, называемое его предварительным потенциалом. Пунктам Аi соответствуют числа ui, пунктам Bj - числа vj. Они выбираются таким
образом, чтобы их разность на k-й итерации была равна Сij - стоимости перевозки единицы продукции между пунктами Аi и Вj:
vj[k] – ui[k] Cij, i 1, ..., m; j 1, …, п.
Если разность предварительных потенциалов для каждой пары пунктов Аi, Вj не
превосходит Сij, то полученный план перевозок является решением задачи. В противном
случае указывается способ получения нового допустимого плана, связанного с меньшими
транспортными издержками. За конечное число итераций находится оптимальный план
задачи.
3.4. Программа и тестирование.
Была выбрана среда Visual Studion, программа реализовывалась на языке C#.
Интегрированная среда разработки Visual C# представляет собой набор средств
разработки, предоставляемых через единый пользовательский интерфейс. Некоторые
средства используются совместно с другими языками Visual Studio, в то время как другие,
например, компилятор C#, свойственны только Visual C#. Документация в этом разделе
содержит общие сведения об использовании наиболее важных средств Visual C# при работе в интегрированной среде разработки на различных этапах процесса разработки.
Эта среда является высококвалифицированным набором инструментов, для разработки приложений.
25
Программа состоит из следующих блоков:
Модель
Представление

Контроллер
Модель предоставляет знания: данные и методы работы с этими данными, реагирует
на запросы, изменяя своё состояние. Не содержит информации, как эти знания можно
визуализировать.

Представление. Отвечает за отображение информации (визуализацию). Часто в качестве представления выступает форма с графическими элементами.

Контроллер. Обеспечивает связь между пользователем и системой: контролирует ввод
данных пользователем и использует модель и представление для реализации необходимой реакции.
Тестирование проводилось по сборнику задач «Исследование операций», раздел
транспортная задача.
Результат тестирования показал, что текущая версия программы не способная реализовывать закрытее задачи, т.е. количество единиц запаса и потребностей должно совпадать, что в реальной жизни может отличаться. Это является недостатком, который будет
исправлен в будущем.
Так же выбранные методы реализации транспортной задачи очень эффективны
для ЭВМ, но не являются эффективными для нахождения максимально рационального
плана поставок.
Однако в целом, задача выполняется наиболее удовлетворительно.
26
Пример тестирования:
После ввода входных данных пользователем, которые продемонстрированы ниже
в примере, мы используем «метод северо-западного угла»
В этом примере в условиях задачи заданы возможности поставщиков Ai и потребности потребителей Bj. Требуется найти допустимые объемы перевозки от каждого поставщика к каждому потребителю Xij.
Потребитель B1,
потребность 20 кг
Поставщик A1, запас
30 кг
Поставщик A2, запас
40 кг
Поставщик A3, запас
20 кг
Потребитель B2,
потребность 30 кг
Потребитель B3,
потребность 30 кг
Потребитель B4,
потребность 10 кг
27
Результат должен удовлетворять следующему примеру:
Потребитель B1,
потребность 2020=0 кг
Поставщик A1, запас 3020-10=0 кг
Поставщик A2, запас 4020-20=0 кг
Поставщик A3, запас 1010=0 кг
X11=20 кг
Потребитель B2,
потребность 3010-20=0 кг
Потребитель B3,
потребность 3020-10=0 кг
Потребитель B4,
потребность 1010=0 кг
X12=10 кг
X22=20 кг
X23=20 кг
X33=10 кг
X34=10 кг
Таким образом, весь груз от поставщиков должен быть распределён по потребителям. Если наблюдается недостаток или избыток груза, то это означает, что была допущена арифметическая ошибка, или задача не была приведена к закрытому виду. Чтобы
убедиться в правильности полученного решения, полезно сверить исходные объемы каждого поставщика, которые заданы в условиях транспортной задачи, с суммами отгрузок в
соответствующей строке, а исходные объемы каждого потребителя, которые также заданы
в условиях — с суммами отгрузок по соответствующим столбцам.
Далее используется «метод потенциалов» для нахождения оптимального плана перевозок.
Примечание: есть опасность, что алгоритм впадет в бесконечный цикл из-за вырожденности или каких-либо ошибок реализации, поэтому полезно предусмотреть проверку на максимальное число шагов или максимальное время, которое будет исполняться
программа. Впрочем, по мнению Данцига, те меры, которые можно предпринять для исключения вырожденности приводят к успеху в 100 % случаев.
И в результате его выполнения выводится следующая таблица:
28
Так же нужно упомянуть, что промежуточные результаты скрыты от пользователя, но в данном примере известно, что целевая функция после прохождение через «метод
северо-западного угла» имела значение равное 290 единиц.
Но после использования «метода потенциалов» её значение снизилось до 170
единиц.
Теперь переставим, что одной единицей является один миллион рублей. Явная
экономия на лицо.
29
4. Заключение.
Была проделана работа в результате которой реализована программа, позволяющая решать транспортную задачу. Программа позволяет автоматизировать производственный процесс, что позволяет сократить время на трудоёмкую работу. Т.е. экономия
временных ресурсов.
Так же программа обладает графическим отображением результатов, что обеспечивает лучшее понимание и освоение программы. Этот факт говорит о том, что сотрудники могут самостоятельно и быстро обучится в использование данного приложения.
30
5. Список литературы.
1.
Е. Г. Гольштейн, Д. Б. Юдин «Задачи линейного программирования транспортного
типа», Москва, 1993.
2. И. Л. Акулич, В. Ф. Стрельчонок «Математические методы и компьютерные технологии решения оптимизационных задач», Рига, 2000.
3. www.fmi.asf.ru
4. Википедия. Транспортная задача - ru.wikipedia.org/wiki/Транспортная_задача
5. Решение
транспортной
задачи
http://kb.mista.ru/article.php?id=859
в
1С:Предприятие
8.2.
-
31
Приложение А.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Transport_maps
{
struct comboMatrix
{
public int up; //Матрица опорного решения.
public int left; //Матрица переменных ( количество перевозок )
public int right; //Матрица стоимости ( цена за одну перевозку )
public bool basis; //Является ли элемент базисным (Если да то TRUE иначе FALSE)
}
class BasicPlan
{
struct Point
{
public int x;
public int y;
public void setPoint(int y,int x){
this.x = x;
this.y = y;
}
}
struct potential
{
public int value;
public bool def;
}
//Исходные данные в формате WindowsForms ( Нужны для приёма, преобразования и
передачи для интерфейса с пользователем)
//Для этого нужно создать две приватные функции чтобы конвертировать из одного
формата в другой.
ElementMatrix[,] userElements;
TextBox[] userRequirementsVector;
TextBox[] userResourcesVector;
//Переменные для манипуляции с иходными данными
comboMatrix[,] elements;
int[] requirementsVector;
int[] resourcesVector;
//Проверка на "закратая"(true) задача или нет
32
bool close;
//Проверка на "Вырожденность"
int countBasic = 0;
bool degeneracy; //Если да то true, иначе false
//Для шага 7: Построение цикла (создание рекурсии)
DeltaMatrix[,] deltaMatrix;
public BasicPlan()
{
userElements = null;
userRequirementsVector = null;
userResourcesVector = null;
elements = null;
requirementsVector = null;
resourcesVector = null;
}
public BasicPlan(ref ElementMatrix[,] newElements, ref TextBox[] newrequirementsVector, ref TextBox[] newResourcesVector)
{
userElements = newElements;
userRequirementsVector = newrequirementsVector;
userResourcesVector = newResourcesVector;
elements = new comboMatrix[ newElements.GetLength(0), newElements.GetLength(1)];
requirementsVector = new int[newrequirementsVector.Length];
resourcesVector = new int[newResourcesVector.Length];
//Функция преобразования из формата User в формат BasicPlan для передачи в методы
convertToBasic();
//Проверка на "закрытая".
closeTask(requirementsVector, resourcesVector);
if (!close)
//MessageBox.Show("Всё готово для использования методов");
MessageBox.Show("Необходимо ввести фиктивных производителей или потребителей, ну этим займёмся позже");
//if (close == true)
// MessageBox.Show("Закрытая, можно приступать к нахождению опорного плана");
//else
33
// MessageBox.Show("Открытая, плохо, необходимы фиктивные производители
или потребители");
}
//Метод северо-западного угла
public void MethodNorthWesCorner()
{
int[] newResourcesVector = new int[resourcesVector.Length];
int[] newRequirementsVector = new int[requirementsVector.Length];
resourcesVector.CopyTo(newResourcesVector, 0);
requirementsVector.CopyTo(newRequirementsVector, 0);
//Координаты
int rows = 0;//строки
int cols = 0;//столбцы
//Переменные для вычисления
int minium = 0;
while (rows < newResourcesVector.Length && cols < newRequirementsVector.Length)
{
if (newRequirementsVector[cols] <= newResourcesVector[rows]) minium = newRequirementsVector[cols];
else minium = newResourcesVector[rows];
newResourcesVector[rows] -= minium;
newRequirementsVector[cols] -= minium;
elements[rows, cols].up = minium;
if (newResourcesVector[rows] == 0) rows++;
if (newRequirementsVector[cols] == 0) cols++;
}
//Отправить данные пользователю
translateDateUser();
}
//Метод потенциалов
public void MethodOfPotentials()
{
int valueMinDelta = -1;
int countCycle = 0;
while (valueMinDelta < 0 && countCycle != 1000)
{
// Шаг 1: Проверка распределения объёмов
34
// P.S: Не входит в общий алгоритм.
//
Нужна для поиска арифметических ошибок
if (close != true)
{
//MessageBox.Show("Задача открытая, не совпадает с условиями текущей мат.
модели");
return;
}
else
{
//P.S.: Тут должна быть реализация кол-ва итераций алгоритма
//
Начинается с этого комментария, но пока не известно где заканчивается и
когда.
// Шаг 2: Общая стоимость транспортировки
// +Шаг 3: Разделение на базисные(elements[i,j].basic = true) и свободные
// P.S.: Не входит в общий алгоритм
//
Показывает результат до ишага и после него
//
(оценка эффективности)
//MessageBox.Show("Шаг 1: Проверка объёмов, закончена, задача закрытая.");
int sum = 0;
for (int i = 0; i < elements.GetLength(0); i++)
for (int j = 0; j < elements.GetLength(1); j++)
{
if (elements[i, j].up != 0)
{
sum += (elements[i, j].up * elements[i, j].right);
elements[i, j].basis = true;
countBasic++;
}
else elements[i, j].basis = false;
}
//MessageBox.Show("Шаг 2: Общая стоимость транспортировки = " + sum + "\n
Плюс Шаг 3: Разделение на базисные и свободные");
// Шаг 4: Проверка на выражденность Вырождена( можно использовать )
//
Иначе не вырождена( нужно вводить фиктивне переменные )
//
CountBasic = CountA + CountB - 1;
if (countBasic == (resourcesVector.Length + requirementsVector.Length - 1))
{
degeneracy = true;
//MessageBox.Show("Шаг 4: Проверка на выражденность прошла успешно.");
}
else degeneracy = false;
35
// Шаг 5: Вычисление потенциалов
int a = resourcesVector.Length;
potential[] U_potentialResourcesA = new potential[resourcesVector.Length];
potential[] V_potentialRequirementsB = new potential[requirementsVector.Length];
for (int i = 0; i < elements.GetLength(0); i++)
for (int j = 0; j < elements.GetLength(1); j++)
{
U_potentialResourcesA[i].def = false;
V_potentialRequirementsB[j].def = false;
}
U_potentialResourcesA[0].value = 0;
U_potentialResourcesA[0].def = true;
for (int i = 0; i < elements.GetLength(0); i++)
for (int j = 0; j < elements.GetLength(1); j++)
{
if (elements[i, j].basis == true)
{
if (U_potentialResourcesA[i].def == true &&
V_potentialRequirementsB[j].def == false)
{
V_potentialRequirementsB[j].value = elements[i, j].right U_potentialResourcesA[i].value;
V_potentialRequirementsB[j].def = true;
}
else
{
U_potentialResourcesA[i].value = elements[i, j].right V_potentialRequirementsB[j].value;
U_potentialResourcesA[i].def = true;
}
}
}
//Шаг 6: Проверка решения на оптимальность
deltaMatrix = new DeltaMatrix[elements.GetLength(0), elements.GetLength(1)];
for (int i = 0; i < elements.GetLength(0); i++)
for (int j = 0; j < elements.GetLength(1); j++)
{
deltaMatrix[i, j] = new DeltaMatrix();
}
int value = 0;
Vector2 minDelta = new Vector2();
for (int i = 0; i < elements.GetLength(0); i++)
36
for (int j = 0; j < elements.GetLength(1); j++)
{
if (elements[i, j].basis)
deltaMatrix[i, j].value = 0;
else
{
deltaMatrix[i, j].value = elements[i, j].right U_potentialResourcesA[i].value - V_potentialRequirementsB[j].value;
if (deltaMatrix[i, j].value <= value)
{
minDelta = new Vector2(i, j);
value = deltaMatrix[i, j].value;
}
}
}
valueMinDelta = deltaMatrix[minDelta.x, minDelta.y].value;
//MessageBox.Show(printDeltaMatrix + "\n\n" + "Минимальная длеьта:" + deltaMatrix[minDelta.x, minDelta.y].value);
//Шаг 7: Построение цикла
//Четыре точки составляющие квадрат, последняя это начальная вершина.
Point[] squarePoints = new Point[4];
if (buildSquareCycle(minDelta, ref squarePoints))
{
//Шаг 8: Перераспределение поставок по циклу
//Найти минимальную поставку по отрицательным(не чётным элементам
массива точек) вершинам(Находиться в пределах первой по третью точку)
int minX = 400000000;
for (int i = squarePoints.Length - 1; i >= 0; i--)
{
if (elements[squarePoints[i].y, squarePoints[i].x].up <= minX && (i + 1) % 2
!= 0)
minX = elements[squarePoints[i].y, squarePoints[i].x].up;
}
//Вычесть минимальную поставку из отрицательных (Нечётных elements.up)
и сложить с положительными (Чётными)
for (int i = squarePoints.Length - 1; i >= 0; i--)
{
if ((i + 1) % 2 == 0)
{
//Прибавляем к elements.up minX
elements[squarePoints[i].y, squarePoints[i].x].up += minX;
}
else
{
//Уменьшаем elevents.up на minx
37
elements[squarePoints[i].y, squarePoints[i].x].up -= minX;
}
}
}
else break;
}
countCycle++;
}
//Отправить данные пользователю
translateDateUser();
}
private bool buildSquareCycle(Vector2 minDelta, ref Point[] squarePoints)
{
int n = deltaMatrix.GetLength(0);
int m = deltaMatrix.GetLength(1);
int count = 0;
bool fl = false;
Point[] points = new Point[n * m];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
if (deltaMatrix[i, j].value == 0)
{
points[count].setPoint(i, j);
count++;
}
points[count + 1].setPoint(minDelta.x, minDelta.y);
count += 2;
if (count < 4)
{
//MessageBox.Show("Извините, не хватает точек для нахождения квадрата");
return fl;
}
for (int p1 = 0; p1 < count - 3; p1++)
for (int p2 = p1 + 1; p2 < count - 2; p2++)
for (int p3 = p2 + 1; p3 < count - 1; p3++)
for (int p4 = p3 + 1; p4 < count; p4++)
if (isSquare(points[p1], points[p2], points[p3], points[p4]))
{
squarePoints[0] = points[p1];
squarePoints[1] = points[p2];
squarePoints[2] = points[p3];
squarePoints[3] = points[p4];
fl = true;
break;
38
}
if (!fl)
{
//MessageBox.Show("Квадратов нет");
return fl;
}
//string mb = "";
//for (int i = 0; i < squarePoints.Length; i++)
//{
// mb += "Точка " + (i + 1) + ": " + "[" + Convert.ToString(squarePoints[i].x) + "][" +
Convert.ToString(squarePoints[i].y) + "]";
//}
//MessageBox.Show(mb);
return fl;
}
private float distance(Point p1, Point p2) {
return (float)Math.Sqrt(Math.Pow((p2.x - p1.x),2) + Math.Pow((p2.y - p1.y),2));
}
bool isSquare( Point p1, Point p2, Point p3, Point p4 )
{
float d12 = distance(p1, p2);
float d23 = distance(p2, p3);
float d34 = distance(p3, p4);
float d41 = distance(p4, p1);
float d24 = distance(p2, p4);
float d13 = distance(p1, p3);
/*и т.д.*/
return d12 == d23 && d23 == d34 && d34 == d41 && d24 == d13;
}
//Функция преоборазования из формата пользователя в необходимый нам формат для
нахождения опорного плана
//Далее преобразование в обратном порядке и передача пользователю через ссылки
//Это необходимо для полиморфизма, ведь инерфес пользователя может меняться
//А нам это не страшно, лишь понадобится написать одну функцию для взаимодействия с интерфейсом, при этом
//Алгоритм обработки останется тем же =) Полиморфизм ёпта xD
private void convertToBasic()
{
//Преобразование комбинированнаой матрицы
for (int i = 0; i < userElements.GetLength(0); i++)
for (int j = 0; j < userElements.GetLength(1); j++)
{
39
//Сразу сделать конвертирование из текста в int, поскольку проверка идёт в основном классе
if (userElements[i, j].upBox.Text.Count() != 0)
elements[i, j].up = Convert.ToInt32(userElements[i, j].upBox.Text);
else
elements[i, j].up = 0;
if (userElements[i, j].leftBox.Text.Count() != 0)
elements[i, j].left = Convert.ToInt32(userElements[i, j].leftBox.Text);
else
elements[i, j].left = 0;
if (userElements[i, i].rightBox.Text.Count() != 0)
elements[i, j].right = Convert.ToInt32(userElements[i, j].rightBox.Text);
else
elements[i, j].right = 0;
}
//Преобразование вектора Поторебностей
for (int i = 0; i < userRequirementsVector.Length; i++)
{
if (userRequirementsVector[i].Text.Count() != 0)
requirementsVector[i] = Convert.ToInt32(userRequirementsVector[i].Text);
else
requirementsVector[i] = 0;
}
//Преобразование вектора Ресурсов
for (int i = 0; i < userResourcesVector.Length; i++)
{
if (userResourcesVector[i].Text.Count() != 0)
resourcesVector[i] = Convert.ToInt32(userResourcesVector[i].Text);
else
resourcesVector[i] = 0;
}
}
//Передача данных пользователю
private void translateDateUser()
{
for (int i = 0; i < elements.GetLength(0); i++)
for (int j = 0; j < elements.GetLength(1); j++)
40
{
if (elements[i, j].up != 0)
userElements[i, j].upBox.Text = Convert.ToString(elements[i, j].up);
else
userElements[i, j].upBox.Text = "";
if (elements[i, j].left != 0)
userElements[i, j].leftBox.Text = Convert.ToString(elements[i, j].left);
if (elements[i, j].right != 0)
userElements[i, j].rightBox.Text = Convert.ToString(elements[i, j].right);
}
for (int i = 0; i < requirementsVector.Length; i++)
if(requirementsVector[i] != 0)
userRequirementsVector[i].Text = Convert.ToString(requirementsVector[i]);
for (int i = 0; i < resourcesVector.Length; i++)
if(resourcesVector[i] != 0)
userResourcesVector[i].Text = Convert.ToString(resourcesVector[i]);
}
//Проверка на "Закрытая" или "Открытая"
private void closeTask( int[] vector1, int[] vector2)
{
int sumA = 0;
int sumB = 0;
for (int i = 0; i < vector1.Length; i++)
sumA += vector1[i];
for (int i = 0; i < vector2.Length; i++)
sumB += vector2[i];
if (sumA == sumB)
close = true;
else
close = false;
}
//Функция для проверки внутреннего состояния (Вывдит на печать текущее состояние
данных Матриц формата BasicPlan)
//printMatrix("Up");
//printMatrix("Left");
//printMatrix("Right");
//printMatrix("All");
41
private void printMatrix( string nameMatrix)
{
string printMatrix = "";
int count = 0;
if (nameMatrix.Contains("All")) count = 3;
else count = 1;
for (int countMatrix = 0; countMatrix < count; countMatrix++)
{
if (count == 3)
{
if (countMatrix == 0)
{
nameMatrix = "Up";
printMatrix += "Матрица Up:\n";
}
if (countMatrix == 1)
{
nameMatrix = "Left";
printMatrix += "Матрица Left:\n";
}
if (countMatrix == 2)
{
nameMatrix = "Right";
printMatrix += "Матрица Right:\n";
}
}
else printMatrix += nameMatrix + "\n";
for (int i = 0; i < elements.GetLength(1); i++)
{
for (int j = 0; j < elements.GetLength(0); j++)
{
if (nameMatrix.Contains("Up"))
printMatrix += "[" + elements[j, i].up + "] ";
if (nameMatrix.Contains("Left"))
printMatrix += "[" + elements[j, i].left + "] ";
if (nameMatrix.Contains("Right"))
printMatrix += "[" + elements[j, i].right + "] ";
}
42
printMatrix += "\n";
}
printMatrix += "\n\n";
}
MessageBox.Show(printMatrix);
}
//Функция для проверки внутреннего состояния (Вывдит на печать текущее состояние
данных Вектора формата BasicPlan)
private void printVector(int[] vector)
{
string messege = "";
for (int i = 0; i < vector.Length; i++)
{
messege += "[" + Convert.ToString(vector[i]) + "] ";
}
MessageBox.Show(messege);
}
private void printPotencial(potential[] U_potentialResourcesA, potential[]
V_potentialRequirementsB)
{
//Просто печать результатов, удалить при окончательной реализации или переделать в PRIVATE функцию.
//MessageBox.Show("Шаг 5: Вычисление потенциалов, следующее 2-а сообщение
покажет результат (U и V)");
int[] U = new int[U_potentialResourcesA.Length];
int[] V = new int[V_potentialRequirementsB.Length];
for (int i = 0; i < elements.GetLength(0); i++)
for (int j = 0; j < elements.GetLength(1); j++)
{
U[i] = U_potentialResourcesA[i].value;
V[j] = V_potentialRequirementsB[j].value;
}
}
//Передача данных классу DrowLines, для построения гарфа
public comboMatrix[,] setDateForDrowLines()
{
return elements;
}
43
}
}
44
Приложение Б.
В поле размер матрицы указывается количество строк и столбцов, матрицы.
Каждый элемент матрицы состоит из трёх ячеек, верхняя результирующая, т.е. автоматически заполняется после исполнения рабочей части программы (кнопка «Поиск
опорного плана»).
В правую нижнюю ячейку, каждого элемента помещается цена одной перевозки (
матрица стоимости).
В левом нижней ячейке фиксируют промежуточные результаты, который показывают эффективность решения.
По нажатию на кнопку «Построить граф», всплывает дополнительное окно, на котором отображаются вершины. Поставщики, вершины A и потребители вершины B.
По нажатию на любую из вершин, рисуются ориентированные рёбра, вес ребра
показывает количество единиц поставки. Направление ребра, указывает от какого поставщика идёт поставка и до какого потребителя.
Download