【问题标题】:ortools / linear programming - minimise cost of shopping basket across vendorsortools / 线性规划 - 最小化跨供应商的购物篮成本
【发布时间】:2021-04-23 17:51:44
【问题描述】:

通常是约束编程和 ORTools 的新手,我不确定下一步如何解决这个问题..

这是经典的“将多个供应商之间的购物车成本降至最低”(抱歉!!)

我有 python/ORTools 计算整个篮子的最低成本(如果可能),使用变量矩阵 - 项目与从每个供应商订购的数量 - 但我想在模型中添加以下内容:

  1. 运费(可能因供应商而异,以及来自该供应商的商品数量(例如: 供应商 1:5 件商品 = 2 美元运费 供应商 2:5 件商品 = 免运费
  2. 商店信用 - 如果我有商店信用,我想将其考虑在内 - 首先优先使用商店信用

如果找不到完整的购物篮(例如,我想要 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)

【问题讨论】:

    标签: python linear-programming or-tools constraint-programming


    【解决方案1】:

    尝试手动创建解决方案,您会发现没有解决方案。

    sum(variable_list[i]) == items[i] i = 0 是不可能满足的,您总共有 7 件库存,但您强迫求解器购买 10 个。

    如果您想找到“最接近”的解决方案,您需要使用“软约束”定义一个最接近可行解决方案的优化问题。在您的示例中,最简单的方法是定义一个具有无限库存和非常昂贵物品的假第三供应商。只有在常规供应商之一无法满足需求时才会使用此选项。

    https://colab.research.google.com/drive/1nBrMsUxCVea5PG8juzfdYPm4PdM6N9dJ?usp=sharing

    【讨论】:

    • 没错,我明白-问题更像是这种方法是否可以用来给出“最接近解决方案”的方法,如果可以,如何?
    • 当然,您定义了一个额外的供应商,该供应商有足够的库存来满足全部需求,它将以每件 100 万美元的价格向您出售物品(理想情况下,这是显然仍然不可能的最小数量)。跨度>
    • 有趣...好吧,这样一来,我的购物篮总数将是 10 件商品,但成本非常高。这并没有让我更接近部分解决方案……所以我们添加了一个约束,即总数也必须小于大数的 1 倍……让我试试,谢谢!
    • 嗯,没有那个额外的约束不会像我想象的那样起作用......还有其他想法吗?
    • 为什么需要额外的约束。只需添加第三个供应商,它应该完全符合您的要求 - 如果无法在其他地方满足该需求,它应该只从第三个供应商订购,并且应该高兴地从 1 和/或 2 订购一小部分需求,因为它们更便宜. colab.research.google.com/drive/…
    猜你喜欢
    • 1970-01-01
    • 2011-02-18
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多