剁手党必看——转转红包使用规则与最优组合计算全解析

  • 1、省钱攻略基础之“了解平台红包使用规则”

  • 2、举个栗子

  • 3、最优红包组合计算方法进化过程

    • 3.1、初代“笛卡尔乘积”版

    • 3.2、二代“边算边比较Map聚合”版

    • 3.3、三代“边算边比较数组索引定位”版

  • 4、总结

1、省钱攻略基础之“了解平台红包使用规则”

规则一:红包大类别分为“商品红包”、“叠加券”、“邮费红包”三种。

规则二:每个SKU(同一个商品ID),商品红包、叠加券、邮费红包最多每种使用一张。

规则三:商品红包和叠加券都有可能设定使用门槛金额,门槛金额是商品促销优惠后金额(如果有促销),邮费红包使用门槛基于商品红包和叠加券优惠后金额计算。

规则四:门槛金额高的红包优惠不一定高于门槛低的(虽然大概率如此)。

规则五:绝大多数红包都有使用限制条件,与商品相关的:分类、归属的业务、卖家、包含的服务、特定的商品范围、商品发布时间;与场景相关:终端类型、卖场;与买卖家相关:是否是“新客户”、买卖家是否被风控等等。

规则六:商品红包和叠加券小类分为:满额减和满额折,其中满额折红包又有最大优惠金额如满10元8.8折最多优惠1000元,此时如果商品10000元最多也只能减1000元;邮费红包分为定额红包和免邮红包。

2、举个栗子

在开始计算最大优惠前,我们先举个例子具象化实际场景,此处忽略“规则五”计算过程,直接给出符合红包使用限制的商品与红包关系;由于邮费红包门槛金额基于商品红包和叠加券后金额较为复杂,且不影响最优红包解题思路,此处忽略邮费红包,仅以商品红包为例。

场景如下:

5个商品分别为:P1=10元、P2=20元、P3=30元、P4=40元、P5=50元。

5个商品红包:R1=满10元减5元、R2=满20元减12元、R3=满30元减10元、R4=满90元减60元、R5=满100元减80元。商品与红包的关系如下表格:

3、最优红包组合计算方法进化过程

3.1、初代“笛卡尔乘积”版

首先,将每个红包的可用商品聚合:

R1->P2、P3、P4、P5 R2->P1、P3、P4、P5 R3->P1、P2、P4、P5 R4->P1、P2、P3、P5 R5->P1、P2、P3、P4

将每个红包的可用商品进行排列组合得到下表(黄色为该组合不符合红包门槛):

将上表改写成矩阵:

计算纵列笛卡尔积:

计算各组合红包的优惠情况,按红包优惠金额倒序,取红包最大优惠组合情况, 得到:P5商品使用R2;P1P2P3P4使用R5,得到最大优惠金额80+12=92元。

该版本核心思想:计算出所有商品使用红包的组合情况,并行计算各组合的优惠金额,按优惠金额倒序取最大优惠。存在的问题:商品和红包数量增加时组合数呈指数级增长,计算笛卡尔积时很容易OOM。

3.2、二代“边算边比较Map聚合”版

一代算法最大的问题是将所有组合全部排列好后再进行价格计算和比较,导致内存占用过大;二代算法核心思想是“边排列组合边计算边比较”保留最优解,计算耗时到达规定阈值时停止,取已算组合中的最优。这一代算法中,用到了HashMap作为记录商品使用红包的标记指针,数据结构如下:

//用于记录每个商品上,各大类可用红包的列表
private Map<ERedMetaBigType, List<RedBaseInfoInput>> prodRed = Maps.newHashMap();//用于记录该商品在各大类红包列表List<RedBaseInfoInput>上使用红包的列表index位置private Map<ERedMetaBigType, Integer> pointer = Maps.newHashMap();

指针移动抽象示例(黄色为此轮组合指针位置):

移动一次指针就形成一个新的组合,根据根据标记将使用相同红包的商品“聚合” 如组合2:R5<P1,P2,P3,P4> R3

//使用Map结构记录
Map<ERedMetaBigType, Map<Long, List<EngineInput>>> oneType2RedId2Prods = Maps.newEnumMap(ERedMetaBigType.class);

优点:不需要将所有组合都排列出后再计算比较,超过规定时间可以中断降级处理。缺点:每次移动指针后,都需要使用Map结构将红包商品重新“聚合”后才能计算红包门槛和优惠,频繁生产销毁Map和List对象,GC压力大。

3.3、三代“边算边比较数组索引定位”版

三代主要通过数据结构与虚拟逻辑关系,减少上一代算法大量生成中间临时Map导致GC压力大问题。使用数组Long[] infoArray存储商品列表,此时infoArray数组下标就含有了商品ID的含义,同理,Long[] redArray存储红包列表,redArray数组下标就含有了红包ID的含义。使用byte[][] infoRedRel二维数组用于存储商品红包关系,数组值0表示此轮计算未使用,1表示此轮计算使用,-1表示该商品不可使用此红包。关系数组如下:

拥有这个二维数组后,就可以通过修改这个位数数组的值(不包含-1不可用的),实现红包使用组合的变更。

此时聚合商品不再需要使用Map生成新的结构存储,只需要遍历红包列表数组,根据数组下标去infoRedRel维数组中获取数组值,然后去infoArray取商品即可。

4、总结

本文简述了最优红包组合的整体演进,下表是二代和三代在不同红包总量、商品数量、商品可用红包数量时,200ms完成计算组合数的情况对比(30次均值)如下图:

通过二代三代的对比,我们不难发现,在面对大量计算时除了要注意JVM内存使用情况外(一代FullGC或溢出),还需要关注对象生成销毁的数量与频率,因为在面临大量计算时对象生成和GC也将成为性能瓶颈,三代相较二代,完成计算的组合数在5倍以上,这其间的差距都是因为二代Map对象的生成和销毁。


关于作者

马宝山,  转转交易中台Java开发工程师

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/678827.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

论文分享[cvpr2018]Non-local Neural Networks非局部神经网络

论文 https://arxiv.org/abs/1711.07971 代码https://github.com/facebookresearch/video-nonlocal-net 非局部神经网络 motivation:受计算机视觉中经典的非局部均值方法[4]的启发&#xff0c;非局部操作将位置的响应计算为所有位置的特征的加权和。 非局部均值方法 NLM&#…

C++之初阶模板

个人主页&#xff1a;救赎小恶魔 欢迎大家来到小恶魔频道 好久不见&#xff0c;甚是想念 今天我们要深入讲述C内存管理 目录 引言&#xff1a; 模板 1. 泛型编程 2. 模板函数 2.1函数模板的原理 2.2模板函数的实例化 2.3函数模板的匹配 3.类模板 STL STL 的主要组…

HackMyVM-Slowman

目录 信息收集 arp nmap whatweb WEB web信息收集 gobuster FTP匿名登录 hydra mysql爆破 mysql登录 fcrackzip爆破 hashcat爆破 ssh登录 提权 系统信息收集 python Capabilities提权 信息收集 arp ┌──(root㉿0x00)-[~/HackMyVM] └─# arp-scan -l Interf…

svg画扇形进度动画

有人问下面这种图好怎么画&#xff1f;svg 想了下&#xff0c;确实用svg可以&#xff0c;可以这么设计 外层是一个容器放置内容&#xff0c;并且设置overflow:hidden&#xff0c; 内层放一个半径大于容器宽高一半的svg&#xff0c;并定位居中&#xff0c;然后svg画扇形&#x…

Spring Task及订单状态定时处理

1&#xff1a;Spring Task概念&#xff1a; Spring Task 是Spring框架提供的任务调度工具&#xff0c;可以按照约定的时间自动执行某个代码逻辑 定时任务的理解 定时任务即系统在特定时间执行一段代码&#xff0c;它的场景应用非常广泛&#xff1a; 购买游戏的月卡会员后&a…

【华为OD机试】攀登者2(C++/Java/Python)

【华为OD机试】-(A卷+B卷+C卷+D卷)-2024真题合集目录 【华为OD机试】-(C卷+D卷)-2024最新真题目录 题目描述 攀登者喜欢寻找各种地图,并且尝试攀登到最高的山峰。 地图表示为一维数组,数组的索引代表水平位置,数组的元素代表相对海拔高度。其中数组元素0代表地面。 例如:[…

嵌入式引脚工作模式

一.引脚工作模式的基本概念 引脚的工作模式通常包括输入模式、输出模式和双向模式&#xff1a; 输入模式&#xff1a;引脚设置为输入模式时&#xff0c;可以接收外部信号或触发器的信号。这种模式通常用于读取传感器数据、接收外部设备的信号等。 输出模式&#xff1a;引脚设…

认识大模型提示词

一、写作助理 &#x1f4a5;最常使用的 prompt&#xff0c;用于优化文本的语法、清晰度和简洁度&#xff0c;提高可读性。 输入&#xff1a;作为一名写作改进助理&#xff0c;你的任务是改进所提供文本的拼写、语法、清晰、简洁和整体可读性&#xff0c;同时分解长句&#xff…

Windows下启动Tomcat显示乱码解决办法

1、Windows下启动Tomcat显示乱码 2、解决办法 找到 D:\apache-tomcat-9.0.89\conf下的logging.properties&#xff0c;找到java.util.logging.ConsoleHandler.encoding的值改为GBK&#xff0c;就可以了 完美解决&#xff01;显示正常的中文了

「网络流 24 题」魔术球 【最小路径覆盖】

「网络流 24 题」魔术球 注意这里的球是依次放置&#xff0c;也就是说如果当前放到第 i i i 号球&#xff0c;那么 1 → i − 1 1 \rarr i - 1 1→i−1 号球都已经放好了&#xff0c;否则可以放无数个球 思路 首先我们对于 i < j 且 i j 完全平方数 i < j 且 i j…

Django-新冠疫情数据分析系统-67684

目 录 摘要 1 绪论 1.1 研究背景 1.2论文结构与章节安排 2 新冠疫情数据分析系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据增加流程 2.2.2 数据修改流程 2.2.3 数据删除流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2.4 系统用例分析…

SlowFast报错:ValueError: too many values to unpack (expected 4)

SlowFast报错&#xff1a;ValueError: too many values to unpack (expected 4) 报错细节 File "/home/user/yuanjinmin/SlowFast/tools/visualization.py", line 81, in run_visualizationfor inputs, labels, _, meta in tqdm.tqdm(vis_loader): ValueError: too …