日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

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

發布時間:2023/12/15 python 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python波峰波谷算法_波动均分算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

波動均分算法

by leeenx on 2018-01-11

「波動」和「均分」大部分讀者朋友是知道的,但看到「波動均分」應該是一頭霧水的。其實,這個名詞是筆者拼湊出來的。

什么是「波動均分」?

把指定的數值 A,分成 N 份,此時每份的數值在一個固定的區間 [max, min] 內。 從視覺上看,每份的數量在平均線上下波動,并帶有隨機性:

這種分配不是嚴格意義上的「均分」,但它卻跟「均分」很相似,按筆者的理解給這個算法取個名字 —— 「波動均分」。

波動均分算法應該具備的特征如下:

  • 分配數量
  • 波峰高度
  • 波谷深度
  • 隨機分配
  • 組合全面

前三個特征是提供對外配置的接口,保證算法的使用者可以指定分配的數量和定制波動的波峰和波谷(盡管大部分情況下,波峰 = 波谷);「隨機分配」表示算法的結果是隨機的;

「 組合全面」表示算法的結果是可以覆蓋所有可能的結果。

接下來,筆者將介紹兩種實現「波動均分」的算法:

  • 窮舉法
  • 快速分配

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

窮舉法

「窮舉法」顧名思義就是列舉所有可能出現的組合,再隨機抽取一個組合作為輸出結果。

下面是一個「波動均分」任務:

有一張 10x10 的表格,需要對格子上5種顏色并要求每種顏色的數量在區間 [18, 22] 內。

由上述可得:每種顏色都會有5種分配結果(18, 19, 20, 21, 22)。窮舉這些顏色分配數量的組合其實就是建設一棵高度為 6 的 5 叉樹的過程。

第 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; }

窮舉法的局限:

  • 「無窮集合」不適用
  • 窮舉算法效率低下
  • 由于「窮舉法」的這兩個致命限制,所以它不是適用于業務。事實上,筆者主要是使用「窮舉法」校驗「快速分配」方案的全面性。

    快速分配

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

  • 獲取可分配波動范圍;
  • 在波動范圍內隨機取值
  • 代碼的實現過程如下:

    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/

    作者:凹凸實驗室

    總結

    以上是生活随笔為你收集整理的python波峰波谷算法_波动均分算法的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。