Постановка задачи


Стандартная транспортная задача приведена в следующей таблице [1].



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

Для открытой задачи запасы поставщиков и потребности равны — Для закрытой задачи они разные —

Математическая модель открытой задачи состоит из целевой функции и балансовых уравнений.


Для закрытой задачи. В математической модели для закрытой задачи целевая функция та же что и в открытой, а условий два.
Для условия — :
— целые числа; (3)

Для условия — ;

— целые числа; (4)

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

Ограничения на грузоподъемность транспорта определяется следующим условием.



Такие модели не всегда имеют решение. Условием решаемости является наличие хотя бы одного допустимого решения.

Ограничение по задержке на таможне однородного груза объёмом d.



где натуральное число d, удовлетворяет условию:



В этом случае решение модели (6) дает план перевозок минимизирующий транспортные расходы, и, соответственно, план размещения груза на таможнях:

Если или , то модель (6) принимает вид (1, 3) или (1, 4), соответственно.

Приоритеты


При условии в соотношении (3) для некоторых значений индекса i, пробегаемых переменной I, добавляются ограничения .

При условии в соотношениям (4) для некоторых значений индекса j, пробегаемых переменной J, добавляются ограничения.



Ограничения (7, 8) появляются тогда, когда торговые отношения с каким-либо поставщиком или потребителем ограничены по времени, например, при покупке или продажи энергоносителей сезонного потребления. То, что в определенный срок не вывезено – будет продано другим. То, что не завезено – позже восполнить нельзя, а значит, такие пункты должны быть обязательно закрыты.

Паритет


При условии в (1, 3) для некоторых значений i, k добавляется ограничение то есть из пунктов и вывозятся равные объемы груза.

При условии в (1, 4) для некоторых значений j, r добавляются ограничения то есть в пункты и завозятся равные объемы груза.

Об особенностях решателя CVXOPT Python [2]


CVXOPT обеспечивает возможность задавать элементы модели в матричном виде, что очень удобно. Переменные модели могут быть заданы при помощи класса cvxopt. modeling. variable. Например, так x = variable (9, 'x').

Для класса variable ограничения могут определяться как логические выражения с одним из операторов “<=”, “==”, “>=”, операндами которого являются линейные выражения относительно объектов variable. В том числе, могут использоваться и векторные операции. Например, для скалярных выражений применительно к транспортной задаче:




Функция cvxopt. modeling. op по переданым в качестве параметров целевой функции переменным и набору ограничений создает объект модели, например, применительно к транспортной задаче.

problem =op(7*x[0] + 3*x[1] +6* x[2] +4*x[3] + 8*x[4] +2* x[5]+x[6] + 5*x[7] +9* x[8], [mass1, mass2, mass3, mass4, mass5, mass6,x_non_negative])

Пример исходных данных для моделирования




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

  1. Модель закрытой транспортной задачи минимизации расходов на закупку товаров
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    import numpy
    from cvxopt.modeling import variable, op
    def count(mass1, mass2, mass3, mass4,mass5,mass6,z):         
             x_non_negative = (x >= 0) #общее условие для всех х      
             problem =op(z,[mass1,mass2,mass3,mass4 ,mass5,mass6, x_non_negative])
             problem.solve(solver='glpk')  
             problem.status
             print("Минимальная стоимость закупки -",problem.objective.value()[0])
             print("Матрица закупок:")
             for i in [1,4,7]:
                      print("|",x.value[i-1],"|", x.value[i],"|", x.value[i+1],"|")
    x = variable(9, 'x')
    z=(7*x[0] + 3*x[1] +6* x[2] +4*x[3] + 8*x[4] +2* x[5]+x[6] + 5*x[7] +9* x[8])# целевая функция
    mass1 = (x[0] + x[1] +x[2] <= 74)# условие для первой строки матрицы закупок
    mass2 = (x[3] + x[4] +x[5] <= 40)#условие для второй строки матрицы закупок
    mass3 = (x[6] + x[7] + x[8] <= 36)# #условие для третьей строки матрицы закупок
    mass4 = (x[0] + x[3] + x[6] == 20)# условия для столбца
    mass5 = (x[1] +x[4] + x[7] == 45)#условия для столбца
    mass6 = (x[2] + x[5] + x[8] == 30)#условия для столбца
    count (mass1, mass2, mass3, mass4, mass5,mass6,z)
    

    Решение:

    Минимальная стоимость закупки — 215.0
    Матрица закупок:

    | 0.0 | 45.0 | 0.0 |
    | 0.0 | 0.0 | 30.0 |
    | 20.0 | 0.0 | 0.0 |

  2. Вносим небольшие изменения в предыдущую программу – добавляем переменную mass7 = (x[1] == 30).

    Торговые ограничения для второго поставщика в 30 условных единиц
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    import numpy
    from cvxopt.modeling import variable, op
    def count(mass1, mass2, mass3, mass4,mass5,mass6,mass7,z):         
             x_non_negative = (x >= 0)       
             problem =op(z,[mass1,mass2,mass3,mass4 ,mass5,mass6 ,mass7,x_non_negative])
             problem.solve(solver='glpk')  
             problem.status
             print("Минимальная стоимость закупки -",problem.objective.value()[0])
             print("Матрица закупок:")
             for i in [1,4,7]:
                      print("|",x.value[i-1],"|", x.value[i],"|", x.value[i+1],"|")
    x = variable(9, 'x')
    z=(7*x[0] + 3*x[1] +6* x[2] +4*x[3] + 8*x[4] +2* x[5]+x[6] + 5*x[7] +9* x[8])
    mass1 = (x[0] + x[1] +x[2] <= 74)
    mass2 = (x[3] + x[4] +x[5] <= 40)
    mass3 = (x[6] + x[7] + x[8] <= 36)
    mass4 = (x[0] + x[3] + x[6] == 20)
    mass5 = (x[1] +x[4] + x[7] == 45)
    mass6 = (x[2] + x[5] + x[8] == 30)
    mass7 = (x[1] == 30)
    count(mass1, mass2, mass3, mass4,mass5,mass6,mass7,z)
    


    Решение:

    Минимальная стоимость закупки — 245.0
    Матрица закупок:

    | 0.0 | 30.0 | 0.0 |
    | 0.0 | 0.0 | 30.0 |
    | 20.0 | 15.0 | 0.0 |

  3. Ограничение по пропускной способности таможни на общий товарооборот в 80 условных единиц
    Для этого в программе п.1 заменим строку:
    mass5 = (x[1] +x[4] + x[7] == 45)
    на
    mass5 = (x[1] +x[4] + x[7] == 30)

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    import numpy
    from cvxopt.modeling import variable, op
    def count(mass1, mass2, mass3, mass4,mass5,mass6,z):         
             x_non_negative = (x >= 0)    
             problem =op(z,[mass1,mass2,mass3,mass4 ,mass5,mass6, x_non_negative])
             problem.solve(solver='glpk')  
             problem.status
             print("Минимальная стоимость закупки -",problem.objective.value()[0])
             print("Матрица закупок:")
             for i in [1,4,7]:
                      print("|",x.value[i-1],"|", x.value[i],"|", x.value[i+1],"|")
    x = variable(9, 'x')
    z=(7*x[0] + 3*x[1] +6* x[2] +4*x[3] + 8*x[4] +2* x[5]+x[6] + 5*x[7] +9* x[8])
    mass1 = (x[0] + x[1] +x[2] <= 74)
    mass2 = (x[3] + x[4] +x[5] <= 40)
    mass3 = (x[6] + x[7] + x[8] <= 36)
    mass4 = (x[0] + x[3] + x[6] == 20)
    mass5 = (x[1] +x[4] + x[7] == 30)
    mass6 = (x[2] + x[5] + x[8] == 30)
    count(mass1, mass2, mass3, mass4,mass5,mass6,z)
    

    Решение:

    Минимальная стоимость закупки — 170.0
    Матрица закупок:

    | 0.0 | 30.0 | 0.0 |
    | 0.0 | 0.0 | 30.0 |
    | 20.0 | 0.0 | 0.0 |

  4. Ограничения на поставку товара у второго поставщика
    Для этого в программе п.1 заменим строку:

    mass2 = (x[3] + x[4] +x[5] <= 40)
    на
    mass2 = (x[3] + x[4] +x[5] == 40)

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    import numpy
    from cvxopt.modeling import variable, op
    def count(mass1, mass2, mass3, mass4,mass5,mass6,z):         
             x_non_negative = (x >= 0)    
             problem =op(z,[mass1,mass2,mass3,mass4 ,mass5,mass6, x_non_negative])
             problem.solve(solver='glpk')  
             problem.status
             print("Минимальная стоимость закупки -",problem.objective.value()[0])
             print("Матрица закупок:")
             for i in [1,4,7]:
                      print("|",x.value[i-1],"|", x.value[i],"|", x.value[i+1],"|")
    x = variable(9, 'x')
    z=(7*x[0] + 3*x[1] +6* x[2] +4*x[3] + 8*x[4] +2* x[5]+x[6] + 5*x[7] +9* x[8])
    mass1 = (x[0] + x[1] +x[2] <= 74)
    mass2 = (x[3] + x[4] +x[5] == 40)
    mass3 = (x[6] + x[7] + x[8] <= 36)
    mass4 = (x[0] + x[3] + x[6] == 20)
    mass5 = (x[1] +x[4] + x[7] == 45)
    mass6 = (x[2] + x[5] + x[8] == 30)
    count(mass1, mass2, mass3, mass4,mass5,mass6,z)
    


    Решение:

    Минимальная стоимость закупки — 245.0
    Матрица закупок:

    | 0.0 | 45.0 | 0.0 |
    | 10.0 | 0.0 | 30.0 |
    | 10.0 | 0.0 | 0.0 |

  5. Паритеты на поставки второго и третьего поставщиков
    Для этого в программе п.1 заменим строки:
    mass2 = (x[3] + x[4] +x[5] <= 40)
    mass3 = (x[6] + x[7] + x[8] <= 36)

    на
    mass2 = (x[3] + x[4] +x[5] == 30)
    mass3 = (x[6] + x[7] + x[8] == 30)


    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    import numpy
    from cvxopt.modeling import variable, op
    def count(mass1, mass2, mass3, mass4,mass5,mass6,z):         
             x_non_negative = (x >= 0)    
             problem =op(z,[mass1,mass2,mass3,mass4 ,mass5,mass6, x_non_negative])
             problem.solve(solver='glpk')  
             problem.status
             print("Минимальная стоимость закупки -",problem.objective.value()[0])
             print("Матрица закупок:")
             for i in [1,4,7]:
                      print("|",x.value[i-1],"|", x.value[i],"|", x.value[i+1],"|")
    x = variable(9, 'x')
    z=(7*x[0] + 3*x[1] +6* x[2] +4*x[3] + 8*x[4] +2* x[5]+x[6] + 5*x[7] +9* x[8])
    mass1 = (x[0] + x[1] +x[2] <= 74)
    mass2 = (x[3] + x[4] +x[5] == 30)
    mass3 = (x[6] + x[7] + x[8] == 30)
    mass4 = (x[0] + x[3] + x[6] == 20)
    mass5 = (x[1] +x[4] + x[7] == 45)
    mass6 = (x[2] + x[5] + x[8] == 30)
    count(mass1, mass2, mass3, mass4,mass5,mass6,z)
    


    Решение:

    Минимальная стоимость закупки — 235.0
    Матрица закупок:

    | 0.0 | 35.0 | 0.0 |
    | 0.0 | 0.0 | 30.0 |
    | 20.0 | 10.0 | 0.0 |


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

Анализ интерфейса решателя Excel Solver при решении данной закрытой транспортной задачи.



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

Анализ интерфейса решателя Minimize Mathcad при решении данной закрытой транспортной задачи.



Для работы функции Minimize необходимо устанавливать условия x>=0 для каждой переменной отдельно и вручную вычислять затраты по полученным значениям –x. В решателе CVXOPT для указанных действий предусмотрены следующие функции:

x_non_negative = (x >= 0)
problem. objective.value () [0]


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

Вывод


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

Ссылки


  1. А. В. Кузнецов, Н. И. Холод, Л. С. Костевич. Руководство к решению задач по математическому программированию. — Минск: Высшая школа, 1978. — С. 110.
  2. CVXOPT Modeling.
Поделиться с друзьями
-->

Комментарии (3)


  1. kvothe
    03.06.2017 21:17
    -1

    Python, Mathcad, Excel, большое количество формул, ни слова о CVXOPT — всё в одну кучу. Я не понял, о чём вы хотите больше рассказать из этого. Может быть я, конечно, ошибаюсь, но у меня такое ощущение, что сюда просто случайную часть курсовой свалили.


    1. Scorobey
      04.06.2017 06:25
      -3

      Вы комментировали " Python, Mathcad, Excel, большое количество формул, ни слова о CVXOPT — всё в одну кучу". Очевидно Вы не внимательно читали статью. Пять листингов и раздел «Об особенностях решателя CVXOPT в среде моделирования Python» о решателе CVXOPT. Для Mathcad, Excel приведены сравнения решателей Minimize Solver с решателем CVXOPT.Формулы объясняют ограничения и условия для транспортной модели и их ровно столько сколько возможных условий.Вы компрометировали " Я не понял, о чём вы хотите больше рассказать из этого. Может быть я, конечно, ошибаюсь, но у меня такое ощущение, что сюда просто случайную часть курсовой свалили.". Вы просто не прочитали статью и видимо совсем недавно закончили Вуз, поэтому всё прочитанное ассоциируется с курсовыми и дипломными работами. Статья оригинальная, на цитирование приведены ссылки — проверяйте тогда не ошибётесь и боритесь с фобиями. Спасибо за комментарий !!!..


  1. yanchick
    04.06.2017 08:40

    Если разрешите немного критики. Название работы не очень удачное: вы говорите больше об cvxopt так и выносите его в заголовок. Опять же коробит от словосочетания "среда моделирование Python", на мой взгляд не очень корректное. Создалось ощущение вырванной статьи. Что за задача, а без математики её можно описать и если да то как. Хотя бы абзац. Ну и по выводам: доп действия на мой взгляд не всегда преимущество, хотелось бы еще фишек.
    ЗЫ а вообще если и публиковать результаты исследований на хабре то нужно соблюдать "формат ресурса"