如何使用约束编程来优化购物篮?

时间:2010-05-12 19:24:00

标签: java constraints mathematical-optimization constraint-programming

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

实施例

  • 第1项目在Shop1以100美元的价格在Shop2以111美元的价格提供。
  • 第2项目在Shop1以90美元的价格在Shop2以85美元的价格提供。
  • Shop1的交付成本:如果总订单数为10美元,则为10美元。 $ 150,否则为$ 0
  • Shop2的运送成本:如果总订单数为5美元,则为5美元。 $ 50;否则为$ 0
  • 如果我在Shop1购买Item1和Item2,总成本为100美元+ 90美元+ 0美元= 190美元。
  • 如果我在Shop2购买Item1和Item2,总成本为111美元+ 85美元+ 0美元= 196美元。
  • 如果我在Shop1购买Item1,在Shop2购买Item2,总费用为100美元+ 10美元+ 85美元+ 0美元= 195。

如果我在Shop1订购Item1和Item2,我会得到最低价格:$ 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 是此商店中商品的价格
  • 一行中只有一个价格应为非零
  • 如果从一个商店购买一件或多件商品且价格总和低于限额,则将运费增加到总成本中
  • 店铺总成本是商店中所有商品价格的总和
  • 总费用是所有商店总数的总和

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

在奶油中,我无法表达有条件运费的“if then”限制。

在choco中存在这些约束,但即使对于5个项目和10个商店,程序运行10分钟而没有找到解决方案。

问题

如何表达我的约束以使约束编程求解器能解决这个问题?

3 个答案:

答案 0 :(得分:4)

我在MiniZinc(高级约束编程语言)中实现了这个问题:shopping_basket.mzn。它非常前瞻,可能可以用作Java模型的模型。

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

顺便说一下,您可能要查看的另一个Java约束编程解算器是JaCoP

答案 1 :(得分:3)

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

首先要记住的是,在约束问题中,您可能最终会花费大量时间来生成解决方案。在您之前的示例中,虽然五个项目和十个商店看起来很小,但实际上,它会产生一个大的问题空间(大约1e5,不包括条件定价的额外复杂性,这进一步影响了问题)。

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

  

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

    答案 2 :(得分:1)

    我不太确定这是一个k -ackackack问题。这个问题确实提到了“购物篮”这个词,但未指明任何特定货物的容量。如果您指定了最大装运尺寸,则问题开始看起来更像是背包问题。

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

    考虑解决线性规划问题:

    最低:运输+产品成本

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

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