2014년 7월 16일

프로세스 공정 능력 계산

어떤 기계장치의 계측값 내지는 측정되는 데이타를 축적하여 이를 분석하여 공정능력 (cp : capability of process) 이란 값을 산출할수 있다. 이 값은 결국 불량율 즉 수율(yield)등으로 환산할수도 있다.

관련링크 :
http://en.wikipedia.org/wiki/Process_capability_index
http://www.itl.nist.gov/div898/handbook/pmc/section1/pmc16.htm

링크에는 자세한 수식이 나와있으니 이를 기반으로 계산을 하여도 된다. Cpk 가 의미하는 바를 그래프로 보면 아래와 같다.



어쨋든 이 공정능력을 계산해주는 프로그램을 만든다면 다음과 같을 것이다.



이를 구현한 클래스를 소개하는 선에서 설명을 마치고자 한다.


---------------------------------- procap.h --------------------------------------
#ifndef procapH
#define procapH

///
/// copyright to sepwind@gmail.com (http://sepwind.blogspot.com)
///

#include <windows.h>
#include <vector>


class ProcessCapabilityPimpl;
class ProcessCapability
{
public:
 int   size();
    void  clear();
    void  reserve(int count);
    void  push_back(double sample);
    double&  operator[](int index);
 double  mean();
    double  stddev();
    double  solveCp(double lower, double upper);
    double  solveCpk(double lower, double upper);

protected:
    ProcessCapabilityPimpl*  _pPimpl;

public:
 ProcessCapability();
    virtual ~ProcessCapability();
};


#endif

---------------------------------- procap.cpp------------------------------------
#include "procap.h"
#include <cassert>
#include <math.h>

///
/// copyright to sepwind@gmail.com (http://sepwind.blogspot.com)
///

class ProcessCapabilityPimpl
{
public:
 std::vector<double> samples;

    ProcessCapabilityPimpl()
    {}
    ~ProcessCapabilityPimpl()
    {}
};

// ----------------

ProcessCapability::ProcessCapability()
{
 _pPimpl = new ProcessCapabilityPimpl;
}


ProcessCapability::~ProcessCapability()
{
 delete _pPimpl;
    _pPimpl = NULL;
}

int ProcessCapability::size()
{
 return _pPimpl->samples.size();
}

void ProcessCapability::clear()
{
 _pPimpl->samples.clear();
}

void ProcessCapability::reserve(int count)
{
 _pPimpl->samples.reserve(count);
}

void ProcessCapability::push_back(double sample)
{
 _pPimpl->samples.push_back(sample);
}

double& ProcessCapability::operator[](int index)
{
 return _pPimpl->samples[index];
}

double ProcessCapability::mean()
{
 double sum(0.0);
    std::vector<double>::iterator it;
 for(it = _pPimpl->samples.begin(); it != _pPimpl->samples.end(); it++)
    {
  sum += *it;
    }

    return sum / (double)this->size();
}

double ProcessCapability::stddev()
{
 /// sigma

 double m = this->mean();
    int n = this->size();
    double sum(0.0);

    std::vector<double>::iterator it;
 for(it = _pPimpl->samples.begin(); it != _pPimpl->samples.end(); it++)
    {
     sum += pow(*it - m, 2);
    }

    return sqrt(sum / (double)n);
}

double ProcessCapability::solveCp(double lower, double upper)
{
 assert(lower < upper);

 double cp(0.0);
    cp = (upper - lower) / (6.0 * this->stddev() );
    return cp;
}

double ProcessCapability::solveCpk(double lower, double upper)
{
 assert(lower < upper);

 double cpk(0.0);
    double m = this->mean();
    double σ = this->stddev();

    cpk = std::min<double>( \
     (upper - m) / (3.0*σ),
        (m - lower) / (3.0*σ)
        );

    return cpk;
}


원리는 링크에 나온 수식을 구현하여 매우 간단하며, solve cp, solve cpk 함수의 구현부를 참고.

댓글 1개:

  1. 좋은글 잘보고 갑니다. 작성하시는 내용들이 대부분 제가 일하는 업종이랑 유사하네요..^^ 앞으로 자주 뵐께요~~

    답글삭제

시리우스 라이브러리 홈페이지 오픈

현재 시리우스(Sirius) 라이브러리라는 제품을 개발하고 이를 소개하는 홈페이지를 오픈 하였습니다. 관심있는 분들의 많은 방문 요청드립니다. 앞으로 업데이트 소식및 변경사항은 스파이럴랩 홈페이지를 통해 진행할 예정입니다. 스파이럴랩 홈페이지 :  h...