가우스 분산(Gauss Distribution) 난수 발생

정규분포(Normal Distribution)이라고도 하는 이 정규분산을 이루는 난수 발생의 필요는 어떤 폴리곤 안에 무작위로 점을 찍어야할 경우에서이다.

처음의 접근은 단순히 폴리곤 안의 점을 무작위로 발생시켜 찍었으나, 폴리곤 안의 점들이 너무 고르게 분포되어져 있다는 문제점이 있었다. 폴리곤의 중심으로 점들이 몰리도록하는 방법이 무엇을까 생각해보니, 가우스분산을 이루도록 점들이 폴리곤안에 난수로 발생시키도록 하였다.

가우스분산을 이루는 난수발생…. 가우스분산이라는 정의를 곰곰이 들여다보면, 어떤 구간에서 그 구간의 중심점에 더 많은 빈도(가중치)가 몰린다는 것이다. 그렇다면 몇번의 난수를 발생시켜 그 평균을 구한다면, 그 값이 가우스분산을 이루는 난수가 아니겠는가?

아래는 이러한 생각에 의한 실제 구현된 코드이다.

double gaussDistributeRand(double begin, double end, size_t detail=5) {
    double r = 0;
    for(size_t i=0; i

인자 detail은 난수를 몇번 발생시켜 평균을 구할 것인가에 대한 것으로 이 값이 커질수록 난수발생값이 중심(평균)으로 집중하는 강도를 나타낸다.

실제로 위의 코드를 적용해서 detail을 1(가우스분산이 아닌 그냥 난수발생), 2, 4, 8, 20, 100으로 주었을때의 실행결과를 보면 아래와 같다.


이미 언급한것과 같이 결과에서도 알수있듯 detail값이 커질 수록 중심으로 난수발생값이 집중된다는 것을 알 수 있다.

아름다운 코드를 만나다!

ASP.NET의 코드 조각인데, 오늘 잔잔한 감동을 준 코드이다.

	TableCell td = new TableRow();
	td.Width = Unit.Pixel(300);

두번째 줄, td의 Width 속성값의 지정이 한번에 두가지 목적을 이뤄내고 있는게 아닌가! Table Cell의 폭(Width)에 대한 단위(Pixel Unit)와 실제값(300 Pixels). programming code는 절대로 Art 따위가 될 수 없다는게 나의 생각이지만.. 오늘 왠지 센치해져서 그런지… 요런 코드가 감동을 주네…. ㅜ_ㅜ

Windows Vista Architecture


클릭하여 확대해 보시길… 첨언하지면, 그림의 “Longhorn”은 잘못된 표기입니다. Longhorn은 Window Vista의 서버버전의 제품명으로 의미변경 되었다고합니다. 꽤 오래전에 인터넷 상에서 받아 보던 것으로 자료가 옛날것이긴 하지만, 명칭 이외의 부분에 대해서는 거의 틀린 부분이 없기 때문에 Vista의 전체적인 아키텍쳐 구성 요소가 어떻게 되는지를 살펴보기에 용이할 것 같습니다.http://www.gisdeveloper.co.kr/?p=209&preview=true

C++/CLI의 Dispose Pattern에 대한 고찰

리소스 해제를 위한 .NET 개발환경에서 제공하는 Dispose 패턴을 파악하기 위해 테스트용으로 적용할 클래스 정의는 다음과 같으며 총 세가지의 경우로 시험을 해보았다.

ref class T : public IDisposable {
public:
    T() {
        Console::WriteLine(L"T() invoked");
    }

    ~T() {
        Console::WriteLine(L"~T() invoked");
    }

    !T() {
        Console::WriteLine(L"!T() invoked");
    }
};

첫번째 시험 코드는 마치 지역변수처럼 할당하는 경우이다. 하지만 절대 지역 변수가 아니라는 점.. CLR Heap에 할당된다.

int main(array ^args)
{
    T a;
    return 0;
}

실행 결과는 다음과 같다. 지역변수처럼 변수의 유효 Scope를 벗어나는 순간 소멸자가 호출되었다. 실제 IL에 의해 구현된 내부 흐름은 소멸자 호출이 아니라 IDisposable::Dispose 매서드의 호출이다. 즉, 소멸자가 IDisposable::Dispose의 재구현이다. 또한 내부적으로 GC에 의해 호출되어져야했을 Finalize 매서드는 호출되지 않게 조치된다. C#과는 다르게 Finalize가 호출되지 않도록 자동화되었다는 점이 매우 특이하다.

T() invoked
~T() invoked

두번째 시험 코드는 C++에서는 포인터 개념으로 생각되는, 즉 C++/CLI는 Handle 개념으로 CLR의 Heap에 객체를 생성하였고 delete를 호출하지 않은 경우이다.

int main(array ^args)
{
    T ^a = gcnew T();
    return 0;
}

실행 결과는 다음과 같다. Finalize에 해당하는 !T()가 호출되었다는 점에 유의하자.

T() invoked
!T() invoked

세번째 시험 코드는 두번째와 다르게 delete 연산자를 적용해 주었다.

int main(array ^args)
{
    T ^a = gcnew T();
    delete a;
    return 0;
}

실행 결과는 다음과 같다. Finalize가 아닌 Dispose가 호출되었다.

T() invoked
~T() invoked

여기서 얻을 수 있는 가장 중요한 한가지 결론은 ~T()에 해당하는 Dispose()와 !T()에 해당하는 Finalize()의 코드는 절대로 같이 호출되지 않는다는 점이다. C++/CLI의 사용자가 .NET의 참조형 변수를 지역변수처럼 사용하든지, gcnew에 의해 할당하여 사용하든지.. 또한 사용한 후 delete를 했든지, 하지 않았든지 간에 ~T()와 !T() 둘중에 하나는 반드시 실행되다는 점이다. ~T()는 기존의 C++ 개념으로써 호출되며 !T()는 .NET의 GC에 의해 호출된다. 즉, 리소스 해제를 위한 코드는 ~T()와 !T()에 똑 같이 중복적으로 와야한다고 생각한다.