175 lines
5.2 KiB
C#
175 lines
5.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace DAL
|
|
{
|
|
public static class CpCpkHelper
|
|
{
|
|
public static int SubGroup { get; set; } = 5;
|
|
public static double d2 { get; set; } = 2.326;
|
|
public static double D4 { get; set; } = 2.114;
|
|
public static double A2 { get; set; } = 0.577;
|
|
public static double D3 { get; set; } = 0;
|
|
public static double B3 { get; set; } = 0;
|
|
public static double B4 { get; set; } = 1.964;
|
|
|
|
/// <summary>
|
|
/// 获取List数组的平均值
|
|
/// </summary>
|
|
/// <param name="data">list string 数组</param>
|
|
/// <returns>数组平均值</returns>
|
|
public static double GetAverage(List<string> data)
|
|
{
|
|
List<double> dataDouble = data.Select(double.Parse).ToList();
|
|
double sum = dataDouble.Sum();
|
|
double average = sum / dataDouble.Count;
|
|
return average;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取标准差(此处是样本标准差 除以样本的个数-1)
|
|
/// </summary>
|
|
/// <param name="data">list string 数组</param>
|
|
/// <returns>数组标准差</returns>
|
|
public static double GetSigma(List<string> data)
|
|
{
|
|
List<double> dataDouble = data.Select(double.Parse).ToList();
|
|
double dAverage = dataDouble.Average();
|
|
double sumOfSquaredDifferences = dataDouble.Sum(x => Math.Pow(x - dAverage, 2));
|
|
double standardDeviation = Math.Sqrt(sumOfSquaredDifferences / (dataDouble.Count - 1));
|
|
return standardDeviation;
|
|
}
|
|
|
|
//计算R_(横线实际在上方)S_(子组极差平均值和子组标准差平均值)
|
|
public static List<double> GetR_S_(List<string> data)
|
|
{
|
|
//丢弃最后无法满足子组内测量值个数的子组
|
|
int abandon = data.Count() % SubGroup;
|
|
data.RemoveRange(data.Count() - abandon, abandon);
|
|
|
|
List<double> numericData = data.Select(double.Parse).ToList(); // 将数据转换为double类型
|
|
List<double> R_List = new List<double>();
|
|
List<double> S_List = new List<double>();
|
|
List<double> R_S_List = new List<double>();
|
|
|
|
//计算每个子组的极差和标准差
|
|
for (int i = 0; i <= numericData.Count() / SubGroup - 1; i++)
|
|
{
|
|
List<double> group = numericData.GetRange(SubGroup * i, SubGroup);
|
|
R_List.Add(group.Max() - group.Min());
|
|
S_List.Add(GetSigma(data.GetRange(SubGroup * i, SubGroup)));
|
|
}
|
|
R_S_List.Add(R_List.Average());
|
|
R_S_List.Add(S_List.Average());
|
|
|
|
return R_S_List;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取Cp相关数值
|
|
/// </summary>
|
|
/// <param name="data">测量数组</param>
|
|
/// <param name="USL">测量上限值</param>
|
|
/// <param name="LSL">测量下限值</param>
|
|
/// <returns></returns>
|
|
public static List<double> GetCpList(List<string> data, double USL, double LSL)
|
|
{
|
|
List<double> R_S_ = GetR_S_(data);
|
|
double sigma = R_S_[0] / d2;
|
|
double Cp = (USL - LSL) / (6 * sigma);
|
|
double average = GetAverage(data);
|
|
double Cp_l = (USL - average) / (3 * sigma);
|
|
double Cp_u = (average - LSL) / (3 * sigma);
|
|
double Cp_k = Math.Min(Cp_l, Cp_u);
|
|
return new List<double> { Cp, Cp_l, Cp_u, Cp_k };
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取Pp相关数值
|
|
/// </summary>
|
|
/// <param name="data">测量数组</param>
|
|
/// <param name="USL">测量上限值</param>
|
|
/// <param name="LSL">测量下限值</param>
|
|
/// <returns></returns>
|
|
public static List<double> GetPpList(List<string> data, double USL, double LSL)
|
|
{
|
|
int abandon = data.Count() % SubGroup;
|
|
data.RemoveRange(data.Count() - abandon, abandon);
|
|
double s = GetSigma(data);
|
|
double average = GetAverage(data);
|
|
double Pp = (USL - LSL) / (6 * s);
|
|
double Pp_u = (USL - average) / (3 * s);
|
|
double Pp_l = (average - LSL) / (3 * s);
|
|
double Pp_k = Math.Min(Pp_l, Pp_u);
|
|
return new List<double> { Pp, Pp_l, Pp_u, Pp_k };
|
|
}
|
|
|
|
/// <summary>
|
|
/// 计算CPCPK柱状图
|
|
/// </summary>
|
|
/// <param name="data"></param>
|
|
/// <returns></returns>
|
|
public static Dictionary<string, string> GetHistogramData(List<double> data)
|
|
{
|
|
if (data.Count == 0) return new Dictionary<string, string>();
|
|
|
|
// 计算合适的区间个数和区间宽度
|
|
var n_bins = (int)Math.Sqrt(data.Count());
|
|
var bin_width = (data.Max() - data.Min()) / n_bins;
|
|
|
|
//计算每个区间的数量,存在List中
|
|
List<int> countsList = new List<int>();
|
|
for (int i = 0; i <= n_bins - 1; i++)
|
|
{
|
|
countsList.Add(0);
|
|
}
|
|
for (int i = 0; i <= data.Count() - 1; i++)
|
|
{
|
|
if (bin_width == 0)
|
|
{
|
|
countsList[0] = countsList[0] + 1;
|
|
}
|
|
else
|
|
{
|
|
int groupIndex = (int)Math.Floor((data[i] - data.Min()) / bin_width);
|
|
if (groupIndex == n_bins)
|
|
{
|
|
groupIndex--;
|
|
}
|
|
countsList[groupIndex] = countsList[groupIndex] + 1;
|
|
}
|
|
}
|
|
//计算范围
|
|
List<string> rangeList = new List<string>();
|
|
if (bin_width == 0)
|
|
{
|
|
string rangeStr = (data.Min()) + "-" + (data.Min());
|
|
rangeList.Add(rangeStr);
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i <= n_bins - 1; i++)
|
|
{
|
|
string rangeStr = (i * bin_width + data.Min()) + "-" + ((i + 1) * bin_width + data.Min());
|
|
rangeList.Add(rangeStr);
|
|
}
|
|
}
|
|
|
|
Dictionary<string, string> result = new Dictionary<string, string>();
|
|
if (bin_width == 0)
|
|
{
|
|
result.Add(rangeList[0], countsList[0].ToString());
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i <= n_bins - 1; i++)
|
|
{
|
|
result.Add(rangeList[i], countsList[i].ToString());
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|
|
} |