资讯动态

5G信道容量随距离衰减仿真:Python源码与避坑指南

发布时间:2026/10/13 12:39:21 来源:尧图企业网站定制
简介这份源码资源面向通信工程、无线网络方向的学生与工程师聚焦5G系统中通信距离变化对信道容量的影响这一核心问题。压缩包共8个文件全部为m脚本文件整体约9KB涵盖路径损耗计算、MIMO复用与混合预编码、氧气吸收损耗、平均容量统计及球面单位向量等模块可支撑从信号衰减建模到容量评估的完整仿真链路。已有145人学习下载适合作为课程设计、毕业设计或科研入门的参考素材。读者可借助这些脚本复现自由空间与NLOS场景下的路径损耗曲线对比不同MIMO配置与毫米波频段的信道容量表现并在此基础上扩展功率控制、信道编码等实验快速搭建可运行的5G链路级仿真框架理解距离、信噪比与容量之间的定量关系。1. 5G 通信系统下信道容量随距离衰减一份能跑起来的仿真源码拆解做 5G 链路预算的工程师迟早会撞上这个问题基站覆盖半径从 300 米拉到 1000 米理论峰值速率标称 1Gbps实测却掉到几十兆中间到底发生了什么很多人第一反应是查调度、查终端能力其实根子在信道容量本身——它随通信距离增加而衰减而且衰减不是线性的是带着路径损耗指数、阴影衰落和噪声底一起往下掉。这份「5G 通信系统下随着通信距离增加信道容量的仿真-源码」要解决的就是把这条衰减曲线用代码画出来让你在动手布站之前先看清容量和距离的定量关系。它适合做 5G 网络架构规划、链路预算、MIMO 信道容量评估的从业者也适合通信系统综合实验里需要交仿真报告的学生。核心工具就是 Python 加 NumPy、Matplotlib不需要任何硬件一台笔记本就能跑通。2. 先把信道容量公式立住香农、路径损耗与 5G 参数怎么对上2.1 香农公式在 5G 里到底怎么用信道容量的理论底座是香农公式 C B·log₂(1 SNR)B 是带宽SNR 是信噪比。这个公式本身不复杂难的是在 5G 场景下把 SNR 算准。SNR P_rx / P_noise接收功率 P_rx 又由发射功率、天线增益和路径损耗决定。很多人仿真时直接把 SNR 设成一个固定值去扫距离这是典型的翻车做法——距离一变路径损耗就变SNR 必须跟着重算否则画出来的曲线是假的。5G 常用的路径损耗模型是对数距离模型PL(d) PL(d₀) 10·n·log₁₀(d/d₀) X_σ。d₀ 是参考距离一般取 1 米或 10 米n 是路径损耗指数自由空间取 2城市宏站视距场景取 2.02.5非视距能到 3.54.5X_σ 是阴影衰落服从零均值高斯分布标准差 σ 典型值 48 dB。这三个参数直接决定容量曲线的陡峭程度后面调参章节会细说。接收功率写成 dB 形式更顺手P_rx(dBm) P_tx(dBm) G_tx G_rx − PL(d)。噪声功率 P_noise(dBm) −174 10·log₁₀(B) NF其中 −174 dBm/Hz 是室温热噪声谱密度NF 是接收机噪声系数5G 基站典型值 57 dB。把这些串起来SNR 就能随距离动态计算容量曲线才有物理意义。2.2 为什么选对数距离模型而不是自由空间自由空间模型 PL 20·log₁₀(4πd/λ) 只在理想视距、无遮挡时成立一旦进入城市环境建筑物、树木、人体都会带来额外损耗实测往往比自由空间高 1020 dB。对数距离模型用一个可调的 n 把这些因素打包进去工程上更实用。5G 的 3.5GHz 频段和 28GHz 毫米波频段n 的取值差别很大毫米波非视距场景 n 经常取到 4 以上这也是为什么毫米波覆盖半径普遍只有几百米。选模型时还要注意参考距离 d₀ 的取值。如果 d₀ 取 1 米PL(d₀) 用自由空间公式算如果取 10 米就要用实测或标准里的参考损耗值。两者混用会导致整条曲线平移这是新手最容易踩的坑之一。2.3 5G 关键参数取值表下面这张表是我做仿真时常用的参数集覆盖 3.5GHz 典型宏站场景可以直接抄进代码。参数符号典型值说明载波频率f_c3.5 GHz5G 主流频段系统带宽B100 MHz单载波最大带宽发射功率P_tx46 dBm宏站典型值发射天线增益G_tx8 dBi定向天线接收天线增益G_rx0 dBi终端全向噪声系数NF7 dB基站接收机路径损耗指数n3.0城市非视距阴影衰落标准差σ6 dB对数正态参考距离d₀1 m自由空间参考这张表里的每个值都可以改改完曲线形状会变后面会讲怎么调。3. 用 Python 把容量-距离曲线跑出来从单点到批量扫描3.1 环境准备与依赖安装仿真只需要三个库NumPy 做数值计算Matplotlib 画图Pandas 可选用于导出数据。安装命令如下pip install numpy matplotlib pandas如果你用的是 Anaconda这些库基本都自带跳过即可。Python 版本建议 3.8 以上NumPy 1.20 以上避免老版本里 log10 对数组处理的兼容问题。3.2 核心仿真代码单条容量曲线先写一个最小可运行版本计算一条距离-容量曲线。import numpy as np import matplotlib.pyplot as plt # 5G 系统参数 f_c 3.5e9 # 载波频率 3.5 GHz B 100e6 # 带宽 100 MHz P_tx_dBm 46 # 发射功率 46 dBm G_tx 8 # 发射天线增益 dBi G_rx 0 # 接收天线增益 dBi NF 7 # 噪声系数 dB n 3.0 # 路径损耗指数 sigma 6.0 # 阴影衰落标准差 dB d0 1.0 # 参考距离 m # 距离扫描范围 d np.linspace(10, 2000, 500) # 10m 到 2000m # 参考距离处路径损耗自由空间 PL_d0 20 * np.log10(4 * np.pi * d0 * f_c / 3e8) # 对数距离路径损耗 PL PL_d0 10 * n * np.log10(d / d0) # 接收功率 P_rx_dBm P_tx_dBm G_tx G_rx - PL # 噪声功率 P_noise_dBm -174 10 * np.log10(B) NF # 信噪比 SNR_dB P_rx_dBm - P_noise_dBm SNR_linear 10 ** (SNR_dB / 10) # 香农容量 C B * np.log2(1 SNR_linear) # 单位 bps C_Mbps C / 1e6 # 绘图 plt.figure(figsize(10, 6)) plt.plot(d, C_Mbps, labeln3.0, sigma6dB) plt.xlabel(Distance (m)) plt.ylabel(Channel Capacity (Mbps)) plt.title(5G Channel Capacity vs Distance) plt.grid(True) plt.legend() plt.savefig(capacity_vs_distance.png, dpi150) plt.show()这段代码的逻辑链条是距离数组 → 路径损耗 → 接收功率 → 噪声功率 → SNR → 容量。每一步都保留了中间变量方便你单独检查某一环节是否合理。比如你可以打印 P_rx_dBm 在 100 米处的值和链路预算手算结果对一下差 12 dB 以内算正常。参数说明d的扫描范围决定曲线横轴10 到 2000 米覆盖了典型宏站覆盖半径n和sigma是影响曲线陡峭程度的核心参数B直接线性缩放容量带宽翻倍容量翻倍但 SNR 也会因为噪声功率增加而略降实际增益略小于 2 倍。3.3 加入阴影衰落的随机性蒙特卡洛扫描上面那条曲线是确定性的实际信道里阴影衰落是随机的。用蒙特卡洛方法跑多次取均值和分位数才能看出容量的波动范围。import numpy as np import matplotlib.pyplot as plt # 参数同上省略重复定义 np.random.seed(42) # 固定随机种子保证可复现 N_realizations 1000 # 蒙特卡洛次数 d np.linspace(10, 2000, 200) PL_d0 20 * np.log10(4 * np.pi * d0 * f_c / 3e8) PL_mean PL_d0 10 * n * np.log10(d / d0) P_noise_dBm -174 10 * np.log10(B) NF C_all np.zeros((N_realizations, len(d))) for i in range(N_realizations): # 每次实现生成一组阴影衰落 X_sigma np.random.normal(0, sigma, len(d)) PL PL_mean X_sigma P_rx_dBm P_tx_dBm G_tx G_rx - PL SNR_dB P_rx_dBm - P_noise_dBm SNR_linear 10 ** (SNR_dB / 10) C_all[i, :] B * np.log2(1 SNR_linear) / 1e6 # 统计量 C_mean np.mean(C_all, axis0) C_p50 np.percentile(C_all, 50, axis0) C_p10 np.percentile(C_all, 10, axis0) C_p90 np.percentile(C_all, 90, axis0) plt.figure(figsize(10, 6)) plt.plot(d, C_mean, b-, labelMean) plt.fill_between(d, C_p10, C_p90, alpha0.3, label10%-90% range) plt.xlabel(Distance (m)) plt.ylabel(Channel Capacity (Mbps)) plt.title(5G Channel Capacity with Shadow Fading) plt.grid(True) plt.legend() plt.savefig(capacity_with_fading.png, dpi150) plt.show()蒙特卡洛的关键是N_realizations1000 次已经能给出稳定的统计量再往上收益递减。np.random.seed一定要固定否则每次跑出来的图不一样写报告时没法复现。10% 分位数代表边缘用户容量做覆盖规划时看这个值比看均值更有意义。3.4 多参数对比一张图看清 n 和 sigma 的影响把不同路径损耗指数画在一起能直观看出环境对容量的影响。n_values [2.0, 3.0, 4.0] plt.figure(figsize(10, 6)) for n_val in n_values: PL PL_d0 10 * n_val * np.log10(d / d0) P_rx_dBm P_tx_dBm G_tx G_rx - PL SNR_dB P_rx_dBm - P_noise_dBm SNR_linear 10 ** (SNR_dB / 10) C B * np.log2(1 SNR_linear) / 1e6 plt.plot(d, C, labelfn{n_val}) plt.xlabel(Distance (m)) plt.ylabel(Channel Capacity (Mbps)) plt.title(Capacity vs Distance for Different Path Loss Exponents) plt.grid(True) plt.legend() plt.savefig(capacity_n_comparison.png, dpi150) plt.show()n2 时曲线下降最慢1000 米处还有几百兆n4 时 500 米就掉到几十兆。这就是为什么毫米波非视距场景覆盖这么难做。把这张图放进报告比写一堆文字有说服力。4. 仿真里的避坑清单这五个地方最容易翻车4.1 单位混用导致 SNR 算错现象容量曲线整体偏高或偏低和链路预算对不上。原因dBm 和 dB 混用或者线性值和 dB 值没转换干净。P_tx_dBm 是 dBmPL 是 dB两者相减得到 dBm再减 P_noise_dBm 得到 dB这个链条不能断。解决在每个中间变量后面加注释标明单位打印几个关键点的值手算验证。4.2 参考距离处路径损耗算错现象整条曲线平移形状对但绝对值不对。原因PL(d₀) 用了错误的公式或者 d₀ 取 1 米却用了 10 米的参考损耗。解决d₀1m 时用 20·log₁₀(4πf_c/3e8)d₀10m 时用标准里的参考值两者不能混。4.3 噪声功率带宽用错现象容量随带宽线性增长但实际增益偏大。原因噪声功率里的带宽用了 Hz但计算时忘了 10·log₁₀(B) 里的 B 是 Hz 不是 MHz。解决统一用 Hz100MHz 写成 100e6。4.4 蒙特卡洛没固定随机种子现象每次跑出来的图不一样报告没法复现。原因np.random 默认用系统时间做种子。解决开头加 np.random.seed(42)数字随便选固定就行。4.5 距离扫描范围不合理现象曲线在近端或远端出现异常平坦或陡降。原因扫描范围超出了模型适用区间比如对数距离模型在 10 米以内不准。解决近端从 10 米或 20 米起步远端不超过模型验证过的最大距离。5. 进阶玩法把 MIMO 和毫米波加进来让仿真更贴近真实 5G5.1 MIMO 信道容量的扩展写法单天线容量跑通后下一步自然是 MIMO。5G 大规模 MIMO 的容量公式在香农基础上多了空间复用增益简化写法是 C B·log₂det(I (SNR/N_t)·H·Hᴴ)H 是信道矩阵。用 Python 生成瑞利衰落信道矩阵就能画出 MIMO 容量随距离的变化。Nt 4 # 发射天线数 Nr 4 # 接收天线数 C_mimo np.zeros(len(d)) for idx, dist in enumerate(d): PL PL_d0 10 * n * np.log10(dist / d0) P_rx_dBm P_tx_dBm G_tx G_rx - PL SNR_dB P_rx_dBm - P_noise_dBm SNR_linear 10 ** (SNR_dB / 10) # 瑞利衰落信道矩阵 H (np.random.randn(Nr, Nt) 1j * np.random.randn(Nr, Nt)) / np.sqrt(2) # 容量计算 M np.eye(Nr) (SNR_linear / Nt) * H H.conj().T C_mimo[idx] B * np.log2(np.linalg.det(M)) / 1e6 plt.plot(d, C_mimo, label4x4 MIMO) plt.xlabel(Distance (m)) plt.ylabel(Capacity (Mbps)) plt.legend() plt.grid(True) plt.savefig(mimo_capacity.png, dpi150) plt.show()MIMO 容量在近端比 SISO 高好几倍但随距离衰减也更快因为 SNR 降低后空间复用增益吃不满。这张图能帮你判断什么距离范围内值得上大规模 MIMO。5.2 毫米波频段的参数替换把 f_c 改成 28e9n 改成 4.0sigma 改成 8重跑一遍就能看到毫米波的覆盖短板。28GHz 下 200 米处容量可能就掉到 100Mbps 以下这就是为什么毫米波适合热点覆盖而不是广覆盖。5.3 验证仿真结果是否靠谱的三个方法第一和链路预算手算结果对比选 100 米、500 米、1000 米三个点手算 SNR 和容量误差在 5% 以内算合格。第二把 n 改成 2、去掉阴影衰落结果应该接近自由空间容量公式。第三改变带宽容量应该近似线性变化如果偏离太大说明噪声功率计算有问题。我自己的习惯是每次改完参数先跑一遍单点验证再跑全曲线最后把关键数据导出成 CSV 存档。这样下次有人问「你这个曲线怎么来的」直接把参数和代码甩过去省得扯皮。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑