using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using System.Windows.Forms.DataVisualization.Charting; namespace LargeSquareOne { public partial class FrmCpkCount : Form { public FrmCpkCount() { InitializeComponent(); } #region 减少闪烁 protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; return cp; } } #endregion private void FrmCpkCount_Load(object sender, EventArgs e) { } private void btn_Add_Click(object sender, EventArgs e) { List data = GetSPCData(); // 计算Xbar和R double xbar = CalculateXbar(data); double r = CalculateR(data); // 计算控制限 double uclXbar = CalculateUCLXbar(data.Count); double lclXbar = CalculateLCLXbar(data.Count); double uclR = CalculateUCLR(data.Count); double lclR = CalculateLCLR(data.Count); // 清空图表 chartControl.Series.Clear(); double xmaxValue = Math.Max(xbar, Math.Max(uclXbar, uclR)); double xminValue = Math.Max(xbar, Math.Max(lclXbar, lclR)); chartControl.ChartAreas[0].AxisY.Maximum = xmaxValue + 2; chartControl.ChartAreas[0].AxisY.Minimum = xminValue + 2; //double rmaxValue = Math.Max(r, uclR); //double rminValue = Math.Max(r, lclR); //chartControl.ChartAreas[1].AxisY.Maximum = rmaxValue; //chartControl.ChartAreas[1].AxisY.Minimum = rminValue; // 绘制Xbar-R控制图 Series seriesXbar = new Series(); seriesXbar.ChartType = SeriesChartType.Line; seriesXbar.Name = "Xbar"; Series seriesR = new Series(); seriesR.ChartType = SeriesChartType.Line; seriesR.Name = "R"; // 添加数据点和控制限 chartControl.Series.Add(seriesXbar); chartControl.Series.Add(seriesR); for (int i = 0; i < data.Count; i++) { seriesXbar.Points.AddXY(i + 1, xbar); seriesR.Points.AddXY(i + 1, r); } } // 假设这是获取SPC数据的方法 private List GetSPCData() { // 返回样本数据的List // 根据需要修改为实际的获取方法 return new List { 1.2, 1.3, 1.0, 2.5, 2.2, 2.8, 0.8, 0.9, 1.1 }; } /// /// 对样本进行分组 /// /// /// /// private List> groupedData(List sampleData, int groupSize = 3) { List> groupedData = new List>(); for (int i = 0; i < sampleData.Count; i += groupSize) { List group = sampleData.Skip(i).Take(groupSize).ToList(); groupedData.Add(group); } return groupedData; } // 假设这是计算Xbar的方法 private double CalculateXbar(List data) { // 根据输入的样本数据计算Xbar // 根据需要修改为实际的计算方法 double sum = 0; foreach (var value in data) { sum += value; } return sum / data.Count; } // 假设这是计算R的方法 private double CalculateR(List data) { // 根据输入的样本数据计算R // 根据需要修改为实际的计算方法 double max = data[0]; double min = data[0]; foreach (var value in data) { if (value > max) max = value; if (value < min) min = value; } return max - min; } #region 根据样本大小计算UCL(Xbar) // 这是计算UCL(Xbar)的方法 private double CalculateUCLXbar(int sampleSize) { // 根据样本大小计算UCL(Xbar) // 根据需要修改为实际的计算方法 double Xbar_bar = 0; // 所有样本均值的平均值 double R_bar = 0; // 所有样本范围的平均值 double A2 = 0; // 控制系数 // 根据样本大小确定控制系数A2 if (sampleSize <= 25) { A2 = 0.577; } else if (sampleSize <= 100) { A2 = 0.425; } else if (sampleSize <= 500) { A2 = 0.372; } else { // 根据需要添加更多样本大小的控制系数A2 } //对样本进行分组 List data = GetSPCData(); // 计算每个样本的均值和范围 List sampleMeans = CalculateSampleMeans(groupedData(data)); List sampleRanges = CalculateSampleRanges(groupedData(data)); // 计算所有样本均值的平均值和所有样本范围的平均值 Xbar_bar = sampleMeans.Average(); R_bar = sampleRanges.Average(); // 计算UCL(Xbar) double UCL_Xbar = Xbar_bar + (A2 * R_bar); return UCL_Xbar; } // 根据需要实现计算样本均值的方法 private List CalculateSampleMeans(List> sampleData) { // 根据样本数据计算每个样本的均值,并返回一个包含所有样本均值的List // 根据实际的计算方法进行修改 List sampleMeans = new List(); foreach (var sample in sampleData) { double sum = 0; int count = sample.Count; foreach (var value in sample) { sum += value; } double mean = sum / count; sampleMeans.Add(mean); } return sampleMeans; } // 根据需要实现计算样本范围的方法 private List CalculateSampleRanges(List> sampleData) { // 根据样本数据计算每个样本的范围,并返回一个包含所有样本范围的List // 根据实际的计算方法进行修改 List sampleRanges = new List(); foreach (var sample in sampleData) { double min = sample.Min(); double max = sample.Max(); double range = max - min; sampleRanges.Add(range); } return sampleRanges; } #endregion #region 计算LCL(Xbar)的方法 private double CalculateLCLXbar(int sampleSize) { // 根据样本大小计算LCL(Xbar) // 根据需要修改为实际的计算方法 double Xbar_bar = 0; // 所有样本均值的平均值 double R_bar = 0; // 所有样本范围的平均值 double A2 = 0; // 控制系数 // 根据样本大小确定控制系数A2 if (sampleSize <= 25) { A2 = 0.577; } else if (sampleSize <= 100) { A2 = 0.425; } else if (sampleSize <= 500) { A2 = 0.372; } else { // 根据需要添加更多样本大小的控制系数A2 } //对样本进行分组 List data = GetSPCData(); // 计算每个样本的均值和范围 List sampleMeans = CalculateSampleMeans(groupedData(data)); List sampleRanges = CalculateSampleRanges(groupedData(data)); // 计算所有样本均值的平均值和所有样本范围的平均值 Xbar_bar = sampleMeans.Average(); R_bar = sampleRanges.Average(); // 计算LCL(Xbar) double LCL_Xbar = Xbar_bar - (A2 * R_bar); return LCL_Xbar; } /// /// 根据样本大小选择合适的A2值 /// /// /// private double GetA2(int sampleSize) { double A2 = 0; // 控制系数 // if (sampleSize == 2) { A2 = 1.880; } else if (sampleSize == 3) { A2 = 1.023; } else if (sampleSize == 4) { A2 = 0.729; } else if (sampleSize == 5) { A2 = 0.577; } else if (sampleSize == 6) { A2 = 0.483; } else if (sampleSize > 6) { A2 = 3 / Math.Sqrt(sampleSize); } else { // 根据需要添加更多样本大小的A2值 } return A2; } #endregion #region 计算UCL(R)的方法 // 假设这是计算UCL(R)的方法 private double CalculateUCLR(int sampleSize) { // 根据样本大小计算UCL(R) // 根据需要修改为实际的计算方法 double R_bar = 0; // 所有样本范围的平均值 double D4 = 0; // 控制系数 // 根据样本大小确定控制系数D4 D4 = GetD4(sampleSize); //对样本进行分组 List data = GetSPCData(); // 计算每个样本的范围 List sampleRanges = CalculateSampleRanges(groupedData(data)); // 计算所有样本范围的平均值 R_bar = sampleRanges.Average(); // 计算UCL(R) double UCL_R = D4 * R_bar; return UCL_R; } #region 控制系数D4计算 //如果样本大小大于或等于2,但小于等于8,那么D4的值为2.282。 //如果样本大小大于8,但小于等于10,那么D4的值为2.115。 //如果样本大小大于10,但小于等于15,那么D4的值为2.004。 //如果样本大小大于15,但小于等于20,那么D4的值为1.924。 //如果样本大小大于20,但小于等于25,那么D4的值为1.864。 //如果样本大小大于25,但小于等于30,那么D4的值为1.816。 //对于更大的样本大小,您可以在SPC的相关文献或标准表中查找合适的D4的值。 private double GetD4(int sampleSize) { double D4 = 0; // 控制系数 // 根据样本大小选择合适的D4值 if (sampleSize >= 2 && sampleSize <= 8) { D4 = 2.282; } else if (sampleSize > 8 && sampleSize <= 10) { D4 = 2.115; } else if (sampleSize > 10 && sampleSize <= 15) { D4 = 2.004; } else if (sampleSize > 15 && sampleSize <= 20) { D4 = 1.924; } else if (sampleSize > 20 && sampleSize <= 25) { D4 = 1.864; } else if (sampleSize > 25 && sampleSize <= 30) { D4 = 1.816; } else { // 对于更大的样本大小,根据需要添加更多D4的值 } return D4; } #endregion #endregion #region 计算LCL(R)的方法 private double CalculateLCLR(int sampleSize) { // 根据样本大小计算LCL(R) // 根据需要修改为实际的计算方法 double R_bar = 0; // 所有样本范围的平均值 double D3 = 0; // 控制系数 // 根据样本大小确定控制系数D3 D3 = GetD3(sampleSize); //对样本进行分组 List data = GetSPCData(); // 计算每个样本的范围 List sampleRanges = CalculateSampleRanges(groupedData(data)); // 计算所有样本范围的平均值 R_bar = sampleRanges.Average(); // 计算LCL(R) double LCL_R = D3 * R_bar; return LCL_R; } /// /// 根据样本大小选择合适的D3值 /// /// /// /// ///如果样本大小大于或等于2,但小于等于6,那么D3的值为0。 //如果样本大小为7,那么D3的值为0。 //如果样本大小大于7,但小于等于8,那么D3的值为0.076。 //如果样本大小大于8,但小于等于10,那么D3的值为0.136。 //如果样本大小大于10,但小于等于12,那么D3的值为0.184。 //如果样本大小大于12,但小于等于16,那么D3的值为0.223。 //如果样本大小大于16,但小于等于20,那么D3的值为0.251。 //如果样本大小大于20,但小于等于25,那么D3的值为0.277。 //对于更大的样本大小,您可以在SPC的相关文献或标准表中查找合适的D3的值。 private double GetD3(int sampleSize) { double D3 = 0; // 控制系数 if (sampleSize >= 2 && sampleSize <= 6) { D3 = 0; } else if (sampleSize == 7) { D3 = 0; } else if (sampleSize > 7 && sampleSize <= 8) { D3 = 0.076; } else if (sampleSize > 8 && sampleSize <= 10) { D3 = 0.136; } else if (sampleSize > 10 && sampleSize <= 12) { D3 = 0.184; } else if (sampleSize > 12 && sampleSize <= 16) { D3 = 0.223; } else if (sampleSize > 16 && sampleSize <= 20) { D3 = 0.251; } else if (sampleSize > 20 && sampleSize <= 25) { D3 = 0.277; } else { // 对于更大的样本大小,根据需要添加更多D3的值 } return D3; } #endregion } }