milp#
- scipy.optimize.milp(c, *, integrality=None, границы=None, ограничения=None, опции=None)[источник]#
Смешанно-целочисленное линейное программирование
Решает задачи следующего вида:
\[\begin{split}\min_x \ & c^T x \\ \mbox{such that} \ & b_l \leq A x \leq b_u,\\ & l \leq x \leq u, \\ & x_i \in \mathbb{Z}, i \in X_i\end{split}\]где \(x\) является вектором переменных решения; \(c\), \(b_l\), \(b_u\), \(l\), и \(u\) являются векторами; \(A\) является матрицей, и \(X_i\) это множество индексов переменных решения, которые должны быть целочисленными. (В этом контексте переменная, которая может принимать только целые значения, называется "целочисленной"; она имеет ограничение "целочисленности".)
Альтернативно, это:
минимизировать:
c @ x
такой, что:
b_l <= A @ x <= b_u l <= x <= u Specified elements of x must be integers
По умолчанию,
l = 0иu = np.infесли не указано с помощьюbounds.- Параметры:
- c1D плотный массивоподобный объект
Коэффициенты линейной целевой функции для минимизации. c преобразуется в массив двойной точности перед решением задачи.
- integrality1D плотный array_like, опционально
Указывает тип ограничения целочисленности для каждой переменной решения.
0: Непрерывная переменная; ограничение целочисленности отсутствует.1: Целочисленная переменная; переменная решения должна быть целым числом в пределах границы.2: Полунепрерывная переменная; переменная решения должна находиться в пределах границы или принимать значение0.3: Полуцелая переменная; переменная решения должна быть целым числом в пределах границы или принимать значение0.По умолчанию все переменные непрерывны. integrality преобразуется в массив целых чисел перед решением задачи.
- границыscipy.optimize.Bounds, опционально
Границы на переменные решения. Нижние и верхние границы преобразуются в массивы двойной точности перед решением задачи.
keep_feasibleпараметрBoundsобъект игнорируется. Если не указано, все переменные решения ограничены неотрицательными значениями.- ограниченияпоследовательность scipy.optimize.LinearConstraint, опционально
Линейные ограничения задачи оптимизации. Аргументы могут быть одним из следующих:
Один
LinearConstraintobjectОдин кортеж, который можно преобразовать в
LinearConstraintобъект какLinearConstraint(*constraints)Последовательность, полностью состоящая из объектов типа 1 и 2.
Перед решением задачи все значения преобразуются в двойную точность, а матрицы коэффициентов ограничений преобразуются в экземпляры
scipy.sparse.csc_array.keep_feasibleоценок.LinearConstraintобъектов игнорируется.- опцииdict, optional
Словарь параметров решателя. Распознаются следующие ключи.
- dispbool (по умолчанию:
False) Установить в
Trueесли индикаторы статуса оптимизации должны выводиться в консоль во время оптимизации.- node_limitint, необязательный
Максимальное количество узлов (релаксаций линейного программирования) для решения перед остановкой. По умолчанию нет максимального количества узлов.
- предварительное решениеbool (по умолчанию:
True) Предварительное решение пытается выявить тривиальные несовместимости, определить тривиальную неограниченность и упростить задачу перед отправкой в основной решатель.
- time_limitfloat, опционально
Максимальное количество секунд, выделенное на решение задачи. По умолчанию ограничения по времени нет.
- mip_rel_gapfloat, опционально
Критерий остановки для решателя MIP: решатель завершит работу, когда разрыв между значением целевой функции для прямой задачи и границей целевой функции для двойственной задачи, масштабированный значением целевой функции для прямой задачи, будет <= mip_rel_gap.
- dispbool (по умолчанию:
- Возвращает:
- resOptimizeResult
Экземпляр
scipy.optimize.OptimizeResult. Объект гарантированно имеет следующие атрибуты.- statusint
Целое число, представляющее статус завершения алгоритма.
0: Оптимальное решение найдено.1: Достигнут предел итераций или времени.2: Задача неразрешима.3: Задача неограничена.4: Другое; подробности см. в сообщении.- successbool
Trueкогда найдено оптимальное решение иFalseв противном случае.- messagestr
Строковый дескриптор статуса завершения алгоритма.
Следующие атрибуты также будут присутствовать, но их значения могут быть
None, в зависимости от статуса решения.- xndarray
Значения переменных решения, которые минимизируют целевую функцию при соблюдении ограничений.
- funfloat
Оптимальное значение целевой функции
c @ x.- mip_node_countint
Количество подзадач или "узлов", решаемых MILP-решателем.
- mip_dual_boundfloat
Окончательная оценка решателем MILP нижней границы оптимального решения.
- mip_gapfloat
Разница между значением прямой целевой функции и границей двойственной целевой функции, нормированная на значение прямой целевой функции.
Примечания
milpявляется оболочкой для программного обеспечения линейной оптимизации HiGHS [1]. Алгоритм детерминирован и обычно находит глобальный оптимум умеренно сложных смешанно-целочисленных линейных программ (если он существует).Ссылки
[1]Huangfu, Q., Galabova, I., Feldmeier, M., and Hall, J. A. J. “HiGHS - высокопроизводительное программное обеспечение для линейной оптимизации.” alphap
[2]Хуанфу, К. и Холл, Дж. А. Дж. «Параллелизация двойственного пересмотренного симплексного метода». Математическое программирование и вычисления, 10 (1), 119-142, 2018. DOI: 10.1007/s12532-017-0130-5
Примеры
Рассмотрим задачу на https://en.wikipedia.org/wiki/Integer_programming#Example, что выражается как задача максимизации двух переменных. Поскольку
milpтребует чтобы задача была выражена как задача минимизации, коэффициенты целевой функции для переменных решения:>>> import numpy as np >>> c = -np.array([0, 1])
Обратите внимание на отрицательный знак: мы максимизируем исходную целевую функцию, минимизируя отрицание целевой функции.
Мы собираем коэффициенты ограничений в массивы, такие как:
>>> A = np.array([[-1, 1], [3, 2], [2, 3]]) >>> b_u = np.array([1, 12, 12]) >>> b_l = np.full_like(b_u, -np.inf, dtype=float)
Поскольку для этих ограничений нет нижнего предела, мы определили переменную
b_lзаполнен значениями, представляющими отрицательную бесконечность. Это может быть незнакомо пользователямscipy.optimize.linprog, который принимает только ограничения типа "меньше" (или "верхняя граница") видаA_ub @ x <= b_u. Принимая обаb_lиb_uограниченийb_l <= A_ub @ x <= b_u,milpпозволяет кратко задавать ограничения-неравенства «больше», ограничения-неравенства «меньше» и ограничения-равенства.Эти массивы собираются в единый
LinearConstraintобъект, подобный:>>> from scipy.optimize import LinearConstraint >>> constraints = LinearConstraint(A, b_l, b_u)
Ограничения неотрицательности на переменные решения применяются по умолчанию, поэтому нам не нужно предоставлять аргумент для границы.
Наконец, в задаче указано, что обе переменные решения должны быть целыми числами:
>>> integrality = np.ones_like(c)
Мы решаем задачу следующим образом:
>>> from scipy.optimize import milp >>> res = milp(c=c, constraints=constraints, integrality=integrality) >>> res.x [2.0, 2.0]
Обратите внимание, что если бы мы решили ослабленную задачу (без целочисленных ограничений):
>>> res = milp(c=c, constraints=constraints) # OR: >>> # from scipy.optimize import linprog; res = linprog(c, A, b_u) >>> res.x [1.8, 2.8]
мы бы не получили правильное решение, округляя до ближайших целых чисел.
Другие примеры приведены в учебнике.