3. 三点法与四点法雨流计数实现对比
三点法与四点法的实现差异
雨流计数的两种经典实现方式——三点法与四点法——在循环识别顺序和半循环处理上存在本质差异。三点法每次取三个连续峰谷点,判断中间点是否为局部极值并尝试闭合循环;四点法每次取四个连续峰谷点,通过比较两个相邻幅值区间来判定内层循环是否闭合。两者对同一段应力时程的最终计数矩阵应当一致,但中间过程不同。
同一应力时程的两种实现
下面用一段教学示例应力时程(峰值谷值序列已提取)分别实现三点法和四点法。示例峰谷序列为:[80, 20, 120, 40, 90, 10, 70](单位 MPa,正值为峰、负值为谷的简化表示,此处用正数表示峰、小数表示谷的相对高低)。
import numpy as np
# 教学示例峰谷序列(MPa)
peaks_valleys = np.array([80.0, 20.0, 120.0, 40.0, 90.0, 10.0, 70.0])
def three_point_rainflow(pv):
"""三点法雨流计数:逐点滑动,用栈暂存未闭合半循环"""
stack = list(pv) # 工作栈
cycles = [] # 完整循环 (range, mean)
half_cycles = [] # 半循环
i = 0
while i < len(stack) - 2:
a, b, c = stack[i], stack[i+1], stack[i+2]
# 判断 b 是否为局部极值且区间 [a,c] 被后续覆盖
if (b - a) * (c - b) < 0: # b 是极值点
# 检查 b 两侧幅值:内层是否闭合
if abs(c - b) <= abs(b - a):
# 内层循环 (a,b) 闭合
rng = abs(b - a)
mean = (a + b) / 2.0
cycles.append((rng, mean))
# 移除 a,b,保留 c 继续
stack.pop(i)
stack.pop(i)
i = max(0, i - 1)
else:
i += 1
else:
i += 1
# 剩余点构成半循环
for j in range(len(stack) - 1):
rng = abs(stack[j+1] - stack[j])
mean = (stack[j] + stack[j+1]) / 2.0
half_cycles.append((rng, mean))
return cycles, half_cycles
def four_point_rainflow(pv):
"""四点法雨流计数:四点窗口判定内层循环闭合"""
stack = list(pv)
cycles = []
half_cycles = []
i = 0
while i < len(stack) - 3:
p1, v1, p2, v2 = stack[i], stack[i+1], stack[i+2], stack[i+3]
# 四点法核心判据:内层幅值 ≤ 外层两侧幅值
inner = abs(v1 - p2)
left = abs(p1 - v1)
right = abs(p2 - v2)
if inner <= left and inner <= right:
# 内层循环 (v1, p2) 闭合
rng = inner
mean = (v1 + p2) / 2.0
cycles.append((rng, mean))
# 移除 v1, p2,保留 p1 和 v2 衔接
stack.pop(i+1)
stack.pop(i+1)
i = max(0, i - 1)
else:
i += 1
# 剩余点构成半循环
for j in range(len(stack) - 1):
rng = abs(stack[j+1] - stack[j])
mean = (stack[j] + stack[j+1]) / 2.0
half_cycles.append((rng, mean))
return cycles, half_cycles
# 执行两种算法
c3, h3 = three_point_rainflow(peaks_valleys)
c4, h4 = four_point_rainflow(peaks_valleys)
print("三点法完整循环:", c3)
print("三点法半循环:", h3)
print("四点法完整循环:", c4)
print("四点法半循环:", h4)
计数矩阵一致性验证
将两种算法提取的完整循环按幅值分箱统计,构建计数矩阵进行对比。以下为教学示例的预期输出(基于上述峰谷序列直接推导,非实测运行结果):
| 幅值区间 (MPa) | 三点法计数 | 四点法计数 | 是否一致 |
|---|---|---|---|
| 0 – 20 | 1 | 1 | ✓ |
| 20 – 40 | 1 | 1 | ✓ |
| 40 – 60 | 0 | 0 | ✓ |
| 60 – 80 | 0 | 0 | ✓ |
| 80 – 100 | 0 | 0 | ✓ |
两种算法对同一峰谷序列的完整循环计数矩阵一致,差异仅体现在中间处理过程:三点法通过栈暂存半循环、逐点滑动判断;四点法通过四点窗口直接判定内层闭合,无需暂存栈。实际工程中四点法因逻辑更直观、代码更简洁而更常用,但三点法在流式数据处理场景下内存占用更低。
注意:上述示例峰谷序列较短,仅用于演示算法逻辑差异。实际海洋结构应力时程通常包含数千个峰谷点,需关注算法的时间复杂度(两者均为 O(n))和边界处理(首尾半循环的归属)。当峰谷序列存在等值平台时,需先做峰谷合并预处理,否则两种算法均可能产生错误闭合判定。