简体   繁体   English

路线上的纸浆运输问题,而不是数量上的问题

[英]Pulp transportation problem on routes and not on quantities

The transportation problem in PuLP works on each item transported.纸浆中的运输问题适用于运输的每件物品。 However, in my case, every route/lane you use has a cost rather than each item shipped ie the objective function is to minimize number of routes (trucks) used.但是,在我的情况下,您使用的每条路线/车道都有成本,而不是运送的每件物品,即目标 function 是尽量减少使用的路线(卡车)的数量。

* ie in below code if any route_var (quantity) is chosen as >0 by optimizer, I want to attach same cost to it irrespective of quantity, else ignore it (0 cost). *即在下面的代码中,如果优化器将任何 route_var(数量)选择为 >0,我想对其附加相同的成本,而不管数量如何,否则忽略它(0 成本)。 prob +=lpSum([np.minimum(route_vars[w][b],1) costs[w][b] for (w,b) in Routes]), "Total Lanes" prob +=lpSum([np.minimum(route_vars[w][b],1) cost[w][b] for (w,b) in Routes]), “总车道”

I tried to use np.minimum but the solution doesnt seem to take it into account.我尝试使用 np.minimum 但解决方案似乎没有考虑到它。 What is the alternative?什么是替代方案?

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]

Your code is not very clear and incomplete;您的代码不是很清晰和不完整; we have no idea what costs looks like.我们不知道成本是什么样的。 Please improve it by explaining or using clearer variable names, for example.例如,请通过解释或使用更清晰的变量名称来改进它。

To add a parameter denoting where you're using a route, in LP terms, the following condition should work:要添加一个参数来表示您使用路线的位置,在 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}

Here, if there is nothing shipped over route r, then r will be zero to minimise the objective function, and if d_r > 0 , then r will be 1, Mr = M , which will work if d_r <= M . Here, if there is nothing shipped over route r, then r will be zero to minimise the objective function, and if d_r > 0 , then r will be 1, Mr = M , which will work if d_r <= M . Thus it all depends on the value you choose for M.因此,这完全取决于您为 M 选择的值。

In python terms:在 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"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM