You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

589 lines
21 KiB
C#

1 year ago
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Mesnac.Action.Feeding
{
// 摘要:
// 过程能力控制类
public class SixSigmaHelper
{
public static double d2 = 1.128;
public static double d3 = 1.693;
public static double d4 = 2.059;
public static double d5 = 2.326;
/// <summary>
/// 求和
/// </summary>
/// <param name="originalData">原始数据数组</param>
/// <returns></returns>
public static double GetSumValue(Double[] originalData)
{
Double sum = 0.0;
for (int i = 0; i < originalData.Length; i++)
{
sum = sum + originalData[i];
}
return DoubleFormat(sum);
}
/// <summary>
/// 求平均数
/// </summary>
/// <param name="originalData">原始数据数组</param>
/// <returns></returns>
public static Double GetAverageValue(Double[] originalData)
{
Double sum = 0.0;
Double ave = 0.0;
for (int i = 0; i < originalData.Length; i++)
{
sum = sum + originalData[i];
}
ave = sum / originalData.Length;
return DoubleFormat(ave);
}
/// <summary>
/// 按指定精度求平均值
/// </summary>
/// <param name="digits">精度,即保留的小数位数</param>
/// <param name="originalData"原始数据></param>
/// <returns></returns>
public static Double GetAverageValue(int digits, Double[] originalData)
{
Double sum = 0.0;
Double ave = 0.0;
for (int i = 0; i < originalData.Length; i++)
{
sum = sum + originalData[i];
}
ave = sum / originalData.Length;
return DoubleFormat(digits, ave);
}
/// <summary>
/// 获取整体平均值:先分组,计算组内平均值,然后计算整体平均值
/// </summary>
/// <param name="digits">精度,小数位数</param>
/// <param name="groupSize">组大小</param>
/// <param name="originalData"> 原始数据</param>
/// <returns></returns>
public static Double GetTotalAveByGroup(int digits, int groupSize, Double[] originalData)
{
Double[] groupAve = GetGroupAve(digits, groupSize, originalData);
return SixSigmaHelper.GetAverageValue(digits, groupAve);
}
/// <summary>
/// 获取子组平均数,以数组形式返回
/// </summary>
/// <param name="digits">精度,小数位数</param>
/// <param name="groupSize">组大小</param>
/// <param name="originalData">原始数据</param>
/// <returns>返回子组平均值</returns>
public static Double[] GetGroupAve(int digits, int groupSize, Double[] originalData)
{
Double groupNum = Math.Ceiling(Convert.ToDouble(originalData.Length / groupSize));
Double[] groupAve = new Double[Convert.ToInt32(groupNum)];
for (int i = 0; i < Convert.ToInt32(groupNum); i++)
{
int index = i * groupSize;
Double[] temp = new Double[groupSize];
for (int j = 0; j < groupSize; j++)
{
temp[j] = originalData[index + j];
}
groupAve[i] = SixSigmaHelper.GetAverageValue(digits, temp);
}
return groupAve;
}
/// <summary>
/// 求整体标准差
/// </summary>
/// <param name="originalData">原始数据</param>
/// <returns>返回标准差</returns>
public static Double GetTotalStdDev(Double[] originalData)
{
Double ave = 0.0;
Double stdDev = 0.0;
if (originalData.Length == 1 && originalData[0] == 0.0)
{
return stdDev = 0.0;
}
ave = GetAverageValue(originalData);
for (int i = 0; i < originalData.Length; i++)
{
stdDev = (Double)(stdDev + Math.Pow((originalData[i] - ave), 2));
}
stdDev = (Double)Math.Sqrt(stdDev / (originalData.Length - 1));
return DoubleFormat(stdDev);
}
/// <summary>
/// 按指定精度获取标准差
/// </summary>
/// <param name="digits">精度,即小数位数</param>
/// <param name="originalData">原始数据</param>
/// <returns>返回标准差</returns>
public static Double GetStdDev(int digits, Double[] originalData)
{
Double ave = 0.0;
Double stdDev = 0.0;
ave = GetAverageValue(originalData);
for (int i = 0; i < originalData.Length; i++)
{
stdDev = (Double)(stdDev + Math.Pow((originalData[i] - ave), 2));
}
stdDev = (Double)Math.Sqrt(stdDev / (originalData.Length - 1));
return DoubleFormat(digits, stdDev);
}
/// <summary>
/// 求移动极差均值
/// </summary>
/// <param name="size">子组容量</param>
/// <param name="originalData">原始数据</param>
/// <returns>返回移动极差均值</returns>
public static Double GetMoveRangeMean(int size, Double[] originalData)
{
Double moveSum = 0.0;
Double moveAve = 0.0;
Double[] range = new Double[originalData.Length - (size - 1)];
for (int i = (size - 1); i < originalData.Length; i++)
{
Double[] temp = new Double[size];
int count = size;
int idx = 0;
do
{
temp[idx] = originalData[i - (count - 1)];
idx++;
count--;
} while ((count > 0));
range[i - (size - 1)] = (Double)Math.Abs(GetArrMax(temp) - GetArrMin(temp));
}
for (int i = 0; i < range.Length; i++)
{
moveSum = moveSum + range[i];
}
moveAve = moveSum / range.Length;
return DoubleFormat(moveAve);
}
/// <summary>
/// 求组内标准差
/// </summary>
/// <param name="size">子组容量</param>
/// <param name="originalData">原始数据</param>
/// <returns>返回组内标准差</returns>
public static Double GetInGroupStdDev(int size, Double[] originalData)
{
Double gourpStdDev = 0.0;
Double moveAve = GetMoveRangeMean(size, originalData);
switch (size)
{
case 2:
gourpStdDev = (Double)(moveAve / d2);
break;
case 3:
gourpStdDev = (Double)(moveAve / d3);
break;
case 4:
gourpStdDev = (Double)(moveAve / d4);
break;
case 5:
gourpStdDev = (Double)(moveAve / d5);
break;
default:
gourpStdDev = (Double)(moveAve / d2);
break;
}
return DoubleFormat(gourpStdDev);
}
/// <summary>
/// 获取整体正态分布曲线数组值
/// </summary>
/// <param name="target">望目</param>
/// <param name="original">原始数据</param>
/// <returns>返回整体正态分布曲线数组值</returns>
public static Dictionary<String, Object> GetNormalDistribution(Double target, Double[] original)
{
Dictionary<String, Object> json = new Dictionary<String, Object>();
Double sigma = GetTotalStdDev(original);
Double lcl = DoubleFormat(target - 3 * sigma);
Double ucl = DoubleFormat(target + 3 * sigma);
int idx = 10;
Double plus = 0.0;
plus = ((double)((int)(ucl - lcl + 1))) / 10;
Double[] categories = new Double[idx];
Double[] values = new Double[idx];
categories[0] = lcl;
for (int i = 1; i < idx; i++)
{
categories[i] = DoubleFormat(categories[i - 1] + plus);
}
for (int i = 0; i < idx; i++)
{
values[i] = 0.0;
}
for (int i = 1; i < categories.Length; i++)
{
values[i] = DoubleFormat(1
/ ((Math.Sqrt(2 * Math.PI) * GetTotalStdDev(original)))
* Math.Pow(
Math.E,
-Math.Pow((categories[i] - GetAverageValue(original)), 2)
/ (2 * Math
.Pow(GetTotalStdDev(original), 2))));
}
json.Add("categories", categories);
json.Add("values", values);
return json;
}
/// <summary>
/// 获取组内正态分布曲线数组值
/// </summary>
/// <param name="target">望目</param>
/// <param name="original">原始数据</param>
/// <returns>返回组内正态分布曲线数组值</returns>
public static Dictionary<String, Object> GetInGroupNormalDistribution(Double target, Double[] original)
{
Dictionary<String, Object> json = new Dictionary<String, Object>();
Double sigma = GetTotalStdDev(original);
Double lcl = DoubleFormat(target - 3 * sigma);
Double ucl = DoubleFormat(target + 3 * sigma);
int idx = 10;
Double plus = 0.0;
plus = ((double)((int)(ucl - lcl + 1))) / 10;
Double[] categories = new Double[idx];
Double[] values = new Double[idx];
Double inGroupStdDev = GetInGroupStdDev(2, original);
Double ave = GetAverageValue(original);
categories[0] = lcl;
for (int i = 1; i < idx; i++)
{
categories[i] = DoubleFormat(categories[i - 1] + plus);
}
for (int i = 0; i < idx; i++)
{
values[i] = 0.000000;
}
for (int i = 1; i < categories.Length; i++)
{
values[i] = DoubleFormat(1
/ ((Math.Sqrt(2 * Math.PI) * inGroupStdDev))
* Math.Pow(
Math.E,
-Math.Pow((categories[i] - ave), 2)
/ (2 * Math.Pow(inGroupStdDev, 2))));
}
json.Add("categories", categories);
json.Add("values", values);
return json;
}
/// <summary>
/// 获取数据分布情况
/// </summary>
/// <param name="target">望目</param>
/// <param name="original">原始数据</param>
/// <returns>返回数据分布情况</returns>
public static Dictionary<String, Object> GetDataDistribution(Double target, Double[] original)
{
Dictionary<String, Object> json = new Dictionary<String, Object>();
Double sigma = GetTotalStdDev(original);
Double lcl = DoubleFormat(target - 3 * sigma);
Double ucl = DoubleFormat(target + 3 * sigma);
int idx = 10;
Double plus = 0.0;
plus = ((double)((int)(ucl - lcl + 1))) / 10;
Double[] categories = new Double[idx];
Double[] values = new Double[idx];
String[] test = new String[idx];
categories[0] = lcl;
for (int i = 1; i < idx; i++)
{
categories[i] = DoubleFormat(categories[i - 1] + plus);
}
for (int i = 0; i < idx; i++)
{
values[i] = 0.0;
test[i] = "";
}
for (int i = 0; i < original.Length; i++)
{
for (int j = 0; j < categories.Length; j++)
{
if (categories[j] - 0.5 < original[i] && original[i] <= categories[j] + 0.5)
{
values[j] += 1;
test[j] += original[i] + ",";
}
}
}
for (int i = 0; i < idx; i++)
{
values[i] = values[i] / 100;
}
json.Add("categories", categories);
json.Add("values", values);
return json;
}
/// <summary>
/// 无偏移过程能力指数
/// </summary>
/// <param name="upperT">公差上限</param>
/// <param name="lowerT">公差下限</param>
/// <param name="original">原始数据</param>
/// <returns>返回无偏移过程能力指数</returns>
public static Double GetPP(Double upperT, Double lowerT, Double[] original)
{
Double pp = new Double();
Double sigma = GetTotalStdDev(original);
pp = (upperT - lowerT) / (6 * sigma);
return DoubleFormat(pp);
}
/// <summary>
/// 无偏移下单限过程能力指数
/// </summary>
/// <param name="lowerT">公差下限</param>
/// <param name="original">原始数据</param>
/// <returns>返回无偏移下单限过程能力指数</returns>
public static Double GetPPL(Double lowerT, Double[] original)
{
Double ppl = new Double();
Double sigma = GetTotalStdDev(original);
Double ave = GetAverageValue(original);
ppl = (ave - lowerT) / (3 * sigma);
return DoubleFormat(ppl);
}
/// <summary>
/// 无偏移上单限过程能力指数
/// </summary>
/// <param name="upperT">公差上限</param>
/// <param name="original">原始数据</param>
/// <returns>返回无偏移上单限过程能力指数</returns>
public static Double GetPPU(Double upperT, Double[] original)
{
Double ppl = new Double();
Double sigma = GetTotalStdDev(original);
Double ave = GetAverageValue(original);
ppl = (upperT - ave) / (3 * sigma);
return DoubleFormat(ppl);
}
/// <summary>
/// 有偏移过程能力指数
/// </summary>
/// <param name="upperT">公差上限</param>
/// <param name="lowerT">公差下限</param>
/// <param name="original">原始数据</param>
/// <returns>返回有偏移过程能力指数</returns>
public static Double getPPK(Double upperT, Double lowerT, Double[] original)
{
Double ppl = GetPPL(lowerT, original);
Double ppu = GetPPU(upperT, original);
return DoubleFormat(ppl > ppu ? ppu : ppl);
}
/// <summary>
/// 无偏移短期过程能力指数
/// </summary>
/// <param name="upperT">公差上限</param>
/// <param name="lowerT">公差下限</param>
/// <param name="original">原始数据</param>
/// <returns>返回无偏移短期过程能力指数</returns>
public static Double GetInGroupCP(Double upperT, Double lowerT, Double[] original)
{
Double cp = new Double();
Double sigma = GetInGroupStdDev(2, original);
if (sigma == 0)
{
cp = 0;
}
else
{
cp = (upperT - lowerT) / (6 * sigma);
}
return DoubleFormat(cp);
}
/// <summary>
/// 无偏移下单限短期过程能力指数
/// </summary>
/// <param name="lowerT">公差下限</param>
/// <param name="original">原始数据</param>
/// <returns>返回无偏移下单限短期过程能力指数</returns>
public static Double GetInGroupCPL(Double lowerT, Double[] original)
{
Double cpl = new Double();
Double sigma = GetInGroupStdDev(2, original);
if (sigma == 0)
{
return 0;
}
else
{
Double ave = GetAverageValue(original);
cpl = (ave - lowerT) / (3 * sigma);
return DoubleFormat(cpl);
}
}
/// <summary>
/// 无偏移上单限短期过程能力指数
/// </summary>
/// <param name="upperT">公差上限</param>
/// <param name="original">原始数据</param>
/// <returns>反回无偏移上单限短期过程能力指数</returns>
public static Double GetInGroupCPU(Double upperT, Double[] original)
{
Double cpu = new Double();
Double sigma = GetInGroupStdDev(2, original);
if (sigma == 0)
{
return 0;
}
else
{
Double ave = GetAverageValue(original);
cpu = (upperT - ave) / (3 * sigma);
return DoubleFormat(cpu);
}
}
/// <summary>
/// 有偏移短期过程能力指数
/// </summary>
/// <param name="upperT">公差上限</param>
/// <param name="lowerT">公差下限</param>
/// <param name="original">原始数据</param>
/// <returns>返回有偏移短期过程能力指数</returns>
public static Double GetInGroupCPK(Double upperT, Double lowerT, Double[] original)
{
Double cpl = GetInGroupCPL(lowerT, original);
Double cpu = GetInGroupCPU(upperT, original);
return DoubleFormat(cpl > cpu ? cpu : cpl);
}
/// <summary>
/// 自然上限
/// </summary>
/// <param name="target">望目</param>
/// <param name="original">原始数据</param>
/// <returns>返回自然上限</returns>
public static Double GetUCL(Double target, Double[] original)
{
Double sigma = GetTotalStdDev(original);
return DoubleFormat(target + 3 * sigma);
}
/// <summary>
/// 自然下限
/// </summary>
/// <param name="target">望目</param>
/// <param name="original">原始数据</param>
/// <returns>返回自然下限</returns>
public static Double GetLCL(Double target, Double[] original)
{
Double sigma = GetTotalStdDev(original);
return DoubleFormat(target - 3 * sigma);
}
/// <summary>
/// 最小值
/// </summary>
/// <param name="array">原始数据数组</param>
/// <returns>返回最小值</returns>
public static Double GetArrMin(Double[] array)
{
Double min = array[0];
for (int i = 0; i < array.Length; i++)
{
if (min > array[i])
min = array[i];
}
return min;
}
/// <summary>
/// 最大值
/// </summary>
/// <param name="array">原始数据数组</param>
/// <returns>返回最大值</returns>
public static Double GetArrMax(Double[] array)
{
Double max = array[0];
for (int i = 0; i < array.Length; i++)
{
if (max < array[i])
max = array[i];
}
return max;
}
/// <summary>
/// 数据格式化默认保留5位小数
/// </summary>
/// <param name="d">要格式化的数据</param>
/// <returns>返回格式化后的数据</returns>
public static Double DoubleFormat(Double d)
{
double result = 0.0;
if (double.TryParse(d.ToString(), out result))
{
Decimal b = new Decimal(d);
Double formatD = Convert.ToDouble(Math.Round(b, 5));
//b.setScale(5, BigDecimal.ROUND_HALF_UP).doubleValue();
return formatD;
}
else
{
return 0.0;
}
}
/// <summary>
/// 按指定精度进行数据格式化
/// </summary>
/// <param name="digits">精度,小数位数</param>
/// <param name="d">要格式化的数据</param>
/// <returns>返回格式化后的数据</returns>
public static Double DoubleFormat(int digits, Double d)
{
double result = 0.0;
if (double.TryParse(d.ToString(), out result))
{
Decimal b = new Decimal(d);
Double formatD = Convert.ToDouble(Math.Round(b, digits));
//Double formatD = b.setScale(digits, BigDecimal.ROUND_HALF_UP).doubleValue();
return formatD;
}
else
{
return 0.0;
}
}
}
}