Files
602_FD/LargeSquareOne/FrmCpkCount.cs
T

485 lines
15 KiB
C#
Raw Normal View History

2025-09-17 20:04:00 +08:00
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<double> 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<double> GetSPCData()
{
// 返回样本数据的List<double>
// 根据需要修改为实际的获取方法
return new List<double> { 1.2, 1.3, 1.0, 2.5, 2.2, 2.8, 0.8, 0.9, 1.1 };
}
/// <summary>
/// 对样本进行分组
/// </summary>
/// <param name="sampleData"></param>
/// <param name="groupSize"></param>
/// <returns></returns>
private List<List<double>> groupedData(List<double> sampleData, int groupSize = 3)
{
List<List<double>> groupedData = new List<List<double>>();
for (int i = 0; i < sampleData.Count; i += groupSize)
{
List<double> group = sampleData.Skip(i).Take(groupSize).ToList();
groupedData.Add(group);
}
return groupedData;
}
// 假设这是计算Xbar的方法
private double CalculateXbar(List<double> data)
{
// 根据输入的样本数据计算Xbar
// 根据需要修改为实际的计算方法
double sum = 0;
foreach (var value in data)
{
sum += value;
}
return sum / data.Count;
}
// 假设这是计算R的方法
private double CalculateR(List<double> 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<double> data = GetSPCData();
// 计算每个样本的均值和范围
List<double> sampleMeans = CalculateSampleMeans(groupedData(data));
List<double> 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<double> CalculateSampleMeans(List<List<double>> sampleData)
{
// 根据样本数据计算每个样本的均值,并返回一个包含所有样本均值的List<double>
// 根据实际的计算方法进行修改
List<double> sampleMeans = new List<double>();
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<double> CalculateSampleRanges(List<List<double>> sampleData)
{
// 根据样本数据计算每个样本的范围,并返回一个包含所有样本范围的List<double>
// 根据实际的计算方法进行修改
List<double> sampleRanges = new List<double>();
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<double> data = GetSPCData();
// 计算每个样本的均值和范围
List<double> sampleMeans = CalculateSampleMeans(groupedData(data));
List<double> 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;
}
/// <summary>
/// 根据样本大小选择合适的A2值
/// </summary>
/// <param name="sampleSize"></param>
/// <returns></returns>
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<double> data = GetSPCData();
// 计算每个样本的范围
List<double> 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<double> data = GetSPCData();
// 计算每个样本的范围
List<double> sampleRanges = CalculateSampleRanges(groupedData(data));
// 计算所有样本范围的平均值
R_bar = sampleRanges.Average();
// 计算LCL(R)
double LCL_R = D3 * R_bar;
return LCL_R;
}
/// <summary>
/// 根据样本大小选择合适的D3值
/// </summary>
/// <param name="sampleSize"></param>
/// <returns></returns>
///
///如果样本大小大于或等于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
}
}