算法

算法

雪花算法

[主要后端使用]

正态分布随机数算法

正态分布:NormalDistribution

根据中心极限定理,多次均匀分布的结果相加会服从正态分布,而多少次会比较合适呢。根据计算最合适的是12次,具体算法参考连接。

Javascript 随机数函数 学习之二:产生服从正态分布随机数


   /**范围-6~6 */
    function uniform2NormalDistribution() {
        var sum = 0.0;
        for (var i = 0; i < 12; i++) {
            sum = sum + Math.random();
        }
        return sum - 6.0;
    }

这个函数可以得到-6~6之间的随机数程正太分布。怎么处理成常用的方法有很多:

  1. 两边截断
  2. +6/12转换成0~1(但这样基本集中在中间分布情况会变)

具体使用方法:

/**
 * @param base 中间值
 * @param offset 区间范围
 */
function getNumberInNormalDistribution(mean,std_dev){    
    return mean+(uniform2NormalDistribution()*std_dev);
}

波动均布

/**
 * 波动均布 算法
 * @param n 数量
 * @param crest 波峰 
 * @param trough 波谷 
 * @param isInteger 是否整数 
 */
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; 
}

评论