背景:
这是一个非常简单的脚本,希望实现以下目标:
到目前为止,我已经完成了从没有发货的地方返回最低成本和订购内容的细分。
我目前仍然坚持如何在SUM(VendorVar[x]{0:1} * ShippingData[x])
部分工作,因为如果我从卖家订购的商品数量,我基本上需要一种方法将二进制值切换为ON/1
是> 0
from pulp import *
items = ["Item1", "Item2", "Item3", "Item4"]
vendors = ["Vendor1", "Vendor2", "Vendor3", "Vendor4"]
# List containing lists for each Vendor and their Item costs for Item1, Item2, Item3, Item4 respectively:
costData = [[1.00,5.00,10.00,0.15],
[1.50,2.50,5.00,0.25],
[0.50,1.00,15.00,0.50],
[1.75,10.00,2.00,0.10]]
# List containing lists for each Vendor and their Supply for Item1, Item2, Item3, Item4 respectively:
supplyData = [[0,2,4,1],
[4,0,1,4],
[1,1,1,1],
[8,8,8,8]]
# Created nested dictionaries per Item per Vendor for Costs: {Item1: {Vendor1:Cost, Vendor2:Cost...}}
vendoritemcosts = makeDict([items,vendors],costData)
# Created nested dictionaries per Item per Vendor for Supply: {Item1: {Vendor1:Supply, Vendor2:Supply...}}
vendoritemsupply = makeDict([items,vendors],supplyData)
# Shipping costs per Vendor:
shippingData = {"Vendor1":0.99,
"Vendor2":1.99,
"Vendor3":0.00,
"Vendor4":2.99}
# Number of items desired:
demand = {"Item1":4,
"Item2":4,
"Item3":4,
"Item4":8}
# Number of items to purchase for each Vendor/Item combination:
vendoritemvar = LpVariable.dicts("item",(items,vendors),0,None,LpInteger)
# Binary flag that (hopefully) will determine if a Vendor is included in the final optimized formula or not:
vendorvar = LpVariable.dicts("vendor",vendors,0,1,LpBinary)
prob = LpProblem("cart",LpMinimize)
# Objective Function: Take the sum of quantity ordered of each unique Vendor+Item combination multiplied by its price
# For every Vendor included in the list, multiple {0:1} to their shipping costs, with 1 being used if they have any items in the first portion of the function above
prob += lpSum([vendoritemvar[a][b] * vendoritemcosts[a][b] for a in vendoritemvar for b in vendoritemvar[a]]) \
+ lpSum(vendorvar[c] * shippingData[c] for c in vendorvar)
for a in vendoritemvar:
# Sum total of each item must equal Demand
prob += lpSum(vendoritemvar[a]) == demand[a]
# Currently testing minimum checkout values which will be a future addition that isn't a fixed value:
prob += lpSum(vendoritemvar[a][b] * vendoritemcosts[a][b] for b in vendoritemvar[a]) >= 2.00
for b in vendoritemvar[a]:
# Non-negativity constraint
prob += vendoritemvar[a][b] >= 0
# Can't exceed available supply
prob += vendoritemvar[a][b] <= vendoritemsupply[a][b]
prob.solve()
print("Status: %s" % LpStatus[prob.status])
for v in prob.variables():
print("%s = %s" % (v.name,v.varValue))
print("Total cart = %s" % value(prob.objective))
答案 0 :(得分:1)
我认为你只需要添加含义
vendorvar[v] = 0 => vendoritemvar[i,v] = 0
这可以用big-M约束建模:
vendoritemvar[i,v] ≤ M * vendorvar[v]
M的良好值可以从supplyData/vendoritemsupply
表中得出:
vendoritemvar[i,v] ≤ vendoritemsupply[i,v] * vendorvar[v]