Skip to content

A+B 问题:算法性能对比研究

下载链接:https://chenyuheee.github.io/blog/notes/FDS/hard/submission.zip

研究目标:对比两种求解两数之和问题的算法的实际性能差异:

  • 算法 1:暴力穷举 (O(N²))
  • 算法 2:排序+双指针 (O(N log N))

系统要求

项目已在 macOS 环境验证;Linux/Windows 可按下列等价命令复现。

  • 编译器gcc(或其他支持 C11 的兼容编译器)
  • Python 3(用于绘图,可选)
  • pdflatex(用于编译报告,可选;PDF 已预编译)

快速开始

在项目根目录执行以下命令:

bash
# 1. 编译基准测试程序
gcc src/test.c -O0 -std=c11 -Wall -Wextra -o build/test_bench

# 2. 生成基准数据(预计耗时:1-2 分钟)
./build/test_bench 1000 42 > data/results_v1000.csv
./build/test_bench 10000 42 > data/results_v10000.csv
./build/test_bench 100000 42 > data/results_v100000.csv

# 3. 合并结果
{ head -n 1 data/results_v1000.csv; tail -n +2 data/results_v*.csv; } > data/results.csv

# 4. (可选)使用 matplotlib 生成性能对比图
python3 src/graph.py --input data/results.csv --out-dir figures --format png

# 5. 查看编译后的报告(按系统选择其一)
open report/report.pdf                 # macOS
# xdg-open report/report.pdf           # Linux
# start report/report.pdf              # Windows (PowerShell/CMD)

目录结构

.
├── src/                          # 源代码
│   ├── main.c                    # 交互式版本(手动测试用)
│   ├── test.c                    # 基准测试程序(8个N值 × 3个V值)
│   └── graph.py                  # 绘图脚本(基于 matplotlib)
├── data/                         # 原始基准测试结果
│   ├── problem.txt               # 原题目描述
│   ├── results_v1000.csv         # V=1000 的结果(8行)
│   ├── results_v10000.csv        # V=10000 的结果(8行)
│   ├── results_v100000.csv       # V=100000 的结果(8行)
│   └── results.csv               # 合并结果(24行)
├── figures/                      # 生成的性能对比图
│   ├── runtime_V1000.png         # V=1000 对比图
│   ├── runtime_V10000.png        # V=10000 对比图
│   └── runtime_V100000.png       # V=100000 对比图
├── report/                       # 报告文件
│   ├── report.tex                # LaTeX 源文件(供参考)
│   └── report.pdf                # 编译后的最终报告(当前版本 3 页)
├── build/                        # 编译后的可执行文件
│   └── test_bench                # 基准测试可执行程序
└── README.md                     # 本文件

算法实现

算法方法时间复杂度空间复杂度说明
1暴力穷举 O(N²)O(N²)O(1)嵌套循环枚举所有数对
2排序+双指针O(N log N)O(N)使用辅助数组备份

基准数据格式

每个 CSV 文件的结构如下:

V,N,K1,func1_time,K2,func2_time
1000,1000,1,0.000207000,1,0.000059000
...

列的含义:

  • V:数值范围 [2, V]
  • N:数组元素个数
  • K1, K2:每个算法的重复次数(自动选择以达到 ≥10 个 clock ticks)
  • func1_time:算法 1 的平均执行时间(秒)
  • func2_time:算法 2 的平均执行时间(秒)

预期输出文件

运行完所有步骤后,应该生成以下文件:

文件说明行数
data/results.csv合并后的基准数据1 个表头 + 24 行数据
figures/runtime_V*.png3 张性能对比图
report/report.pdf正式报告(页数可能随排版微调)

数据验证

bash
# 检查行数
wc -l data/results.csv          # 应显示 25(1 个表头 + 24 行数据)

# 查看前几行结果
head -n 3 data/results.csv

# 预期加速比(算法 1 vs 算法 2):
# ~100-400 倍,取决于 N 和 V 的大小

实现细节

测试数据生成

  • 随机值:均匀分布在 [2, V] 范围内
  • 保证的解:最后两个元素都是 1,保证和为 2
  • 目的:避免最佳情况偏差(解在数组开头)

计时方法

  • 使用 C 标准库的 clock() 函数
  • 自适应 K 选择:K 从 1 开始,每次翻倍,直到经历 ≥10 个 ticks
  • 目的:根据题目要求达到 ≥10% 的测量精度
  • 公式:平均时间 = (总 ticks / K) / CLOCKS_PER_SEC

关键特性

  • 两个算法操作相同的测试数据(无输入偏差)
  • 算法 2 使用备份数组(memcpy)以保护原始数据
  • 测量不包括内存分配/释放的开销
  • -O0 编译下,编译器通常不会把函数调用优化掉

常见问题与解决方案

问题解决方案
"command not found: gcc"安装编译器:brew install gcc(macOS)或 apt install build-essential(Ubuntu)
"No module named 'matplotlib'"安装:pip3 install matplotlib(可选,仅用于绘图)
"pdflatex: command not found"安装:brew install basictex(macOS)或 apt install texlive-latex-base(Ubuntu)
"Memory error for large N"增加系统内存或减小 N 值
结果与示例不同CPU 负载导致的正常波动;检查 K 值是否 ≥1

报告结构

编译后的 report/report.pdf 包含:

  1. 第 1 章:问题描述与算法设计
  2. 第 2 章:复杂度分析、实验设置、结果、可视化图表及讨论

说明:LaTeX 源文件(report.tex)用于追踪排版与内容来源;peer review 可直接基于仓库现有数据与 PDF 完成复核。

注意事项与提示

  • 随机数种子:使用 seed=42 可确保测试数据的可重复性
  • 运行时间:完整基准测试(三个 V 值)通常需要 1-2 分钟
  • 性能图表figures/ 中的三张 PNG 图表清晰展示算法 2(对数坐标)相比算法 1 的性能优势
  • CSV 格式:结果格式清晰易读,便于导入 Excel 或 Python 进行进一步分析

如有疑问,请参考 data/problem.txt 中的原题目描述。