基于深度强化学习的MEC计算卸载与资源分配Python源码实战
2026/9/23 22:32:32 网站建设 项目流程

简介:这份资源是面向计算机、人工智能、通信工程等专业学生与教师的毕业设计/课程设计参考包,聚焦移动边缘计算(MEC)场景下的计算卸载与资源分配问题,采用深度强化学习(DQN)方法实现。包内共19个文件,以py源码、sh运行脚本、txt日志、png结果图和md说明文档为主,压缩包约112KB,结构清晰,便于按模块阅读与复现。核心代码包含MEC环境建模与DQN智能体实现,配套脚本可分别运行不同实验配置,日志与图表用于对比算法性能,帮助理解卸载决策与资源分配策略的训练与评估流程。目前已有290人学习下载,适合作为毕设项目、课程大作业或项目初期立项演示,也可在现有代码基础上修改扩展,实现其他功能。

1. 从一份毕设源码说起:MEC 计算卸载到底在算什么

移动边缘计算(MEC)把算力从中心云推到基站侧,手机、车机、AR 眼镜这类终端就能把重任务甩给边缘服务器跑。可问题来了:任务什么时候本地跑、什么时候卸载、卸载到哪台边缘节点、给多少带宽和算力,这一连串决策组合起来是个 NP 难的混合整数问题。传统方法要么穷举、要么启发式,场景一变就得重调。深度强化学习(DRL)的价值在于让智能体自己从交互里学策略,不用为每种网络状态手写规则。这份「基于深度强化学习的 MEC 计算卸载与资源分配 python 源码」要解决的,正是把状态、动作、奖励建模清楚,再用 DRL 算法训出一个能在线决策的卸载策略。适合做毕设、课程设计,或者想从仿真入手理解 MEC 调度的同学。

2. 把 MEC 卸载问题翻译成 DRL 能吃的 MDP

2.1 状态、动作、奖励三件套怎么定

DRL 不是拿来就能套的,第一步是把 MEC 场景写成马尔可夫决策过程。状态通常包含:终端任务队列积压、任务数据量、本地 CPU 频率、各边缘节点的剩余算力与信道增益。动作空间有两种设计思路——离散动作把「本地执行 / 卸载到节点 1 / 卸载到节点 2」编码成 one-hot,连续动作则直接输出卸载比例和资源分配系数。奖励函数是整套代码的灵魂,一般写成时延与能耗的加权负值:

# 奖励函数:时延 + 能耗加权,取负值供最大化 def compute_reward(task, action, local_cpu, edge_cpu, channel_gain): # action: [offload_ratio, bandwidth_ratio, edge_cpu_ratio] offload_ratio, bw_ratio, cpu_ratio = action # 本地执行时延 local_delay = task.data_size * (1 - offload_ratio) / local_cpu # 卸载传输时延 + 边缘执行时延 trans_rate = bw_ratio * channel_gain # 简化香农公式 trans_delay = task.data_size * offload_ratio / max(trans_rate, 1e-6) edge_delay = task.data_size * offload_ratio / (cpu_ratio * edge_cpu) total_delay = max(local_delay, trans_delay + edge_delay) # 能耗:本地按 CPU 频率立方,传输按功率 energy = 0.5 * local_cpu**3 * local_delay + 0.1 * trans_delay return -(0.7 * total_delay + 0.3 * energy) # 权重可调

这段代码里offload_ratio是卸载比例,bw_ratio是分到的带宽占比,cpu_ratio是边缘节点分给该任务的算力占比。权重 0.7 和 0.3 分别控制时延和能耗的偏好,做毕设时建议先固定权重跑通,再改权重看策略变化。注意max(trans_rate, 1e-6)是防止除零,这个坑后面还会提。

2.2 为什么选 DDPG 而不是 DQN

动作空间如果是连续的(卸载比例 0 到 1),DQN 就废了,它只能处理离散动作。DDPG 用 Actor-Critic 结构,Actor 输出连续动作,Critic 评估价值,适合这种混合决策。如果动作设计成离散的「卸载或不卸载」,DQN 或 Double DQN 也能用,但资源分配那部分还是连续量,所以多数 MEC 论文选 DDPG、TD3 或 PPO。选型时看两点:动作是否连续、样本效率要求高不高。DDPG 样本效率比 PPO 高,但容易过估计,TD3 加了双 Critic 和延迟更新更稳。源码里如果用的是 DDPG,重点看它有没有加目标网络软更新。

2.3 环境搭建与依赖安装的最小步骤

拿到源码先别急着跑训练,环境不对全是报错。常见依赖是 gym、numpy、torch、matplotlib。建议用 conda 建独立环境,避免和系统 Python 打架:

# 创建并激活环境 conda create -n mec_drl python=3.9 -y conda activate mec_drl # 安装核心依赖,torch 按自己 CUDA 版本选 pip install numpy gym matplotlib pip install torch==2.0.1 --index-url https://download.pytorch.org/whl/cu118 # 验证 python -c "import torch, gym; print(torch.__version__, gym.__version__)"

python=3.9是兼容性较好的版本,torch 2.0.1 配 cu118 是常见组合,没有 GPU 就装 CPU 版。验证那行能打印出版本号说明环境通了。如果gymAttributeError,多半是版本太新,pip install gym==0.21.0降级即可。

3. 源码结构拆解与训练主循环怎么跑通

3.1 目录里每个文件在干什么

这类毕设源码通常分四块:env/放 MEC 环境模拟,agent/放 DRL 算法,train.py是训练入口,evaluate.py是测试入口。环境文件里会有reset()step(action)两个核心方法,reset初始化任务队列和信道状态,step执行动作并返回next_state, reward, done。Agent 文件里是网络定义和select_actionupdate方法。先读env再读agent,顺序反了会一头雾水。

3.2 训练主循环的关键代码与参数

主循环的逻辑是:重置环境,每步选动作、执行、存经验、采样更新。下面是一个精简版:

# 训练主循环 for episode in range(MAX_EPISODES): state = env.reset() episode_reward = 0 for step in range(MAX_STEPS): action = agent.select_action(state) # 加噪声探索 next_state, reward, done, _ = env.step(action) agent.store_transition(state, action, reward, next_state, done) if len(agent.buffer) > BATCH_SIZE: agent.update() # 采样更新网络 state = next_state episode_reward += reward if done: break print(f"Episode {episode}, Reward: {episode_reward:.2f}")

MAX_EPISODES一般设 500 到 1000,MAX_STEPS是每回合步数,BATCH_SIZE常见 64 或 128。select_action里的探索噪声很关键,DDPG 用 Ornstein-Uhlenbeck 噪声或高斯噪声,噪声方差随训练衰减。如果奖励曲线一直不涨,先看噪声是不是太大导致动作乱跳。

3.3 训练不收敛时先查这三个地方

第一看奖励尺度,如果时延是毫秒级、能耗是焦耳级,两者数量级差太多,加权后能耗项被淹没,建议归一化。第二看经验回放池,容量太小(比如小于 1000)样本不够,太大会训得慢,常见 10000 到 100000。第三看学习率,Actor 用 1e-4、Critic 用 1e-3 是常见起点,太大直接发散。这三处调完还不收敛,再怀疑网络结构。

4. 避坑与排查:那些让毕设卡三天的坑

4.1 奖励一直下降或震荡

现象:训练几百回合奖励不升反降。原因:奖励函数里时延和能耗量纲没统一,或者探索噪声方差没衰减。解决:对时延和能耗分别做 min-max 归一化,噪声方差从 0.2 线性衰减到 0.01。

4.2 环境 step 返回的 done 永远是 False

现象:每回合跑满 MAX_STEPS 才结束,学不到终止逻辑。原因:done条件写成了任务队列为空,但队列一直在补充新任务。解决:改成「连续 N 步队列积压低于阈值」或「达到最大时延约束」才置 True。

4.3 显存溢出或训练极慢

现象:跑几十回合就 OOM。原因:经验回放池存了完整状态张量且没 detach,或者 batch 太大。解决:存经验时用.detach().cpu().numpy(),batch 从 64 起步,回放池用 deque 限制容量。

4.4 评估时策略和训练时表现差很多

现象:训练奖励不错,测试一塌糊涂。原因:评估时忘了关探索噪声,动作带随机性。解决:select_actioneval_mode参数,评估时噪声置零,只取 Actor 输出均值。

4.5 多边缘节点场景下动作维度对不上

现象:节点数从 3 改成 5 就报维度错误。原因:网络输出层维度写死了。解决:把动作维度写成num_nodes * 3(卸载比例、带宽、算力各一份),网络输出层用num_nodes * 3动态构建。

5. 让策略更稳的两个进阶技巧与验证方法

5.1 用优先经验回放提升样本效率

普通回放池均匀采样,优先经验回放(PER)按 TD 误差采样,误差大的样本多学几次。在 MEC 场景里,任务突发的样本少但重要,PER 能让智能体多练这些边缘情况。实现时给每个经验存一个优先级,采样概率正比于优先级,更新时按重要性采样权重修正偏差。代码上把agent.buffer换成PrioritizedReplayBuffer,采样返回(state, action, reward, next_state, done, weights),更新损失时乘上 weights。注意优先级参数 α 设 0.6、β 从 0.4 退火到 1.0 是常用值。

5.2 用固定随机种子验证策略可复现

毕设答辩最怕「我跑出来和你不一样」。在训练脚本开头固定种子:

import numpy as np, torch, random def set_seed(seed=42): random.seed(seed) np.random.seed(seed) torch.manual_seed(seed) torch.cuda.manual_seed_all(seed) torch.backends.cudnn.deterministic = True set_seed(42)

cudnn.deterministic = True会让 GPU 卷积结果可复现,代价是略慢。固定种子后跑三次,奖励曲线方差应该在可接受范围,如果差太多说明算法本身不稳定,得回去查超参。

5.3 对比实验怎么设计才有说服力

至少跑三组:全本地执行、全卸载、DRL 策略。指标看平均时延、平均能耗、任务完成率。每组跑 5 个随机种子取均值,画带误差棒的柱状图。如果 DRL 只比全本地好一点点,检查奖励权重是不是偏向能耗了。我自己的习惯是先把全本地和全卸载的基线跑出来,心里有数了再调 DRL,不然连「好」的标准都没有。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询