python - ortools / 线性规划 - 最小化跨供应商的购物篮成本
问题描述
作为约束编程和 ORTools 的新手,我不知道下一步该如何解决这个问题。
它是经典的“将多个供应商之间的购物车成本降至最低”(对不起!!)
我有 python/ORTools 计算整个篮子的最低成本(如果可能),使用变量矩阵 - 项目与从每个供应商订购的数量 - 但我想在模型中添加以下内容:
- 运费(可能会因每个供应商以及该供应商的商品数量而变化(例如:供应商 1:<=5 件 = 1 美元运费,>5 件 = 2 美元运费)供应商 2:<=5 件 = 1 美元运费,>5 件= 免费送货
- 商店信用 - 如果我有商店信用,我想将其考虑在内 - 优先使用商店信用
如果找不到完整的篮子(例如,我想要 10 件商品,但所有供应商只有 5 件有库存,是否有可能获得最接近的解决方案?(最接近最低价格的最想要的商品?) - 目前它只是说没有找到解决方案。(更改第 18 行 - items[0] = 10 来触发)
很高兴去挖掘,但不确定要寻找什么!谢谢!!
代码如下:
from ortools.linear_solver import pywraplp
#prices at vendors of each item
#(eg item 2 is 0.05 at vendor 2)
allStockPrice = {}
allStockPrice[0] = [10, 11]
allStockPrice[1] = [0.15, 0.20]
allStockPrice[2] = [0.04, 0.05]
#stock at vendors of each item
allStockQty = {}
allStockQty[0] = [1, 6]
allStockQty[1] = [0, 2]
allStockQty[2] = [5, 1]
#number of each item that I want to purchase
items = {}
items[0] = 5
items[1] = 2
items[2] = 1
#create a variable array for the solver
#how many of each item am I ordering from each vendor?
variable_list = [[]] * len(items)
variable_list[0] = [[]] * len(allStockPrice[0])
variable_list[1] = [[]] * len(allStockPrice[0])
variable_list[2] = [[]] * len(allStockPrice[0])
def configure_objective(solver):
global allStockPrice, variable_list
objective = solver.Objective()
#coefficient for each variable is the cost to purchase
for i in items:
for j in range(len(allStockPrice[0])):
objective.SetCoefficient(variable_list[i][j], allStockPrice[i][j])
objective.SetMinimization()
return objective
def configure_constraints(solver):
global allStockPrice, allStockQty, items, variable_list
#can only have upto the maximum amount wanted of each item
for i in items:
solver.Add(sum(variable_list[i]) == items[i])
#items must be in stock at the vendor
for i in items:
for j in range(len(allStockPrice[0])):
solver.Add(variable_list[i][j] <= allStockQty[i][j])
def configure_variables(solver):
global allStockPrice, allStockQty, items
#must get between 0 and x items
for i in items:
for j in range(len(allStockPrice[0])):
variable_list[i][j] = solver.IntVar(0, items[i], str('x_i%i_v%i' % (i, j)))
return variable_list
def solve(solver):
result_status = solver.Solve()
return result_status
def print_solution(solver, result_status, variable_list, constraint_list):
if result_status == solver.OPTIMAL:
print('Successful solve.')
# The problem has an optimal solution.
print(('Problem solved in %f milliseconds' % solver.wall_time()))
# The objective value of the solution.
print(('Optimal objective value = %f' % solver.Objective().Value()))
# The value of each variable in the solution.
var_sum = 0
print (variable_list)
for variable in variable_list:
for vendor in variable:
print(('%s = %f' % (vendor.name(), vendor.solution_value())))
var_sum += vendor.solution_value()
print(('Variable sum = %f' % var_sum));
print('Advanced usage:')
print(('Problem solved in %d iterations' % solver.iterations()))
for variable in variable_list:
for vendor in variable:
print(('%s: reduced cost = %f' % (vendor.name(), vendor.reduced_cost())))
elif result_status == solver.INFEASIBLE:
print('No solution found.')
elif result_status == solver.POSSIBLE_OVERFLOW:
print('Some inputs are too large and may cause an integer overflow.')
solver = pywraplp.Solver('SolveSimpleSystem', pywraplp.Solver.GLOP_LINEAR_PROGRAMMING)
variable_list = configure_variables(solver)
constraint_list = configure_constraints(solver)
objective = configure_objective(solver)
result_status = solve(solver)
print_solution(solver, result_status, variable_list, None)
解决方案
尝试手动创建解决方案,您会发现没有解决方案。
sum(variable_list[i]) == items[i]
如果 i = 0 是不可能满足的,那么您总共有 7 件库存,但您迫使求解器购买 10 个。
如果您想找到“最接近”的解决方案,您需要通过使用“软约束”定义一个最接近可行解决方案的优化问题。在您的示例中,最简单的方法是定义一个具有无限库存和非常昂贵物品的假第三供应商。仅当常规供应商之一无法满足需求时才会使用此功能。
请参阅https://colab.research.google.com/drive/1nBrMsUxCVea5PG8juzfdYPm4PdM6N9dJ?usp=sharing
推荐阅读
- async-await - Loopback js 连接器使用 async / await
- android - 在 Android 中,奥利奥通知图标颜色为灰色
- airflow - ariflow dag_run 未设置 end_date
- c# - 使用 ODBC 从 Excel 中以字符串形式读取 excel 数据
- c# - 关于 C# 中的泛型和列表方法 Contains()
- python - 使用 PySpark 创建具有空格分隔数据的数据框
- python - 元组列表到字符串列表的转换
- python - 如何在 loader.render_to_string 中发送变量以在 html 中显示它
- r - ggplot2 - 使用具有缺失值的数据制作连续图
- javascript - 检索地点 api 的 json