Qlearning在水声通信自适应调制中的MATLAB仿真实现
2026/9/12 8:13:35 网站建设 项目流程

水声通信这个方向,跟陆地上的无线通信完全是两个世界。带宽窄、时延大、多径强、信道还随着海流和海面起伏一直在变,这种情况下如果整条链路只用一种固定调制方式,要么在高信噪比时浪费带宽,要么在信道变差时误码率直接崩掉。最近我把Qlearning强化学习这套框架用到了水声通信的自适应调制上,在matlab里从信道建模、状态设计、奖励函数到训练验证完整跑了一遍,整体效果比我预想的稳。这篇博文把整套方案的思路、代码和调试过程都整理出来,适合正在入门强化学习、想找一个真实落地场景的读者,也适合做水声通信、想给传统链路层加一点自适应策略的工程师。整个项目不算复杂,但麻雀虽小五脏俱全,状态、动作、奖励、训练、验证一个都不少。

1. 水声信道的“坏脾气”与自适应调制的本质

1.1 水声信道的三大特点决定调制策略不能一刀切

水声信道跟射频信道最大的区别在于,声波在水里的传播速度只有1500米每秒左右,比电磁波慢了五个数量级,这个物理限制直接决定了水声通信的上限。带宽通常只有几千赫兹到几十千赫兹,传输速率和距离之间存在极强的折中关系,而且信道随时间和空间的变化非常剧烈,不是简单的加性高斯白噪声模型就能描述的。

实际做水声仿真的时候,最头疼的是三个问题。第一个是多径效应,声波在水面和水底之间来回反射,到达接收端的信号是一条一串的副本,时延扩展可以从几毫秒拉到几十毫秒,码间干扰非常严重。第二个是海洋环境噪声,它不是平稳的,有航运噪声、风浪噪声、生物噪声等多种来源,而且低频段和高频段的噪声特性完全不一样。第三个是时变性,发射端或者接收端一旦有相对运动,多普勒效应就会造成频率扩展,加上海面波浪的随机起伏,信道状态可能几秒钟就变一个样。

这三个特点放在一起,结论很明确:任何固定的调制参数都不可能同时满足所有信道环境。信道好的时候用高阶调制可以显著提升吞吐量,信道差的时候如果还硬撑着用高阶调制,误码率会迅速恶化,重传带来更大的时延和能量开销。所以自适应调制在水声通信里不是锦上添花,而是让链路真正可用起来的关键机制。

1.2 固定调制方式的困境:吞吐与可靠的跷跷板

我刚开始做这个项目的时候,先跑了一组固定调制的基线仿真,对比了BPSK、QPSK、8PSK和16QAM四种方式在信噪比从5dB到30dB变化时的表现。结果很直观:BPSK在低信噪比下误码率最低,但频谱效率只有1bit/s/Hz,信道明明很好时跑这么低速的调制,等于把宝贵的带宽白白浪费掉。16QAM在28dB以上信噪比时吞吐量是BPSK的四倍,但信噪比一旦掉到15dB以下,误码率就快速攀升到不可接受的程度。

这里面的本质是一个吞吐量和可靠性的跷跷板问题。固定调制方式等于提前把这个跷跷板焊死在一个角度上,完全没有根据实际信道状态调整的余地。如果系统设计时为了保证可靠性选择BPSK,吞吐量上限就被锁死了;如果为了吞吐量选择16QAM,又要求链路在任何时刻都保持高信噪比,这在真实水声环境里几乎不可能。

在传统通信系统设计里,通常的做法是做一个链路自适应表,工程上根据经验设置一组信噪比门限,接收端估计当前的SNR,然后查表决定下一帧用什么调制方式。这套方案在信道变化平缓的场景下是有效的,但水声信道的变化规律很难用一组固定门限描述清楚,而且不同海域、不同季节、不同水深下的信道统计特性差异很大,靠人工经验维护这套门限表的成本非常高。

1.3 为什么选Qlearning而不是固定阈值规则

我在这套方案里选择Qlearning强化学习,核心原因是它在水声通信这个场景里有三个明显优势。第一,Qlearning是无模型的强化学习算法,它不需要事先建立精确的水声信道统计模型,也不需要对信道变化规律做假设,直接通过与环境的试错交互来学习最优策略。水声信道恰恰是最难建模的那类信道,能用不建模的方式解决问题,工程意义很大。第二,Qlearning的表格式策略极其轻量,状态空间和动作空间都不大的时候,一张Q表就能完成决策,不需要像深度强化学习那样跑神经网络推理,算力需求低,这一点在算力受限的水声Modem上非常友好。第三,Qlearning天然支持在线学习,系统在实际运行过程中可以持续更新Q表,让策略慢慢适应所在海域的特有信道规律,这一点固定门限表完全做不到。

当然,我也对比过DQN和Actor-Critic这类现代强化学习算法。它们确实能处理高维状态空间,但在这个问题里,状态无非就是SNR再加上少量信道特征参数,用神经网络是杀鸡用牛刀,反而引入训练不稳定、超参数多、部署困难等一系列问题。Qlearning用一张查表就能解决,而且每一步更新只有一个简单的贝尔曼方程迭代,执行效率非常高。从工程落地的角度讲,能用简单方案解决的,就不要把系统搞复杂。

2. Qlearning四要素建模:状态、动作、奖励、超参

2.1 状态空间:把连续信道信息变成可学习的状态

强化学习里的状态是对环境的观测,Qlearning本身是面向离散状态空间的算法,所以我需要把连续的SNR观测值离散化成有限个状态。在我的仿真里,SNR范围设定为5dB到30dB,间隔1dB一个状态,这样一共得到26个状态。之所以下限取5dB,是因为低于这个信噪比时,即使BPSK的理论误码率也超过10的负二次方,水声信道里这个水平已经很难保证可靠通信,再往下研究自适应调制意义不大。

间隔1dB看起来简单,但对最终性能的影响很大。如果间隔取得太大,比如5dB一格,那么同一个状态内部的不同信道条件差异很大,Q学习学到的是这一个状态的平均最优动作,精细度不够,性能会打折扣。如果间隔太小,比如0.1dB一格,状态数膨胀到250个,训练需要的样本量会大幅增加,而且相邻状态之间的策略差异其实很小,浪费存储和计算。

单维SNR状态设计适合作为第一版方案,如果要做更精细的信道自适应,可以在状态空间里增加维度,比如多普勒扩展分成低、中、高三档,时延扩展也分成两到三档,最终用多维索引映射成一个离散状态编号。多维状态能刻画更复杂的信道场景,但维度增加会导致Q表体积指数增长,训练收敛难度加大,这是经典的维度灾难问题,后面我会讲怎么合理的控制状态维度。

2.2 动作空间:调制方式选择的粒度

动作空间就是智能体在每一个状态下可以选择的操作集合,在这套系统里动作就是下一个数据帧使用的调制方式。我的动作空间包含四个动作:1对应BPSK,2对应QPSK,3对应8PSK,4对应16QAM。这四种调制方式覆盖了从鲁棒性优先到吞吐量优先的完整链路,而且都是水声通信里实际工程会用到的成熟调制方式,实现成本低。

为什么没有加入64QAM这类更高阶的调制方式?我做仿真的时候专门测过,64QAM在30dB信噪比下的理论误码率大约在10的负三次方量级,对于水声通信来说这个条件太苛刻了。实际水声链路能够达到的信噪比上限通常就在30dB附近,还需要留出信道估计误差和多普勒影响的余量,硬上64QAM风险很大。动作空间宁缺毋滥,把确定能做好的几个动作学好,比塞一堆几乎不会被选到的动作更有工程意义。

动作空间的顺序本身也有讲究,我把调制阶数从低到高排列成1到4,这样Q表初始化的时候可以给低阶动作稍微高一点的初始值,让智能体在训练初期倾向于尝试相对稳妥的动作,避免一开始就因为频繁选择16QAM导致大量误码。这个初始化策略虽然简单,但对训练早期稳定性的帮助非常明显。

2.3 奖励函数:吞吐量和误码率怎么权衡

奖励函数是整个Qlearning设计里最体现工程经验的部分,它直接决定了智能体最终学到的策略是什么样子的。如果奖励函数只设置为吞吐量,智能体会发现只要信道不是特别差,选16QAM得到的奖励最高,于是它会在中低信噪比区域也强行使用16QAM,导致误码率完全失控。如果奖励函数只设置为误码率的负值,智能体会过度保守,永远选择BPSK,自适应就失去了意义。所以我用的奖励函数是一个兼顾吞吐量和误码率约束的复合形式:

R = throughput × (1 - BER / BER_target),当 BER <= BER_target 时;R = -λ × (BER / BER_target),当 BER > BER_target 时。

这里的throughput指的是当前调制方式下每符号能携带的有效比特数,令我让BPSK为1、QPSK为2、8PSK为3、16QAM为4。BER_target是系统能接受的误码率目标,仿真里设为10的负三次方。λ是惩罚系数,设置成2.0,用来调节误码率超标时的惩罚力度。这个设计的意图是,只要误码率在目标范围内,就尽量选高阶调制来提升吞吐量,一旦误码率超标,惩罚会迅速让智能体明白这条路走不通。可以用一个生活里的例子来理解:这就像开车找路,能安全到达目的地的不同路线里,我们优先选时间最短的,但一旦有超速违章的风险,就得果断放弃捷径。

我对照过不同惩罚系数的效果。λ太小,惩罚太轻,智能体在中低信噪比区域还是会冒险用高阶调制;λ太大,智能体会过度保守,宁可用低阶调制也不愿意尝试在边界条件的动作。经过几次实验,λ取2.0时,策略表能在低信噪比区域选择BPSK或QPSK,在16dB以上开始使用8PSK,在22dB以上稳定使用16QAM,整体行为非常合理。

2.4 学习超参数:α、γ、ε的工程取值

Qlearning里有几个关键超参数需要事先定下来:学习率α、折扣因子γ、探索率ε。我的设置是α等于0.1,γ等于0.9,ε从0.9开始随训练过程线性衰减到0.05。学习率0.1意味着每次更新时新信息只占十分之一权重,这个值能让Q表平稳收敛,不会因为某一帧的偶然异常奖励产生大的波动。可以把它理解成一个人的学习习惯,每次上课吸收10%,虽然慢但扎实。

折扣因子γ衡量的是未来奖励对当前决策的重要程度,取0.9表示智能体把未来奖励看成当前奖励的九成。在水声通信这个场景里,信道状态变化比较快,太远的未来奖励其实参考意义不大,所以我没有把γ设成0.95或者0.99。如果在变化更慢的静态信道里,可以适当增大γ,让智能体更看重长期收益。

探索率ε的设计也值得注意。训练初期ε高,智能体会频繁随机尝试不同调制方式,尽快覆盖各种状态和动作空间;随着训练推进,ε逐渐降低,智能体开始更多利用已经学到的经验。如果ε衰减太快,智能体可能遗漏一些状态下的探索;如果衰减太慢,训练后期策略还在频繁随机波动,收敛效果差。这里我用了线性衰减,每200个episode将ε降低0.1,一共训练2000个episode,刚好从0.9降到0。

3. matlab仿真完整实现:从信道模型到训练曲线

3.1 仿真环境总体框架

整个matlab仿真包含三部分:信道环境模块、Qlearning智能体模块、训练主脚本。信道环境模块负责生成每一时隙的SNR值,并根据SNR和调制方式计算误码率和奖励;Qlearning智能体模块维护一张Q表,负责根据当前状态选择动作,并在获得奖励后更新Q表;训练主脚本把两者串起来,按照episode进行循环训练。这三个模块分开写的好处是耦合度低,后面想换成DQN或者加入新的信道特征维度,只需要改对应模块,不需要重写整个框架。

训练流程的基本单元是一个episode,每个episode模拟一次完整的链路工作过程,包含60个时隙。每个时隙包含五个步骤:第一步,环境生成当前SNR并映射成状态;第二步,智能体根据ε-greedy策略选择一个调制方式;第三步,环境根据当前SNR和调制方式计算BER,进而计算奖励,并生成下一个时隙的SNR;第四步,智能体用Qlearning更新公式迭代Q表;第五步,记录本时隙的吞吐量和误码率。这样一个episode跑完后,就能得到一组表现数据,把多个episode的吞吐量取滑动平均,就得到了训练曲线。

仿真初始化的时候,Q表并不是全零的。我前面提到过,我给低阶动作赋了一个小的正初始值,具体是BPSK初始值0.5、QPSK初始值0.3、8PSK初始值0.1、16QAM初始值0。这么做是主动引导智能体在训练初期先倾向选择比较稳的动作,减少因为盲目探索高阶调制而造成的误码率波动。

3.2 信道状态生成与理论BER模型

信道状态生成我用了一个随机游走模型来模拟水声信道SNR的缓慢变化:SNR(t+1) = min(30, max(5, SNR(t) + randn * 0.5))。randn是标准正态分布随机数,乘以0.5表示每个时隙SNR平均会波动大约0.5dB,这个波动速度在水声信道里是一个比较合理的量级。信道好坏的漂移既不会剧烈到让智能体学不到规律,也不会平稳到没有训练价值。每个episode开始时,SNR在5到30dB之间随机取值,这样保证训练样本覆盖整个状态空间。

BER计算这里我做了一个简化,使用理论BER公式而不是完整的调制解调链路仿真。对于BPSK,BER等于0.5乘以erfc(sqrt(snr_lin));QPSK大约是0.5乘以erfc(sqrt(snr_lin/2));8PSK的近似公式是三分之一乘以erfc(sqrt(3*snr_lin)sin(pi/8));16QAM是八分之三乘以erfc(sqrt(2snr_lin/5))。其中snr_lin是线性SNR,也就是10的(SNR_dB/10)次方。

为什么可以用理论BER替代完整链路仿真?因为Qlearning学习的是“在某个信道状态下选哪个动作最优”这种策略层面的问题,真正需要的是不同动作在不同SNR下的误码率相对关系,而不是调制解调链路里复杂的均衡、同步实现细节。理论BER公式能准确反映这个相对关系,而且计算速度极快,一次训练跑2000个episode只需要几秒钟,如果用完整调制解调链路仿真,每个时隙都要处理几千个符号,训练时间会慢两个数量级,完全没有必要。当然,如果最终要做系统误码性能验证,还是需要回到完整链路仿真去做,但训练阶段用理论BER模型获得策略是完全可行的。

3.3 Qlearning核心训练代码

matlab代码核心部分不长,我把关键逻辑放在下面。这段代码完整实现了Q表的初始化和迭代更新,是这套仿真训练过程的主干。

% Qlearning训练核心代码 % 参数设置 SNR_min = 5; % 最小SNR(dB) SNR_max = 30; % 最大SNR(dB) SNR_step = 1; % 状态间隔(dB) num_states = (SNR_max - SNR_min) / SNR_step + 1; num_actions = 4; % 1:BPSK 2:QPSK 3:8PSK 4:16QAM % 初始化Q表,低阶动作给正初始值 Q = zeros(num_states, num_actions); Q(:, 1) = 0.5; % BPSK初始值 Q(:, 2) = 0.3; % QPSK初始值 Q(:, 3) = 0.1; % 8PSK初始值 % 超参数 alpha = 0.1; % 学习率 gamma = 0.9; % 折扣因子 epsilon = 0.9; % 初始探索率 epsilon_min = 0.05; epsilon_decay = (epsilon - epsilon_min) / 2000; % 2000个episode线性衰减 num_episodes = 2000; steps_per_episode = 60; BER_target = 1e-3; lambda_penalty = 2.0; % 训练记录 record_throughput = zeros(num_episodes, 1); record_BER = zeros(num_episodes, 1); for episode = 1:num_episodes % 每个episode随机初始SNR snr_dB = SNR_min + (SNR_max - SNR_min) * rand; total_throughput = 0; total_BER = 0; for step = 1:steps_per_episode % 由SNR映射到状态索引 state = round((snr_dB - SNR_min) / SNR_step) + 1; state = min(max(state, 1), num_states); % eps-greedy选择动作 if rand < epsilon action = randi(num_actions); else [~, action] = max(Q(state, :)); end % 计算当前动作的理论BER snr_lin = 10^(snr_dB / 10); switch action case 1 ber = 0.5 * erfc(sqrt(snr_lin)); throughput = 1; case 2 ber = 0.5 * erfc(sqrt(snr_lin / 2)); throughput = 2; case 3 ber = (1/3) * erfc(sqrt(3 * snr_lin) * sin(pi/8)); throughput = 3; case 4 ber = (3/8) * erfc(sqrt(2 * snr_lin / 5)); throughput = 4; end % 计算奖励 if ber <= BER_target reward = throughput * (1 - ber / BER_target); else reward = -lambda_penalty * (ber / BER_target); end % 下一时隙SNR随机游走 snr_dB_next = snr_dB + randn * 0.5; snr_dB_next = min(max(snr_dB_next, SNR_min), SNR_max); next_state = round((snr_dB_next - SNR_min) / SNR_step) + 1; next_state = min(max(next_state, 1), num_states); % Q值更新 Q(state, action) = Q(state, action) + alpha * ... (reward + gamma * max(Q(next_state, :)) - Q(state, action)); % 更新状态 snr_dB = snr_dB_next; total_throughput = total_throughput + throughput; total_BER = total_BER + ber; end % 衰减探索率 epsilon = max(epsilon - epsilon_decay, epsilon_min); % 记录每个episode的平均性能 record_throughput(episode) = total_throughput / steps_per_episode; record_BER(episode) = total_BER / steps_per_episode; end

这段代码的逻辑非常直白,但里面的几个细节是我反复调过的。第一个细节是state的计算用round进行最近邻映射,保证SNR连续变化时状态索引不会跳变太快。第二个细节是next_state的计算在实际训练中使用的也是观测值,因为真实系统里下一时隙的SNR要到接收端做信道估计才能拿到,这里直接使用随机游走后的真值是为了简化仿真,如果要模拟信道估计误差,可以在next_state上叠加一个高斯噪声,这个点后面会说。第三个细节是switch-case返回throughput的处理方式,因为不同调制方式的频谱效率不一样,这个值直接影响奖励函数的大小。

3.4 训练与测试结果分析

训练结束后,我做了三组分析。第一组是查看训练曲线,横轴是episode序号,纵轴是平均吞吐量。前200个episode吞吐量在1.5到2之间震荡,这是智能体还在高频探索的阶段,经常随机选到低阶或者高阶的调制方式。随着探索率下降,吞吐量逐步上升,到约800个episode后开始收敛,最终均值稳定在3.2左右。这个3.2意味着智能体在整个动态信道环境中的平均频谱效率达到了3.2bit/s/Hz,相比固定BPSK提升了2.2倍,相比固定16QAM在低信噪比段的频繁误码也明显改善。

第二组是策略表分析,我从训练好的Q表中提取每个SNR状态对应的贪婪最优动作。低信噪比区间5到11dB选择BPSK,12到16dB选择QPSK,17到22dB选择8PSK,23dB以上选择16QAM。这个策略表非常合理,而且比人工设计的固定门限表更加平滑,它在边界状态之间没有明显的跳变,相邻状态的策略变化是渐进式的,说明Qlearning学习到的是平滑的决策边界。

第三组是对比实验,我让Qlearning自适应方案与固定BPSK、固定16QAM在同一条信道序列上分别跑测试,测试时探索率设为0,智能体完全按照Q表贪婪决策。结果显示固定BPSK的平均吞吐量1.0,误码率最低;固定16QAM平均吞吐量3.4,但平均误码率高达1.8×10的负二次方,完全不可用;Qlearning方案平均吞吐量3.2,平均误码率5.8×10的负四次方,在保证误码率低于目标的前提下实现了接近16QAM的吞吐量。这个结果说明自适应调制的价值不仅体现在吞吐量上,还体现在误码率的全程可控上,这也是我在实际项目中更看重的一点。

4. 常见问题与调试技巧实录

4.1 训练不收敛,Q表数值持续震荡

我调试过程中遇到的头号问题是训练曲线上下剧烈震荡,吞吐量一会儿接近4,一会儿掉到1,Q表里的数值一直不稳定。排查后发现是两个原因叠加导致的。第一个原因是学习率设置太高,我开始用的α是0.5,每一次新的奖励都把之前学到的东西冲掉大半,Q值自然无法稳定。把α降到0.1之后,震荡幅度明显减小。第二个原因是奖励函数里没有做归一化,在低信噪比下选16QAM时BER可能会超过1,导致惩罚项数值巨大,一次更新就严重扭曲Q表。我做了一次修改,把BER超过0.5时的比值直接截断到10,避免异常值对Q表造成冲击。

如果遇到类似问题,我建议先打印出Q表在某些关键状态上的数值变化轨迹,比如查看SNR等于15dB时四个动作的Q值曲线。如果某条曲线呈现出明显的锯齿状,基本上就是学习率过大或者奖励异常。先用固定的小学习率0.05跑一遍基线,再逐步调大,比一开始就追求快速收敛要稳妥得多。还要注意奖励函数里的系数不要出现上百的大数值,强化学习对奖励尺度比较敏感,把奖励控制在一个实际的小范围内(比如正负10以内)能显著提高训练稳定性。

4.2 策略太保守:一直选低阶调制,不敢尝试高阶

另一个典型的坑是训练到后期,智能体在绝大多数状态下都选BPSK,吞吐量只有1出头。这种情况我刚开始做的时候也遇到过,原因通常有两个。第一个是惩罚系数λ设得太大,误码率超标时惩罚过于严厉,智能体学到一个结论:与其冒险选高阶调制被惩罚,不如永远选最稳的BPSK。把λ从5.0降到2.0后,智能体开始愿意在中高信噪比下尝试高阶调制。第二个原因是探索率衰减太快,智能体还没来得及充分尝试16QAM在好信道下的高额奖励,ε就已经降得很低,Q表里高阶调制的Q值没有机会被充分探索,策略自然偏向保守。

解决这个问题有一个很实用的技巧:在训练初期强制覆盖所有状态和动作组合。我在代码里加了一个前置探索阶段,前300个episode完全随机选择动作,不依赖Q表做决策,只负责积累经验数据。这种做法看起来浪费了一些训练时间,但实际上让Q表的所有格子都得到了初始更新,后续利用阶段策略会更全面,整体收敛效果反而更好。如果你发现一个动作在整个训练过程中被选择的次数非常少,Q表里对应的格子基本还是初值,那就说明探索覆盖不够。

4.3 状态粒度和状态维度怎么确定

状态粒度的选择是一个精度和样本效率的权衡。我测试过把SNR间隔从1dB改成2dB,状态数减少一半,训练收敛速度确实加快了,但最终策略表在边界处的跳变更大,平均吞吐量下降了约0.4。反过来把间隔改成0.5dB,状态数变成51个,训练需要的episode明显增多,在同样的2000个episode下Q表还没有完全收敛。综合来看,1dB间隔在26个状态的情况下,2000个episode足够让Q表充分收敛,是一个合适的平衡点。

关于增加状态维度,比如加入多普勒扩展状态,我建议采用“分阶段扩展”的方式。先把单维SNR状态的方案跑通、验证策略合理,然后再增加维度。每次增加一个新维度,都保留之前的Q表结构,只是把Q表按照新维度的档位数复制扩展,然后在新维度上进行针对性探索。这种迁移式的扩展方式比从头训练快很多,也能让我清楚地看到每个新维度对性能的贡献。

4.4 训练与测试分布不一致:一个隐蔽的坑

最后一个想重点提醒的坑是训练和测试环境不一致导致的结果虚高。有一版仿真里我在训练时用的随机游走信道SNR变化步长是0.5,测试时用的却是完全随机跳变的信道,SNR每个时隙在5到30dB之间均匀随机取值。前一种信道有很强的时间相关性,智能体可以依靠上一时隙的SNR推断下一时隙的大致范围;后一种信道完全没有相关性,智能体学到的策略在测试中的表现自然大幅下降。这个坑非常隐蔽,因为训练曲线看着很漂亮,一旦换到真正随机的信道序列上测试,性能就露馅了。

更贴近实际的做法是在状态观测中加入信道估计噪声。真实系统里接收端对SNR的估计不可能完全准确,我通过在训练时给SNR观测值叠加一个标准差为0.5dB的高斯噪声,让智能体学会在信道信息不完美的情况下依然做出合理的调制选择。这样训练出来的策略在测试时,即使信道估计有一定误差,吞吐量和误码率也不会发生明显恶化。这个细节对工程落地很重要,因为真实水声系统中的信道估计误差通常比仿真里假设的还要大一些。

我自己做完这套仿真最大的体会是,Qlearning虽然是一个三十多年前的经典算法,但在水声通信这种状态空间可控、环境模型不精确、算力资源受限的场景里,它依然是一个非常实用的选择。整个项目的关键不在算法本身,而在于状态怎么划分、奖励怎么设计、信道模型怎么贴近真实,这几个问题想清楚了,训练只是水到渠成的事情。后续如果想把方案做得更精细,可以在这个框架的基础上把状态空间扩展到多普勒扩展和时延扩展,或者换成Double Q-Learning来减少Q值过估计的影响,整体架构都不用动,只需要改状态映射和更新公式。我计划下一步把完整的水声调制解调链路加进来,用真正的收发端误码率替代理论BER,再看看这套策略在更逼真的信道下的表现。

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

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

立即咨询