组合“产品”以形成促销

时间:2012-11-26 11:21:23

标签: algorithm set combinations shopping-cart bipartite

我正在重新开发一个遗留系统,该系统将用户选择的零售产品购物篮与一个或多个有效的促销相匹配。这些促销活动是行业标准BOGOF(买一送一),买二送三,购买产品X和Y并获得10%折扣等等......但都需要您可以将潜在商品列表过滤到那些满足这些促销活动。

我希望解决方案能够整个购物篮零售商品并在一次操作中对其进行分析,而不是现有的方法在订购时匹配单个产品。 (目前的解决方案会导致不良限制)

每次促销活动都必须有一系列符合条件的产品才能触发促销活动。它们以n组(或位置)排列,例如:

Example "Buy two get third free" Promotion =

| Item 1 |             | Item 1 |             | Item 2 |
|   or   |             |   or   |             |   or   |
| Item 2 |     AND     | Item 4 |     AND     | Item 6 |
|   or   |             |   or   |             |   or   |
| Item 3 |             | Item 9 |             | Item 4 |

  Set 1                   Set 2                  Set 3

每个促销必须只有一个产品来自每个组,除非该项目多次出现在同一个集合中。促销可以有无限制(但通常是<10)'套'的产品。

作为一个简单示例,Item 1, Item 4 and Item 6的购物篮将触发促销, 类似地,Item 1, Item 1 and Item 2的篮子也会触发它。 然而,Item 1, Item 2 and Item 3的篮子并不会因为每一组都不满意。

除了检测促销何时被触发的最佳方法的一个重要问题,我还需要恢复该项目已被匹配的集合(位置)以处理定价的细节等。如果在将它们分配给促销时比较便宜(同等匹配)的项目更受欢迎(以货币计算)项目,也是可取的。


希望下一部分有助于解决方案,而不是声音如此不清楚它会产生不必要的噪音,随意忽略!

到目前为止,我最好的解决方案是为每个零售商品创建一个新的集合 在“购物篮”中持有该项目将满足的促销集(位置)。 即

Item 1 satisifies sets: {1,2}
Item 4 satisifies sets: {2,3}
Item 6 satisifies sets: {3}

然后我的理论是你“检查”这个集合列表在每个位置包含一个唯一的项目,并且每个促销位置都被填充。到目前为止,我的工作示例都使用强力,循环或递归来生成集合的所有组合(上图),以尝试检查是否存在唯一组合。这非常非常严重,除了一个非常简单的例子以外的任何东西在现实世界中根本不起作用。 (当项目被添加到篮子中时,将实时调用此函数,因此需要快速)

许多研究表明,双向匹配会产生一些预期的结果,但我只能找到有关该主题的研究论文和相当复杂的数学文本。一些伪代码或基本逻辑会很棒。


我的两个问题基本上是:

1)是否有人看到更好/更快/更简单的方法来分析客户购物篮以产生匹配的促销活动 2)假设我已经确定了将项目匹配到相关职位的最有效方式,那么确定要根据促销记录的零售商品列表的最便宜方式是什么。

任何帮助都会感激不尽,因为我不能再在隧道尽头看到光明了! (最终解决方案将在.NET中,我们使用SQL Server 2008 R2。)

1 个答案:

答案 0 :(得分:1)

检查每个促销在特定购物车上的有效性可以减少到Max Flow。在描述我的解决方案时,我假设您能够实现并解决基于图形的Max流问题。如果不是那就是要解决的第二个问题(幸运的是一个更普遍的问题)。

让算法的输入如下:

  • 一组有效的所有项I。不一定用于算法的最终编码。
  • 尺寸为C的购物车n,是I个包含商品C_1 ... C_n的子集。因此C = {C_i}
  • i = 1...n
  • P个子集组成的单个促销m,每个子集包含可变数量的项目。每个子集S都是I的子集。每个子集都不能有重复项,但是可以在多个子集中存在单个项目。

构建图表G,如下所示:

  • 添加标记为SOURCE
  • 的超级源节点
  • 添加标记为SINK
  • 的超级汇聚合节点
  • 对于购物车C_i中的每个唯一商品C,添加可用商品节点A_i,然后添加SOURCEA_i的优势等于C_iC的出现次数。
  • 对于促销S_i中的每个子集P,请添加以下内容:
    • 单个集合节点S_i,以及从S_iSINK的边缘,容量为1
    • 针对I_j的每个必需项目S_i,必填项目节点B_i_j以及B_i_jS_i的边距,容量为1 }。
  • 最后,对于每对节点A_xB_y,使得它们所代表的项目是等效的,从A_xB_y的边缘具有容量{{1} }。

最后,运行最大流量算法,其中1作为源,SOURCE作为接收器。如果得到的最大流量值等于子集数量(SINK),则输出为true - 此购物车可以满足促销。否则输出错误 - 此购物车无法满足促销。

例如,对于您的设置示例,使用购物车m,应创建以下图表:

Sample graph for example

预计时间复杂度,其中项目数为{1,1,4,6},促销中的子集数量为n

  • 图形构造:
    • 添加mSOURCE - SINK
    • 从购物车中添加唯一商品,从来源添加边缘 - O(1)
    • 在 - O(N)
    • 之间添加子集和所需的项目节点和边缘
    • 将子集节点中的边添加到接收器 - O(N*M)
    • 在相应的项目节点之间添加边缘 - O(M)
    • 总计 - O(N^2)
  • 最大流算法 - 请参阅维基百科页面。简单的实施成本 - O(N^2 + N*M) = O(N * (N+M))。可以使用更复杂的算法进行改进。
  • 检索解决方案 - O((N*M)^3)