// 阈值管理与异常识别 class ThresholdManager { constructor() { this.normalCycles = []; this.stageThresholds = []; } // 收集一轮正常周期数据 addNormalCycle(cycle, stageDurations) { this.normalCycles.push({ cycle, stageDurations }); // 只保留最近10轮 if (this.normalCycles.length > 10) this.normalCycles.shift(); this._recalculateThresholds(); } // 重新计算每阶段的上下阈值(均值±3倍标准差) _recalculateThresholds() { if (this.normalCycles.length === 0) return; // 以最新一轮的阶段分布为准 const { stageDurations } = this.normalCycles[this.normalCycles.length - 1]; const stageCount = stageDurations.length; this.stageThresholds = []; for (let s = 0, idx = 0; s < stageCount; s++) { let values = []; for (const { cycle, stageDurations: sd } of this.normalCycles) { // 兼容不同轮阶段长度 let start = sd.slice(0, s).reduce((a, b) => a + b, 0); let end = start + sd[s]; values = values.concat(cycle.slice(start, end)); } const mean = values.reduce((a, b) => a + b, 0) / values.length; const std = Math.sqrt(values.reduce((a, b) => a + (b - mean) ** 2, 0) / values.length); this.stageThresholds.push({ lower: mean - 3 * std, upper: mean + 3 * std }); } } // 根据当前index判断属于哪个阶段 getStageByIndex(index, stageDurations) { let sum = 0; for (let i = 0; i < stageDurations.length; i++) { sum += stageDurations[i]; if (index < sum) return i; } return stageDurations.length - 1; } // 判断异常 checkAbnormal(value, index, stageDurations) { const stage = this.getStageByIndex(index, stageDurations); if (!this.stageThresholds[stage]) return { isAbnormal: false, lower: null, upper: null }; const { lower, upper } = this.stageThresholds[stage]; return { isAbnormal: value < lower || value > upper, lower, upper }; } } module.exports = { ThresholdManager };