# 更新日志 (Changelog)

本文档记录 PyNetIM 项目的所有重要变更。

格式基于 [Keep a Changelog](https://keepachangelog.com/)。

## [0.4.3] - 2026-03-30

### 新增 (Added)
- **IC 和 LT 模型新增激活节点记录功能**:
  - 添加 `record_activated` 参数（默认为 `false`），用于控制是否记录种子集激活的节点
  - 添加 `set_record_activated(record)` 方法，可在运行时动态开启/关闭记录功能
  - 添加 `run_single_simulation(seed=0)` 方法，用于单次独立传播模拟
  - 每次调用 `run_single_simulation` 都会进行一次独立的传播模拟，从种子集出发，返回该次模拟中被激活的所有节点
  - 支持通过不同的 `seed` 参数进行多次独立的模拟实验

### API 更新 (API Changes)
- **IndependentCascadeModel**:
  - 构造函数新增 `record_activated` 参数
  - 新增 `set_record_activated(record: bool)` 方法
  - 新增 `run_single_simulation(seed: int = 0) -> Set[int]` 方法

- **LinearThresholdModel**:
  - 构造函数新增 `record_activated` 参数
  - 新增 `set_record_activated(record: bool)` 方法
  - 新增 `run_single_simulation(seed: int = 0) -> Set[int]` 方法

### 测试 (Testing)
- **新增功能验证测试**:
  - IC 模型单次模拟测试
  - LT 模型单次模拟测试
  - 多次独立模拟测试（使用不同 seed）
  - `set_record_activated` 动态切换测试
  - 编译和运行测试全部通过

### 技术细节 (Technical Details)
- **修改文件**:
  - `src/pynetim/cpp/include/diffusion_model.h` - 添加核心功能实现
  - `src/pynetim/cpp/bindings/ic_bind.cpp` - IC 模型 Python 绑定
  - `src/pynetim/cpp/bindings/lt_bind.cpp` - LT 模型 Python 绑定
  - `src/pynetim/cpp/diffusion_model/independent_cascade_model.pyi` - 类型提示
  - `src/pynetim/cpp/diffusion_model/linear_threshold_model.pyi` - 类型提示

- **实现细节**:
  - `run_single_trial` 方法新增 `activated_nodes` 参数，用于记录激活节点
  - 当 `record_activated` 为 `true` 时，遍历所有节点收集激活的节点
  - 使用独立的随机数生成器确保每次模拟的独立性
  - 保持向后兼容性，`record_activated` 默认为 `false`

### 使用示例 (Usage Examples)
```python
# IC 模型
from pynetim.cpp.diffusion_model import IndependentCascadeModel

ic_model = IndependentCascadeModel(graph, seeds, record_activated=True)
activated_nodes = ic_model.run_single_simulation(seed=42)
print(f"激活的节点: {activated_nodes}")

# LT 模型
from pynetim.cpp.diffusion_model import LinearThresholdModel

lt_model = LinearThresholdModel(graph, seeds, theta_l=0.0, theta_h=1.0, record_activated=True)
activated_nodes = lt_model.run_single_simulation(seed=42)
print(f"激活的节点: {activated_nodes}")

# 动态开启/关闭记录
ic_model.set_record_activated(True)
```

---

## [0.4.2] - 2026-03-24

### 修复 (Fixed)
- **修复 Graph 对象生命周期管理问题**:
  - 修复了 Python 层 Graph 对象被垃圾回收后，C++ 层模型仍持有悬空指针导致的段错误
  - 根本原因：Graph 没有以正确的 `std::shared_ptr` 形式被 Python 管理
  - 解决方案：在 `graph_bind.cpp` 中使用 `std::make_shared` 创建 Graph 对象
  - 现在 Python 和 C++ 共享同一个 `shared_ptr`，引用计数统一管理
  - `py::keep_alive` 真正生效，确保 Graph 对象在模型使用期间不会被回收

### 测试 (Testing)
- **新增生命周期验证测试**:
  - `test_weakref.py` - 使用 weakref 验证 Graph 对象生命周期
  - `test_weakref2.py` - 带 seeds 的生命周期测试
  - 测试结果：Graph 对象在模型使用期间保持存活，不会发生段错误

### 技术细节 (Technical Details)
- **关键知识点**: `py::class_<T, std::shared_ptr<T>>` 只保证 Python 用 shared_ptr 管理对象，但前提是这个对象本来就是 shared_ptr 创建的
- **修改文件**: `src/pynetim/cpp/bindings/graph_bind.cpp` (L18-L28)
- **修改内容**: 将 `py::init<int, ...>()` 改为使用 lambda 函数和 `std::make_shared` 创建 Graph 对象

---

## [0.4.1] - 2026-03-24

### 修复 (Fixed)
- **修复 C++ 扩展的线程安全问题**:
  - 修复 `IndependentCascadeModel` 和 `LinearThresholdModel` 在多线程模式下的线程安全问题
  - 通过参数传递替代直接访问成员变量 `seeds`，消除跨线程共享 `std::set` 的状态
  - 解决了与 PyTorch 等多线程库结合使用时的 segmentation fault 问题
  - 经过严格测试：5000 次迭代、8 线程并发、10 图并发均稳定运行
  - 单线程和多线程结果完全一致，确保正确性

### 测试 (Testing)
- **新增严格验证测试**:
  - 单线程/多线程一致性测试
  - 长时间多线程压力测试 (2000 次迭代)
  - 多线程并发访问测试 (8 线程)
  - 多图并发处理测试 (10 个图)
  - 极限压力测试 (5000 次迭代)

---

## [0.4.0] - 2026-03-23

### 新增 (Added)
- **C++ 图支持**: 为所有工具函数添加了对 `IMGraphCpp`（C++ 图）的完整支持
  - `set_edge_weight()` - 支持 C++ 图的边权重设置
  - `infection_threshold()` - 支持 C++ 图的感染阈值计算
  - `graph_statistics()` - 支持 C++ 图的统计信息计算
  - `graph_density()` - 支持 C++ 图的密度计算
  - `connectivity_analysis()` - 支持 C++ 图的连通性分析

### 优化 (Improved)
- **性能优化**:
  - `infection_threshold()` - 避免重复计算度字典
  - `graph_statistics()` - 使用 `Counter` 替代手动循环统计度分布
  - `connectivity_analysis()` - 合并有向图和无向图的分支逻辑，消除重复代码
  - `graph_density()` - 修复整数除法问题，确保返回浮点数

- **代码质量**:
  - 删除无用的 `TYPE_CHECKING` 代码块
  - 统一函数签名，支持多种图类型
  - 优化导入语句，添加缺失的 `networkx` 模块

### 修复 (Fixed)
- **Bug修复**:
  - 修复 `utils.py` 中缺失的 `import networkx as nx` 导入
  - 修复 `graph_density()` 函数中的整数除法 `// 2` 导致的精度丢失
  - 修复 `infection_threshold()` 函数中重复调用 `dict(graph.degree())` 的性能问题
  - **修复 C++ 扩展的线程安全问题**:
    - 修复 `IndependentCascadeModel` 和 `LinearThresholdModel` 在多线程模式下的线程安全问题
    - 通过参数传递替代直接访问成员变量 `seeds`，消除跨线程共享 `std::set` 的状态
    - 解决了与 PyTorch 等多线程库结合使用时的 segmentation fault 问题
    - 经过严格测试：5000 次迭代、8 线程并发、10 图并发均稳定运行
    - 单线程和多线程结果完全一致，确保正确性

### 文档 (Documentation)
- **学术参考文献**: 为所有主要模型和算法添加了学术参考文献
  - **传播模型**:
    - Linear Threshold Model - Granovetter (1978)
    - Independent Cascade Model - Kempe et al. (2003)
    - SIR Model - Kermack & McKendrick (1927)
    - SI Model - Kermack & McKendrick (1927)
  - **影响力最大化算法**:
    - Degree Discount Algorithm - Chen et al. (2009)
    - Reverse Influence Sampling (RIS) - Borgs et al. (2014)
    - IMM Algorithm - Tang et al. (2015)
  - **工具函数**:
    - `infection_threshold()` - Pastor-Satorras & Vespignani (2001, 2015)

- **新增文档**:
  - `UTILS_OPTIMIZATION_SUMMARY.md` - utils.py 优化总结
  - `OPTIMIZATION_SUMMARY.md` - C++ 模块优化总结
  - `REFERENCES_DOCUMENTATION.md` - 参考文献添加文档
  - `CHANGELOG.md` - 本更新日志

### 兼容性 (Compatibility)
- **向后兼容**: 所有修改都保持了向后兼容性
  - NetworkX 图的使用方式完全不变
  - 新增的 C++ 图支持是可选的
  - 函数签名使用 `Union` 类型，支持两种图类型

### 技术细节 (Technical Details)
- **图类型检测**: 使用 `hasattr(graph, 'num_nodes') and hasattr(graph, 'directed')` 检测 C++ 图
- **类型注解**: 使用 `TYPE_CHECKING` 避免循环导入 `IMGraphCpp`
- **统一接口**: NetworkX 图和 C++ 图使用相同的函数接口

---

## [0.3.0] - 2025-XX-XX

### 新增 (Added)
- 初始版本发布
- 实现了多种影响力最大化算法
- 实现了多种传播模型
- 提供了 Python 和 C++ 双实现

---

## 版本说明

### 版本号规范
PyNetIM 遵循 [语义化版本控制](https://semver.org/) (Semantic Versioning)：

- **主版本号 (MAJOR)**: 不兼容的 API 修改
- **次版本号 (MINOR)**: 向下兼容的功能性新增
- **修订号 (PATCH)**: 向下兼容的问题修正

### 版本类型
- **主版本更新**: 重大架构变更、API 不兼容
- **次版本更新**: 新增功能、性能优化
- **修订版本更新**: Bug 修复、文档更新

---

## 更新分类

### 🎯 功能新增
- 新的算法实现
- 新的传播模型
- 新的图操作功能

### ⚡ 性能优化
- 算法效率提升
- 内存使用优化
- 计算速度提升

### 🐛 Bug 修复
- 代码错误修复
- 边界情况处理
- 兼容性问题修复

### 📚 文档改进
- API 文档更新
- 示例代码更新
- 学术参考文献添加

### 🔧 内部改进
- 代码重构
- 测试覆盖提升
- 构建流程优化

---

## 贡献指南

如果您想为 PyNetIM 做出贡献，请：

1. Fork 本仓库
2. 创建特性分支 (`git checkout -b feature/AmazingFeature`)
3. 提交更改 (`git commit -m 'Add some AmazingFeature'`)
4. 推送到分支 (`git push origin feature/AmazingFeature`)
5. 开启 Pull Request

---

## 许可证

本项目采用 MIT 许可证 - 详见 [LICENSE](LICENSE) 文件。

---

## 联系方式

- **作者**: Zhang Kaijing
- **项目主页**: https://zzzkhj.github.io/PyNetIM/
- **问题反馈**: [GitHub Issues](https://github.com/zzzkhj/PyNetIM/issues)

---

**最后更新**: 2026-03-24