Я пытаюсь написать программу для сопряжения некоторых барж с некоторыми лодками. Каждая баржа имеет определенный объем. Каждая лодка может вмещать до 4 барж и подниматься до определенного общего объема (зависит от лодки). Конечная цель - использовать как можно меньше лодок при размещении каждой баржи.
Я пытался использовать scipy.optimize.differential_evolution с различными стратегиями, параметрами и начальными догадками. Я просто превращаю числа, которые он выплевывает, в целые числа, чтобы их можно было использовать для ссылки на конкретные баржи. После получения аргументов от оптимизатора целевая функция выполняет некоторую работу (не показана), а затем проверяет, выполнены ли условия, и возвращает значение, основанное на этом. Вот некоторый код, который обычно показывает, что я делаю в fobj (я не включаю полный код, потому что это трудно понять без структуры классов, которые я настроил и т.д.):
bargeSpecsMet = True
boatSpecsMet = True
dumbBarge = 0
dumbBoat = 0
#sums up how many barges have either no assignment or more than 1 assignement
#each barge can only be in one place
for each in barges:
dumbBarge += abs(barge.numAssignments - 1)
if dumbBarge > 0:
bargeSpecsMet = False
#checks each boat to see if it over capacity
for each in boats:
if boats.totalBBLs > boats.maxBBLs:
boatSpecsMet = False
dumbBoat += 1
#returns a very large number based on how many barges aren't correct first
#does this until the barges have exactly 1 assignment each
if bargeSpecsMet == False:
return dumbBarge * 1e20
#returns a still large but smaller number based on how many boats are overcapacity
#does this until each barge is under capacity
if boatSpecsMet == False:
return dumbBoat * 1E10
#there will be more code for minimizing number of boats but i haven't gotten there yet
Я использовал diff_evolution главным образом потому, что я знаком с ним по тому, как использовал его в другом проекте, который минимизировал более традиционную математическую функцию. Я не думаю, что это, вероятно, предназначено для дискретного размещения вещей, но это работает. К сожалению, он не хочет уходить далеко от моих первоначальных догадок. У кого-нибудь есть советы по этому поводу? Кто-нибудь знаком с другим решателем или методом, который лучше подходит? Я относительно новичок в Python, а также такого рода проблемы, поэтому я просто не знаю, чего я не знаю ...
Единственный другой метод, который я до сих пор придумал, - это перебор, путем создания комбинации назначений, посмотреть, работает ли это, если не прополоскать и повторить. Я еще не реализовал это, потому что я знаю, что это займет вечность, чтобы найти решение.