ОСТОРОЖНО МОШЕННИКИ! В последнее время в соиальных сетях учстились случаи педложения помощи в написании прогамм от лиц, прикрвающихся сайтом vscode.ru. Мы никогда не пишем первыми и не размещаем никакие материалы в псторонних группах ВК. Для связи с нами используйте исключительно эти контакт: vscoderu@yandex.ru, https://vk.com/vscode


Симплекс-метод. Реализация


В этой статье рассматривается симплекс-метод, который применяется при решении задач линейного программирования (ЗЛП). Приводится алгоритм метода, а также его реализация на языке C#. Реализация представлена в конце статьи.

Определения

Симплекс-метод — это алгоритм, используемый при решении оптимизационной задачи линейного программирования.

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

Оптимизация — задача нахождения минимума или максимума (экстремума) целевой функции.

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

Алгоритм симплекс-метода

В начале исходную задачу линейного программирования приводят к каноническому виду, затем составляют симплекс-таблицу вида:

Симплекс-метод. Симплекс-таблица

где в столбце «базис» указываются базисные переменные, а в последней строке столбца «базис» пишется f(x). В столбец «B» записываются свободные члены ограничений bi и значение целевой функции (на 1-м этапе оно равно 0, т.е. никакой прибыли).

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

В последней строке -cj — это коэффициенты при переменных целевой функции взятые с противоположным знаком.

Симплекс-таблица составлена, теперь опишем сам симплекс-метод.

Шаг 1: Выполняется проверка полученного базисного плана на оптимальность по условию: если при каком-либо ДБР (допустимое базисное решение) в симплекс-таблице все коэффициенты строки f(x) (то есть -cj) не отрицательны, то данное ДБР оптимально, следовательно КОНЕЦ решения. В противном случае:

Шаг 2: Переход к новому базисному плану. Для этого из числа небазисных переменных с отрицательными значениями в последней строке (то есть -cj < 0) выбирается переменная, вводимая в базис — xk, это переменная которой соответствует наибольшая по модулю отрицательная оценка:

Симплекс-метод. Выбор ведущего столбца

Столбец, отвечающий переменной xk, называется главным, или ведущим. Элементы данного столбца обозначаются через aik.

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

Шаг 3: Выбираем переменную r — переменную, которая выводится из базиса. Данная переменная находится из соотношения:

Симплекс-метод. Выбор ведущей строки

Строка таблицы, в которой получено наименьшее отношение элемента столбца «В» к соответствующему положительному элементу ведущего столбца, является ведущей, или главной.


Элементы главной строки обозначаются через arj. Выбранная переменная xr будет выводиться из базиса, то есть это исключаемая переменная.

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

Элемент, который стоит на пересечении главного столбца и строки называется главным, или ведущим, и обозначается ark.

Шаг 4: Для определения нового базисного плана проводится пересчет элементов симплекс-таблицы, и результаты заносятся в новую таблицу. Выбранные переменные среди базисных и не базисных, лежащих на главной строке и главном столбце, меняются местами.

Процедура пересчета элементов выполняется следующим образом:

а) элементы главной строки необходимо разделить на ведущий элемент:

Замена базиса. Пересчет ведущей строки

б) элементы полученной строки умножаются на -aik, и результаты складываются с i-той строкой, причем i ≠ k:

Замена базиса. Пересчет элементов

После определения новой симплекс-таблицы переходят к шагу 1.

Симплекс-метод. Реализация C#

Приводим программную реализацию симплекс-метода. Программа написана на языке программирования C#.

Важная информация! Пожалуйста прочтите!

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

Формат входных данных: двумерный массив из элементов типа double.

Входные данные передаются в качестве аргумента, при создании экземпляра класса Simplex.

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

Выходные данные: метод Calculate возвращает ссылку на двумерный массив, содержащий решенную симплекс-таблицу. Кроме того решение будет занесено в массив, переданный в качестве аргумента в метод Calculate.

Формат выходных данных: двумерный массив из элементов типа double и одномерный массив из элементов типа double.

 

Скачать файл Simplex.cs

 

 

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

Симплекс-метод. Пример решаемой задачи

Демонстрация работы симплекс-метода:

Использование реализации симплекс-метода при решении задачи

4.5/5 - (37 голосов)



Поделиться в соц. сетях:

33 комментария(ев) к статье “Симплекс-метод. Реализация

  1. Миша

    А что нужно сделать, чтобы функции искали переменные для минимума, а не для максимума?

      1. Миша

        то есть сменить знаки коэффициентов при переменных? если так, то программа всё равно считает максимум

  2. Гость

    получается здесь не учитывается знак ограничения? и прога только для <=?

    1. admin Автор статьи

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

      1. Xambey

        Что вы подразумеваете под привести задачу к каноническому виду? Канонический вид, это же вроде:
        1)инвертировать знаки у ф-ции F
        2)добавить доп.переменные, 1 если знак неравенства =, это канонический вид.

        У вас же таблица на входе имеет вид —-B—X1—X2 или я что-то не понимаю? Скажите пожалуйста, как именно нужно обработать систему неравенств?

        1. admin Автор статьи

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

          А в программу заносятся коэффициенты из приведённых ограничений:

          b1 a11 a12 …
          b2 a21 a22 …

          0 -c1 -c2 …

          При этом коэффициенты при базисных переменных (тех, которые вы добавляли, чтобы в ограничениях сделать равенства) НЕ нужно давать на вход программе!

  3. Nikita

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

    1. admin Автор статьи

      Перед вычислениями сохраните в отдельный массив значения коэффициентов при иксах: например в массив a.

      После того, как массив result будет получен, найдём значение целевой функции F:

      double F = 0;

      for(int i = 0; i < result.Length; i++) { F += a[i] * result[i]; }

      1. Nikita

        Спасибо за ответ! Скажите, а как всё-же сделать так, чтобы выполнялось составление симплексной таблицы для решения задачи на определение минимального плана?

        1. admin Автор статьи

          Есть два пути.

          1) Самый простой: привести задачу минимизации (сами исходные данные) к задаче максимизации и использовать приведённый выше алгоритм. Как преобразовать написано здесь.

          2) Изменить приведённый алгоритм конкретно под задачу минимизации. При минимизации целевой функции ведущий столбец определяется по наибольшему значению в строке индексов. Читать про это подробнее.

  4. Алексей

    Админ, спасибо за реализацию, а какой будет алгоритм, если мне необходимо в одной задачи использовать ограничения ‘=>’ и ‘<=' Можете посоветовать русскую литературу по симплекс методу.

    1. admin Автор статьи

      Алгоритм будет точно такой же. Ведь система неравенств всё равно приводится к каноническому виду (в системе ограничений знаки становятся равенствами).

      В предыдущем моём комментарии есть ссылка, там как раз есть пример с разными знаками в системе неравенств.

      1. Михаил

        admin, помогите, пожалуйста, разобраться с вводом данных моей задачи. Заранее извиняюсь за столь глупый вопрос.
        Ограничения:
        2*y1+5*y2=1
        6*y1+1*y2=1
        Функция:
        1*y1+1*y2 —> max

  5. Мария

    Будет ли программа работать для более, чем двух переменных? Что нужно менять в коде, кроме входной матрицы?

  6. Иван

    Здравствуйте. Простите за глупый вопрос, а как запустить эту программу?

    1. admin Автор статьи

      Здравствуйте! Нужно создать проект консольного приложения на C#, например, в Visual Studio, добавить в проект класс Simplex (из данной статьи) и код в классе Program заменить на тот, что представлен в статье.

      1. Иван

        Сделал так, как и описали. Но в 21 строке 13 и 29 столбцы помешает как ошибку : simplex является «пространство имен» но используется как «тип». Не подскажете в чем причина может быть?

        1. admin Автор статьи

          Изменили в файле с классом Simplex название пространства имен «Simplex» на то, которое у вас в проекте?

          1. Иван

            Я как понял. Program.cs здесь ничего не меняем из Вашего кода. А в simplex.cs меняем namespace Simplex на namespace имя проекта, правильно?

  7. Анатолий

    А если вот такая задача:
    целевую функцию минимизировать:
    801*x000 + 391*x001 + 705*x002 + 596*x010 + 472*x011 + 821*x012 + 490*x020 + 261*x021 + 710*x022 + 590*x100 + 322*x101 + 373*x102 + 496*x110 + 514*x111 + 600*x112 + 492*x120 + 405*x121 + 591*x122 + 632*x200 + 535*x201 + 533*x202 + 375*x210 + 564*x211 + 597*x212 + 288*x220 + 372*x221 + 505*x222
    Ограничения
    1*x000 + 1*x001 + 1*x002 + 1*x010 + 1*x011 + 1*x012 + 1*x020 + 1*x021 + 1*x022 = 1
    1*x100 + 1*x101 + 1*x102 + 1*x110 + 1*x111 + 1*x112 + 1*x120 + 1*x121 + 1*x122 = 1
    1*x200 + 1*x201 + 1*x202 + 1*x210 + 1*x211 + 1*x212 + 1*x220 + 1*x221 + 1*x222 = 1
    1*x000 + 1*x001 + 1*x002 + 1*x100 + 1*x101 + 1*x102 + 1*x200 + 1*x201 + 1*x202 = 1
    1*x010 + 1*x011 + 1*x012 + 1*x110 + 1*x111 + 1*x112 + 1*x210 + 1*x211 + 1*x212 = 1
    1*x020 + 1*x021 + 1*x022 + 1*x120 + 1*x121 + 1*x122 + 1*x220 + 1*x221 + 1*x222 = 1
    1*x000 + 1*x010 + 1*x020 + 1*x100 + 1*x110 + 1*x120 + 1*x200 + 1*x210 + 1*x220 = 1
    1*x001 + 1*x011 + 1*x021 + 1*x101 + 1*x111 + 1*x121 + 1*x201 + 1*x211 + 1*x221 = 1
    1*x002 + 1*x012 + 1*x022 + 1*x102 + 1*x112 + 1*x122 + 1*x202 + 1*x212 + 1*x222 = 1
    x000 >= 0
    x001 >= 0
    x002 >= 0
    x010 >= 0
    x011 >= 0
    x012 >= 0
    x020 >= 0
    x021 >= 0
    x022 >= 0
    x100 >= 0
    x101 >= 0
    x102 >= 0
    x110 >= 0
    x111 >= 0
    x112 >= 0
    x120 >= 0
    x121 >= 0
    x122 >= 0
    x200 >= 0
    x201 >= 0
    x202 >= 0
    x210 >= 0
    x211 >= 0
    x212 >= 0
    x220 >= 0
    x221 >= 0
    x222 >= 0

    1. admin Автор статьи

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

      1. Анатолий

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

        1. admin Автор статьи

          Посмотрите выше мой ответ на комментарий Михаила (от 11.04.2017). И подобно его примеру можно построить матрицу.

          Нужно учесть, что у вас задача минимизации, поэтому необходимо сделать min(f(x)) = max(-f(x)).

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

          1 1 1 …
          1 1 1 …

          0 801 391 …

  8. Сергей

    Так и не смог понять, как нужно записать выражение вида =>. Можете привести пример?

    1. admin Автор статьи

      Посмотрите мой комментарий от 20.12.2016 в 22:09. Там есть вся информация по данному вопросу.

Добавить комментарий

Ваш адрес email не будет опубликован.