【问题标题】:How to use constraint programming for optimizing shopping baskets?如何使用约束规划来优化购物篮?
【发布时间】:2011-02-18 19:23:46
【问题描述】:

我有一份我想购买的物品清单。这些商品由不同的商店和不同的价格提供。商店有单独的送货费用。我正在寻找一种最佳的购物策略(以及支持它的 java 库)以最低的总价购买所有商品。

示例:

  • 商品 1 在 Shop1 的售价为 100 美元,在 Shop2 的售价为 111 美元。
  • 商品 2 在 Shop1 的售价为 90 美元,在 Shop2 的售价为 85 美元。
  • Shop1 的运费:如果总订单
  • Shop2 的运费:如果总订单
  • 如果我在 Shop1 购买商品 1 和商品 2,总成本为 100 美元 + 90 美元 + 0 美元 = 190 美元。
  • 如果我在 Shop2 购买商品 1 和商品 2,总成本为 111 美元 + 85 美元 + 0 美元 = 196 美元。
  • 如果我在 Shop1 购买商品 1,在 Shop2 购买商品 2,总成本为 $100 + $10 + $85 + $0 = 195.

如果我在 Shop1 订购商品 1 和商品 2,我将获得最低价格:190 美元

到目前为止我尝试了什么

我问过another question,然后才让我进入约束编程领域。我查看了creamchoco,但我没有弄清楚如何创建一个模型来解决我的问题。

         | shop1 | shop2 | shop3 | ...
-----------------------------------------
item1    | p11   | p12   | p13   |
item2    | p21   | p22   | p23   |
 .       |       |       |       |
 .       |       |       |       |
-----------------------------------------
shipping | s1    | s2    | s3    |
limit    | l1    | l2    | l3    |
-----------------------------------------
total    | t1    | t2    | t3    |
-----------------------------------------

我的想法是定义这些约束:

  • 每个价格“p xy”定义在域 (0, c) 中,其中 c 是该商店中商品的价格
  • 一行中只有一个价格不应为零
  • 如果从一家商店购买一件或多件商品并且价格总和低于限额,则将运费添加到总费用中
  • 商店总成本是商店中所有商品价格的总和
  • 总成本是所有店铺总和的总和

目标是“总成本”。我想尽量减少这种情况。

在奶油中,我无法表达有条件运输成本的“如果那么”约束。

在 choco 中存在这些限制,但即使对于 5 件商品和 10 家商店,该程序也运行了 10 分钟而没有找到解决方案。

问题

我应该如何表达我的约束以使这个问题可以被约束规划求解器解决?

【问题讨论】:

    标签: java constraints mathematical-optimization constraint-programming


    【解决方案1】:

    我已经在MiniZinc(一种高级约束编程语言)中实现了这个问题:shopping_basket.mzn。它非常先进,也许可以用作您的 Java 模型的模型。

    对于 Choco 模型,您是否尝试过不同的搜索策略?不同的策略可能会更快。

    顺便说一句,您可能想查看的另一个 Java 约束编程求解器是 JaCoP

    【讨论】:

    • 非常感谢!我一定会仔细研究 MiniZinc,尤其是您的程序!
    • 您如何模拟并非所有商店都出售所有商品的事实?只需给他们一个非常高的价格,比如 999999999?
    • 这是一种方法,可能是最简单的方法。另一种方法是将其编码为 0(零)并相应地调整计算,但这可能更混乱。我现在修复了模型中的一个错误,并添加了第三家没有商品 1 的商店(编码为 9999999)。
    • 下一次尝试:hakank.org/minizinc/shopping_basket5.mzn 在这里,我继续使用单数组方法,但对域进行了相当大的改进(这似乎是正确的)。此外,N/A 编码为 99999(对于 Gecode/fz 而言并非真正需要),搜索启发式为“最大/indomain_max”。 Gecode/fz 在大约 25 秒内求解,结果如下: total = 42013 x = [13, 20, 17, 18, 18, 13, 17, 17, 20, 13, 17, 17, 13, 13, 18, 17、13、13、17、8、13、36、10、17、13、13、17、20、13]
    • 我在我的博文“优化购物篮:MiniZinc 模型的开发”中对此进行了详细解释:hakank.org/constraint_programming_blog/2010/05/…
    【解决方案2】:

    您要问的实质上是k-knapsack problem。我喜欢的维基百科页面有丰富的解决方案资源。然而问题是 NP-Complete 可以完全解决,因此您可能希望通过simulated annealing 或其他形式寻找接近最佳的解决方案,以搜索问题空间。

    首先要记住的是,在约束问题中,您最终可能会花费大量时间来生成解决方案。在您之前的示例中,虽然 5 件商品和 10 家商店看起来很小,但实际上会产生很大的问题空间(大约 1e5 不包括进一步引起问题的附加条件定价的复杂性)。

    这个问题的限制是你每件都买一件。目标是最低价格。我认为您所拥有的相当不错,尽管我不太确定要点一和二。

  • 每个价格“p xy”在域 (0, c) 中定义,其中 c 是该商店中商品的价格
  • 一行中只有一个价格不应为零
  • 我会考虑将运费摊销到所购买物品的成本上,而不是在计算时将其作为总价值添加。

    【讨论】:

    • 好的,现在我认识到优化中的背包问题。但我仍然没有解决它的想法。对于运输成本条件,我认为背包问题中没有等价物。
    • 我将编辑我的答案并尝试提供一些建议。认为最好的办法是对问题本身进行一些研究。它有一个相当丰富的身体,有一些非常有趣的论文。
    • 你能再解释一下你的最后一段吗?你会怎么处理运费?
    【解决方案3】:

    我不太确定这是一个 k-knapsack 问题。该问题确实提到了“购物篮”一词,但没有具体说明任何给定货物的容量。如果您指定了最大装运尺寸,那么问题开始看起来更像是一个背包问题。

    这个问题实际上只是一个基本的网络流问题,弧上的运输成本和起点的成本。因为您有一个明确的目标函数 - 最小化运输 + 产品成本,并且因为可能只有一种解决方案,所以 CP 可能不是最好的方法。

    将求解视为线性规划问题:

    最小值:运输 + 产品成本

    ST:总出货量 >= 需求(每种产品)

    您可能需要为运输成本开发一些分段线性方程,但这应该不是问题。

    【讨论】:

      猜你喜欢
      • 2018-05-24
      • 1970-01-01
      • 2013-03-24
      • 2019-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-07
      • 2015-05-11
      相关资源
      最近更新 更多