br_maths/
process.rs

1use std::fmt::Display;
2use crate::stats::stdev;
3
4/// 制程能力指标
5pub struct Cpk {
6    /// 制程能力
7    pub cpk: f64,
8    /// 制程准确度
9    pub ca: f64,
10    /// 制程精密度
11    pub cp: f64,
12
13    /// 规格上限
14    pub usl: f64,
15    /// 规格下限
16    pub lsl: f64,
17    /// 标准差
18    pub stddev: f64,
19    /// 平均值
20    pub avg: f64,
21    /// 最大值
22    pub max: f64,
23    /// 最小值
24    pub min: f64,
25}
26
27impl Cpk {
28    /// 初始化
29    ///
30    /// * usl 上限值
31    /// * lsl 下限值
32    /// * array 数据
33    pub fn new<T: Display + std::fmt::Debug>(usl: f64, lsl: f64, array: Vec<T>) -> Self {
34        let mut total = 0.0;
35        let list: Vec<f64> = array.iter().map(|x|
36            {
37                let y = x.to_string().parse::<f64>().unwrap();
38                total += y;
39                y
40            }
41        ).collect();
42
43        // 标准差
44        let stddev = stdev(array);
45        // 样本数量
46        let n = list.len();
47        // 平均值
48        let x = total / n as f64;
49
50        let mut max = 0.0;
51        for item in list.iter() {
52            if item > &max {
53                max = *item;
54            }
55        }
56
57        let mut min = list[0];
58        for item in list.iter() {
59            if item < &min {
60                min = *item;
61            }
62        }
63
64        // 规格公差
65        let t = usl - lsl;
66
67        // 规格中心
68        let u = (usl + lsl) / 2.0;
69        let mut cp = t / (6.0 * stddev);
70        let cpu = (usl - x).abs() / (3.0 * stddev);
71        let cpl = (x - lsl).abs() / (3.0 * stddev);
72        let ca = (x - u) / (t / 2.0);
73        let mut cpk = if cpu > cpl { cpl } else { cpu };
74        if cpk.is_infinite() {
75            cpk = 0.0;
76        }
77        if cp.is_infinite() {
78            cp = 0.0;
79        }
80        Self {
81            stddev,
82            max,
83            min,
84            avg: x,
85            cpk,
86            ca: ca * 100.0,
87            cp,
88            usl,
89            lsl,
90        }
91    }
92    pub fn cpk_rating_criteria(&self) -> (&'static str, &'static str) {
93        if self.cpk >= 2.0 {
94            ("A++", "特优,可考虑降低成本。")
95        } else if 1.67 <= self.cpk && self.cpk < 2.0 {
96            return ("A+", "优,应当保持之。");
97        } else if 1.33 <= self.cpk && self.cpk < 1.67 {
98            ("A", "良,能力好,状态稳定,但应尽力提升到A+级。")
99        } else if 1.00 <= self.cpk && self.cpk < 1.33 {
100            ("B", "一般,制程因素稍有变异即有生产不良的危险,应利用各种资源及方法将其提升为A级。")
101        } else if 0.67 <= self.cpk && self.cpk < 1.00 {
102            ("C", "差,制程不良较多。须提升其能力。")
103        } else {
104            ("D", "不可接受,其能力太差,应考虑重新整改设计制程。")
105        }
106    }
107    pub fn ca_rating_criteria(&self) -> (&'static str, &'static str) {
108        if self.ca <= 12.5 {
109            ("A", "作业员遵守作业标准操作并达到要求,需继续保持。")
110        } else if 12.5 <= self.ca && self.ca <= 25.0 {
111            ("B", "有必要将其改进为A级。")
112        } else if 25.0 <= self.ca && self.ca <= 50.0 {
113            ("C", "作业员可能看错规格或不按作业标准操作。须检讨规格及作业标准。")
114        } else {
115            ("D", "应采取紧急措施全面检讨所有可能影响之因素,必要时得停止生产。")
116        }
117    }
118    pub fn cp_rating_criteria(&self) -> (&'static str, &'static str) {
119        if self.cp >= 1.67 {
120            ("A+", "无缺点,可考虑降低成本。")
121        } else if 1.33 <= self.cp && self.cp <= 1.67 {
122            ("A", "状态良好维持现状。")
123        } else if 1.00 <= self.cp && self.cp <= 1.33 {
124            ("B", "可以改进为A级。")
125        } else if 0.67 <= self.cp && self.cp <= 1.00 {
126            ("C", "制程不良较多。须提升能力。")
127        } else {
128            ("D", "制程能力好差,应考虑重新整改设计制程。")
129        }
130    }
131}