二項式分布html實驗

二項式分布html實驗

本文將帶你一步步搭建一個純前端的二項分布 Monte-Carlo 模擬器。
只要一個 HTML 文件,打開就能運行:

  • 動態輸入試驗次數 n、成功概率 p 與重復次數 m
  • 點擊按鈕立刻得到「模擬頻數 vs 理論頻數」柱狀圖
  • 隨著 m 增大,兩組柱狀圖逐漸重合,從視覺上 印證二項分布公式

目錄

  1. 為什么要做這個實驗
  2. 技術選型
  3. 功能與界面預覽
  4. 逐段解析核心代碼
  5. 完整源碼(復制即用)
  6. 如何使用 & 實驗建議
  7. 可能的擴展方向

1. 為什么要做這個實驗

學習概率論時,我們經常“紙上談兵”——寫下

[
P(X=k)=\binom{n}{k}p{k}(1-p){n-k}
]

就宣稱“這就是答案”。
如果能親手做實驗,讓抽樣分布真實地落在眼前,
不僅能直觀體會“大數定律”與“二項分布”的關系,也能加深對公式每一項含義的理解。


2. 技術選型

角色工具說明
樣式Tailwind CSS(Play CDN)無需構建、開箱即用的原子化類
圖表Chart.js v4體積小、易上手、對柱狀圖支持好
邏輯原生 JavaScript僅用 ES6 語法即可完成全部計算與交互

優勢:

  • 單文件、零依賴后端,復制到本地或放到 GitHub Pages 就能跑
  • 代碼總行數 < 200,便于教學與改造

3. 功能與界面預覽

  • 三個輸入框:
    • 試驗次數 n:每個伯努利實驗重復多少次
    • 成功概率 p:0 ~ 1
    • 重復實驗次數 m:Monte-Carlo 總抽樣次數
  • 「運行模擬」按鈕
  • 雙數據集柱狀圖
    • 藍色 = 模擬得到的實際頻數
    • 綠色 = 理論 PMF×m 得到的期望頻數

隨著 m 增大,兩種柱子高度越貼近 —— 這就是經驗分布逼近理論分布的過程。


4. 逐段解析核心代碼

4.1 組合數 comb(n,k)

function comb(n, k) {k = Math.min(k, n - k);      // 對稱性優化let c = 1;for (let i = 0; i < k; i++)  // 逐項相乘避免溢出c = (c * (n - i)) / (i + 1);return c;
}

思路:用遞推而非階乘,避免中間結果溢出并減少運算量。


4.2 理論 PMF binomPMF(n,p)

function binomPMF(n, p) {const q = 1 - p;return Array.from({ length: n + 1 }, (_, k) =>comb(n, k) * Math.pow(p, k) * Math.pow(q, n - k));
}

返回長度 n+1 的數組,第 k 項即公式值。


4.3 Monte-Carlo 模擬 simulate(n,p,m)

function simulate(n, p, m) {const freq = Array(n + 1).fill(0);for (let i = 0; i < m; i++) {let successes = 0;for (let j = 0; j < n; j++)if (Math.random() < p) successes++;freq[successes]++;}return freq;
}

雙層循環:外層m 次實驗,內層n 次伯努利試驗。


4.4 Chart.js 初始化與刷新

const chart = new Chart(ctx, {type: "bar",data: { labels: [], datasets: [...] },options: { scales: { x: {...}, y: {...} } }
});runBtn.onclick = () => {const n = +nInput.value, p = +pInput.value, m = +mInput.value;const sim = simulate(n,p,m);const theory = binomPMF(n,p).map(x => x*m);chart.data.labels = [...Array(n+1).keys()];chart.data.datasets[0].data = sim;chart.data.datasets[1].data = theory;chart.update();
};

Chart.js 會自動在同一 X-軸按類別疊放兩組柱子。


5. 完整源碼(復制即用)

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8" /><title>二項分布模擬實驗</title><script src="https://cdn.tailwindcss.com"></script><script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js"></script>
</head>
<body class="min-h-screen bg-slate-50 flex flex-col items-center py-8"><h1 class="text-3xl font-bold mb-6">二項分布模擬實驗</h1><div class="bg-white shadow-md rounded-lg p-6 w-full max-w-md mb-8"><div class="mb-4"><label class="block font-semibold mb-1" for="n">試驗次數 n</label><input id="n" type="number" min="1" max="100" value="10" class="w-full border rounded px-3 py-2" /></div><div class="mb-4"><label class="block font-semibold mb-1" for="p">成功概率 p (0~1)</label><input id="p" type="number" step="0.01" min="0" max="1" value="0.5" class="w-full border rounded px-3 py-2" /></div><div class="mb-4"><label class="block font-semibold mb-1" for="m">重復實驗次數 m</label><input id="m" type="number" min="1" max="20000" value="1000" class="w-full border rounded px-3 py-2" /></div><button id="runBtn" class="w-full bg-blue-600 hover:bg-blue-700 text-white font-semibold py-2 rounded">運行模擬</button></div><div class="w-full max-w-3xl"><canvas id="chart"></canvas></div><script>const comb = (n, k) => {if (k < 0 || k > n) return 0;k = Math.min(k, n - k);let c = 1;for (let i = 0; i < k; i++) c = (c * (n - i)) / (i + 1);return c;};const binomPMF = (n, p) => {const q = 1 - p;return Array.from({ length: n + 1 }, (_, k) =>comb(n, k) * Math.pow(p, k) * Math.pow(q, n - k));};const simulate = (n, p, m) => {const freq = Array(n + 1).fill(0);for (let i = 0; i < m; i++) {let success = 0;for (let j = 0; j < n; j++) success += Math.random() < p ? 1 : 0;freq[success]++;}return freq;};const ctx = document.getElementById("chart");const chart = new Chart(ctx, {type: "bar",data: {labels: [],datasets: [{ label: "模擬頻數", data: [], backgroundColor: "rgba(59,130,246,0.6)" },{ label: "理論期望頻數", data: [], backgroundColor: "rgba(16,185,129,0.6)" }]},options: {responsive: true,scales: {x: { title: { display: true, text: "成功次數 k" } },y: { title: { display: true, text: "頻數" } }}}});document.getElementById("runBtn").onclick = () => {const n = +document.getElementById("n").value;const p = +document.getElementById("p").value;const m = +document.getElementById("m").value;if (n <= 0 || p < 0 || p > 1 || m <= 0) {alert("請輸入合法參數!");return;}const sim = simulate(n, p, m);const theory = binomPMF(n, p).map(v => v * m);chart.data.labels = [...Array(n + 1).keys()];chart.data.datasets[0].data = sim;chart.data.datasets[1].data = theory;chart.update();};</script>
</body>
</html>

6. 如何使用 & 實驗建議

  1. 下載/復制源文件 → 直接雙擊或用 VS Code Live Server 打開。
  2. 先用默認參數 n=10,p=0.5,m=1000 運行一次。
  3. 增大 m(如 5000、10000):觀察柱狀圖差距逐漸減小。
  4. 改變 p(偏心硬幣):體驗圖形從對稱到偏斜的變化。
  5. 改變 n:試驗次數越大,橫軸成功次數種類越多,曲線越接近正態分布形狀。

小實驗:設置 n=1,此時模擬結果就會精確落在伯努利分布 ( {0,1} ) 上,驗證“二項分布在 n=1 時退化為伯努利”。


7. 可能的擴展方向

想法技術提示
加入 泊松近似/正態近似 曲線再添加一個折線數據集,公式計算期望值
計算并展示 卡方檢驗 χ2在 JS 中對兩組頻數做 Σ((obs-exp)2/exp)
支持 動畫增量抽樣setInterval 每隔 N 次刷新一次柱狀圖
WebWorker 提升大規模模擬性能simulate 放到 worker 線程

復制本文源碼,親眼見證經驗分布二項分布收斂的全過程吧!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/77206.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/77206.shtml
英文地址,請注明出處:http://en.pswp.cn/web/77206.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

通過 API 對接應用網絡商城實現訂單自動化

前言 API&#xff08;Application Programming Interface&#xff09;即應用程序編程接口&#xff0c;是一種允許不同軟件應用程序之間進行交互和數據共享的工具。它通過定義一組明確的規則和協議&#xff0c;使得各個軟件系統能夠以標準化的方式相互通信。 在支付領域&#x…

openwrt作旁路由時的幾個常見問題 openwrt作為旁路由配置zerotier 圖文講解

1 先看openwrt時間&#xff0c;一定要保證時間和瀏覽器和服務器是一致的&#xff0c;不然無法更新 2 openwrt設置旁路由前先測試下&#xff0c;路由器能否ping通主路由&#xff0c;是否能夠連接外網&#xff0c;好多旁路由設置完了&#xff0c;發現還不能遠程好多就是旁路由本…

FANUC機器人GI與GO位置數據傳輸設置

FANUC機器人GI與GO位置數據傳輸設置&#xff08;整數小數分開發&#xff09; 一、概述 在 Fanuc 機器人應用中&#xff0c;如果 IO 點位足夠&#xff0c;可以利用機器人 IO 傳輸位置數據及偏移位置數據等。 二、操作步驟 1、確認通訊軟件安裝 首先確認機器人控制柜已經安裝…

UE5 Assimp 自用

記錄一下配assimp庫到ue中的過程。因為想在ue里面實現一些幾何處理(雖然ue好像有相關的geo的代碼&#xff09;&#xff0c;遂配置了一下assimp。 1. 編譯整理生成自己所需要的文件。cmake編譯&#xff0c;下載github 的官方的assimp-master&#xff0c;然后cmake都是默認的就行…

第18章:MCP在創作領域中的應用

第18章:MCP在創作領域中的應用 創意過程,無論是寫作、繪畫、音樂創作還是設計,往往充滿了不確定性、迭代和靈感的迸發。傳統 AI 在創意領域的應用常常局限于風格遷移、簡單內容生成等。MCP 框架通過其對記憶、上下文和規劃的整合,為 AI Agent 參與和輔助更深層次的創意活動…

電子電子架構 --- 主機廠視角下ECU開發流程

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 簡單,單純,喜歡獨處,獨來獨往,不易合同頻過著接地氣的生活,除了生存溫飽問題之外,沒有什么過多的欲望,表面看起來很高冷,內心熱情,如果你身…

【Agent】LangManus深度解析:AI自動化框架的對比與langgraph原理

LangManus深度解析&#xff1a;AI自動化框架的技術演進與實踐 本文將帶你深入探索LangManus這一AI自動化框架的核心技術與其基于langgraph的實現原理&#xff0c;并與OpenManus進行全面對比&#xff0c;助你掌握多智能體系統的前沿技術。 本文3萬字&#xff0c;沒有時間的話可以…

機器學習-08-推薦算法-案例

總結 本系列是機器學習課程的系列課程&#xff0c;主要介紹機器學習中關聯規則 參考 機器學習&#xff08;三&#xff09;&#xff1a;Apriori算法&#xff08;算法精講&#xff09; Apriori 算法 理論 重點 MovieLens:一個常用的電影推薦系統領域的數據集 23張圖&#x…

OpenCV 圖形API(63)圖像結構分析和形狀描述符------計算圖像中非零像素的邊界框函數boundingRect()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 計算點集或灰度圖像非零像素的 upright&#xff08;不旋轉&#xff09;邊界矩形。 該函數計算并返回指定點集或灰度圖像非零像素的最小 upright …

Redis ⑥-string | hash | list

string類型基本介紹 Redis 中的字符串&#xff0c;是直接按照二進制的方式進行存儲的。也就是說&#xff0c;在存取的過程中&#xff0c;是不會做任何編碼轉換的。存的是啥&#xff0c;取的時候就是啥。 Redis 的這個機制&#xff0c;就使得 Redis 非常適合用來存儲各種各樣的…

星火燎原:大數據時代的Spark技術革命在數字化浪潮席卷全球的今天,海量數據如同奔涌不息的洪流,傳統的數據處理方式已難以滿足實時、高效的需求。

星火燎原&#xff1a;大數據時代的Spark技術革命 在數字化浪潮席卷全球的今天&#xff0c;海量數據如同奔涌不息的洪流&#xff0c;傳統的數據處理方式已難以滿足實時、高效的需求。Apache Spark作為大數據領域的璀璨明星&#xff0c;憑借其卓越的性能和強大的功能&#xff0c…

通信算法之273 : 循環自相關函數和自相關函數

一、循環自相關函數定義與計算流程 ?定義式?: 循環自相關函數為時間平均自相關函數的傅里葉變換: Rxα(τ)=1T∫?T/2T/2Rx(t+τ2,t?τ2)e?j2παtdtRxα?(τ)=T1?∫?T/2T/2?Rx?(t+2τ?,t?2τ?)e?j2παtdt 其中,Rx(t,τ)Rx?(t,τ) 是信號的自相關函數,α為循…

使用 VMware 安裝一臺 Linux 系統之Centos

使用 VMware 安裝一臺 Linux 系統之Centos 想體驗一下 Linux 的魅力&#xff0c;又不想在現有電腦上進行大刀闊斧的改動&#xff1f;使用 VMware 虛擬機是一個絕佳的選擇。它能讓你在 Windows 或 macOS 系統中輕松創建一個獨立的 Linux 環境。本文將手把手帶你完成從下載 VMwa…

uniapp-商城-36-shop 購物車 選好了 進行訂單確認2 支付方式顏色變化和顏色濾鏡filter

顏色濾鏡&#xff0c;在好多網頁都這樣使用&#xff0c;濾掉彩色&#xff0c;顯示黑白&#xff0c;這在一些關鍵的日子中都這樣使用。 1、依然回到訂單確認頁面 看到支付的顏色了嘛&#xff1f; <view class"payType"><view class"box" :class&q…

gerbera文件轉PCB文件-Altium Designer

gerbera文件轉PCB文件-Altium Designer 1. 新建 CAM 文檔2. 導入 Gerber 文件和鉆孔文件導入 Gerber 文件導入鉆孔文件&#xff08;NC Drill&#xff09; 3. 提取網絡表4. 檢查并設置層映射5. 導出為 PCB 文件 1. 新建 CAM 文檔 打開 Altium Designer&#xff0c;執行以下操作…

Flask 請求數據獲取方法詳解

一、工作原理 在 Flask 中&#xff0c;所有客戶端請求的數據都通過全局的 request 對象訪問。該對象是 請求上下文 的一部分&#xff0c;僅在請求處理期間存在。Flask 在收到請求時自動創建 request 對象&#xff0c;并根據請求類型&#xff08;如 GET、POST&#xff09;和內容…

隊列基礎和例題

基礎 #include <queue> #include <iostream>/*** 入隊*/ void Test01() {std::queue<int> q;q.push(1);q.push(2);q.push(3);q.push(4);q.push(777);std::cout << "隊列大小:" << q.size() << std::endl;std::cout << &q…

U-Mail郵件加速服務:全球鏈路加速,安全穩定收發

由于跨國網絡擁堵、帶寬不穩定等因素&#xff0c;導致海外用戶在使用企業郵箱收發郵件時&#xff0c;經常出現郵件收發不暢的問題。針對這種情況&#xff0c;U-Mail正式推出了郵件加速服務&#xff0c;U-Mail郵件加速服務依托全球優質加速鏈路和轉發集群服務器&#xff0c;為海…

從工作到娛樂:Codigger Desktop 讓桌面環境更智能

在數字化時代&#xff0c;我們的桌面環境幾乎成了第二個家。Codigger Desktop 就像是這個家的設計師&#xff0c;幫你打造一個既實用又舒適的數字空間。無論你是想放松娛樂&#xff0c;還是高效工作&#xff0c;Codigger Desktop 都能滿足你的需求。 想象一下&#xff0c;你有一…

用python進行OCR識別

原文鏈接&#xff1a;https://www.bilibili.com/opus/1036675560501149699 我擔心原作者刪除&#xff0c;所以重新拷貝了一遍 1.下載tesseract 鏈接&#xff1a;https://github.com/UB-Mannheim/tesseract/wiki 這里示例安裝最新版本 點擊下載tesseract安裝包 2.安裝tess…