周末时间基本都在带娃,断更了一段时间,难得有点时间还是得有毅力坚持写,坚持总结。

最近公司在拓展电商相关业务,其中一个环节是物流发货。物流打包环节有一个需求是希望能给运营同事一个小工具能快速计算最优的包裹组合。

我们这里不关注过多业务细节,只是把这个问题抽象总结一下。

问题:

假设我们有如下4种规格的包裹可供选择:

name size weight price
Package S 20 5KG 4.99€
Package M 40 10KG 6.99€
Package L 80 20KG 8.99€
Package XL 120 30KG 10.99€

由于我们的货物是抛货, 所以只考虑给定任意总Size的的打包需求,能得到最优的包裹组合。

抛重:即是体积重,
1、当实重大于体积重,就属于重货,按实重计费度;
2、当体积重大于实重就叫抛货,按体积重计费;

这里最优的标准比较简单:包裹个数最少,同时也是总运费最低。

例如,我需要发153个货,那么最优的就是Package XL * 1 + Package M * 1。

贪心算法

很符合直觉的策略是先尽可能选大的包裹,先从小号开始匹配,小号的装不下就升级大一号的包裹,直到能装下或者没有更大的箱子了,依次类推。例如总共要装箱150个,那么:

  • 先用Package S 发现装不下,
  • 升级成Package M也装不下,
  • 继续升级成Package L也装不下,
  • 继续升级成Package XL也装不下,但是没有更大的选择了,所以(贪心)打包一次。更新待装箱的商品数据量 = 150 - 120 = 30;

这样每次一个周期结束,再次用剩余没装箱的数量继续这样做打包操作:

  • 先用Package S 发现装不下,
  • 升级成Package M发现能装下了,所以打包一次。更新待装箱的商品数据量 = 30 - 40 <= 0;

总结上述过程,我们发现每次迭代打包本质都是把当前需要求解的问题分成了一个子问题,每次解决子问题的策略都是尽量优先用最大的箱子,且任意子问题是不依赖上次迭代的结果。可以理解为每次迭代无非是传入了一个新的需要打包的产品数量,这样就能每次迭代都是朝着问题的最终解进了一步。

贪心算法不是对所有问题都能得到整体最优解,选择的贪心策略必须具备无后效性,即每次贪心决策不会影响以前的状态,只与当前状态有关。所以对所采用的贪心策略一定要仔细分析其是否满足无后效性。

所以贪心策略适用的前提是,局部最优策略能最终产生全局最优解。也就是当算法终止的时候,局部最优正好就是全局最优

实现

由于只是单纯的计算,不需要持久化业务的数据,如果把计算业务逻辑写在后端每次API调用也比较耗时,所以我索性直接用JS把计算代码也撸了。

计算代码:

  function minPackageCal(packages, amount) {let minimumUnit = Number.MAX_SAFE_INTEGER;let maximumUnit = 0;let packageMap = new Map();for (let i = 0; i < packages.length; i++) {packageMap.set(packages[i], 0);minimumUnit = Math.min(packages[i], minimumUnit);maximumUnit = Math.max(packages[i], maximumUnit);}let packageResult = [];let totalPacked = 0;while (totalPacked < amount) {for (let i = 0; i < packages.length; i++) {var packageUnit = packages[i];if(packageUnit > amount - totalPacked || packageUnit === maximumUnit){packageResult.push(packageUnit);packageMap.set(packageUnit, packageMap.get(packageUnit)+1);totalPacked += packageUnit;break;}}}return packageMap;}

调用代码:

    //given package typesconst packageTypes = [20, 40, 80, 120];//amountInputValue should be data binding with the input box    var result = minPackageCal(packageTypes, amountInputValue);

最终实现的效果:

贪心的局限性

在这里例子中,由于可供选择的包裹条件限制,我们使用贪心算法得出来的局部最优解恰好是全局最优解。但是如果我们换一个包裹组合阵型就不一定了,
比如:
假设今天我们的包裹Package M做了推广特价,从6.99€ 打折到3.99€,那么按照贪心我们不一定能得到最佳的组合了:

name size weight price
Package S 20 5KG 4.99€
Package M 40 10KG 3.99€
Package L 80 20KG 8.99€
Package XL 120 30KG 10.99€

如果局部最优不是全局最优,那么就不能用贪心算法,可以考虑用动态规划来解决这类最优解问题。

如果觉得有所收获,麻烦帮我顺手点个在看或者转发吧,你的举手之劳对我来说就是最大的鼓励。 END~

欢迎关注我的公众号:好奇心森林

最优包裹组合问题-贪心算法相关推荐

  1. 最优装载c语言贪心算法,最优装载(贪心算法)

    算法设计例题:最优装载(贪心) memory limit: 32768KB    time limit: 1000MS accept: 24    submit: 68 Description 有一批 ...

  2. 磁盘最优存储问题【贪心算法】

    题目描述 设有n 个程序{1,2,-, n }要存放在长度为L的磁带上.程序i存放在磁带上的长度是Li, 1<= i<= n.这n 个程序的读取概率分别是p1,p2,...,pn,且pi+ ...

  3. 最优服务次序问题-贪心算法

    1.最优服务次序问题 (1)问题描述: 设有n 个顾客同时等待一项服务.顾客i需要的服务时间为ti, 1<=i <= n .应如何安排n个顾客的服务次序才能使平均等待时间达到最小?平均等待 ...

  4. 贪心算法解决最优装载问题c语言,贪心算法解决最优装载问题

    <贪心算法解决最优装载问题>由会员分享,可在线阅读,更多相关<贪心算法解决最优装载问题(4页珍藏版)>请在人人文库网上搜索. 1.author : Kevin Black/这个 ...

  5. 贪心算法下的两大经典问题:最优装载问题、最小延迟调度问题

    上一篇主要介绍了贪心算法的内容和活动选择问题.本篇主要介绍最优装载问题和最小延迟调度问题 1.最优装载问题 什么是最优装载问题 类似于0-1背包问题那样,有n个集装箱1,2,-,n装上轮船,集装箱i的 ...

  6. 三十六、贪心算法--集合覆盖问题

    一.贪心算法介绍 1.贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解 2.贪心算法不是对所有问题都 ...

  7. 贪心算法(Java)

    贪心算法 文章目录 贪心算法 0.写在前面 1.贪心算法的基本要素 1.1 贪心选择性质 1.2 最优子结构性质 1.3 贪心算法与动态规划算法的差异 2.贪心算法的特点 3.贪心法的正确性证明 4. ...

  8. <贪心算法>学习及经典实例分析

    前言 人生如逆旅,我亦是行人. 贪心算法(Greedy Algorithm) 贪心算法(Greedy Algorithm,又称贪婪算法):是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说 ...

  9. 贪心算法及Jump Game系列题详解

    本博文所有的代码均可在 https://github.com/Hongze-Wang/LeetCode_Java https://github.com/Hongze-Wang/LeetCode_Pyt ...

最新文章

  1. etcd 在超大规模数据场景下的性能优化
  2. SecureCRT通过密钥进行SSH登录
  3. 如何使用 Redis 实现大规模的帖子浏览计数
  4. 关于MongDB数据迁移方案的研究
  5. gcc汇编汇编语言_什么是汇编语言?
  6. 队列与栈结构的相同点与不同点
  7. 646. Maximum Length of Pair Chain 最长的链条长度
  8. PLMN中的USSD与IMS域中的USSD
  9. 47 Python - 装饰器 回忆函数基础
  10. IDEA 公司,又出新神器,一套代码适应多端!
  11. 大学生游戏静态HTML网页作业--美丽中国
  12. 【vn.py】源码解析之 Dual Thrust 策略
  13. 数据技术大融合,HSTAP数据库有多少想象空间?
  14. 公众号裂变一般用什么方法?小白如何做好一场公众号裂变活动?
  15. 空洞卷积(膨胀卷积)的相关知识以及使用建议(HDC原则)
  16. 用Python绘制K线图
  17. debconf-set-selections mysql_在Ubuntu上的MySQL脚本安装
  18. Android原生编解码接口MediaCodec详解
  19. 转载:Vmware 虚拟化 云桌面实操:万字长文,近百张图,完整步骤带你学会Vmware 虚拟化 云桌面
  20. matlab 非结构网格,基于MATLAB的非结构网格生成器和浅水问题的数值模拟

热门文章

  1. 回调?是什么,简单讲解一下
  2. 如何搭建一个高效、可靠的积分商城系统?
  3. 华为路由交换由浅入深系列(四)OSPF单区域、多区域配置、时间参数 DRBDR选举 重分布路由与认证演示
  4. 【Linux】Linux 安装“宝塔”服务
  5. [论文笔记] highway networks
  6. html的td中自动折行无效,Html中td自动换行问题
  7. MMX,SSE,SSE2扫盲
  8. 办公室的衣着打扮 FORMAL, BUSINESS CASUAL,AND CASUAL
  9. 2021年软件测试高薪就业秘诀:高薪工作地点+必修技能+涨薪技能
  10. hibernate 读取Blob字段 OutOfMemoryError