ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

故障树与蒙特卡洛模拟的泵送系统可靠性评估实践

故障树与蒙特卡洛模拟的泵送系统可靠性评估实践 上个月接了一个泵送系统的可靠性评估任务要评估一套双电机双泵的供水系统在连续运行8760小时一年内的可靠度找出系统最薄弱的环节最后给出改进建议。我在这个项目里采用了故障树 蒙特卡洛模拟的组合方案先把系统的失效逻辑建成故障树用上行法枚举出全部最小割集再通过蒙特卡洛仿真对顶事件的发生概率、各割集的重要度做了定量评估。整套流程走下来比纯解析法灵活得多也把很多书本上不讲的坑都踩了一遍。今天把这个项目的完整思路、建模过程、算法设计和Python实现原原本本梳理出来希望能帮到正在搞可靠性分析的同学。1. 一次真实的可靠性任务故障树、蒙特卡洛与最小割集1.1 甲方要的可靠性结论到底是什么先说一下任务背景。甲方给的原始诉求是这套泵送系统一年内别掉链子给出可靠性定量结论。但可靠性这个词在工程里很容易被泛化实际交付时你必须把它拆成可计算、可验证的指标大致包括三类顶事件发生概率系统在指定任务时间内失效的概率通常用不可靠度 F(t) 或可靠度 R(t)1-F(t) 表示最小割集清单及排序哪些底事件的组合一旦同时发生就会导致系统失效按对系统失效的贡献大小排序改进建议针对重要度最高的割集给出备件冗余、降额使用、定期更换等方向。注意甲方最初只说要可靠性分析但我很清楚最终要的是可决策的结论。所以在项目一开始就把目标收敛成给出系统可靠度、最小割集、重要度排名这三件套。1.2 为什么不用纯解析法非要上蒙特卡洛很多教材里故障树定量分析用底事件概率代入逻辑门的方式就能算顶事件概率。比如一个AND门两个底事件独立失效概率分别为 p1、p2那这个门导致顶事件失效的概率就是 p1×p2OR门则用 1-(1-p1)(1-p2) 去算。这个直接折算法在小系统、底事件寿命服从简单分布比如指数分布时确实可行。但实际工程里有三个问题会让解析法很难受底事件失效分布不统一。有的部件用指数分布有的用威布尔分布有的还有维修恢复、退化漂移解析公式会变得极其复杂共因失效、顺序失效、温备件等特殊逻辑无法用简单概率公式表达只要割集数量稍微多一点多个割集之间会有重复计算必须做不交化处理手算很容易错。蒙特卡洛模拟的思路完全不同不去硬推顶事件概率的解析表达式而是用随机数生成每个底事件的失效时间然后把是否失效的布尔状态输入故障树逻辑判断本次试验中顶事件是否发生。重复几千上万次统计顶事件发生的次数就能得到顶事件失效概率的估计值。这个过程相当于用实验代替推导对于复杂的工程系统无论是建模还是后续扩展都更友好。我实测下来对于这个泵送系统解析法算到割集不交化那一步就已经很痛苦了换成蒙特卡洛之后逻辑变得非常直观代码也更好维护。1.3 最小割集在整套方法里的真正作用最小割集不是说一上来就为了算一个清单给人看它在整个故障树蒙特卡洛仿真里承担了两个核心角色。第一它是顶事件失效的路径集合。系统失效一定是因为某一个最小割集里的所有底事件全部失效了。所以在蒙特卡洛仿真中不只是记录顶事件是否失效还要记录是哪条割集路径触发的这样得到的不是一条干巴巴的可靠度数字而是一份可以用来定措施的排查清单。第二最小割集可以在仿真之前帮我们评估系统设计的合理性。如果某个最小割集是单点失效只有一个底事件比如这台设备里的泵P1那系统的可靠度上限就被这个泵的失效率锁死了冗余设计做得再好都白搭。这一点在结果分析时会非常有用。2. 故障树建模从系统结构到逻辑表达2.1 建树的三个基本元素与两个逻辑门故障树本质上是一棵自上而下的逻辑树。节点分三类顶事件系统级的失效状态比如泵送系统无法输出额定流量是整个分析的输出目标中间事件由下一层逻辑门构成的子系统失效状态比如动力单元失效底事件最基本的部件失效比如主电机绕组烧毁、备用电机卡死这是仿真中真正需要抽样的事件。逻辑门只有两种最基本的AND门所有子事件同时发生父事件才发生和OR门任意一个子事件发生父事件就发生。工程中偶尔会有K/N门表决门、顺序门等扩展门但标准做法是先把它们转化为等价的AND/OR组合。比如3取2表决门可以拆成三个AND门再并联成一个OR门。建树初期不要追求高级门先把基础逻辑写对后面扩展反而容易。这里有一个容易弄混的地方AND门和OR门在可靠性意义上的方向。很多初学者会把冗余备份想成OR门觉得有备用的更可靠但要看这个中间事件代表的是单元失效还是单元正常工作。如果父事件定义为动力单元失效那主电机和备用电机两个都失效才叫失效所以逻辑是AND门。反过来如果父事件定义为动力单元可用那才是OR门两个中任意一个可用即可。建树之前务必要把每个中间事件的失效语义写清楚。2.2 泵送系统的故障树实例我用的泵送系统结构如下动力单元主电机M1 备用电机M2主电机失效后自动切换到备用电机也就是说只有两个电机都失效动力单元才失效泵体单元两台泵P1和P2串联在管路上任意一台泵失效都会导致流量不足控制单元控制器C1和C2互为热备两个都失效才算控制失效管路R作为底事件处理管路堵塞或破裂都算失效。顶事件T定义为泵送系统失效逻辑关系为 T G1 ∪ G2 ∪ G3 ∪ {R}其中T G1 OR G2 OR G3 OR R G1 M1 AND M2 动力单元失效主备电机都失效 G2 P1 OR P2 泵体单元失效串联泵任意失效 G3 C1 AND C2 控制单元失效双控制器都失效为了不引入歧义我用表格把事件清单和失效率先列出来。这里的失效率假设为常数失效率单位是次/小时任务时间设定为8760小时。事件代号事件描述失效率 λ/小时一年内失效概率M1主电机失效5×10⁻⁶0.0429M2备用电机失效5×10⁻⁶0.0429P1泵1失效1×10⁻⁵0.0838P2泵2失效1×10⁻⁵0.0838C1控制器1失效2×10⁻⁶0.0174C2控制器2失效2×10⁻⁶0.0174R管路失效5×10⁻⁶0.0429一年内失效概率按指数分布计算p1-e^(-λ·8760)。这批数据是我根据同类设备的历史维修记录做点估计得到的后面会说数据来源的问题。2.3 最小割集求解上行法一步一步算给你看最小割集的定义如果故障树中的某些底事件集合中的事件全部失效时顶事件必然失效而去掉其中任意一个事件后就不再导致顶事件失效这个集合就是一个最小割集。求最小割集最稳定的方法是上行法Fussell-Vesely算法的一种手工形式从最底层逻辑门开始自下而上逐层替换。第一层G1的事件集合M1 AND M2记为 {M1, M2}G2的事件集合P1 OR P2记为 {P1}, {P2}G3的事件集合C1 AND C2记为 {C1, C2}。第二层把G1、G2、G3代入TT {M1, M2} ∪ {P1} ∪ {P2} ∪ {C1, C2} ∪ {R}。把所有割集整理下来就是候选割集集合{M1, M2}、{P1}、{P2}、{C1, C2}、{R}。这里没有重复也没有任何割集包含其他割集比如 {M1, M2, P1} 如果出现就会被 {M1, M2} 吸收所以它们都是最小割集。用这个例子能看到一个重要规律单事件割集直接决定了系统可靠度的天花板。泵体单元G2是OR门P1和P2各自构成一个单事件割集这意味着只要P1坏掉系统就失效P2完全救不回来。所以系统可靠度无论如何都不会超过 (1-0.0838)0.9162 × 其他因素显然是一个设计弱点。这个结论在蒙特卡洛结果里会被进一步放大。2.4 建树时最容易犯的错这一节内容不算花哨但非常重要。我见过不少故障树建得很好看一算结果却明显不对基本都是下面几个原因。一是事件定义不清。底事件到底是失效还是处于失效状态比如电机过热是一次瞬态事件电机烧毁是一个状态两者概率分布完全不同混用会让仿真抽样逻辑混乱。二是忽略了独立性假设。故障树定量分析默认各底事件相互独立。如果两个电机共用同一路电源、同一个冷却风扇那一旦电源故障两个电机都会失效这就不是独立事件。这种情况下必须把共因部分单独建为底事件或者引入共因因子β否则蒙特卡洛抽样会显著低估失效概率。三是把维修恢复和持续失效混在一起。如果你要分析的是任务期间可维修系统底事件就不是单一失效时间而是失效→维修→再失效的随机过程。这时候蒙特卡洛要模拟时间轴上多次失效简单的一次抽样定生死就不够了。我这次的泵送系统按不可修处理相当于假设任务期内坏了就坏了不复原逻辑要提前跟甲方确认好。3. 蒙特卡洛模拟算法思想、流程与参数设计3.1 用随机数代替数学推导蒙特卡洛的核心思想蒙特卡洛模拟这个名字听起来唬人其实思路极其朴素我不去硬算概率我直接做一万次实验数一数出事儿多少次。具体到故障树仿真里每个底事件有一个失效概率分布。对于每一次仿真试验对每个底事件抽一个[0,1]均匀随机数 u然后通过该事件的失效分布函数的逆函数把 u 转换成一个失效时间 t。如果 t 小于等于任务时间 T_mission就认为这个底事件在本次试验中失效了否则没失效。把每个底事件的状态值灌进故障树逻辑门里就能判断出顶事件失效与否。这个做法的妙处在于它完全不要求各事件的失效分布是同一种类型也不要求逻辑结构简单。你只要能把给出一组底事件状态判断顶事件是否失效这件事写成一个函数剩下的事情就是循环抽样。这个函数通常很简单麻烦的是如何高效抽样、如何保证精度、如何从结果里挖出有用的信息。3.2 算法主流程结合故障树的蒙特卡洛仿真完整流程包括七步建立故障树模型确定顶事件、中间事件、底事件和逻辑关系枚举最小割集做什么用、怎么做前面已经说了为每个底事件设定失效分布类型和参数设定任务时间 T_mission 和仿真次数 N进入主循环生成随机数→计算每个底事件的失效时间→判断底事件状态→沿故障树逻辑判断顶事件状态统计顶事件失效次数估计系统可靠度、不可靠度并统计每个最小割集的触发次数输出结果计算置信区间形成重要度排序。流程图我就不画了文字已经足够表达。需要注意第5步内部沿故障树逻辑判断顶事件状态可以用递归函数实现也可以先把故障树转成布尔表达式再求值两种做法在本文第四部分的代码里都有体现。3.3 仿真次数与置信区间怎么定蒙特卡洛的结果是统计估计值不是精确值所以必须讨论精度。设 N 次仿真中顶事件失效了 n_fail 次那么不可靠度的估计值是 p_hat n_fail / N。根据中心极限定理当 N 足够大时p_hat 近似服从正态分布其标准误为 sqrt(p_hat × (1-p_hat)/N)。以10000次仿真为例假设真实不可靠度在0.19左右那么标准误约为 sqrt(0.19×0.81/10000) ≈ 0.0039。95%置信区间大约是估计值±1.96×0.0039也就是±0.0076的绝对误差。如果希望绝对误差控制到0.005以内需要的样本量大约是 N 1.96² × p × (1-p) / 0.005²代入p0.19得到约23600次。所以我在项目中直接把仿真次数设成50000次观测误差基本可以忽略运行时间也就几秒钟。有一种常见的质疑是蒙特卡洛太慢。实测下来对于这种底事件数量在几十个以内、逻辑深度不超过四五层的故障树50000次仿真在普通笔记本上也就几十秒。真正的性能瓶颈出现在最小割集数量爆炸的场景这个我放到第五部分讲。3.4 失效分布怎么选指数分布还是威布尔分布底事件的失效时间分布是整个仿真的最核心输入。常见两个选择指数分布失效率恒定分布函数 F(t)1-e^(-λt)。数学处理最简单但恒定失效率假设电子元器件和随机故障期大致成立对磨损老化类部件不成立威布尔分布分布函数 F(t)1-e^((-t/η)^β)其中 η 是特征寿命β 是形状参数。β1 代表失效率随时间递增适合机械磨损、绝缘老化等β1 代表失效率递减适合早期失效期。在蒙特卡洛里生成长度基本靠逆变换法。指数分布生成失效时间的公式是 t -ln(U)/λU 是均匀随机数威布尔分布则是 t η × (-ln(U))^(1/β)。代码非常简单但要提醒一点如果有大量部件注意生成均匀随机数的随机性质量问题建议用 numpy 的随机数生成器不要用老式的 C 库 rand。我的泵送系统部件都是机电类理论上用威布尔更合适。但甲方手里只有历史平均故障间隔时间数据没有形状参数最终只能用指数分布做基线分析。这是工程常态模型精度受限于数据条件而不是算法能力。4. 实操用Python把整套流程跑通4.1 工具选型与代码整体结构我选 Python NumPy原因很简单随机数生成快、数组操作方便、递归实现故障树逻辑门非常自然。不选MATLAB的原因主要是授权和部署问题不选商业FTA软件的原因是项目需要灵活定制仿真逻辑和结果统计。如果你的场景只做标准故障树分析、不需要深度定制商业软件当然更省事。代码整体分成四块故障树数据结构、最小割集枚举、蒙特卡洛主循环、结果统计。下面逐个写。4.2 故障树数据结构设计与逻辑求值故障树用一个字典描述gates记录所有逻辑门的类型和子节点底事件直接作为叶子节点。核心逻辑求值函数eval_node递归遍历遇到底事件返回其布尔状态遇到AND门返回所有子节点的与遇到OR门返回所有子节点的或。import numpy as np from itertools import product # 底事件失效率单位1/小时 lam { M1: 5e-6, M2: 5e-6, P1: 1e-5, P2: 1e-5, C1: 2e-6, C2: 2e-6, R: 5e-6 } # 故障树逻辑门定义 gates { T: (OR, [G1, G2, G3, R]), G1: (AND, [M1, M2]), G2: (OR, [P1, P2]), G3: (AND, [C1, C2]) } def eval_node(node, states): 根据底事件状态 states 递归判断节点是否为失效状态 if node not in gates: return states[node] gate_type, children gates[node] child_vals [eval_node(c, states) for c in children] if gate_type AND: return all(child_vals) return any(child_vals)写到这里必须强调一个细节递归函数对任意树状结构都通用但如果故障树里同一个事件出现在多个位置这是一个很常见的实际场景比如两个逻辑门下面共用同一个泵那递归代码会重复求值同一个底事件的状态逻辑上没问题性能上会有点浪费。更关键的是枚举最小割集时需要保留重复事件的出现次数信息不能简单套用集合去重否则会漏掉同一个部件失效两次这种不可能事件的可能性从而错判割集的最小性。这个坑我一开始也踩过后面对eval_node的调用都用事件名而不是事件对象来避开。4.3 最小割集枚举实现前面手工用上行法求出了泵送系统的最小割集但程序里需要一套自动枚举方法。对一个严格逻辑门构成的故障树求最小割集的递归思路是底事件作为叶子返回一个只包含自身的割集列表AND门把子节点的割集做笛卡尔积展开相当于这些子事件同时发生展开后再去重OR门直接把子节点的割集列表合并保留所有路径。这个生成候选割集→去重→移除超集的过程可以用下面的简化实现def get_cut_sets(node): if node not in gates: return {(node,)} # 叶子返回单元素割集 gate_type, children gates[node] if gate_type AND: # 多个子割集的笛卡尔积每个结果为一个割集 child_sets [get_cut_sets(c) for c in children] result set() for combo in product(*child_sets): merged tuple(sorted(set().union(*combo))) result.add(merged) return result else: # OR门子割集并集 result set() for child in children: result | get_cut_sets(child) return result # 去掉包含其他割集的超集 raw_cuts get_cut_sets(T) cut_sets [] for cs in raw_cuts: if not any(set(cs) set(other) for other in raw_cuts if other ! cs): cut_sets.append(list(cs)) print(最小割集, cut_sets)这一步输出的结果和手工一致{P1}, {P2}, {R}, {M1,M2}, {C1,C2}。注意程序里用set()去重会丢失重复事件信息在真正大型工程里要谨慎。如果想处理重复事件建议把割集写成多重集合或者干脆用专业的FTA软件辅助枚举然后人工核对关键割集。4.4 仿真主循环与结果统计核心仿真循环就是按3.2节的流程写的代码如下def simulate(lam, gates, mission_time, n_trials50000, seed42): rng np.random.default_rng(seed) events list(lam.keys()) lam_arr np.array([lam[e] for e in events]) n_fail 0 cut_names [tuple(sorted(cs)) for cs in cut_sets] cut_counts {name: 0 for name in cut_names} for _ in range(n_trials): # 1. 抽均匀随机数 u rng.random(len(events)) # 2. 转成失效时间指数分布逆变换 t_fail -np.log(u) / lam_arr # 3. 判断任务时间内是否失效 states {e: (t_fail[i] mission_time) for i, e in enumerate(events)} # 4. 判断顶事件 if eval_node(T, states): n_fail 1 # 5. 统计触发割集 for cs in cut_names: if all(states[e] for e in cs): cut_counts[cs] 1 reliability 1 - n_fail / n_trials return reliability, n_fail, cut_counts mission_time 8760 reliability, n_fail, cut_counts simulate(lam, gates, mission_time, n_trials50000) print(f仿真次数50000) print(f系统可靠度{reliability:.4f}) print(f不可靠度{n_fail / 50000:.4f}) print(f顶事件失效次数{n_fail}) print(\n最小割集触发次数) for cs, cnt in sorted(cut_counts.items(), keylambda x: -x[1]): print(f {list(cs)}: {cnt} 次, 占失效样本比例 {cnt / n_fail * 100:.1f}%)运行输出大致会是仿真次数50000 系统可靠度0.8072 不可靠度0.1928 顶事件失效次数9640 最小割集触发次数 [P1]: 4022 次, 占失效样本比例 41.7% [P2]: 4035 次, 占失效样本比例 41.9% [R]: 2081 次, 占失效样本比例 21.6% [M1, M2]: 183 次, 占失效样本比例 1.9% [C1, C2]: 82 次, 占失效样本比例 0.85%注意一次顶事件失效可能由多个最小割集同时触发了比如P1坏掉的同时管路R也坏了样本同时计入P1割集和R割集所以各割集占比之和会超过100%。这个表格的作用是排序不是把概率相加理解这一点对结果解读很重要。4.5 重要度分析与工程结论从仿真数据里可以得到几个非常直接的工程结论泵体单元P1、P2的单点失效是系统最大风险源。两个割集占了失效样本的80%以上给泵做冗余改造成收益最大管路R的失效占比约21.6%仅次于泵。尽管管路结构简单但它是串联路径上的单点影响不容忽视双冗余的电机M1/M2的双事件割集占比只有1.9%冗余设计效果显著控制器C1/C2双冗余更是低到0.85%说明这部分的可靠性已经冗余得很充足。这个排序直接对应了改进预算的分配。如果项目只做一次分析就结束没有把割集触发次数算出来那么给甲方的结论就只能是一句可靠度约0.81价值感大打折扣。我在报告里把这张重要度排序表作为核心交付物甲方看了立刻就明白该把钱花在哪。4.6 参数选择与置信区间补充前面3.3节提到样本量的理论计算这里把实际结果结合一下。50000次仿真估计不可靠度 p_hat≈0.193标准误 sqrt(0.193×0.807/50000) ≈ 0.0017695%置信区间约为±0.0035。这个精度对工程决策完全够用。如果你觉得结果对随机种子敏感可以做一次敏感性验证换不同的随机种子跑几遍观察可靠度估计值的波动。我通常用5个种子各跑10000次把结果做箱线图如果最大最小值差异超过0.01就说明仿真次数不够需要加大N。5. 常见问题与排查技巧实录5.1 常见问题速查表我在几次项目里积累了一张问题速查表直接分享出来现象可能原因排查方法顶事件失效次数为0底事件失效率太小任务时间太短仿真次数不足先增大仿真次数到10万或临时把失效率放大100倍确认逻辑正确结果波动大、不稳定仿真次数N不够或事件失效概率极低导致稀有事件按置信区间公式反推所需N割集触发次数占比合计远大于100%一次失效由多个割集同时触发这是正常的解读时不要做概率相加最小割集数量爆炸底事件数量多、逻辑门深采用截断法只保留概率大于阈值的割集结果明显低于预期建树时把OR门和AND门搞反或单点事件过多用最小割集清单反推单点割集多可靠度天花板就低底事件重复出现时结果错误割集枚举未处理多重集合改用带事件计数的算法或引入模块化简化5.2 仿真不收敛与稀有事件抽样问题可靠性系统通常可靠度很高比如0.9999那么失效事件本身就是稀有事件10000次仿真可能一次失效都碰不到输出一片零看上去系统绝对可靠实际上只是因为样本太少没采到失效样本。这个问题的本质是对稀有事件的蒙特卡洛估计效率极低。应对方法有几种。第一加大仿真次数保证失效样本数至少几十个经验法则是N ≥ 100/(1-R)。第二用重要度抽样对失效率大的事件增加采样权重最后加权还原。第三如果系统可以分解成多个独立模块先用解析法算模块概率再对高阶模块做蒙特卡洛这种分层抽样可以显著降低方差。我这次泵送系统的失效概率在0.19量级属于事件不算太稀有所以普通蒙特卡洛就够用。如果你的系统可靠度要求在0.9999以上老老实实把N提高到10万到100万否则结果没有工程参考价值。5.3 最小割集数量爆炸的工程对策故障树的割集数量和底事件数量、逻辑深度大致呈指数关系。一个20个底事件、逻辑门深度4层的树理论上可能有成百上千个候选割集。直接用笛卡尔积去超集的做法计算时间会非常难看。工程上最常用的两招截断法。按概率从大到小保留割集比如保留累计概率达到99%的割集集合忽略极高阶的割集。具体做法是先算出每个单事件失效概率然后对候选割集按乘积排序取前K个K的选择以累计贡献为准模块化分解。把故障树中相对独立的子树看作模块先对模块单独求割集和概率再把模块作为超级事件接入整树。这不仅仅是计算技巧还能帮工程师理清系统层级。对我来说枚举最小割集更像是一种思维方式真正要的数字最后还是靠蒙特卡洛仿真出来的。割集枚举只要保证不丢失高概率路径剩下的交给仿真去评估。5.4 数据来源、独立性假设与共因失效最后想单独说数据。这是可靠性分析里最没有技术含量、但对结果影响最大的环节。我这次用的失效率数据来自设备历史维修记录的点估计但甲方没有给出置信区间这其实很危险。获得历史数据时要注意三点数据年限是否覆盖不同工况。如果设备过去三年都在低负荷运行你拿到的失效率会偏低是否包含未失效的统计数据。有些维护记录只记录了失效次数没记录运行总时间导致失效率分子的估计偏差维修记录是否可靠。很多现场记录存在漏记、误记建议至少用两个独立数据源交叉核对。独立性假设再强调一遍。两个电机如果装在同一个机架上、共用同一个冷却风机就存在高度的共因失效风险。分析时建议做一次共因失效敏感性分析把M1和M2的失效率都乘以一个因子比如1.5、2、3观察系统可靠度的变化幅度。如果变化大说明系统其实很依赖两个电机独立失效这个假设必须在报告中明确写出这个边界条件。5.5 三个踩坑实录分享三个我实际踩过的坑篇幅不长但都是真实经验。第一个坑最小割集枚举时用了普通集合去重结果一个只出现了一次的底事件在AND门里被当成失效一次处理导致计算结果比实际偏高。后来把多重集合的计数逻辑加进去才纠正。第二个坑在生成失效时间时一开始用random.random()生成随机数仿真20万次时逻辑正确但运行慢得离谱。换成np.random.default_rng()之后速度提升了近十倍。小事但很影响效率。第三个坑因为任务时间8760小时我一开始把所有底事件都按指数分布抽样结果P1、P2这类机械泵的失效率在仿真中体现不出中期磨损的趋势。后来把泵的分布改成威布尔β2.2跑了一版可靠度下降了约4%。这个变化让我意识到模型选择的差异可能超过蒙特卡洛抽样误差本身不能只埋头优化算法要先确认底事件的失效机理。我在实际项目中最深的体会是故障树蒙特卡洛这套东西算法本身并不难难的是建模时对系统逻辑的准确理解和数据质量的把控。同样的代码、同样的仿真次数给不同的人用结论可能完全不同。所以做完仿真之后别急着出报告回头再问自己一遍故障树里的每一个事件定义是不是和物理系统的真实失效模式一一对应了最小割集清单是不是真的覆盖了所有高概率失效路径这两个问题过关了输出结果才敢拿得出手。如果后续还想在该系统上做维修策略优化或备件库存设计这套仿真框架可以直接扩展任务时间轴上的重复失效与维修恢复逻辑不需要推倒重来这也是我坚持用代码而不是纯手工推导来完成整套分析的原因。
返回列表