동적계획으로 구현을 위해서는 동적계획 부터 알고 넘어가야겠다. 동적 계획이란...
알고리즘 구현방법 중의 하나로 문제를 해결함에 있어서 기존에 계산된 결과가 있다면 그것을 사용하여 수행 시간을 단축 시키는 방법이다.
그럼 이 동적계획법을 사용하여 TSP를 구현함에 있어서의 기존에 구해진 재귀관계식 부터 살펴보자..맨땅에 헤딩 할 순 없으니깐;;;;;;ㅋ

사용자 삽입 이미지

위의 식에서 D[V1][V-{V1}] 이라는 배열이 바로 동적계획에 사용될 최소 여행 경로의 거리를 저장할 배열이다. 그리고 W[i][j]배열이 정점 i에서 j로 가는 간선의 가중치를 담을 배열이다.
위의 식을 일반화 해서 i<>1 이고 Vi가 A에 속하지 않을때라 하면 아래와 같이 된다라고 하는....

사용자 삽입 이미지

위 수식을 얻는 과정은 알고리즘 책을 봐야겠다...;
.
.
그럼 위의 주어진 재귀식을 통해 프로그램으로 승화 시켜보자~! ㅡ_ㅡ+

일단 필요한 배열들... 동적계획을 위해 계산된 결과를 저장할 이차원 배열 D[][]와 간선들의 가중치를 저장할 배열 W[][]가 있어야겠다. 그럼 여기서 문제되는게 A로 표기된 'V-{vi}' 요녀석을 어떻게 표현 할껀지가 이번 동적계획의 핵심이 되겠다.
검색을 좀 해보게되면 배열(?) 또는 리스트로 담는다는 분들도 있고, bit로 해서 표현한다는 분들도 있는데.. 난  bit로 하기로 결정!
bit로 하게 되었을때 간단히 보면 v1,v2,v3,v4가 있을 때 v1,v2가 포함되어 있다면 0011로 표시될수 있다. 흠 이렇게 하면 이해가 잘 되지 않지만 아래를 보면
 


V4

V3

V2

V1

십진수

모든 정점이 포함되지 않음

0

0

0

0

0

정점 V1이 포함

0

0

0

1

1

정점 V2가 포함

0

0

1

0

2

이렇게 표로 나타내보면 이해가 쉬울 것이다. 하지만 이방법에도 불필요한 메모리 공간을 사용한다는 문제점이 존재하고 이문제가 TSP를 해결하는데 정점의 수가 제한되게 된다.
이제 본격적으로 코드를 살표보기로 하자!


Posted by hazeyun
,

TSP란 Traveling Salesman Problem으로 외판원 문제로 많이 알려져있다.
wiki백과를 찾아보면
외판원 문제(Traveling salesperson problem) 또는 순회 외판원 문제는 조합 최적화 문제의 일종이다. 줄여서 TSP라고도 쓴다. 이 문제는 NP-난해에 속하며, 흔히 계산 복잡도 이론에서 해를 구하기 어려운 문제의 대표적인 예로 많이 다룬다.
라고 어렵게 적혀있다ㅡ_ㅡ;
간단히 적어보면 그래프로 설명하면 되는데 아래와 같은 그래프가 있을때 각각의 정점을 있는 간선에는 가중치가 주어져 있다. 이 그래프에서 정점 v1에서 모든 정점을 거쳐 v1으로 다시 돌아 오기까지거치 간선들의 가중치가 최소가 되도록 하는 경로를 구하는 문제다. 이렇게 적고보니 별거 아닌거 같기도ㅋ

사용자 삽입 이미지
그럼 이제 이녀석을 동적계획법, 깊이우선탐색법, 최상우선탐색으로 정복해보자!


 

Posted by hazeyun
,

이번 네트워크 프로그래밍 과제로 선정된 snmp ! 그것도 snmp manager만들기!;;;
이때 까진 ftp 잘 해나가다가 왜 갑자기 바꾸냔 말이다 ㅡ_ㅡ+ 자료도 없는걸..ㅋ
.
.
SNMP란 Simple Network Management Protocol의 약자로 해석 그대로 간단한 네트워크 관리 프로토콜이다. 이렇게 듣고는 잘 이해가 안간다. 그래서 이놈을 자세히 일단 이놈은  TCP/IP의 응용계층 프로토콜로 디자인 되었고, 전송계층의 프로토콜로는 UDP를 사용한다. 이점이 좀 중요한듯!
아래 그림을 보면(ppt에서 훔쳐 왔음ㅋㅋ) snmp의 구성을 알수가 있다.

사용자 삽입 이미지

 한마디로 관리를 하게되는 Manager와 Manager의 관리를 받게 되는 Agent로 되어있다. 근데 아래 그림에서보면 Agent가 클라이언트로 되어있는데..저부분이 맘에 안든다. 돌아가는 구조를 보게되면!
어쨌든 위와 같은 구성으로 되어있고 우리가 만들어야 하는 부분은 위쪽에 있는 SNMP Manager이다.
.
.
 그럼 저놈을 만들려면 패킷이 어떻게 구성되고, 패킷의 헤더는 뭐고 등등 저놈이 쓰는 프토로콜의 패킷의 분석을 먼저 해야겠지만 그럼 흥미가 확 저하 됨을 고려해 일단 저놈이 하는 기능이 뭔지 부터 알아보자. 일단 여기저기 자료를 찾아보면 알겠지만 기본 4가지 명령 GET, SET, GETNEXT, WALK명령으로 Agent의 관리를 하게된다. 물론 위의 명령은 기본 명령이고 추가적으로 TRAP, BULK등도 있다.
 그리고 이놈을 알려면 MIB와 OID라는 것도 알아야 한다. 일단 MIB는 Management Information Base의 약자로 SNMP가 관리해야 할 네트워크 상의 요소 들을 관리가 용이하게 하기 위해 분류해 놓은것으로 이것은 트리 구조를 가진다.
사용자 삽입 이미지
 그럼 OID란 무엇이냐? 이것도 약자인데 Object IDentifier의 약자이다. 위의 그림에서 숫자가 보이는데 이것이 OID이다. 관리 객체들이 가지는 식별 id인 것이다. 예를 들어 dod를 나타내려면 1.3.6이라는 것이다. 일단 이녀석들에 대해 너무 완벽히 이해하려 하지말고 이런이런게 있구나 정도로만 하면 크게 어려움은 없다.
.
snmp를 위한 유용한 사이트로 아래 두개를 추천한다.
http://www.net-snmp.org/ - SNMP에 대한 설명, 지원하는 API, 간단한 기본 소스코드등이 있는 SNMP프로젝트 사이트
http://www.oid-info.com/ - MIB객체를 가져올때 쓰는 oid를 알아볼 수 있는 사이트
Posted by hazeyun
,
direct3d를 하면서 기초를 너무 소홀히 한거 같다. 가장기본인 device생성 부터 버벅대다니.

pd3dDevice =  CreateDevice(....,DWORD dwBehaviorflags,...);
여기에 들어가는 옵션으로 3가지가 있다.
첫째, D3DCREATE_MIXED_VERTEXPROCESSING  - 실시간으로 정점연산을 하드웨어와 소프트웨어 방식을 변경이 가능하다. 변경은 pd3dDevice->SetSoftwareVertexProcessing(TRUE); 해줌으로 소프트웨어 방식 사용, FLASE를 넣어주면 하드웨어 방식을 사용.
둘째, D3DCREATE_HARDWARE_VERTEXPROCESSING - 정점연산을 하드웨어 방식에만 의존.
셋째, D3DCREATE_SOFTWARE_VERTEXPROCESSING - 정점연산을 소프트웨어 방식에만 의존.

이런것 조차 간과 하고 있었다니ㅡ_ㅡ;

Posted by hazeyun
,

알고리즘 과제로 0-1배낭채우기와 Fractional 배낭채우기를 구현..
일단 두 문제에 대해서 간단히 짚고 넘어 가자면 0-1배낭채우기란 배낭에 넣을 아이템을 쪼갤 수 없다. 반면 Fractional 배낭채우기란 배낭에 넣을 아이템을 쪼갤 수 있다. 이 두가지의 차이를 빼면 이후에 조건은 배낭의 아이템을 넣어 최대의 이익을 얻는 문제다.
0-1배낭채우기는 동적계획법을 이용해서 구현했고, Fractional 배낭채우기는 Greedy알고리즘을 이용해서 구현 했다. 그리고 두 알고리즘의 비교를 위해 각각의 알고리즘의 수행 속도를 결과에 포함 시켰다.
아래 실행화면...


사용자 삽입 이미지

파일불러오기 버튼으로 데이터가 저장된 파일을 불러와서 시작버튼으로 수행하면 된다.
입력 데이터를 만들 때 입력 데이터 형식을 맞춰 줘야되는데 입력 데이터 형식은 첫번째 줄에는 항목의 수, 두번째 줄에는 배낭의 용량, 세번째 줄에는 항목들의 이익, 네번째줄에는 항목들의 무게..
예)
3
15
10 3 20
5 8 10
이런 식으로 맞춰줘야한다.
첨부된 파일에 기본 입력데이타set 3개도 포함시켜 뒀다.
p.s. win32로 만들어서 노가다도 좀들었고, 생각보다 UI가 이쁘지 않게 나왔다. mfc를 보던지 해야지..ㅋ

Posted by hazeyun
,

WM_CTLCOLORSTATIC - static control 색상을 변경할 때 사용
WM_CTLCOLORBTN      - button control 색상을 변경할 때 사용
WM_CTLCOLOREDIT     - editbox control 색상을 변경할 때 사용

사용예..

HBRUSH    hBrush_Control;

LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
       switch(msg)
       {
        case WM_CREATE:
                 hBrush_Contorl = CreateSolidBrush(RGB(255, 255, 255));   //흰색 브러시 생성.
                   ...
                 return 0;
        case WM_CTLCOLORSTATIC:
                 SetBKColor((HDC)wParam, RGB(255, 255, 255);
                 return (LRESULT)hBrush_Control;
        }
}

대충 이런 식으로 사용한다.
lParam으로 특정 컨트롤의 색상만 변경도 가능하다.
if((HWND)lParam == hWnd_static01)
{
      //컨트롤에 대한 색상처리...
}

버튼같은경우 안먹던데ㅡ_ㅡ. 그리고 처음 브러쉬를 생성할때 색상이랑 SetBkColor함수에 넣어줄 t색상이랑 맞춰주는게 나을꺼 같다. static control의 경우 글자 주위의 배경색만 바뀌는거 같다.

Posted by hazeyun
,
사용자 삽입 이미지

D3DXCreateRenderToSurface 함수에 대한 설명은 msdn이나 Directx 문서에 잘 나와있으니 생략하고 일단 D3DXCreateRenderToSurface함수를 이용해서 텍스쳐에 그려주려면 일단
LPD3DXRENDERTOSURFACE   g_pRenderToSurface;
LPDIRECT3DTEXTURE9           g_pTexture;
LPDIRECT3DSURFACE9          g_pSurface;

와 같은 3개의 개체가 필요하다. 위의 개체 말고도 여러가지 부수적인 것들도 필요하지만 설명을 위한 필수 항목만 언급하겠다.


위의 3개체 가 선언 되었다면 D3DXCreateRenderToSurface 함수를 이용해 RenderToSurface개체를 얻고 D3DXCreateTexture함수로 그려질수 있는 텍스쳐개체를 얻어온다. 그리고 GetSurfaceLevel함수를 사용해서 서페이스에 그려지는걸 텍스쳐에 그대로 옮기도록 설정한다.
D3DXCreateRenderToSurface(g_pd3dDevice, 256, 256, D3DFMT_A8R8G8G8, TRUE, D3DFMT_D24S8, &g_pdRenderToSurface);
D3DXCreateTextureg_pd3dDevice, 256, 256, 0, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_pTexture);
g_pTexture->GetSurfaceLevel(0, &g_pSurface);

초기화가 됐으면 이제 surface에 그려주면 된다.
g_pRenderToSurface->BeginScene(g_pSurface, NULL);
g_pd3dDevice->clear(...)
//여기에 surface(texture)에 그려질 부분을 렌더링
해주면 된다
g_pRenderToSurface->EndScene(0);

이제 texture에 그려진 장면을 정점을 잡아서 uv좌표에 맞춰서 랜더링 해주면 된다. 여기서 가장 중요한건 RenderToSurface를 만들거나 Texture를 만들때 format이랑 width, height를 꼭 맞춰 주어야 한다. 심지어 텍스쳐를 입힐 사각형의 크기도 width, height를 맞춰 주어야 한다.
Posted by hazeyun
,

현재 실행중인 process 확인
~]$ps -aux | grep 검색키워드
이렇게 하면 검색 키워드와 부분 매칭되는 모든 process를 뱉어 준다.

process를 kill할때는 위에서 확인한 pid를 이용해서
~]$kill pid
pid에는 위에서 확인한 프로세스 id를 적어주면 된다.
참고로 백그라운드로 실행중인 프로세스는
~]$jobs
로 확인해서
~]$kill %pid
로 죽여주면 된다!

Posted by hazeyun
,

현재 window api에서 제공되는 가장 정밀한 측정을 할 수 있다. 하지만 그만큼 부하가 크다. 그리고 하드웨어 적으로도 지원이 되어야한다.
일반적으로 시간을 측정할때 쓰는 함수임  timeGetTime()이나 GetTickCount()같은 경우 ms(millisecond)까지의 정확도를 보여준다. 하지만 아래의 두함수 QueryPerformanceFrequency와 QueryPerformanceCounter()를 이용하게 되면 us(microsecond)까지의 측정이 가능하다.

QueryPerformanceFrequecy 함수를 보면
BOOL QueryPerformanceFrequency(  LARGE_INTEGER *lpFrequency   );
parameter로 받은값에 현재 컴퓨터의 초당 tick수를 뱉어낸다. 자신의 컴퓨터하드웨어가 고해상도 타이머를 지원하지 않을겨우에는 false를 반환한다.

QueryPerformanceCounter함수는
BOOL QueryPerformanceCounter( LARGE_INTEGER *lpPerformanceCount);
parameter로 받은값에다가 컴퓨터가 부팅후 지나간tick수를 반한해준다.

그래서 이두함수를 이용하게 되면

LARGE_INTEGER start, end, count;

QueryPerformanceFrequency(&count);
QueryPerformanceCounter(&start);
//수행 시간을 측정할 작업..
QueryPerformanceCounter(&end);

passtime = end.QuadPart - start.QuadPart  / count.QuadPart

passtime * 1000(ms)
passtime * 1000000(us)

하지만 정밀한 측정을 하기에 무조건 좋은것은 아니다. 일부 메인보드 칩센에서 시간이 건너 뛴다거나 하드웨어적인 지원 유무등 문제가 있기때문에 유연한 코드가 필요할듯 하다.

Posted by hazeyun
,

학교 프로젝트 주제로 네트워크 패킷캡쳐 프로그램을 구현하기 winpcap에 대해 알아 보게 됐다!
.
.
.
일단 WinPcap란 무엇인가....!?
www.winpcap.org <- 여기에 가보면 잘 설명이 되어있다 영어로...
일반적으로 네트웍카드에는 항상 패킷이 오고가고 있다! 하지만 그걸 NIC(network interface card)에서는 들어오는 패킷이 나에게 오는것이 맞는가를 확인하고 맞다면 받아들여서 그에맞는 application으로 보내주고, 아니라면 즉각 폐기해 버린다.

사용자 삽입 이미지

대략 이런 구조로 되어있어서 폐기되기전에 읽어들여 버리면 자신의 컴퓨터에 NIC를 거치는 패킷을 볼 수 있다는 것이다. 하지만 물론 패킷들이 암호화 되어있고 또한 패킷의 헤더와 기타 불필요한 정보들이 덧붙어 있기 때문에 분석하기는 어렵다. 그리고 window환경에서는 application층에서 NIC에 직접적인 접근이 불가하다. 완전히 방법이 없는것은 아니다. fillter-driver를 이용한다든지 우회적인 방법이 있다.
여기서 Winpcap는 fillter-driver역활을 하는것이다.
원래는 linux에는 libpcap가 있다.
.
Winpcap작업 환경을 구축하려면 일단 위에 링크된 사이트에 접속하여 왼쪽에 보이는 메뉴에서 Development로 가서 WinPcap Developer's Pack을 다운로드하여 적당한곳에 압축을 푼다. 그리고 visual studio 환경이라면 도구 -> 옵션에서 프로젝트 솔루션 항목을 선택 하위항목인 VC++프로젝트에서 참조파일에 lib폴더를 포함시켜주고, 포함파일에 include폴더를 포함시켜준다. 그리고 dll파일을 필요로 하는데 링크된 사이트에서 winpcap를 받아서 인스톨해준다.
그럼 이상으로 winpcap를 이용할 환경은 구축 되었다!

Posted by hazeyun
,