目录

A10 恶劣环境传感器信号仿真与统计检验台

学生:钟伟 (202521093008) 选题编号:A10 所属分队:红队 指导教师:朱宗晓


项目概述

本项目源自《计算机程序设计艺术》(TAOCP)算法库的知识的系统化工程落地

维度 内容
组合算法 滞后斐波那契生成器(LFG) + 随机数统计检验(卡方/间隔检验)
TAOCP出处 卷2 §3.2.2 (LFG) + 卷2 §3.3.1 (统计检验)
难度 ★★★
支撑目标 目标3(工具开发)、目标5(学习能力)
核心目标 将TAOCP中的纯粹数学与指针魔术,转化为工业级系统底盘

算法史故事

1950年代的蒙特卡洛模拟对随机数的质量要求极高。Mitchell与Moore在1958年发明了滞后斐波那契生成器,用具有一定间隔的历史状态消除了简单线性同余法周期短、多维相关性差的问题。Knuth在随后整理的随机数理论中,为其推荐了j=55,k=24的黄金参数,并确立了卡方检验等统计验收标准。


课程任务

开发一个为控制算法做”压力测试”的噪声仿真模块。使用维护55个历史状态循环队列的LFG算法生成高质量白噪声数据。编写统计模块,执行频度检验(卡方拟合优度)和间隔检验(Gap Test),量化输出噪声数据的均匀性和独立性。


核心要求

  • 实现LFG滞后斐波那契生成器(j=55, k=24,循环缓冲区维护状态)
  • 实现卡方拟合优度检验(Chi-square goodness-of-fit)
  • 实现间隔检验(Gap Test,检测独立性)
  • 实现随机数质量可视化报告(频率分布直方图、统计量输出)
  • 对比LFG与简单线性同余法(LCG)的统计质量
  • 分析”直觉上随机但统计上失败”的伪随机算法灾难

工程哲学:可控可观(Controllability-Observability)

  • 可控:对每一字节内存走向有绝对掌控力,不允许不可预知的系统崩溃
  • 可观:通过打点、日志和统计,让不可见的算法瓶颈变得清晰可见

工程伦理

通过分析早期著名的RANDU问题等伪随机算法灾难,培养对工程测试数据的批判性思维和科学验证精神。

永远不要相信”直觉上觉得没问题”的输入源。 在自动化设备、恶劣环境和安全关键系统中,信号的质量必须经过严密的数学和统计学检验。缺乏”可观性”的盲目信任,就是工程灾难的开端。


新手破冰指南:C语言视角的四步上手路径

如果把学习编程比作研发无人驾驶汽车:

  • 基础编程课:教你如何调用系统自带的 rand() 函数,就像买了一个盲盒造雪机,按一下按钮就喷雪,但你不知道雪花是怎么生成的。
  • TAOCP 算法库:是存放顶级测试设备图纸的绝密档案库。库里的 lagged_fibonacci_generator.c 是一台”高保真工业级环境噪声发生器”(能完美模拟恶劣天气下的传感器电磁干扰);而 random_tests.c 则是一套”极其严苛的数学测谎仪”(能一眼看穿伪造的随机信号)。
  • A10 课程设计:要求你不仅要亲手打造这台”噪声发生器”(LFG),还要为它配备一套”测谎系统”(卡方/间隔检验)。你的任务是向世界证明:你造出的混沌,是真正经得起科学检验的混沌,而不是有规律的低级重复。

简而言之:算法库提供的是”随机数公式”,而A10项目要求你建立一个”可证伪的数字风洞试验台”。

第一步:打破 rand() 黑盒(建立发生器基石)

你的现状:认为随机数是计算机底层自带的玄学。

你要做的:理解随机数其实是确定的数学递推。

先写一个最简单的线性同余发生器(LCG):X = (A * X + C) % M。只需一行代码,你就能明白随机数就是把上一个数字放大、偏移再截断。

但这不够好(周期短,低位规律明显)。所以我们要造滞后斐波那契生成器(LFG)。

第二步:驯服 55 个幽灵(实现 LFG)

你的现状:会写 f[i] = f[i-1] + f[i-2] 这种普通的斐波那契数列。

你要做的:拉开时间的距离。LFG 的公式是 X = (X[前55步] ± X[前24步]) % M。

定义一个长度为 55 的全局数组(你的历史状态机):unsigned int history[55];。

你需要两个游标(指针)j 和 k。每次生成新数字时,提取这两个位置的数字做加减法,并覆盖回数组。

核心挑战:游标移动到数组头部时要”折返”到尾部。这里再次用到了 A09 环网中的循环队列思想(利用取模 % 55 操作实现无缝转圈)。

第三步:打造频度测谎仪(卡方拟合优度检验)

你的现状:会用 for 循环统计数组里每个数字出现了几次。

你要做的:把统计结果量化为系统的”可观性指标”。

假设你生成了 10,000 个 0~9 的随机数。完美情况下,每个数字应该出现 1,000 次(期望值 E)。

统计实际出现的次数(观测值 O)。

套用公式:把每个数字的 (观测值 - 期望值)的平方 / 期望值 算出来,然后全部加起来。

这就是大名鼎鼎的卡方值(Chi-square)。如果这个值太小,说明数据”假得离谱”(比如精确的123456789循环);如果太大,说明数据严重偏科;只有落在一个特定区间,才是合格的噪声。

第四步:打造维度测谎仪(间隔检验 Gap Test)

你的现状:只关注数字出现的总数。

你要做的:警惕隐藏的周期规律。

比如序列:1,2,3,4,5,1,2,3,4,5… 频度检验满分,但它是个死循环。

间隔检验:盯着某一个特定的区间(比如数字0~2)。计算上一次出现和下一次出现之间,隔了几个数字?统计”间隔为0”、”间隔为1”、”间隔为2”的次数,去和理论概率做对比。这就戳破了”低级伪随机”在多维空间中的伪装。


给新手的避坑锦囊

在实现这套”仿真与检验台”时,初学者极易踩中以下三个雷区:

1. “先有鸡还是先有蛋”的初始化陷阱(冷启动问题)

LFG 算法的特点是:生成第 56 个数需要前 55 个数。那么最开始的 55 个数哪里来?

绝对不要全填 0,否则生成的永远是 0!

正确做法:在 lfg_init(seed) 函数中,必须先悄悄借用一个传统的 LCG 发生器,用它生成 55 个初值填满数组,完成”预热”。

2. 整数运算的精度灾难(避开浮点数陷阱)

在算卡方值时,公式里有除法 (O-E)^2 / E。如果全是整数相除,C语言会直接把小数部分截断,导致检验结果完全失效。

工程技巧:先乘再除。将算式改为 (O-E)*(O-E)*100 / E,全程使用 long long。保留两位有效数字的同时,避免引入浮点数 float/double 的舍入误差。

3. 如何检验”检验台”本身是正确的?(双盲测试)

当你写好了卡方检验代码,你传入 LFG 数据发现通过了,这能证明你写对了吗?不能,也许是你的检验代码本身是坏的,对任何数据都放行。

测试驱动:先手工造一个全0数组,传给卡方检验,它必须输出极大值(报警)。再造一个 0123456789 严格循环的数组,它必须输出 0(报警)。只有能抓住”坏人”的测谎仪,才是好测谎仪。


💡 工程伦理探讨:直觉的背叛 (The RANDU Disaster)

在做最后的报告时,你可以引入这段历史:

1960年代,IBM 推出了一款名为 RANDU 的随机数生成器。它的算法极快,单看频率统计也非常完美,被广泛应用于当时的物理核爆炸模拟、流体力学蒙特卡洛计算中。

直到1968年,科学家把 RANDU 每次生成的三个数字当成三维空间中的 (X, Y, Z) 坐标画出来,才惊恐地发现:所有的点居然整齐地排列在 15 个平行的二维平面上!

十几年间,世界上无数顶尖论文的实验数据,因为这个”不合格的随机数传感器”,全部沦为废纸。

A10 项目的最高工程伦理在于:永远不要相信”直觉上觉得没问题”的输入源。在自动化设备、恶劣环境和安全关键系统中,信号的质量必须经过严密的数学和统计学检验。缺乏”可观性”的盲目信任,就是工程灾难的开端。


目录结构

.
├── README.md          # 本文件(项目总览)
├── Makefile           # GCC编译脚本
├── .gitignore         # Git忽略规则
├── src/               # 源代码目录
│   ├── main.c         # 主程序入口
│   ├── algorithm_a.c  # 算法A实现
│   ├── algorithm_b.c  # 算法B实现
│   ├── utils.c        # 工具函数
│   └── include/       # 头文件目录
│       ├── algorithm_a.h
│       ├── algorithm_b.h
│       └── utils.h
├── docs/              # 文档目录
│   ├── 01-需求分析.md
│   ├── 02-算法史故事.md
│   ├── 03-功能框图.png
│   ├── 04-详细设计.md
│   └── 05-测试报告.md
├── report/            # 课程设计报告
│   └── 设计报告模板.md
└── test/              # 测试代码
    ├── unit_test.c    # 单元测试
    └── test_data/     # 测试数据集

快速开始

编译

make        # 编译主程序
make test   # 编译测试
make clean  # 清理

运行

./main
./unit_test

里程碑

里程碑 截止时间 状态
v0.1-方案确定 5月18日 ⏳ 待开始
v0.2-详细设计 6月21日 ⏳ 待开始
v0.3-编码完成 7月5日 ⏳ 待开始
v0.4-验收演示 7月10日 ⏳ 待开始
v1.0-最终提交 7月12日 ⏳ 待开始

Git提交规范

[A-模块] 具体修改内容

示例:
[A-LFG] 实现滞后斐波那契生成器(j=55,k=24)
[A-卡方检验] 实现拟合优度检验
[A-间隔检验] 实现Gap Test独立性检测
[A-可视化] 实现频率分布直方图与统计报告

源自《计算机程序设计艺术》的新故事 —— 这本书的作者栏,写着你的名字。

关于

A10 恶劣环境传感器信号仿真与统计检验台 — 钟伟(202521093008) 课程设计仓库。组合算法:LFG + 卡方/间隔检验。TAOCP出处:卷2 §3.2.2 + §3.3.1。

31.0 KB
邀请码