纯 Python/NumPy 实现的双智能体 DQN 抗干扰仿真:Agent0 负责跳频决策(10 频点),Agent1 负责功率控制(5 档),在含四类干扰(窄带/宽带/跟踪/欺骗近似)的 LEO 卫星链路上协同学习。
proj/
├── environment.py # 仿真环境: 链路预算、轨道几何、干扰模型 (v2 重写)
├── madqn_agent.py # 纯NumPy DQN 智能体 + 启发式预训练模块
├── train.py # 训练主程序 + 真实基线评估 + 绘图
├── aggregate_results.py # 多种子结果汇总 (均值±标准差表格 + 论文主图)
├── requirements.txt # 依赖 (numpy, matplotlib)
├── .gitignore
└── outputs/ # 实验数据 (git 忽略)
├── seed_42/ # 每个训练种子一个目录: 模型/日志/图表
├── seed_1/ ...
├── aggregate_results.json # 跨种子汇总数据
└── aggregate_baseline_comparison.png
pip install -r requirements.txt
python environment.py # 环境自检 (20步演示 + 200步覆盖统计)
python madqn_agent.py # 智能体模块自检
python train.py # 默认种子42训练 → outputs/seed_42/
python train.py 1 # 指定种子训练 → outputs/seed_1/
python aggregate_results.py # 汇总所有 seed_*/ 结果 (论文数据)| # | 原始缺陷 | v2 修复 |
|---|---|---|
| 1 | 卫星 z=0,仰角恒为 0°,雨衰恒 50dB | 2D 轨道面几何:仰角/距离由 Δθ 严格推导 |
| 2 | 干扰机 30dBm 发射功率直接与接收信号比,SINR≈−230dB | 干扰以接收功率建模 (JAM_RX_BASE_DBM=−85, JNR≈25dB) |
| 3 | 干扰对所有信道求和(窄带接收机不合理) | 逐信道干扰谱,只受本信道干扰 |
| 4 | 观测里的干扰是每步重新随机生成的,与真实干扰无关 | 观测读取环境缓存的真实干扰谱 |
| 5 | 跟踪干扰跟踪"当前新信道"(预知未来) | 跟踪上一时隙信道,80% 成功率(1 时隙侦察延迟) |
| 6 | 窄带干扰每步换目标(应驻留) | 驻留 20 步后换频 |
| 7 | JammingModel 内部固定 seed=42,与环境种子脱节 | 共用环境的受控 rng |
| 8 | 3 颗卫星覆盖不足;历史缓存 reset 不清零 | 12 星 30° 均布 + TIME_ACCEL,reset 完整清零 |
- 原 fig4 基线数据是硬编码编造的(如
'固定跳频': [0.3, 0, 0.4])——已删除,改为evaluate_baselines()在 5 个固定评估种子上真实运行固定/随机/启发式/MADQN 四种策略,含标准差误差棒。 - 原"数字孪生预训练"注释声称启发式,实际是随机动作——已改为真实启发式(选干扰最低频点 + SINR 余量功控)。论文表述建议用"基于启发式演示的经验预填充",慎用"数字孪生"一词。
- 冒烟测试提示:短训练下"固定信道+最大功率"基线可能与 MADQN 打平(大功率烧穿干扰)。完整训练后 MADQN 应通过省功率获得更高奖励;若不能,可上调
WEIGHT_ENERGY或增强干扰强度后重新对比。
- 欺骗干扰为简化近似(等效 SINR 恶化),未建协议层欺骗。
- 轨道为 2D 单轨道面简化,未建 3D 星座与多普勒。
- 纯 NumPy DQN,无 GPU 加速;如需扩展建议迁移 PyTorch。
git log查看历史;commit34d5d8c为修复前的原始版本备份。outputs/与*.npy已被 .gitignore 忽略。node_modules/、package.json为误入的 npm 文件,与本 Python 项目无关,确认后可删除。