python波峰波谷算法_波动均分算法

fa0309df4459dbd14a9ba1027c9baa6c.png

波动均分算法

by leeenx on 2018-01-11

「波动」和「均分」大部分读者朋友是知道的,但看到「波动均分」应该是一头雾水的。其实,这个名词是笔者拼凑出来的。

什么是「波动均分」?

把指定的数值 A,分成 N 份,此时每份的数值在一个固定的区间 [max, min] 内。 从视觉上看,每份的数量在平均线上下波动,并带有随机性:

09cf7c310a6144dfa3c37bcbb759c1c3.gif

这种分配不是严格意义上的「均分」,但它却跟「均分」很相似,按笔者的理解给这个算法取个名字 —— 「波动均分」。

波动均分算法应该具备的特征如下:

  • 分配数量
  • 波峰高度
  • 波谷深度
  • 随机分配
  • 组合全面

前三个特征是提供对外配置的接口,保证算法的使用者可以指定分配的数量和定制波动的波峰和波谷(尽管大部分情况下,波峰 = 波谷);「随机分配」表示算法的结果是随机的;

「 组合全面」表示算法的结果是可以覆盖所有可能的结果。

接下来,笔者将介绍两种实现「波动均分」的算法:

  • 穷举法
  • 快速分配

备注:本文算法中使用到的平均值是0

穷举法

「穷举法」顾名思义就是列举所有可能出现的组合,再随机抽取一个组合作为输出结果。

下面是一个「波动均分」任务:

有一张 10x10 的表格,需要对格子上5种颜色并要求每种颜色的数量在区间 [18, 22] 内。

由上述可得:每种颜色都会有5种分配结果(18, 19, 20, 21, 22)。穷举这些颜色分配数量的组合其实就是建设一棵高度为 6 的 5 叉树的过程。

15c76c8bb4bca0c6b72d2a19f15cd749.gif

第 6 层的叶子数就是「所有可能出现的组合」的总数。换而言之,从树的第六层的一片叶子到第二层节点的路径即是一种分配组合。

以下是「穷举法」的代码实现:

function exhaustWave(n = 5, crest = 4, trough = 4) { let root = {parent: null, count: null, subtotal: 0}; // 根节点let leaves = [root]; // 叶子(数组)let level = 0; // 层数 // 检查当前组合是否合法let isOK = subtotal => {if(level < n - 1) {if(-subtotal <= (n - level) * crest || subtotal <= (n - level) * trough) return true; }else if(subtotal === 0) return true; else return false; }// 生成组合树 while(level < n) { let newLeaves = []; // 存储最新叶子leaves.forEach(node => {for(let count = -trough; count <= crest; ++count) {let subtotal = node.subtotal + count; isOK(subtotal) && newLeaves.push({parent: node, count: count, subtotal: subtotal}); }}); leaves = newLeaves, ++level; }// 随机取一片叶子let leaf = leaves[Math.random() * leaves.length >> 0]; let group = [leaf.count]; for(let i = 0; i < 4; ++i) { leaf = leaf.parent; group.push(leaf.count); }return group; }

穷举法的局限:

  1. 「无穷集合」不适用
  2. 穷举算法效率低下

由于「穷举法」的这两个致命限制,所以它不是适用于业务。事实上,笔者主要是使用「穷举法」校验「快速分配」方案的全面性。

快速分配

「快速分配」方案的思路:

  1. 获取可分配波动范围;
  2. 在波动范围内随机取值

代码的实现过程如下:

function quickWave(n = 5, crest = 4, trough = 4, isInteger = true) { let list = []; // 无法进行波动均分,直接返回完全平分if(crest > (n - 1) * trough || trough > (n - 1) * crest) {return new Array(n).fill(0); }let base = 0; // 最少需要消除的高度let wave = 0; // 波动量let high = crest; // 高位let low = -trough; // 低位let sum = 0; // 累计量 let count = n; // 剩余数量 while(--count >= 0) { // 动态当前的波动量if(crest > count * trough - sum) {high = count * trough - sum; }if(trough > count * crest + sum) {low = -sum - count * crest; }base = low; wave = high - low; let rnd; // 随机波动量 if(count > 0) {rnd = base + Math.random() * (wave + 1); // 随机波动} else {rnd = -sum; }if(isInteger === true) {rnd = Math.floor(rnd); } sum += rnd; list.push(rnd); }return list; }

波动均分的「快速分配」方案在算法效率上是高效的,并且「快速分配」适用于「无穷集合」。

如何使用「穷举法」校验「快速分配」的全面性?

「穷举法」能直接返回分配组合的总数,而「快速分配」只能随机返回一次组合,笔者是通过大数量地调用「快速分配」算法并累积不重复组合来验证「快速分配」的全面性。代码如下:

console.log(exhaustWave(5, 4, 4)); // 组合总数: 3951let res = {}, count = 0, len = 10000; for(let i = 0; i < len; ++i) { let name = quickWave(5, 4, 4).join("_"); res[name] !== true && (res[name] = true, ++count); }console.log(count); // len次快速分配后的组合总数

通过调整变量 len 可以发现,当 len 越来越大输出的结果就越逼近 3951,当到达一定量级后,输出的结果就是 3951。

结语

可能网上有类似的算法存在,不过笔者学识太浅没有找到对应的算法,所以自己生造了这个算法,如果有何不妥之处欢迎指正。

希望本文能帮助到您!

点赞+转发,让更多的人也能看到这篇内容(收藏不点赞,都是耍流氓-_-)

关注 {我},享受文章首发体验!

每周重点攻克一个前端技术难点。更多精彩前端内容私信 我 回复“教程”

原文链接:https://aotu.io/notes/2018/01/11/waveaverage/

作者:凹凸实验室

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

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

相关文章

java web 注册登录_javaweb实现登录注册功能实例

前期呢&#xff0c;我们学习了javaweb项目用JDBC连接数据库&#xff0c;还有数据库的建表功能&#xff0c;今天&#xff0c;我们来看一下javaweb实现登录注册功能实例&#xff0c;javaweb项目使用的工具是eclipse&#xff0c;最后把项目部署在了Tomcat中&#xff0c;连接数据库…

source insight 函数不能跳到definition_小技能: Windows10突然不能复制粘贴谁搞鬼

最近连续遇到几次&#xff0c;电脑突然不能复制粘贴了&#xff0c;非常影响工作。(如果不想听我扯&#xff0c;就直接跳到最后看结果啊&#xff0c;我真贴心。)你们都懂得&#xff0c;程序员嘛&#xff0c;用的最多的就是ctrlc&#xff0c;ctrlv。这不能用了&#xff0c;不是让…

hsv 明度的范围_通过HSV转换的方式实现图片数据增强

在我的上一篇文章中&#xff0c;我记录了自己将MOT17-Det数据集转换成VOC格式&#xff1a;HUST小菜鸡&#xff1a;将MOT17-Det数据集转成VOC格式​zhuanlan.zhihu.com但是在后期的测试过程中&#xff0c;发现了一些小问题&#xff1a;首先是train.txt里面写入的图片数和标注的数…

java protected关键字_Java 权限protected关键字纠正

以前一直认为自己理解了Java四种权限访问&#xff0c;昨天突然编程时发现protected居然在子类中不能调用&#xff0c;然后越看越迷糊&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;public&#xff1a; Java语言中访问限制最宽的修饰符&#xff0c;…

互联网java常用框架_来,带你鸟瞰 Java 中4款常用的并发框架!

1. 为什么要写这篇文章几年前 NoSQL 开始流行的时候&#xff0c;像其他团队一样&#xff0c;我们的团队也热衷于令人兴奋的新东西&#xff0c;并且计划替换一个应用程序的数据库。 但是&#xff0c;当深入实现细节时&#xff0c;我们想起了一位智者曾经说过的话&#xff1a;“细…

2020亚太杯数学建模_比赛 | 2020年APMCM亚太地区大学生数学建模竞赛

2020年11月26日到30日&#xff0c;在我院老师指导下&#xff0c;由统计分析竞赛社组织的41支队伍&#xff0c;共123人&#xff0c;参加了亚太地区大学生数学建模竞赛组委会主办的大学生学科类竞赛。此次竞赛题目分为A题和B题&#xff0c;参赛者需从A&#xff0c;B两题中任选其一…

java声明复数类_JAVA声明复数类

声明复数类&#xff0c;成员变量包括实部和虚部&#xff0c;成员方法包括实现由字符串构造复数、复数加法、减法&#xff0c;字符串描述、比较相等等操作。虽然我只是一个刚学一个月JAVA的菜鸡&#xff0c;但是强迫症让我把复数乘法和除法一起写出来了。public class Complex {…

sql 没有调试 菜单_MySQL递归查询上下级菜单

正文在传统的后台管理系统里面经常会需要展示多级菜单关系&#xff0c;今天我们来学一下如何使用一条SQL语句展示多级菜单。现在我们有一张corpinfo单位表&#xff0c;里面有一个belong字段指向上级单位&#xff0c;首先来看一下现在表里有什么数据&#xff1a;SELECT uid,ubel…

java 桥 word_java导出word的6种方式(转发)

最近做的项目&#xff0c;需要将一些信息导出到word中。在网上找了好多解决方案&#xff0c;现在将这几天的总结分享一下。目前来看&#xff0c;java导出word大致有6种解决方案&#xff1a;1&#xff1a;Jacob是Java-COM Bridge的缩写&#xff0c;它在Java与微软的COM组件之间构…

jieba 词典 词频_在Hanlp词典和jieba词典中手动添加未登录词

在使用Hanlp词典或者jieba词典进行分词的时候&#xff0c;会出现分词不准的情况&#xff0c;原因是内置词典中并没有收录当前这个词&#xff0c;也就是我们所说的未登录词&#xff0c;只要把这个词加入到内置词典中就可以解决类似问题&#xff0c;如何操作呢&#xff0c;下面我…

python爬取汽车之家_python爬取 汽车之家(汽车授权经销商)

一&#xff1a;爬虫的目标&#xff1a;打开汽车之家的链接&#xff1a;https://www.autohome.com.cn/beijing/&#xff0c;出现如下页面我们的目标是点击找车&#xff0c;然后出现如下图我们要把图中的信息抓取到二&#xff1a;实现过程我们选择 宝马5系 然后点击找车注意宝马…

Java 调用 Caffe_解决 free(): invalid pointer: 0x00000000019ff700 运行时报错(caffe)(libtool使用)...

编译成功&#xff0c;运行时报错&#xff1a;在使用 pytorch or tensorflow or caffe 时&#xff0c;都可能存在这个问题&#xff1a;*** Error in xxx: free(): invalid pointer: 0x00000000020663b0 ***很可能是缺少libtcmalloc库解决方法1&#xff1a;apt-get安装libtcmallo…

unity 世界坐标间角度_Unity学习笔记—本地坐标转世界坐标

核心用到的方法就是transform.TransformPoint( )这个方法的返回值就是Vector3类型的世界坐标&#xff0c;transform就是相对的物体&#xff0c;括号里的就是相对这个transform的本地坐标&#xff0c;比方说我现在的位置吧&#xff0c;知道我相对于我的邻居的坐标:Pos1&#xff…

webcomponents安装了没有用_Web Components 入门实例教程

来源 | http://www.ruanyifeng.com/blog/2019/08/web_components.html组件是前端的发展方向&#xff0c;现在流行的React和Vue都是组件框架。谷歌公司由于掌握了Chrome浏览器&#xff0c;一直在推动浏览器的原生组件&#xff0c;即Web组件API。部分第三方框架&#xff0c;原生组…

虹软java接摄像头_虹软人脸识别SDK(java+linux/window) 初试

虹软人脸识别全平台demo调用—快速上手之服务端Windows篇demo名称&#xff1a;ArcFace 2.2 Windows(86) Demo [C]一 环境配置&#xff1a;1) 安装VS2013环境安装包(vcredist_x86_vs2013.exe)2) 从官网(http://www.arcsoft.com.cn/ai/arcface.html)申请sdk&#xff0c;下载对应的…

java 循环查询list_Java用list储存,遍历,查询指定信息过程详解

需求说明实现思路见代码注释代码内容使用list储存&#xff0c;遍历&#xff0c;查询&#xff0c;删除import java.util.ArrayList;import java.util.List;/*** auther:&#xff1a;9527* Description: 第七题* program: 多线程* create: 2019-08-09 23:39*/public class Sevent…

低代码开发平台_低代码开发平台系列:6、低代码是编程技术发展大势所趋

一、低代码是一种编程技术低代码是快速开发工具/技术的一种&#xff0c;属于软件开发/编程工具/技术领域&#xff0c;主要应用于企业软件开发领域。借助低代码工具&#xff0c;使用者无需编码即可实现企业软件系统常见功能的交付&#xff1b;少量编码扩展更多功能&#xff0c;相…

abnf java实现_详细讲解如何利用Java实现组合式解析器?

简介&#xff1a;Ward Cunningham 曾经说过&#xff0c;干净的代码清晰地表达了代码编写者所 想要表达的东西&#xff0c;而优美的代码则更进一步&#xff0c;优美的代码看起来就像是专门为了 要解决的问题而存在的。在本文中&#xff0c;我们将展示一个组合式解析器的设计、实…

充电原理_电动汽车充电桩如何设置?充电桩原理介绍

随着新能源产业的蓬勃发展&#xff0c;电动汽车在生活中变得越来越普遍。比亚迪(BYD)&#xff0c;宝马(BMW)和特斯拉(Tesla)等汽车制造商都已经推出了全电动汽车&#xff0c;而混合动力汽车则更为普遍。为了能够方便地为这些电动汽车的电池充电&#xff0c;必须建立充电桩。充电…

java 获取服务器硬件_dell服务器远程获取硬件状态

以dell的R620型号的服务器做的测试登陆上dell服务器ilo的IP地址&#xff0c;首先打开ipmi&#xff0c;ilo2是直接支持ipmi2.0的此框需要点击 “IDRAC设置”->“网络”->“IPMI设置”在”启用LAN上IPMI“后的复选框打钩&#xff0c;才能启动ipmi好像是内置到了ilo2&#x…