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,一经查实,立即删除!

相关文章

formatter java_Java编程中的Java Formatter是什么?

Java编程中的Java Formatter是什么&#xff1f;作者&#xff1a;admin分类&#xff1a;PHP, JAVA, .NET文章时间&#xff1a;2017-03-30 21:13:02点击量&#xff1a;1428Java Formatter是一个实用程序类&#xff0c;可以在Java中使用格式化流输出时使生存变得简单。 它的构建类…

python计算矩阵方程_python/sympy求解矩阵方程的方法

sympy版本:1.2假设求解矩阵方程AXA2X其中求解之前对矩阵方程化简为(A−2E)XA令B(A−2E)使用qtconsole输入下面程序进行求解In [26]: from sympy import *In [27]: from sympy.abc import *In [28]: AMatrix([[4,2,3],[1,1,0],[-1,2,3]])In [29]: AOut[29]:Matrix([[ 4, 2, 3],[…

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;不是让…

flip java_java的flip(). 这里用flip()有什么作用?这是反转缓冲区的方法,好像用不上。...

publicclassNServer{//用于检测所有Channel状态的SelectorprivateSelectorselectornull;staticfinalintPORT30000;privateCharsetcharsetCharset.forName("UTF-8");publicvoidinit(...public class NServer{// 用于检测所有Channel状态的Selectorprivate Selector se…

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

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

java数组如何相加_java数组排序,并将数组内的数据求和

java数据编列并求和&#xff0c;江湖我狼哥&#xff0c;人狠话不多&#xff0c;直接上代码&#xff01;import java.util.Arrays;public class Intarry {public static void main (String[] args){//定义一个数组int intarry[] {20,30,40,10};int num0;Arrays.sort(intarry);/…

python在工厂中的应用_什么是工厂函数?Python 中工厂函数怎么理解?

其实谈工厂函数前必须首先把嵌套作用域和闭包讲清楚python有一个很有意思的地方&#xff0c;就是def函数可以嵌套在另一个def函数之中。调用外层函数时&#xff0c;运行到的内层def语句仅仅是完成对内层函数的定义&#xff0c;而不会去调用内层函数&#xff0c;除非在嵌套函数之…

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

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

老版本fortran语言 内存无效_编程语言的分类

编程语言世代第一代和第二代语言又称低级语言&#xff08;Low-level language&#xff09;&#xff0c;其余被视为高级语言&#xff08;High-level language&#xff09;第一代编程语言即机器语言&#xff0c;由0和1构成&#xff0c;通过面板、打孔带或者打孔卡输入。第二代编程…

金融统计分析python论文_比较好写的本科金融专业论文题目 本科金融专业论文题目怎么取...

为论文写作提供【100道】比较好写的本科金融专业论文题目,海量本科金融专业相关论文题目,包括专科与本科以及硕士论文题目,解决您的本科金融专业论文题目怎么取的相关难题&#xff01;一、比较好写的本科金融专业论文题目:1、微观金融视角下财务管理专业应用型本科人才培养目标…

互联网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 {…

python接口测试非json的断言_荐在接口自动化测试中,如何利用Pytest + JSONPath 进行接口响应断言...

之前有一篇文章&#xff0c;介绍了如何使用JSONSchema对接口响应进行断言&#xff0c;主要的适用场景是对响应的数据结构进行校验&#xff0c;保证客户端收到的数据结构稳定和合法。今天&#xff0c;介绍使用JSONPath对接口响应的值进行断言方法。上一篇文章《在接口自动化测试…

python3中异常处理_python中的五种异常处理机制介绍|python3教程|python入门|python教程...

https://www.xin3721.com/eschool/python.html从几年前开始学习编程直到现在&#xff0c;一直对程序中的异常处理怀有恐惧和排斥心理。之所以这样&#xff0c;是因为不了解。这次攻python&#xff0c;首先把自己最畏惧和最不熟悉的几块内容列出来&#xff0c;里面就有「异常处理…

java static 单例模式_Java 单例模式全面学习

介绍什么是单例模式&#xff1a;保证一个类仅有一个实例&#xff0c;并提供一个访问它的全局访问点解决什么问题&#xff1a;省略创建对象所花费的时间&#xff0c;不需要频繁创建对象&#xff0c;减轻 GC 压力。单例模式有以下几种实现方式&#xff1a;懒汉式第一次使用的时候…

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组件之间构…

python删除指定天数前的文件_python 删除指定时间间隔之前的文件实例

遍历指定文件夹下的文件&#xff0c;根据文件后缀名&#xff0c;获取指定类型的文件列表&#xff1b;根据文件列表里的文件路径&#xff0c;逐个获取文件属性里的“修改时间”&#xff0c;如果“修改时间”与“系统当前时间”差值大于某个值&#xff0c;则删除该文件。#!/usr/b…