简介:面向需要在 MATLAB 环境中实现云模型计算与权重分析的课程实验、科研仿真及综合评价场景,这套代码提供了可直接运行的基础实现,适合具备一定 MATLAB 基础、希望快速验证云模型相关算法而无需从零搭建函数的学生与研究人员。压缩包共 2 个文件,均为 .m 脚本/函数文件,整体约 1KB,体积轻量,便于下载后直接加入现有工程或作为教学示例使用。内容围绕云模型的核心变换过程展开,包含主程序入口与云变换函数两部分,可用于理解云滴生成、隶属度计算及权重处理的基本流程,也可按需修改参数以适配不同评价对象。已有 1581 人学习,说明其在相关实验与入门实践中具有一定参考价值。读者可据此快速搭建可运行的算法骨架,并在此基础上扩展数据输入、结果可视化或与其他评价方法对比,节省环境配置与基础函数编写时间。
1. 云模型代码包接不接得住你的评价矩阵:先看三件事
手里有一份指标打分表,五个专家给了三套权重,等级边界怎么划都能吵起来——这类评价活儿,matlab 云模型 权重这套组合正好能接住。云模型把“大概属于中等偏上”这种带模糊性的判断,用期望 Ex、熵 En、超熵 He 三个数固定下来,再用云滴把离散程度画出来,比单纯用最大隶属度做模糊评价更贴近人打分时的心理波动。这份代码包围绕三件事组织:正向云发生器生云滴、逆向云发生器从样本反推参数、把权重接进综合评价。
它适合方案比选、风险分级、设备状态评估这类需要“打分加定级”的场景,也适合刚接触不确定性建模、想直接跑通一条完整链路的人。拿到手先别急着套数据,看一眼函数清单里有没有逆向云、等级云生成、权重计算这三块,缺一块后面就得自己补。
2. 正向云与逆向云:Ex、En、He 怎么定,云滴数 n 取多少
云模型的计算全压在三个参数上,参数理解错,后面画出来的图再漂亮也是错的。Ex 是云滴分布的中心,对应“最典型的那个值”;En 是熵,衡量指标值的离散范围,En 越大云越扁越宽;He 是超熵,描述熵本身的不确定程度,直观上就是云的“厚度”。三者不是互相独立的统计量,而是一层套一层的随机结构,这也是云模型区别于普通正态隶属函数的地方。
2.1 正向云发生器:两层随机怎么实现
正向云发生器做一件事——给定 (Ex, En, He),生成 n 个云滴,每个云滴带一个坐标 x 和一个确定度 μ。实现上分两步随机:先以 En 为期望、He 为标准差生成一个临时的熵 En',再以 Ex 为期望、En' 为标准差生成云滴坐标 x。这个顺序不能反,反过来就变成普通正态抽样了。
function [x, mu] = forwardCloud(Ex, En, He, n, seed) % forwardCloud 正态云正向发生器 % Ex 期望:云滴分布中心,对应最典型的指标值 % En 熵:反映离散范围,越大云越"胖" % He 超熵:熵的不确定性,决定云滴的"厚度" % n 云滴数量,评价场景常用 1000~3000 % seed 可选随机种子,固定后重复实验可复现 if nargin >= 5 && ~isempty(seed) rng(seed); end Enp = En + He .* randn(n, 1); % 第一层随机:熵本身是随机变量 Enp(Enp <= 0) = En; % 极小概率抽到负标准差,回退到 En x = Ex + Enp .* randn(n, 1); % 第二层随机:在当前熵下生成云滴 mu = exp(-(x - Ex).^2 ./ (2 * Enp.^2)); % 每个云滴的确定度 end代码里Enp(Enp <= 0) = En这一行是我后来加的保护。He 取到 En 的一半以上时,正态抽样有一定概率抽到负的 En',此时2*Enp.^2仍是正数不会报错,但云滴会跑到期望的另一侧,图形上表现为左右不对称的“鬼影”。参数上,n 取 1000 到 3000 足够让云滴轮廓稳定,低于 500 时肉眼能看出稀疏;He 通常取 En 的 1/10 到 1/20,He 越大云越“毛”,超过 En 的一半基本就没有形状可言了。
提示:He 置 0 时,云模型退化成普通的正态隶属函数,确定度曲线变成一条光滑的钟形线。想验证自己的正向发生器写得对不对,把 He 设为 0 跑一遍,看散点是否严格落在理论曲线上。
2.2 逆向云发生器:从样本反推参数与 He 的正定条件
逆向云解决的是反问题——手上有一堆专家打分或者历史监测值,要反推出这组数据对应的 (Ex, En, He)。工程上最常用的是基于一阶中心矩的算法,公式简单、对样本量要求不高,实测在样本量 50 以上就比较稳。
function [Ex, En, He] = backwardCloud(x) % backwardCloud 逆向云发生器(一阶中心矩法) x = x(:); Ex = mean(x); % 期望用样本均值估计 En = sqrt(pi/2) * mean(abs(x - Ex)); % 熵由一阶绝对中心矩换算 S2 = var(x, 1); % 二阶中心矩,注意用 1 而不是 0 He2 = S2 - En^2; if He2 < 0 warning('backwardCloud:negativeHe2', 'He^2 为负,已截断为 0'); He2 = 0; end He = sqrt(He2); endEn = sqrt(pi/2) * mean(abs(x - Ex))这个系数来自正态分布一阶绝对中心矩与标准差的关系,E|x-μ| = σ·sqrt(2/π),反解就得到上面的式子。真正容易出问题的是 He:He² = S² - En²,理论上非负,但样本量小或者数据本身特别集中时,S² 可能小于 En²,开根号直接得到复数。我在一个只有 12 个样本的项目里就撞上过,MATLAB 不报错,直接把 NaN 传下去,后面整张隶属度矩阵全废。处理办法有三个:截断到 0(上面的写法)、把样本量补到 30 以上、或者换用基于四阶中心矩的稳健估计。
还有一个细节,var(x, 1)用的是总体方差(除以 n),不是样本方差(除以 n-1)。逆向云的推导里默认按总体矩处理,用 0 会让 He 系统性偏大一点点,样本量小时能看出来。
2.3 双边约束法:等级云参数的来源
评价类项目里,等级云参数不是拍脑袋定的,而是由等级区间反算。最常见的做法是双边约束法:假设第 k 个等级的取值区间是 [Bmin, Bmax],那么 Ex 取区间中点,En 取区间宽度的 1/6,He 取 En 的一个小比例。
En = (Bmax - Bmin) / 6 的依据是 3σ 原则:正态分布下 99.7% 的取值落在期望 ±3σ 内,把 3σ 对应到半区间宽度 (Bmax-Bmin)/2,解出 σ 就是区间宽度的 1/6。这样生成的云,绝大多数的云滴都落在该等级的区间内,边界附近会有少量云滴溢出,正好对应“等级边界本来就模糊”这件事。
| 等级 | 区间 [Bmin, Bmax] | Ex | En | He(取 0.05·En) |
|---|---|---|---|---|
| 差 | [0, 0.2] | 0.10 | 0.0333 | 0.0017 |
| 较差 | [0.2, 0.4] | 0.30 | 0.0333 | 0.0017 |
| 一般 | [0.4, 0.6] | 0.50 | 0.0333 | 0.0017 |
| 较好 | [0.6, 0.8] | 0.70 | 0.0333 | 0.0017 |
| 好 | [0.8, 1.0] | 0.90 | 0.0333 | 0.0017 |
function C = levelClouds(bounds, heRatio) % bounds: m x 2 矩阵,每行一个等级的 [下界, 上界] % heRatio: 超熵相对熵的比例,常用 0.01~0.05 if nargin < 2, heRatio = 0.05; end m = size(bounds, 1); C = zeros(m, 3); for k = 1:m bmin = bounds(k,1); bmax = bounds(k,2); C(k,1) = (bmin + bmax) / 2; % Ex 取中点 C(k,2) = (bmax - bmin) / 6; % En 取区间宽度 1/6 C(k,3) = heRatio * C(k,2); % He 按比例缩放 end end首尾两个等级如果是单边约束(比如“差”是 [0, 0.2] 但实际可以取到负值,“好”是 [0.8, +∞)),不能直接套公式,否则最外层的 En 会算得过大或者除零。常见做法是让最外层等级的 En 取相邻内层等级 En 的 1.0 到 1.2 倍,Ex 取该等级的边界值再往里收一点。这块没有唯一答案,我一般会把首尾等级的隶属度曲线单独画出来看一眼,确认它在该等级内部保持单调、在边界处和相邻等级有合理重叠。
3. 云模型权重怎么落:AHP、熵权与组合赋权的三步衔接
权重这一步是云评价里最容易被糊弄过去的环节。很多人直接给一组 0.1、0.2、0.3 的权重就往下算,结论能出,但站不住。比较稳妥的链路是主观权重打底、客观权重纠偏,再用组合权重把两者捏到一起。代码包里如果只有正向云和逆向云两个函数,权重这块得自己补,下面三段可以直接抄。
3.1 AHP 判断矩阵:一致性检验不能跳过
层次分析法给的是主观权重,靠专家对指标两两比较。九标度是最常用的:1 表示同等重要,3 表示稍重要,5 表示明显重要,7 表示强烈重要,9 表示极端重要,2、4、6、8 取中间值。判断矩阵填完先别急着算权重,一致性检验不过关的矩阵算出来的特征向量没有意义。
function [w, CR, lambdaMax] = ahpWeight(A) % A: n x n 正互反判断矩阵 n = size(A, 1); [V, D] = eig(A); [lambdaMax, idx] = max(real(diag(D))); w = abs(real(V(:, idx))); w = w / sum(w); % 归一化 CI = (lambdaMax - n) / (n - 1); % 一致性指标 RI = [0 0 0.58 0.90 1.12 1.24 1.32 1.41 1.45 1.49]; if n <= 10 ri = RI(n); else ri = 1.49; end CR = CI / ri; % 随机一致性比率,要求 < 0.1 endCR < 0.1是通行门槛,超过就说明判断矩阵里存在循环矛盾,比如 A 比 B 重要、B 比 C 重要,结果 C 又比 A 重要。这时候改一两个元素比整套重填划算,优先动偏离最大的那一行。RI 表只列到 10 阶,超过 10 个指标时 AHP 本身的可信度就在下降,建议先做指标筛选再进这一步。
3.2 熵权法:指标差异越大权重越高
客观权重这边,熵权法最常用,逻辑是“某个指标在各样本间差异越大,它对区分优劣的贡献越大,权重就越高”。计算前有两个前提:指标要先正向化(成本型指标取倒数或反向归一化),且矩阵非负。
function w = entropyWeight(X) % X: m 个样本 x n 个指标,须已正向化且非负 [m, n] = size(X); X = X + eps; % 避免 log(0) P = X ./ sum(X, 1); % 每个指标下各样本的比重 k = 1 / log(m); e = -k * sum(P .* log(P), 1); % 信息熵,越接近 1 差异越小 d = 1 - e; % 差异系数 w = d / sum(d); endX + eps这一行是血泪经验。原始数据里出现 0 的时候,P .* log(P)会得到0 * (-Inf),MATLAB 返回 NaN 而不是 0,整个权重向量就废了。加 eps 是工程上最省事的补丁,代价是给零值样本一个极小的比重,对结果的影响在 1e-16 量级,可以忽略。另一个坑是某个指标所有样本取值完全一样,此时 e 严格等于 1,d 等于 0,权重算出来是 0——这个指标在区分度上确实没贡献,但如果你不想让它在综合里直接消失,得靠后面的组合权重兜一下。
3.3 组合权重:线性加权还是乘法合成
主观权重和客观权重都有了,合成方式有两种。线性加权是 w = α·w_sub + (1-α)·w_obj,α 常取 0.5,含义是两者各让一半;乘法合成是 w = (w_sub .* w_obj) / sum(w_sub .* w_obj),对两者都低的指标惩罚更重。
function w = combineWeight(wSub, wObj, alpha) % wSub: 主观权重列向量;wObj: 客观权重列向量 % alpha: 主观权重占比,0~1,默认 0.5 wSub = wSub(:) / sum(wSub); wObj = wObj(:) / sum(wObj); if nargin < 3, alpha = 0.5; end w = alpha * wSub + (1 - alpha) * wObj; w = w / sum(w); end选哪种看场景。指标之间相关性弱、希望保留专家经验的,用线性加权;指标数量多、担心主观因素被放大的,用乘法合成。α 的取值不建议随手写 0.5,可以做一个敏感性扫描:α 从 0 到 1 步长 0.1,看最终等级判定在哪个区间开始翻转,把翻转点附近的 α 避开。
3.4 权重如何进入云评价
权重进去的位置很关键。正确做法是先用每个指标值对各等级云算隶属度,得到 p×m 的隶属度矩阵(p 个指标、m 个等级),再用权重向量左乘:b = w' * mu,得到 1×m 的综合隶属度。不要在云滴层面加权——先对每个指标的云滴加权平均再算隶属度,得到的是“加权平均指标值对一个综合云”的隶属度,丢失了指标间的分布信息,等级判定会明显偏向中间等级。
还有一个细节,权重向量和指标顺序必须严格对齐。指标增删之后忘了重排权重,是最隐蔽的一类翻车,结果看起来正常但结论完全错位。
4. 综合评价链路:从指标矩阵到等级结论的五个环节
单看正向云和逆向云,各自都不难,难的是把它们串成一条能对外交付的评价链路。这条链路我一般拆成五步:指标矩阵预处理、单指标隶属度计算、加权合成、等级判定、结果出图。每一步都有各自的参数和校验点,跳步的代价会在最后一步集中爆发。
4.1 指标矩阵预处理:量纲不统一是评分漂移的源头
云模型的等级区间通常定义在 0 到 1 或者某个固定量纲上,而原始指标可能是万元、百分比、台数混在一起。不归一化直接进云评价,Ex 和 En 的量级差几个数量级,隶属度全是 0 或者全是 1。
function Xn = normalizeIndex(X, type) % X: m x n 原始指标矩阵 % type: 1 x n,1 表示效益型(越大越好),-1 表示成本型(越小越好) [m, n] = size(X); Xn = zeros(m, n); for j = 1:n xmin = min(X(:,j)); xmax = max(X(:,j)); if xmax == xmin Xn(:,j) = 1; % 无区分度,统一记满分 continue; end if type(j) == 1 Xn(:,j) = (X(:,j) - xmin) / (xmax - xmin); else Xn(:,j) = (xmax - X(:,j)) / (xmax - xmin); end end endmin-max 归一化的副作用是把每一列强行拉到 [0,1],样本里的最大值恒为 1、最小值恒为 0。如果参与评价的样本只有三五个,这个拉伸会过度放大极值的影响,此时更适合用固定基准归一化——用行业标准值或者历史数据的上下限做分母,而不是当前样本的极值。取哪种,取决于你要的是“样本内相对排序”还是“跨批次可比”。
4.2 单指标隶属度计算:为什么不能只抽一次
给定指标值 x_j 和等级云 (Ex_k, En_k, He_k),最直接的做法是代入确定度公式 μ = exp(-(x-Ex)²/(2En²))。但云模型的 En 本身是随机的,单次代入相当于只抽了一个 En',结果带随机性,同一份数据跑两次可能得到不同的隶属度矩阵。
function mu = cloudMembership(x, C, n) % x: p x 1 指标值(已归一化) % C: m x 3 等级云参数 % n: 每个指标-等级组合的抽样次数,常用 1000 m = size(C, 1); p = numel(x); mu = zeros(p, m); for j = 1:p for k = 1:m Ex = C(k,1); En = C(k,2); He = C(k,3); Enp = En + He .* randn(n, 1); Enp(Enp <= 0) = En; mu(j,k) = mean(exp(-(x(j) - Ex).^2 ./ (2 * Enp.^2))); end end end这里对每个“指标-等级”组合抽 n 次 En',取确定度的均值。n 取 1000 时,均值的波动已经很小,30 次重复实验的等级判定一致率能到 95% 以上。n 取 100 以下时波动肉眼可见,不建议。计算量上,p 个指标乘 m 个等级再乘 n 次,p=10、m=5、n=1000 也就 5 万次运算,MATLAB 里毫秒级,不用省。
注意:隶属度矩阵的行是指标、列是等级。后面加权时用
w' * mu,w 是 p×1 列向量,乘出来是 1×m。方向搞反会得到 p×p 的矩阵,MATLAB 不报错,但结果没法解释。
4.3 加权合成与等级判定
综合隶属度 b = w'·mu 得到之后,判定等级有两种口径。最大隶属度法直接取 b 中最大的那个分量对应的等级,简单但对“平局”不友好;加权得分法把各等级赋一个分值(比如 1 到 5),用 b 做权重求期望得分score = b * levelScore',再按得分落在哪个区间反推等级,结果更平滑,也方便做排序。
function [b, level, score] = cloudEvaluate(x, w, C, levelScore, n) % x: 1 x p 指标值;w: p x 1 权重;C: m x 3 等级云 % levelScore: 1 x m 各等级分值,如 [1 2 3 4 5] if nargin < 5, n = 1000; end mu = cloudMembership(x(:), C, n); b = w(:)' * mu; % 1 x m 综合隶属度 b = b / sum(b); % 归一化,防止浮点误差累积 [~, level] = max(b); % 最大隶属度对应等级 score = b * levelScore(:); % 综合得分 end两种口径建议同时输出。等级给结论,得分给排序,评审现场经常有人问“这两个都是二级,哪个更好一点”,得分能接住这个问题。如果 b 的前两个分量差距小于 0.05,我会在报告里标注“等级接近边界”,而不是硬给一个等级——边界附近的判定本来就该保守。
4.4 出图:云滴图要能看出重叠
评价结果最终要给人看,一张云滴图比一张隶属度表格有说服力得多。图的重点不是好看,是能看出各等级云的重叠关系,重叠太窄说明等级划分过硬,重叠太宽说明等级之间区分度不够。
function plotCloudLevels(C, x, levelName) % C: m x 3 等级云参数;x: 待评对象的指标值向量 figure; hold on; colors = lines(size(C,1)); for k = 1:size(C,1) [xd, md] = forwardCloud(C(k,1), C(k,2), C(k,3), 2000, 100+k); scatter(xd, md, 4, colors(k,:), 'filled', 'MarkerFaceAlpha', 0.12); end for j = 1:numel(x) xline(x(j), '--k', 'LineWidth', 0.8); end xlabel('指标归一化值'); ylabel('确定度'); legend(levelName, 'Location', 'northeast'); grid on; box on; endMarkerFaceAlpha这个参数值得调,默认 1 的时候云滴互相遮盖,重叠区看不出层次,0.1 到 0.2 之间比较合适。xline画出待评对象的实际指标位置,一眼能看出它离哪个等级的期望最近。图例里的 levelName 传等级名称的字符串元胞,别传数字,评审看数字对不上号。
5. 云模型代码避坑:五个跑不通的现场、原因与处理
这套代码我在三个不同类型的项目里用过,每次都会踩到新的坑。下面五条是重复出现频率最高的,按“现象—原因—解决”整理,遇到问题先对照这里,能省掉大半排查时间。
5.1 现象:同一份数据跑两次,等级不一样
原因几乎可以确定是随机数没有固定。正向云发生器和隶属度计算里都有randn,MATLAB 每次启动的随机种子不同,两次运行的云滴序列完全不一样。在云滴数 n 足够大(1000 以上)时,综合隶属度的差异通常在千分位,等级判定不该翻转;如果翻转了,说明 n 太小或者等级边界上的隶属度本来就接近。
解决分两层:调试阶段在脚本开头加rng(20240501)固定种子,保证结果可复现;正式出结论时反过来,主动跑 30 次取等级判定的众数,把一致率作为稳定性指标一起报出去。前者保证自己能对上账,后者保证别人能信。
5.2 现象:逆向云算出的 He 是 NaN 或者复数
前面提过,He² = S² - En² 可能为负。触发条件有两个:样本量低于 30,或者样本本身非常集中(比如 20 个专家里 18 个都打了 4 分)。样本集中的时候 S² 很小,而 En 由一阶绝对矩算出,两者不匹配,差值就翻负。
解决:先加截断保护He2 = max(He2, 0),保证不出 NaN;再看样本量,低于 30 就补数据或者改用区间估计;如果数据本身就是这样,那就接受 He = 0,此时云退化成确定度曲线,反而更符合“专家意见高度一致”的事实。不要为了凑出一个正的 He 去人为打散数据,那是自欺欺人。
5.3 现象:所有评价对象都判成最高等级
这是最典型的翻车姿势,八成出在归一化上。等级云的区间定义在 [0,1],而指标原始值在 [0,100],所有指标值都远大于 Ex,代入确定度公式后最高等级的 μ 恒为最大,结果自然全是最好的。
排查顺序:先打印每个指标的 min 和 max,确认范围和等级区间对不对得上;再检查成本型指标有没有反向,漏掉一个成本型指标会让综合得分系统性偏高;最后检查权重向量,如果某个权重特别大(比如 0.6),它对应的指标会主导整个判定,其他指标的差异被压平。
5.4 现象:熵权法算出的权重里有 0,甚至整列 NaN
零权重的来源是某个指标在所有样本上取值相同,差异系数 d = 0。NaN 的来源是矩阵里有 0 值,P .* log(P)算出0 * (-Inf)。这两个问题经常同时出现。
解决:矩阵进熵权法之前先做非负平移加 eps;算完权重检查any(w == 0),如果有零权重,看那个指标是不是真的没区分度——是的话可以从指标体系里删掉,不是的话说明样本量不够,得扩样本。另外,熵权法对样本量的敏感度比想象中大,5 个样本算出来的权重波动可以到 ±0.1,样本少于 10 个时我一般不建议单独用熵权法。
5.5 现象:云滴图画出来糊成一片,看不出等级
图形糊有两个独立原因。一是 He 设得太大,云滴在纵向上被拉得很散,各等级的散点互相穿插;二是 En 相对画图范围过大,相邻等级的云在横向上完全重叠,视觉上就是一整片。
解决:He 压到 En 的 0.01 到 0.05;坐标轴用xlim卡在[min(Ex) - 6*max(En), max(Ex) + 6*max(En)]范围内,别用自动范围,自动范围会被个别离群云滴拉爆;散点透明度降到 0.1 到 0.2。如果压完 He 还是重叠严重,那不是画图问题,是等级划分本身太粗,得回去重新设计区间。
5.6 现象:AHP 的一致性比率怎么调都超过 0.1
CR 超标说明判断矩阵内部有逻辑冲突。最常见的来源是专家填表时对“稍重要”和“明显重要”的尺度把握不一致,导致 3 和 5 混用。指标数量超过 7 个时,CR 超标概率显著上升,因为人很难同时保持七八个元素的两两比较一致。
解决:优先定位贡献最大的矛盾三元组,把那一行的某个元素往中间调(3 改 2、5 改 4),一次只动一个;指标超过 7 个时,先做一轮指标筛选或者分层,把一个大矩阵拆成两三个小矩阵分别算权重再合成。实在调不过,可以引入一致性修正算法自动逼近,但修正后的矩阵已经偏离专家原意,报告里要注明。
6. 把结果跑稳:云相似度校验与重复实验的稳定性判据
代码能跑通只是及格线,能证明结果稳才算交付。我一般做两件事:一是用云相似度校验等级云之间有没有重叠过度,二是用重复实验统计等级判定的一致率。
云相似度衡量两个云在形状上的接近程度,取值 0 到 1,越接近 1 说明两个等级越难区分。实现上不必追求解析解,用云滴直方图的重叠面积就够工程使用:
function sim = cloudSimilarity(C1, C2, n, seed) % 基于云滴分布重叠度的相似度,0~1 if nargin < 3, n = 2000; end if nargin < 4, seed = 7; end [x1, ~] = forwardCloud(C1(1), C1(2), C1(3), n, seed); [x2, ~] = forwardCloud(C2(1), C2(2), C2(3), n, seed + 1); edges = linspace(min([x1; x2]), max([x1; x2]), 60); h1 = histcounts(x1, edges, 'Normalization', 'probability'); h2 = histcounts(x2, edges, 'Normalization', 'probability'); sim = sum(min(h1, h2)); % 直方图逐格取小后求和,即重叠面积 end相邻等级的相似度落在 0.2 到 0.4 之间比较健康,说明有重叠但不至于混为一谈;超过 0.6 就要回头调 En,或者把等级拆细;低于 0.1 说明等级之间几乎是硬切,边界样本的判定会非常敏感。
稳定性判据更直接,同一份数据重复跑 N 次,统计等级判定结果的一致率:
N = 30; labels = zeros(N, 1); for i = 1:N rng(i); % 每次换种子,模拟真实的不确定性 [~, labels(i)] = cloudEvaluate(x, w, C, [1 2 3 4 5], 1000); end stab = max(histcounts(labels, 1:size(C,1)+1)) / N; fprintf('等级判定一致率: %.1f%%\n', stab * 100);一致率低于 90% 时,先查 n 是不是太小,再把 He 往下压一档,最后才考虑等级边界是不是划得不合理。这三个变量的调整顺序别乱,先动 n 的代价最小。
有个习惯我保持了几年:任何一份云评价结果出门之前,rng固定跑一遍、随机跑 30 遍,两套数字对得上才发。最开始嫌麻烦,直到有一次汇报时被问到“换个种子结果会不会变”,当场重跑翻了个等级,那之后这个流程就没省过。希望帮到你。
本文还有配套的精品资源,点击获取