二项式分布html实验

news2025/4/26 2:16:47

二项式分布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. 可能的扩展方向

想法技术提示
加入 泊松近似/正态近似 曲线再添加一个折线数据集,公式计算期望值
计算并展示 卡方检验 χ²在 JS 中对两组频数做 Σ((obs-exp)²/exp)
支持 动画增量抽样setInterval 每隔 N 次刷新一次柱状图
WebWorker 提升大规模模拟性能simulate 放到 worker 线程

复制本文源码,亲眼见证经验分布二项分布收敛的全过程吧!

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

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

相关文章

大模型如何作为reranker?

大模型如何作为reranker&#xff1f; 作者&#xff1a;爱工作的小小酥 原文地址&#xff1a;https://zhuanlan.zhihu.com/p/31805674335 只为了感动自己而去做一些事情纯属浪费时间。 ————爱工作的小小酥 引言 用于检索的模型中&#xff0c;我们最熟悉的就是单塔和双塔了&…

发放优惠券

文章目录 概要整体架构流程技术细节小结 概要 发放优惠券 处于暂停状态&#xff0c;或者待发放状态的优惠券&#xff0c;在优惠券列表中才会出现发放按钮&#xff0c;可以被发放&#xff1a; 需求分析以及接口设计 需要我们选择发放方式&#xff0c;使用期限。 发放方式分…

试完5个AI海报工具后,我投了秒出设计一票!

随着AI技术的不断发展&#xff0c;越来越多的AI生成工具进入了设计领域&#xff0c;海报生成工具成为了其中的重要一员。今天&#xff0c;我们将为大家介绍三款热门的AI海报生成工具&#xff0c;并进行对比分析&#xff0c;帮助大家选择最适合的工具。 1. 秒出设计&#xff1a;…

PH热榜 | 2025-04-25

1. LambdaTest Accessibility Testing Suite 标语&#xff1a;轻松点击&#xff0c;确保网站的包容性和合规性。 介绍&#xff1a;LambdaTest 的可访问性测试工具可以自动识别你的网站和网络应用中是否符合 WCAG&#xff08;网页内容无障碍指南&#xff09;标准。你可以设置定…

模方ModelFun是什么?如何安装?

摘要&#xff1a;本文主要介绍模方ModelFun的软件简介、特性、安装环境配置、插件及软件安装。 1.软件简介 模方是一款实景三维模型的场景修饰与单体化建模工具&#xff0c;是建模的后处理软件&#xff0c;包括网格模型编辑和单体化建模两大模块。 场景修饰模块可以对 OBJ、OSG…

[AI Workflow] 基于多语种知识库的 Dify Workflow 构建与优化实践

在实际应用中,基于用户提供的资料快速构建高质量的知识库,并以此背景精准回答专业问题,是提升人工智能系统实用性的重要方向。然而,在跨语种环境下(如中、日、英混合资料与提问),传统的知识检索和回答生成流程往往面临匹配不准确、信息检索不全面的问题。 本文将介绍一种…

Pycharm(十六)面向对象进阶

一、继承 概述&#xff1a; 实际开发中&#xff0c;我们发现很多类中的步分内容是相似的&#xff0c;或者相同的&#xff0c;每次写很麻烦&#xff0c;针对这种情况&#xff0c; 我们可以把这些相似&#xff08;相同的&#xff09;部分抽取出来&#xff0c;单独地放到1个类中&…

WebGL图形编程实战【4】:光影交织 × 逐片元光照与渲染技巧

现实世界中的物体被光线照射时&#xff0c;会反射一部分光。只有当反射光线进人你的眼睛时&#xff0c;你才能够看到物体并辩认出它的颜色。 光源类型 平行光&#xff08;Directional Light&#xff09;&#xff1a;光线是相互平行的&#xff0c;平行光具有方向。平行光可以看…

Java高频面试之并发编程-07

hello啊&#xff0c;各位观众姥爷们&#xff01;&#xff01;&#xff01;本baby今天来报道了&#xff01;哈哈哈哈哈嗝&#x1f436; 面试官&#xff1a;线程之间有哪些通信方式&#xff1f; 在 Java 多线程编程中&#xff0c;线程间通信&#xff08;Inter-Thread Communica…

.NET代码保护混淆和软件许可系统——Eziriz .NET Reactor 7

.NET代码保护混淆和软件许可系统——Eziriz .NET Reactor 7 1、简介2、功能特点3、知识产权保护功能4、强大的许可系统5、软件开发工具包6、部署方式7、下载 1、简介 .NET Reactor是用于为.NET Framework编写的软件的功能强大的代码保护和软件许可系统&#xff0c;并且支持生成…

【现代深度学习技术】循环神经网络06:循环神经网络的简洁实现

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上&#xff0c;结合当代大数据和大算力的发展而发展出来的。深度学习最重…

【办公类-89-02】20250424会议记录模版WORD自动添加空格补全下划线

背景需求 4月23日听了一个MJB的征文培训&#xff0c;需要写会议记录 把资料黏贴到模版后&#xff0c;发现每行需要有画满下划线 原来做这套资料&#xff0c;就是手动按空格到一行末&#xff0c;有空格才会出现下划线&#xff0c;也就是要按很多的空格&#xff08;凑满一行&…

解释器模式:自定义语言解析与执行的设计模式

解释器模式&#xff1a;自定义语言解析与执行的设计模式 一、模式核心&#xff1a;定义语言文法并实现解释器处理句子 在软件开发中&#xff0c;当需要处理特定领域的语言&#xff08;如数学表达式、正则表达式、自定义配置语言&#xff09;时&#xff0c;可以通过解释器模式…

AI催生DLP新战场 | 天空卫士连续6年入选Gartner 全球数据防泄漏(DLP)市场指南

“管理数据外泄风险仍然是企业的重大挑战之一&#xff0c;客户处出于各种因素寻求DLP。最近&#xff0c;一些组织对使用DLP控制机器对敏感信息的访问表现出很大兴趣。 随着生成式人工智能&#xff08;GenAI&#xff09;的运用和数据的不断扩散&#xff0c;数据外泄的问题变得更…

Adobe After Effects的插件--------Optical Flares之Lens Objects参数

Lens Objects,即【镜头对象】。 通用设置 全局参数发光多光圈光圈条纹微光反射钉球闪光圆环箍焦散镜头球缩放✔✔✔✔✔✔✔✔✔✔✔✔✔缩放偏移✔长宽比✔✔✔✔✔✔✔✔✔✔✔✔✔混合模式✔颜色✔全局种子✔亮度✔✔✔✔✔✔✔✔✔✔✔✔拉伸✔✔✔✔✔✔✔✔✔✔✔✔距离…

【问题】解决docker的方式安装n8n,找不到docker.n8n.io/n8nio/n8n:latest镜像的问题

问题概览 用docker方式安装n8n&#xff0c;遇到错误&#xff0c;安装不了的问题&#xff1a; Unable to find image docker.n8n.io/n8nio/n8n:latest locally docker: Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request can…

系统与网络安全------弹性交换网络(1)

资料整理于网络资料、书本资料、AI&#xff0c;仅供个人学习参考。 Trunk原理与配置 Trunk原理概述 Trunk&#xff08;虚拟局域网中继技术&#xff09;是指能让连接在不同交换机上的相同VLAN中的主机互通。 VLAN内通信 实现跨交换的同VLAN通信&#xff0c;通过Trunk链路&am…

10天学会嵌入式技术之51单片机-day-3

第九章 独立按键 按键的作用相当于一个开关&#xff0c;按下时接通&#xff08;或断开&#xff09;&#xff0c;松开后断开&#xff08;或接通&#xff09;。实物图、原理图、封装 9.2 需求描述 通过 SW1、SW2、SW3、SW4 四个独立按键分别控制 LED1、LED2、LED3、LED4 的亮…

深入解析微软MarkitDown:原理、应用与二次开发指南

一、项目背景与技术定位 微软开源的MarkitDown并非简单的又一个Markdown解析器&#xff0c;而是针对现代文档处理需求设计的工具链核心组件。该项目诞生于微软内部大规模文档系统的开发实践&#xff0c;旨在解决以下技术痛点&#xff1a; 大规模文档处理性能&#xff1a;能够高…