蜂窝网络仿真场景设计:从参数配置到结果可解释的完整实践

发布时间:2026/10/9 11:15:44
蜂窝网络仿真场景设计:从参数配置到结果可解释的完整实践
做蜂窝网络仿真最怕的不是代码跑不起来而是场景设计错了代码跑得越欢结果越没法看。我这些年用 ns-3 做系统级仿真的最大体会是无线网络仿真里真正决定结果质量的往往是前半段的场景设计与配置而不是后半段的算法实现。蜂窝网络仿真尤其如此——基站摆位、用户分布、信道模型、业务类型随便一个参数变了吞吐率曲线和时延分布就完全不是一回事。所以这一篇我想把仿真场景设计与配置单独拎出来聊透从设计思路到参数计算再到排错经验一次说清楚。这篇内容适合两种人看一种是刚开始做无线网络仿真、想照着搭一套可用城区蜂窝场景的研究生或工程师另一种是已经跑过一些仿真但总觉得自己结果“不对劲”的人——问题大概率就出在场景假设上。我下面的所有内容都基于 ns-3 的 LTE/NR 模块也就是 lena 和 5G-LENA展开但思路对所有支持蜂窝系统仿真的工具都是通用的。1. 场景设计思路先想清楚仿真目的再动手搭拓扑1.1 仿真目的决定场景复杂度很多人在搭场景时犯的第一个错误是一上来就把规模拉满几百个小区、上千个用户全部铺开结果仿真跑几个小时都出不来数据算出来的东西也没人信。场景设计的第一步不是开电脑写代码而是先回答三个问题这个仿真要评估什么要得到哪些指标指标的敏感变量是什么这三个问题的答案直接决定场景的复杂度。如果是做覆盖率评估那场景可以静态一些用户不放移动模型信道只用大尺度衰落路径损耗加阴影衰落小区拓扑要铺得足够大要能看出覆盖空洞。如果是做调度算法对比那业务模型和用户分布就必须精细否则算法之间的差异根本体现不出来。如果是做切换优化那就必须让用户有明确的高速移动轨迹并且把小区间干扰建模做准。我自己的习惯是先画一张“场景要素表”把拓扑、信道、用户、业务、协议栈、网络侧这几个维度列出来每个维度写清楚“用什么配置”和“为什么这么配”。这张表既是设计文档也是后面排查问题的依据。1.2 先小后大先简后全第二个常见错误是小场景没调明白就上大场景。我建议的流程是最小可用场景先搭一个单小区 少量用户的场景把端到端链路跑通确认数据能出、指标能看。这一步花的时间应该控制在半天以内。目标场景在最小场景基础上把小区数、用户数、信道模型、业务模型逐步加进去每加一层就跑一次确认结果没有异常跳变。全量参数扫描场景固定后再去扫需要对比的参数比如不同站间距、不同频段、不同业务负载。这个流程看着慢实际是最快的。我见过太多人一次性把场景写完结果仿真跑不出来回头不知道是拓扑写错了还是信道配错了debug 时间比重搭还长。蜂窝网络仿真的场景配置是高度耦合的必须分层验证。2. 蜂窝网络场景的核心构成要素详解2.1 拓扑与小区部署从六边形蜂窝到 wrap-around蜂窝网络仿真里拓扑的基本单元是小区。常规做法是用三个扇区组成一个基站站址也就是三扇区 120 度定向天线这个设定来自真实网络的部署逻辑——一个站址覆盖三个方向每个方向一个小区的资源块独立调度。经典的六边形蜂窝模型是系统级仿真的标配。六个邻居围绕一个中心小区中心小区加一圈外围共 7 个站址是验证链路预算和干扰模型的最小单位。之所以用六边形而不是圆形覆盖是因为六边形密铺后没有缝隙更贴合基站全向覆盖的规划设计思路。站间距ISDInter-Site Distance是拓扑里的核心参数。城区宏站场景一般取 500 米郊区取 1732 米这是从 3GPP 标准仿真假设里直接拿出来的常用值。ISD 定了路径损耗的基准距离就定了用户分布范围也随之确定。但六边形拓扑有个天然缺陷边缘效应。中心小区受到周围 6 个小区的干扰外围小区受到的干扰来源数不对称导致边缘小区结果明显偏乐观或偏悲观。解决这个问题有两种手段wrap-around 处理把六边形拓扑周期化让左侧的小区“绕”到右侧继续与邻居相互作用这样每个小区都有完整的邻居集。ns-3 的 lena 模块里有专门的 wrap-around 协议扩展用之前要确认你的场景边界条件匹配。只看中心统计如果不想做 wrap-around就只统计中心小区的数据外围小区作为干扰源存在。这个做法简单但会浪费四分之三以上的仿真资源。我个人的建议是如果做算法对比类仿真一定要处理边缘效应。否则两个算法在小区的表现差异还没算法本身的差异大统计检验根本过不了。2.2 无线电参数与信道模型选择信道模型是场景设计里最“物理”的一层也是最容易拍脑袋出错的一层。蜂窝网络仿真常用的信道模型按场景分三类场景类型常见模型适用条件路径损耗公式2GHz 频段参考城区宏站 UMa3GPP TR 38.901 UMa基站高度 25~35m用户室外PL 128.1 37.6·log10(d/km)城区微站 UMi3GPP TR 38.901 UMi基站高度 10m 左右密集城区街道PL 132.8 39.1·log10(d/km)郊区宏站 RMa3GPP TR 38.901 RMa开阔区域用户稀疏分布PL 104.4 23·log10(d/km)公式背后要理解的是什么路径损耗指数第二项系数决定距离对信号衰减的敏感度。UMa 的 37.6 意味着距离翻一倍路径损耗增加约 11.3dB这对覆盖半径的规划影响非常大。如果在城区场景里错误使用自由空间模型20 路径损耗指数算出来的边缘速率会偏高几个数量级整个仿真结果作废。阴影衰落也是一个容易被低估的参数。城区宏站一般取标准差 8dB这个数字对应的是大型建筑物和地形起伏带来的遮挡波动。设小了覆盖空洞和边缘用户竞争力全没了设大了边缘用户信噪比掉得太快调度器几乎永远占不满资源。如果对场景没有把握阴影衰落标准差就用 8dB 起步这也是 3GPP 仿真假设的统一值。天线参数和发射功率也和链路预算强相关。宏站下行发射功率一般取46dBm约 40W天线增益取 17~18dBi三扇区定向天线再加上天线倾角和波束宽度链路预算的结果才有意义。这里我习惯手算一遍链路预算来校验配置46dBm 发射功率 17dBi 天线增益 - 路径损耗 - 阴影衰落余量算出用户收到的参考信号功率再和目标 SNR 对比。如果仿真日志里看到的 SNR 和手算差 3dB 以上那配置里一定有问题别急着往下跑。2.3 用户分布与移动模型用户数量和分布直接决定资源块的竞争状态。一个 10MHz 带宽的 LTE 小区有 50 个 RB 可用。如果小区里只有一个用户这个用户理论上能独占全部 RB如果有 30 个用户每个用户在轮询调度下平均只能分到约 1.67 个 RB。这个数字直接指导业务流的配置——业务速率不能超过物理资源能提供的上限否则队列不断积压时延指标失真。用户分布分两种典型形态均匀分布用户在小区覆盖范围内随机均匀撒点适合评估平均性能也是系统级仿真的默认基线。热点簇分布用户在某个区域集中聚集适合模拟商业区、高校、交通枢纽等场景对调度和负载均衡算法的考验更大。移动模型的选择要和场景类型匹配。我做城区场景时用随机路点模型Random Waypoint用户在设定区域内随机选目标点以固定速度移动做高速路场景时改用固定轨迹移动模型让用户沿一条直线或曲线移动方便观察切换行为。这里有个细节容易踩坑Random Waypoint 模型跑久了用户会在区域中心聚集因为边界处的用户被“反射”回来分布不再均匀。解决办法是先把用户撒在区域边缘外侧一圈“热身”一段时间或者直接使用限制区域边界的行为模型。2.4 业务模型与流量特征业务模型是场景配置里最影响最终指标的一环。网上的通用结论是Full Buffer 模型适合做容量上限评估但做不出真实用户体验。Full Buffer 意味着所有用户永远有无限的待传数据这在实际网络里不存在它的结果是一个理论上界能对比出调度算法在资源分配上的差异但看不出缓冲区延迟、抖动、突发带来的影响。我做业务模型通常按这个思路分业务类型典型参数合适的仿真场景Full Buffer永远有数据可发调度算法上限对比、容量评估FTP 文件下载文件大小 0.5~2MB到达间隔随机下载类应用体验比如 App 商店下载HTTP 浏览页面大小 0.1~2MB页面间思考时间网页浏览用户体验VoIP语音帧 20ms 周期AMR 编码速率时延敏感业务验证Video 流视频帧率 25fps码率可变视频播放卡顿评估业务模型选错最典型的后果是时延抖动数据完全失真。某个项目里我把 HTTP 模型里页面思考时间设成 0结果所有用户都在永不停歇地拉数据缓冲区排队时延飙到 400ms 以上这个数据放到真实网络里是不可能出现的。后来改成按对数正态分布生成思考时间时延数据才回到合理区间。3. 实操搭一个可复现的城区宏站蜂窝场景这一节我按照 ns-3 lena 模块给出核心代码框架参数全部按 3GPP 城区宏站UMa的仿真假设来配置。3.1 配置环境与模块选择首先要确认你用的是哪个分支。如果做 LTE 系统级仿真就用lena模块如果做 5G NR 仿真用5G-LENA。我下面的例子基于 LTE 模块因为它的代码路径更稳定、社区资料更全适合验证流程。操作系统建议直接上 Ubuntu 22.04ns-3 编译源包不要用发行版自带的老版本仓库。#include ns3/core-module.h #include ns3/network-module.h #include ns3/mobility-module.h #include ns3/lte-module.h #include ns3/epc-module.h #include ns3/applications-module.h using namespace ns3;3.2 创建节点基站、用户和移动模型创建 7 个基站站址六边形拓扑每个基站 3 个扇区总共 21 个小区。用户取 60 个均匀撒在中心小区及邻近范围。uint16_t numOfEnb 7; uint16_t numOfUe 60; double isd 500.0; // 站间距 500m NodeContainer enbNodes; enbNodes.Create(numOfEnb); NodeContainer ueNodes; ueNodes.Create(numOfUe);基站位置按六边形顶点摆放。六边形几何参数对于站间距isd中心在原点时6 个邻居的位置间距都是isd。邻居夹角按 60 度步进PtrListPositionAllocator enbPosAlloc CreateObjectListPositionAllocator(); enbPosAlloc-Add(Vector(0.0, 0.0, 30.0)); // 中心站高 30m for (int i 0; i 6; i) { double angle i * 60.0 * M_PI / 180.0; double x isd * cos(angle); double y isd * sin(angle); enbPosAlloc-Add(Vector(x, y, 30.0)); } MobilityHelper enbMobility; enbMobility.SetMobilityModel(ns3::ConstantPositionMobilityModel); enbMobility.SetPositionAllocator(enbPosAlloc); enbMobility.Install(enbNodes);用户位置用随机矩形分配器在中心小区周边撒开MobilityHelper ueMobility; ueMobility.SetMobilityModel(ns3::ConstantPositionMobilityModel); ueMobility.SetPositionAllocator(ns3::RandomRectanglePositionAllocator, X, StringValue(ns3::UniformRandomVariable[Min0.0|Max1000.0]), Y, StringValue(ns3::UniformRandomVariable[Min0.0|Max1000.0])); ueMobility.Install(ueNodes);如果要做移动场景把这个ConstantPositionMobilityModel替换成RandomWaypointMobilityModel或者RandomWalk2dMobilityModel就行。我建议第一版仿真先跑静态结果稳定了再加移动性否则问题排查时很难区分是场景问题还是移动性问题。3.3 配置 LTE 无线参数与信道这一段的参数决定了你的仿真逼近真实网络的程度。PtrLteHelper lteHelper CreateObjectLteHelper(); lteHelper-SetEnbDeviceAttribute(DlEarfcn, UintegerValue(100)); // 下行频点 lteHelper-SetEnbDeviceAttribute(UlEarfcn, UintegerValue(18100)); // 上行频点FDD 模式 lteHelper-SetEnbDeviceAttribute(DlBandwidth, UintegerValue(50)); // 10MHz 50RB lteHelper-SetEnbDeviceAttribute(UlBandwidth, UintegerValue(50)); // 路径损耗模型使用 3GPP UMa 宏站 lteHelper-SetAttribute(PathlossModel, StringValue(ns3::ThreeGppUmaPropagationLossModel)); // 阴影衰落标准差 8dB Config::SetDefault(ns3::LteEnbRrc::DefaultTransmissionMode, UintegerValue(1)); Config::SetDefault(ns3::LteSpectrumPhy::CtrlErrorModelEnabled, BooleanValue(true));发射功率和天线增益要通过设备属性设置lteHelper-SetEnbAntennaModelType(ns3::ParabolicAntennaModel); lteHelper-SetEnbAntennaModelAttribute(Beamwidth, DoubleValue(70.0)); // 3dB 波束宽度三扇区典型值 lteHelper-SetEnbAntennaModelAttribute(MaxGain, DoubleValue(17.0)); // dBi // 每个 eNB 设备安装时设置发射功率 46dBm NetDeviceContainer enbDevices; for (uint16_t i 0; i numOfEnb; i) { NetDeviceContainer dev lteHelper-InstallEnbDevice(enbNodes.Get(i)); dev.Get(0)-GetObjectLteEnbNetDevice()-GetPhy()-SetTxPower(46.0); enbDevices.Add(dev); }关于频点和带宽我加一个参数计算说明DlEarfcn100对应的频段要看 lena 模块的频段映射表带宽 50 对应 10MHz每个 RB 带宽 180kHz。50 个 RB 是我前面算用户资源竞争的基础这里要前后对应。频点选择还会影响路径损耗公式的系数因为 3GPP 的 UMa 公式里频率相关项fc因子不是常数所以换频段后要重新校验链路预算。用户侧设备安装NetDeviceContainer ueDevices; for (uint16_t i 0; i numOfUe; i) { NetDeviceContainer dev lteHelper-InstallUeDevice(ueNodes.Get(i)); ueDevices.Add(dev); } // 把用户“附着”到最近的基站 for (uint16_t i 0; i numOfUe; i) { lteHelper-Attach(ueDevices.Get(i), enbDevices.Get(0)); // 简化起见先全挂中心小区 }要说明的是第一版配置里把所有用户附着到中心小区是为了先验证单小区性能边界。这个配置只是最小场景不是目标场景后面再通过UeMeasurements上报和小区选择算法让用户自动接入最佳小区。3.4 EPC 核心网和承载配置LTE 仿真必须有核心网EPC否则用户面数据无法交换。配置 EPC 是场景配置里最容易漏掉的一步——漏了之后上行业务可能还能通下行业务往往表现异常甚至直接丢包。PtrPointToPointEpcHelper epcHelper CreateObjectPointToPointEpcHelper(); PtrNode pgw epcHelper-GetPgwNode(); // 核心网网关 // 创建远程主机模拟互联网侧的服务器 NodeContainer remoteHostContainer; remoteHostContainer.Create(1); PointToPointHelper p2ph; p2ph.SetDeviceAttribute(DataRate, StringValue(1000Mb/s)); p2ph.SetDeviceAttribute(Mtu, UintegerValue(1500)); p2ph.SetChannelAttribute(Delay, StringValue(5ms)); NetDeviceContainer pgwDevices p2ph.Install(pgw, remoteHostContainer.Get(0));注意到DataRate和Delay这两个参数回程链路的时延设定为 5ms 是有意为之的。真实 LTE 网络中 S1 接口和核心网额外增加几毫秒的时延是正常的如果这里设成 0你测到的端到端时延会偏小几十个毫秒做实时业务评估时这个偏差会掩盖算法本身的差别。承载配置用 EPS Bearer 来指定服务质量PtrEpcTft tft CreateEpcTft(); EpcTft::PacketFilter pf; pf.localPortStart 1234; pf.localPortEnd 1235; tft-Add(pf); EpsBearer bearer; bearer.qci EpsBearer::QCI_1; // 实时语音通道保证速率 lteHelper-ActivateDedicatedEpsBearer(ueDevices, bearer, tft);这里 QCI 的选择是有讲究的。QCI_1 是实时语音承载QCI_9 是尽力而为下载业务。如果你要做视频体验评估用错 QCI 会导致资源调度优先级完全错误帧率波动数据没法看。3.5 配置业务以下行 FTP 下载为例业务层的配置决定你最后拿到的是什么指标。我做下载类业务时习惯用 On/Off 应用模拟突发文件下载uint16_t serverPort 8080; ApplicationContainer serverApps; ApplicationContainer clientApps; // 服务器部署在远程主机上 UdpServerHelper serverHelper(serverPort); serverApps.Add(serverHelper.Install(remoteHost)); // 每个 UE 创建 UDP 下载流目标为 UE 的 IP 地址 for (uint16_t i 0; i numOfUe; i) { PtrUdpClient client CreateObjectUdpClient(); client-SetAttribute(Interval, TimeValue(Seconds(0.01))); // 每 10ms 发一个包 client-SetAttribute(MaxPackets, UintegerValue(1000000)); client-SetAttribute(PacketSize, UintegerValue(1250)); // 10Mbps 的载荷 ueNodes.Get(i)-AddApplication(client); // 远程主机 IP 由 EPC 自动分配这里假设已经从 Pgw 接口获取到固定 IP client-SetRemote(remoteHostAddr, serverPort); }注意PacketSize1250乘以Interval0.01s得到约 1Mbps 的速率这个速率要和前面说的“50 个 RB 的容量上限”匹配。单用户 1Mbps 在 10MHz 带宽里是完全无压力的但如果 60 个用户都同时请求 1Mbps总需求 60Mbps而 10MHz 的理论峰值只有约 37Mbps调度器就会在用户之间强拆带宽队列积压时延指标飙高。这是故意的还是配置错了必须在实验设计里写明。3.6 仿真运行参数时长、随机种子和重复次数仿真场景配置里最容易被忽略的是运行控制参数。我一般这样设置Simulator::Stop(Seconds(10)); // 仿真时长 Config::SetGlobal(RngSeed, UintegerValue(1)); Config::SetGlobal(RngRun, UintegerValue(1)); // 让仿真过程中周期性打印统计数据 lteHelper-EnableRrcTraces(); lteHelper-EnablePhyTraces(); // 记录用户测量上报 Config::Connect(/NodeList/*/DeviceList/*/LteUeRrc/MeasResults, MakeCallback(PrintUeMeasurement));这里我必须强调两个点。第一随机种子和 RngRun 必须显式设置并且每个场景要生成多个不同 RngRun 的重复实验。不设置的话每次仿真结果都一样你根本没法做统计检验只跑一次的话指标方差大到没法对比。我一般每个场景跑 10 到 20 次独立重复取均值和 95% 置信区间。第二仿真时长需要覆盖业务模型的热启动阶段。比如 FTP 下载模型前几百毫秒是用户附着和承载建立时间如果只跑 1 秒后半段的稳定状态根本没出现指标全部失真。我通常前 1~2 秒作为预热期不要统计窗口从第 2 秒才开始持续到仿真结束。4. 场景配置里的典型问题与排查实录场景配置这项工作真正花时间的地方全在查问题上。下面我按实际经验列出最常遇到的四类问题每一类都附上排查路径。4.1 边缘用户性能异常悲观现象中心小区边缘几个用户吞吐率接近 0信噪比 IPC 日志显示负数。排查路径先看 pathloss 日志确认这几个用户到目标基站和干扰基站的路径损耗是否合理。再看发射功率配置确认 eNB 的发射功率生效没有。ns-3 里如果直接在InstallEnbDevice后没有显式SetTxPower默认功率可能只有 30dBm少了 16dB 的链路预算。检查天线模型。ParabolicAntennaModel 的波束宽度设成 70 度时边缘用户收到的增益会比中心用户低 10dB 以上这个是物理正确的但很多第一次做三扇区的人会误以为配置错了。4.2 移动模型导致用户“跑出”仿真区域现象用户节点位置坐标持续增大或减小最终集中在边界处用户长时间不触发切换。原因RandomWaypoint 模型在用户到达边界时如果配置成“镜像反射”而不是“反弹回区域内部”用户会沿边界滑行造成空间分布严重失真。排查方法是把用户位置轨迹打到文件里画出来一眼就能看到问题。修复方案给移动模型加边界限制。ns-3 的RandomWaypointMobilityModel本身在设计时会把目标点约束在矩形区域内但如果你自己实现了移动模型就必须在SetPosition之后做边界裁剪或者在CourseChanged回调里做冲突处理。这个坑我在自研移动模型时踩过后来直接改用系统自带的RandomWalk2dMobilityModel加Bounds属性一劳永逸。4.3 缓冲队列无限增长导致时延失真现象端到端时延从几十毫秒慢慢涨到几百毫秒甚至一秒以上吞吐率却维持在高位。原因业务速率超过了物理层可调度的最大速率。前面我说过 10MHz 带宽下 60 个用户同时请求 1Mbps 的问题队列积压就是物理的必然结果。这个“发现问题”不算 bug但很多人在做时延类对比时忘了这个前提拿一个明明已经过载的场景去对比算法差异结果所有算法都表现一致——排队时延已经掩盖了算法细节。处理思路如果是做算法对比就必须保证场景负载低于系统容量比如把总业务请求控制在容量的 70% 左右。4.4 仿真结果异常稳定或异常抖动现象多次独立重复实验后吞吐率的方差接近 0或者某一项指标分布完全不符合预期分布。解释第一种情况多半是随机种子没变所有重复实验实际上是同一个实验拍了 10 张照片统计上没有意义。第二种情况多半是随机分布函数的参数配错比如用户在区域内的 X、Y 坐标用了同一个随机变量导致所有用户都在对角线上。我处理这个问题的方法很笨但很有效把每个用户的初始位置和业务开始时间都打印出来人工抽查 20 个用户确认分布符合预期。这一步 10 分钟做完能省掉后面一星期的数据清洗时间。5. 从单场景到多场景实验设计与结果统计经验5.1 让多个场景可以横向对比单场景跑通只是开始真正有价值的是多场景对比比如对比不同站间距500m vs 1000m、不同用户负载10 用户 vs 50 用户 vs 100 用户、不同调度算法。这里最大的坑是场景参数之间互相干扰。比如比较站间距如果同时把用户数也改了那结果差异没法归因到站间距变化。我的经验是每次只变一个参数其他参数全部锁死。这句话听起来是常识但实际操作中很容易偷懒一次性改多个参数最后数据没法解释。5.2 结果记录与命名规范场景多了以后结果文件命名如果太随意三个月后你自己都分不清哪份文件对应哪份配置。我的推荐方案是文件名前缀统一用场景关键参数的哈希值加说明。比如isd500_ue60_uma_seed1.csv这种格式比result_v2_final_FINAL.csv好一万倍。参数全部存进 CSV 表头运行时让仿真程序自动打印一份scenario_config.yaml记录包括信道模型、发射功率、移动模型、业务参数在内的全部配置。5.3 并行化与统计方法蜂窝网络仿真场景规模一大单跑一次就花几小时。多场景参数扫描需要并行化。ns-3 本身支持通过多线程并行仿真但更简单的做法是写 shell 脚本把不同 seed 或不同参数组合分配给不同 CPU 核运行最后用 pandas 汇总。统计方法上我建议每个场景至少 10 次独立重复实验输出均值、标准差、95% 置信区间。在做算法对比时用 Welchs t-test 或 Mann-Whitney U 检验来判断两个结果是否有显著性差异不要只看均值大小就妄下结论。注意 仿真的结论不是“跑出来就对了”而是“在特定场景假设下成立”。每次仿真结束都应该把场景假设的边界条件一并写在论文或报告里信道模型、站间距、用户分布、业务模型、仿真时长、随机种子数量。缺了这些信息别人无法复现你的结果。6. 我最后的几点实操心得写到这里我把这些年做无线网络仿真场景设计最浓缩的经验总结一下。第一场景设计不要追求“大”要追求“可解释”。一个 3 小区 10 用户的场景如果能清楚解释每个指标的成因比一个 57 小区 500 用户的场景价值大得多。宁可先在小场景里把每个设计决策论证清楚再逐步扩规模。第二动手前先把场景参数表做出来。不要边写代码边想参数那样你会在第三步就推翻第一步的设置。我已经养成习惯每次仿真开始前先在文档里写满三张表——场景要素表、参数计算表、预期指标表。预期指标表尤其重要因为仿真跑完你和理论值对不上才能快速定位问题。第三仿真代码要像普通代码一样做版本管理。场景配置的演进过程非常快今天改了路径损耗模型明天加了移动模型几天后你可能已经忘了为什么做这些改动。用 git 管理场景配置代码每次改动写清楚 commit message回看历史时能省掉大量重复排查。最后想分享一个我自己一直在用的“土办法”每次仿真跑完把场景参数表打印一份贴在工位上。这个办法听起来很原始但数据对不上时你会发现它是你排查问题最直接的参考。场景设计和配置是整个蜂窝网络仿真里最磨人、但最能锻炼系统感觉的环节把这一层打扎实了后面所有指标分析和算法改进都会有可靠的底座。