В настоящее время я использую Solver в Excel, чтобы найти оптимальное решение для производства. Вот текущая настройка:
Это касается изготовления обуви на роторном станке, то есть производство осуществляется партиями и повторами. Например, одна партия будет «10x A1» (см. A1 в таблице), что даст 10x размер 36, 20x размер 37 ... 10x размер 41.
Есть несколько настроек с префиксом; A1, A2; R7 ... как вы видите в таблице выше.
Затем есть переменная requested
(или, скорее, список переменных), которая в основном говорит о том, что заказчик запрашивал, количество на размер.
целевая функция состоит в том, чтобы найти набор повторений, который максимально соответствует запрошенным количествам. Следовательно, в решателе (извините за неанглийский снимок экрана) вы можете видеть, что цель равна N21
(это сумма абсолютных различий по размеру). Переменные равны N2:N9
- это количество повторов для каждой настройки, и единственное ограничение состоит в том, что N2:N9
является целым числом.
Как я могу смоделировать такое поведение с помощью Python? Мой старт:
from collections import namedtuple
from pulp import *
class Setup(namedtuple('IAmReallyLazy', 'name ' + ' '.join(f's{s}' for s in range(36, 47)))):
# inits with name and sizes 's36', 's37'... 's46'
repetitions = 0
setups = [
Setup('A1', 1, 2, 3, 3, 2, 1, 0, 0, 0, 0, 0),
Setup('A2', 0, 1, 2, 3, 3, 2, 1, 0, 0, 0, 0),
Setup('R7', 0, 0, 1, 1, 1, 1, 2, 0, 0, 0, 0),
Setup('D1', 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0),
# and others
]
setup_names = [s.name for s in setups]
requested = {
's36': 100,
's37': 250,
's38': 300,
's39': 450,
's40': 450,
's41': 250,
's42': 200,
}
def get_quantity_per_size(size: str) -> int:
return sum([getattr(setup, size) * setup.repetitions for setup in setups])
def get_abs_diff(size: str) -> int:
requested_size = requested.get(size, 0)
return abs(get_quantity_per_size(size) - requested_size)
problem = LpProblem('Optimize Batches', LpMinimize)
# goal is to minimise the sum(get_abs_diff(f's{size}') for size in range(36, 47))
# variables are [setup.repetitions for setup in setups]
# constraints are all([isinstance(setup.repetitions, int) for setup in setups])
В идеальном мире, если существует более одного оптимального решения, следует выбрать то, у которого наибольший разброс abs diff (то есть тот, у которого наименьшая наибольшая разница). То есть, если одно решение имеет разницу абс 10 для каждого размера и 10 размеров (всего 100), а другое - 20 + 80 = 100, первое решение более оптимально для клиента.
Другое ограничение должно быть min(setup.repetitions for setup in setups if setup.repetitions > 0) > 9
, в основном ограничение повторений должно быть:
- Целое число
- Либо 0 , либо больше 9 - это невозможно в линейном программировании из того, что я понял до сих пор.