using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Mesnac.Action.Feeding { // 摘要: // 过程能力控制类 public class SixSigmaHelper { public static double d2 = 1.128; public static double d3 = 1.693; public static double d4 = 2.059; public static double d5 = 2.326; /// /// 求和 /// /// 原始数据数组 /// public static double GetSumValue(Double[] originalData) { Double sum = 0.0; for (int i = 0; i < originalData.Length; i++) { sum = sum + originalData[i]; } return DoubleFormat(sum); } /// /// 求平均数 /// /// 原始数据数组 /// public static Double GetAverageValue(Double[] originalData) { Double sum = 0.0; Double ave = 0.0; for (int i = 0; i < originalData.Length; i++) { sum = sum + originalData[i]; } ave = sum / originalData.Length; return DoubleFormat(ave); } /// /// 按指定精度求平均值 /// /// 精度,即保留的小数位数 /// /// public static Double GetAverageValue(int digits, Double[] originalData) { Double sum = 0.0; Double ave = 0.0; for (int i = 0; i < originalData.Length; i++) { sum = sum + originalData[i]; } ave = sum / originalData.Length; return DoubleFormat(digits, ave); } /// /// 获取整体平均值:先分组,计算组内平均值,然后计算整体平均值 /// /// 精度,小数位数 /// 组大小 /// 原始数据 /// public static Double GetTotalAveByGroup(int digits, int groupSize, Double[] originalData) { Double[] groupAve = GetGroupAve(digits, groupSize, originalData); return SixSigmaHelper.GetAverageValue(digits, groupAve); } /// /// 获取子组平均数,以数组形式返回 /// /// 精度,小数位数 /// 组大小 /// 原始数据 /// 返回子组平均值 public static Double[] GetGroupAve(int digits, int groupSize, Double[] originalData) { Double groupNum = Math.Ceiling(Convert.ToDouble(originalData.Length / groupSize)); Double[] groupAve = new Double[Convert.ToInt32(groupNum)]; for (int i = 0; i < Convert.ToInt32(groupNum); i++) { int index = i * groupSize; Double[] temp = new Double[groupSize]; for (int j = 0; j < groupSize; j++) { temp[j] = originalData[index + j]; } groupAve[i] = SixSigmaHelper.GetAverageValue(digits, temp); } return groupAve; } /// /// 求整体标准差 /// /// 原始数据 /// 返回标准差 public static Double GetTotalStdDev(Double[] originalData) { Double ave = 0.0; Double stdDev = 0.0; if (originalData.Length == 1 && originalData[0] == 0.0) { return stdDev = 0.0; } ave = GetAverageValue(originalData); for (int i = 0; i < originalData.Length; i++) { stdDev = (Double)(stdDev + Math.Pow((originalData[i] - ave), 2)); } stdDev = (Double)Math.Sqrt(stdDev / (originalData.Length - 1)); return DoubleFormat(stdDev); } /// /// 按指定精度获取标准差 /// /// 精度,即小数位数 /// 原始数据 /// 返回标准差 public static Double GetStdDev(int digits, Double[] originalData) { Double ave = 0.0; Double stdDev = 0.0; ave = GetAverageValue(originalData); for (int i = 0; i < originalData.Length; i++) { stdDev = (Double)(stdDev + Math.Pow((originalData[i] - ave), 2)); } stdDev = (Double)Math.Sqrt(stdDev / (originalData.Length - 1)); return DoubleFormat(digits, stdDev); } /// /// 求移动极差均值 /// /// 子组容量 /// 原始数据 /// 返回移动极差均值 public static Double GetMoveRangeMean(int size, Double[] originalData) { Double moveSum = 0.0; Double moveAve = 0.0; Double[] range = new Double[originalData.Length - (size - 1)]; for (int i = (size - 1); i < originalData.Length; i++) { Double[] temp = new Double[size]; int count = size; int idx = 0; do { temp[idx] = originalData[i - (count - 1)]; idx++; count--; } while ((count > 0)); range[i - (size - 1)] = (Double)Math.Abs(GetArrMax(temp) - GetArrMin(temp)); } for (int i = 0; i < range.Length; i++) { moveSum = moveSum + range[i]; } moveAve = moveSum / range.Length; return DoubleFormat(moveAve); } /// /// 求组内标准差 /// /// 子组容量 /// 原始数据 /// 返回组内标准差 public static Double GetInGroupStdDev(int size, Double[] originalData) { Double gourpStdDev = 0.0; Double moveAve = GetMoveRangeMean(size, originalData); switch (size) { case 2: gourpStdDev = (Double)(moveAve / d2); break; case 3: gourpStdDev = (Double)(moveAve / d3); break; case 4: gourpStdDev = (Double)(moveAve / d4); break; case 5: gourpStdDev = (Double)(moveAve / d5); break; default: gourpStdDev = (Double)(moveAve / d2); break; } return DoubleFormat(gourpStdDev); } /// /// 获取整体正态分布曲线数组值 /// /// 望目 /// 原始数据 /// 返回整体正态分布曲线数组值 public static Dictionary GetNormalDistribution(Double target, Double[] original) { Dictionary json = new Dictionary(); Double sigma = GetTotalStdDev(original); Double lcl = DoubleFormat(target - 3 * sigma); Double ucl = DoubleFormat(target + 3 * sigma); int idx = 10; Double plus = 0.0; plus = ((double)((int)(ucl - lcl + 1))) / 10; Double[] categories = new Double[idx]; Double[] values = new Double[idx]; categories[0] = lcl; for (int i = 1; i < idx; i++) { categories[i] = DoubleFormat(categories[i - 1] + plus); } for (int i = 0; i < idx; i++) { values[i] = 0.0; } for (int i = 1; i < categories.Length; i++) { values[i] = DoubleFormat(1 / ((Math.Sqrt(2 * Math.PI) * GetTotalStdDev(original))) * Math.Pow( Math.E, -Math.Pow((categories[i] - GetAverageValue(original)), 2) / (2 * Math .Pow(GetTotalStdDev(original), 2)))); } json.Add("categories", categories); json.Add("values", values); return json; } /// /// 获取组内正态分布曲线数组值 /// /// 望目 /// 原始数据 /// 返回组内正态分布曲线数组值 public static Dictionary GetInGroupNormalDistribution(Double target, Double[] original) { Dictionary json = new Dictionary(); Double sigma = GetTotalStdDev(original); Double lcl = DoubleFormat(target - 3 * sigma); Double ucl = DoubleFormat(target + 3 * sigma); int idx = 10; Double plus = 0.0; plus = ((double)((int)(ucl - lcl + 1))) / 10; Double[] categories = new Double[idx]; Double[] values = new Double[idx]; Double inGroupStdDev = GetInGroupStdDev(2, original); Double ave = GetAverageValue(original); categories[0] = lcl; for (int i = 1; i < idx; i++) { categories[i] = DoubleFormat(categories[i - 1] + plus); } for (int i = 0; i < idx; i++) { values[i] = 0.000000; } for (int i = 1; i < categories.Length; i++) { values[i] = DoubleFormat(1 / ((Math.Sqrt(2 * Math.PI) * inGroupStdDev)) * Math.Pow( Math.E, -Math.Pow((categories[i] - ave), 2) / (2 * Math.Pow(inGroupStdDev, 2)))); } json.Add("categories", categories); json.Add("values", values); return json; } /// /// 获取数据分布情况 /// /// 望目 /// 原始数据 /// 返回数据分布情况 public static Dictionary GetDataDistribution(Double target, Double[] original) { Dictionary json = new Dictionary(); Double sigma = GetTotalStdDev(original); Double lcl = DoubleFormat(target - 3 * sigma); Double ucl = DoubleFormat(target + 3 * sigma); int idx = 10; Double plus = 0.0; plus = ((double)((int)(ucl - lcl + 1))) / 10; Double[] categories = new Double[idx]; Double[] values = new Double[idx]; String[] test = new String[idx]; categories[0] = lcl; for (int i = 1; i < idx; i++) { categories[i] = DoubleFormat(categories[i - 1] + plus); } for (int i = 0; i < idx; i++) { values[i] = 0.0; test[i] = ""; } for (int i = 0; i < original.Length; i++) { for (int j = 0; j < categories.Length; j++) { if (categories[j] - 0.5 < original[i] && original[i] <= categories[j] + 0.5) { values[j] += 1; test[j] += original[i] + ","; } } } for (int i = 0; i < idx; i++) { values[i] = values[i] / 100; } json.Add("categories", categories); json.Add("values", values); return json; } /// /// 无偏移过程能力指数 /// /// 公差上限 /// 公差下限 /// 原始数据 /// 返回无偏移过程能力指数 public static Double GetPP(Double upperT, Double lowerT, Double[] original) { Double pp = new Double(); Double sigma = GetTotalStdDev(original); pp = (upperT - lowerT) / (6 * sigma); return DoubleFormat(pp); } /// /// 无偏移下单限过程能力指数 /// /// 公差下限 /// 原始数据 /// 返回无偏移下单限过程能力指数 public static Double GetPPL(Double lowerT, Double[] original) { Double ppl = new Double(); Double sigma = GetTotalStdDev(original); Double ave = GetAverageValue(original); ppl = (ave - lowerT) / (3 * sigma); return DoubleFormat(ppl); } /// /// 无偏移上单限过程能力指数 /// /// 公差上限 /// 原始数据 /// 返回无偏移上单限过程能力指数 public static Double GetPPU(Double upperT, Double[] original) { Double ppl = new Double(); Double sigma = GetTotalStdDev(original); Double ave = GetAverageValue(original); ppl = (upperT - ave) / (3 * sigma); return DoubleFormat(ppl); } /// /// 有偏移过程能力指数 /// /// 公差上限 /// 公差下限 /// 原始数据 /// 返回有偏移过程能力指数 public static Double getPPK(Double upperT, Double lowerT, Double[] original) { Double ppl = GetPPL(lowerT, original); Double ppu = GetPPU(upperT, original); return DoubleFormat(ppl > ppu ? ppu : ppl); } /// /// 无偏移短期过程能力指数 /// /// 公差上限 /// 公差下限 /// 原始数据 /// 返回无偏移短期过程能力指数 public static Double GetInGroupCP(Double upperT, Double lowerT, Double[] original) { Double cp = new Double(); Double sigma = GetInGroupStdDev(2, original); if (sigma == 0) { cp = 0; } else { cp = (upperT - lowerT) / (6 * sigma); } return DoubleFormat(cp); } /// /// 无偏移下单限短期过程能力指数 /// /// 公差下限 /// 原始数据 /// 返回无偏移下单限短期过程能力指数 public static Double GetInGroupCPL(Double lowerT, Double[] original) { Double cpl = new Double(); Double sigma = GetInGroupStdDev(2, original); if (sigma == 0) { return 0; } else { Double ave = GetAverageValue(original); cpl = (ave - lowerT) / (3 * sigma); return DoubleFormat(cpl); } } /// /// 无偏移上单限短期过程能力指数 /// /// 公差上限 /// 原始数据 /// 反回无偏移上单限短期过程能力指数 public static Double GetInGroupCPU(Double upperT, Double[] original) { Double cpu = new Double(); Double sigma = GetInGroupStdDev(2, original); if (sigma == 0) { return 0; } else { Double ave = GetAverageValue(original); cpu = (upperT - ave) / (3 * sigma); return DoubleFormat(cpu); } } /// /// 有偏移短期过程能力指数 /// /// 公差上限 /// 公差下限 /// 原始数据 /// 返回有偏移短期过程能力指数 public static Double GetInGroupCPK(Double upperT, Double lowerT, Double[] original) { Double cpl = GetInGroupCPL(lowerT, original); Double cpu = GetInGroupCPU(upperT, original); return DoubleFormat(cpl > cpu ? cpu : cpl); } /// /// 自然上限 /// /// 望目 /// 原始数据 /// 返回自然上限 public static Double GetUCL(Double target, Double[] original) { Double sigma = GetTotalStdDev(original); return DoubleFormat(target + 3 * sigma); } /// /// 自然下限 /// /// 望目 /// 原始数据 /// 返回自然下限 public static Double GetLCL(Double target, Double[] original) { Double sigma = GetTotalStdDev(original); return DoubleFormat(target - 3 * sigma); } /// /// 最小值 /// /// 原始数据数组 /// 返回最小值 public static Double GetArrMin(Double[] array) { Double min = array[0]; for (int i = 0; i < array.Length; i++) { if (min > array[i]) min = array[i]; } return min; } /// /// 最大值 /// /// 原始数据数组 /// 返回最大值 public static Double GetArrMax(Double[] array) { Double max = array[0]; for (int i = 0; i < array.Length; i++) { if (max < array[i]) max = array[i]; } return max; } /// /// 数据格式化,默认保留5位小数 /// /// 要格式化的数据 /// 返回格式化后的数据 public static Double DoubleFormat(Double d) { double result = 0.0; if (double.TryParse(d.ToString(), out result)) { Decimal b = new Decimal(d); Double formatD = Convert.ToDouble(Math.Round(b, 5)); //b.setScale(5, BigDecimal.ROUND_HALF_UP).doubleValue(); return formatD; } else { return 0.0; } } /// /// 按指定精度进行数据格式化 /// /// 精度,小数位数 /// 要格式化的数据 /// 返回格式化后的数据 public static Double DoubleFormat(int digits, Double d) { double result = 0.0; if (double.TryParse(d.ToString(), out result)) { Decimal b = new Decimal(d); Double formatD = Convert.ToDouble(Math.Round(b, digits)); //Double formatD = b.setScale(digits, BigDecimal.ROUND_HALF_UP).doubleValue(); return formatD; } else { return 0.0; } } } }