C#
偏差STDEV与CPK的计算
最近由于在做一个检测的项目,客户要求报
必须生成CPK
,以前对CPK一点概念都没有,经过查资料,做出CPK相关的函数.
根据百度百科:
标准偏差公式:S = Sqrt[(∑(xi-x拨)^2) /(N-1)]公式中∑代表总和,x拨代表x的均值,^2代表二次方,Sqrt代表平方根。
例:有一组数字分别是200、50、100、200,求它们的标准偏差。 x拨 = (200+50+100+200)/4 = 550/4 = 137.5 S^2 = [(200-137.5)^2+(50-137.5)^2+(100-137.5)^2+(200-137.5)^2]/(4-1) 标准偏差 S = Sqrt(S^2) STDEV基于样本估算标准偏差。标准偏差反映数值相对于平均值 (mean) 的离散程度。
其中:
Cpk:制程能力指标 要求1.33以上
Cp: 技术能力指标 要求1.0以上
k: 管理能力指标 要求0.25以下
Mean:平均值
s: 标准差,值越大,数据越散乱
USL:规格上限
LSL:规格下限
n: 数据数目(30~50)
下面是计算CPK会用到的类:
using System;
using System.Collections.Generic;
using System.Text;
namespace CPKClass
{
class ProCPK
{
public static float StDev(float[] arrData) //计算标准偏差
{
float xSum = 0F;
float xAvg = 0F;
float sSum = 0F;
float tmpStDev = 0F;
int arrNum = arrData.Length;
for (int i = 0; i < arrNum; i++)
{
xSum += arrData[i];
}
xAvg = xSum / arrNum;
for (int j = 0; j < arrNum; j++)
{
sSum += ((arrData[j] - xAvg) * (arrData[j] - xAvg));
}
tmpStDev = Convert.ToSingle(Math.Sqrt((sSum / (arrNum - 1))).ToString());
return tmpStDev;
}
public static float Cp(float UpperLimit, float LowerLimit, float StDev) /
{
float tmpV = 0F;
tmpV = UpperLimit - LowerLimit;
return Math.Abs(tmpV / (6 * StDev));
}
public static float Avage(float[] arrData)
{
float tmpSum = 0F;
for (int i = 0; i < arrData.Length; i++)
{
tmpSum += arrData[i];
}
return tmpSum / arrData.Length;
}
public static float Max(float[] arrData)
{
float tmpMax = 0;
for (int i = 0; i < arrData.Length; i++)
{
if (tmpMax < arrData[i])
{
tmpMax = arrData[i];
}
}
return tmpMax;
}
public static float Min(float[] arrData)
{
float tmpMin = arrData[0];
for (int i = 1; i < arrData.Length; i++)
{
if (tmpMin > arrData[i])
{
tmpMin = arrData[i];
}
}
return tmpMin;
}
public static float CpkU(float UpperLimit, float Avage, float StDev)
{
float tmpV = 0F;
tmpV = UpperLimit - Avage;
return tmpV / (3 * StDev);
}
public static float CpkL(float LowerLimit, float Avage, float StDev)
{
float tmpV = 0F;
tmpV = Avage - LowerLimit;
return tmpV / (3 * StDev);
}
public static float Cpk(float CpkU, float CpkL)
{
return Math.Abs(Math.Min(CpkU, CpkL));
}
private void button1_Click(object sender, EventArgs e)
{
float[] k = { 0.03F, 0.06F, 0.05F, 0.03F, 0.04F, 0.04F, 0.03F, 0.04F, 0.04F, 0.04F, 0.04F, 0.04F, 0.04F, 0.03F, 0.01F, 0.03F, 0.01F, 0.03F, 0.04F, 0.04F, 0.04F, 0.05F, 0.02F, 0.04F, 0.05F, 0.05F, 0.05F, 0.05F, 0.03F, 0.05F, 0.05F, 0.03F, 0.02F, 0.04F, 0.04F, 0.02F, 0.06F, 0.04F, 0.02F, 0.03F, 0.04F, 0.02F, 0.05F, 0.06F, 0.07F, 0.02F, 0.04F, 0.04F, 0.03F, 0.03F };
float Nomial = 0.05F;
float UpperLimit = 0.12F;
float LowerLimit =0F;
textBox1.Text = "检测点:" + k.Length.ToString()+"/r/n";
textBox1.Text += "Nominal:"+Nomial.ToString()+"/r/n";
textBox1.Text += "UpperLimit:"+UpperLimit.ToString("F2")+ "/r/n";
textBox1.Text += "LowerLimit:"+LowerLimit.ToString("F2") + "/r/n";
textBox1.Text += "Average:" + Avage(k).ToString("F3") + "/r/n";
textBox1.Text += "STD:" + StDev(k).ToString("F3") + "/r/n";
textBox1.Text += "Cp:" + Cp(UpperLimit, LowerLimit, StDev(k)).ToString("F3") + "/r/n";
textBox1.Text += "CpkU:" + CpkU(UpperLimit, Avage(k), StDev(k)).ToString("F3") + "/r/n";
textBox1.Text += "CpkL:" + CpkL(LowerLimit, Avage(k), StDev(k)).ToString("F3") + "/r/n";
textBox1.Text += "Cpk:" + Cpk(CpkU(UpperLimit, Avage(k), StDev(k)), CpkL(LowerLimit, Avage(k), StDev(k))).ToString("F3") + "/r/n";
textBox1.Text += "Min:" + Min(k).ToString("F3") + "/r/n";
textBox1.Text += "Max:" + Max(k).ToString("F3") + "/r/n";
}
}
}
由于本人是做机器视觉的,对工厂制程管控并不是很了解,上面公式是根据网上资料而写,难免有些疏漏或勘误(比如有些资料还有Ca的参数,有些并不用到Ca),如果有错,请与我联系。