493 lines
15 KiB
C#
493 lines
15 KiB
C#
using JinYuan.Models;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
using System.Windows.Forms.DataVisualization.Charting;
|
|
using System.Windows.Markup;
|
|
|
|
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
|
|
}
|
|
}
|