Проблема транспортировки целлюлозы по маршрутам, а не по количеству

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

* т.е. в приведенном ниже коде, если какая-либо route_var (количество) выбрана оптимизатором как ›0, я хочу прикрепить к ней одинаковую стоимость независимо от количества, иначе игнорируйте ее (0 стоимость). prob + = lpSum ([np.minimum (route_vars [w] [b], 1) cost [w] [b] для (w, b) в маршрутах]), Всего полос

Я пытался использовать np.minimum, но решение, похоже, не учитывает это. Какая альтернатива?

supply=pd.DataFrame.from_dict({38893: {'location_code': '2025', 'excess_cases': 18.0},
 43872: {'location_code': '1580', 'excess_cases': 16.0},
 43929: {'location_code': '1036', 'excess_cases': 16.0},
 62403: {'location_code': '1607', 'excess_cases': 10.0},
 67220: {'location_code': '1983', 'excess_cases': 9.0}}).T

demand=pd.DataFrame.from_dict({12223: {'location_code': '3321', 'deficit_cases': 12.0},
 15682: {'location_code': '3077', 'deficit_cases': 9.0},
 16147: {'location_code': '1264', 'deficit_cases': 9.0},
 18964: {'location_code': '3208', 'deficit_cases': 7.0},
 19389: {'location_code': '1031', 'deficit_cases': 7.0}}).T


VendorStores = supply['location_code']
excess = supply.set_index(['location_code'])['excess_cases'].to_dict()
deficitStores = demand['location_code']
deficit = demand.set_index(['location_code'])['deficit_cases'].to_dict()
costs = makeDict((VendorStores, deficitStores),[[1]*len(deficitStores)]*len(VendorStores))

prob = LpProblem("LP Problem",LpMinimize)
Routes = [(w,b) for w in VendorStores for b in deficitStores]
route_vars = LpVariable.dicts("Route",(VendorStores,deficitStores),0,None,LpInteger)
prob += lpSum([np.minimum(route_vars[w][b],1)*costs[w][b] for (w,b) in Routes]), "Total Lanes"
for w in VendorStores:
    prob += lpSum([route_vars[w][b] for b in deficitStores]) <= excess[w], "Sum of Cases out of VendorStore {0}".format(str(w))
for b in deficitStores:
    prob += lpSum([route_vars[w][b] for w in VendorStores]) >= deficit[b]

person Ankit Goel    schedule 31.07.2020    source источник


Ответы (1)


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

Чтобы добавить параметр, обозначающий, где вы используете маршрут, в терминах LP должно работать следующее условие:

Let c_r = cost of using route r
    r   = whether route r is being used
    d_r = total quantity shipped over route r
    M   = a very big number (at least the sum of all quantities or the capacity of a truck)

min  sum(c_r * r)
s.t. Mr >= d_r
     d_r >= 0
     r in {0, 1}

Здесь, если по маршруту r ничего не отправлено, тогда r будет равно нулю, чтобы минимизировать целевую функцию, а если d_r > 0, то r будет 1, Mr = M, что будет работать, если d_r <= M. Таким образом, все зависит от значения, которое вы выбираете для M.

В терминах Python:

prob = LpProblem("LP Problem", LpMinimize)

route_vars = LpVariable.dicts("Route",(VendorStores, deficitStores), 0, None, LpInteger)  # d_r in the example
route_used = LpVariable.dicts("Route",(VendorStores, deficitStores), 0, 1, LpInteger)  # d_r in the example
a_very_large_number = 10000 # replace or calculate

# Objective function
prob += lpSum([(route_used[w][b],1)*costs[w][b] for (w,b) in Routes])

for w in VendorStores:
    prob += lpSum([route_vars[w][b] for b in deficitStores]) <= excess[w], "Sum of Cases out of VendorStore {0}".format(str(w))
for b in deficitStores:
    prob += lpSum([route_vars[w][b] for w in VendorStores]) >= deficit[b]

for (w, b) in routes:
    prob += a_very_large_number * route_used[w][b] >= route_vars[w][b], "Route used"
person Ruben Helsloot    schedule 31.07.2020
comment
Спасибо! Я нашел решение из следующего: prob + = a_very_large_number * route_used [w] [b] ›= route_vars [w] [b], Route used - person Ankit Goel; 31.07.2020