Dijkstra의 알고리즘은 V에서부터 다른 모든 정점들까지 증가하는 거리의 순으로 최단 경로를 찾을 수 있다. 이 알고리즘은 팡의 최소 스패닝 트리 알고리즘에서처럼 정점 V에서 시작하여 새로운 정점들로 도달하는 특정한 에지들을 선택하면서 분기해 나간다. 또한 항상 가장 가까운 거리를 갖는 정점으로의 에지를 선택한다. 그리고, 각 인접 정점에 대해 오직 하나의 후보 에지만을 추적한다.

예를 들어, 어떤 회사에서 1000만원짜리 기계와 100만원짜리 기계중에 하나를 꼭 구입해야 하는 상황에 빠져 있을 때, Greedy는 말그대로 가장 싼것을 택하는 것이다. 1000만원짜리 기계를 써서 1억원이 넘게 벌수 있고, 100만원짜리를 써서, 10만원도 벌지 못한다 하더라도, 우선 뒤를 생각하지 않고 무조건 지금 상황에서의 최적만을 찾는 것이다. 그런 의미에서 Greedy라는 알고리즘은 항상 최적해를 뽑아내지 못하는 경우가 많다. 따라서, Greedy방법으로 최적해를 해결하고자 할 때 사용되는 선택규칙이 궁극적으로 최적해를 구해낸다는 것에 대한 증명이 반드시 뒷받침 되어야 한다.

Dynamic이라는 것은 Divide and Conquer의 반대말이다. Divide and Conquer는 큰 문제를 먼저 작은 문제들로 분할하고 각각 해결해나가는 것인데 반해, Dynamic은 작은 문제를 먼저 해결하고, 그 결과를 저장한 다음, 후에 똑같은 계산을 반복하는 대신, 그 저장한 결과를 이용하는 방식이다. 따라서 메모리가 많이 필요하다는 것이 Dynamic의 단점이다.


-----------------------------------------------------------------------------------------------------

다익스트라 알고리즘(Dijkstra algorithm)은 네덜란드컴퓨터과학자 에츠허르 다익스트라의 이름을 딴, 어떤 간선도 음수 값을 갖지 않는 유향 그래프에서 주어진 출발점과 도착점 사이의 최단 경로 문제를 푸는 알고리즘이다.

예를 들어, 그래프의 점들이 각각 도시를 나타내고, 연결선들이 도시 사이를 연결하는 도로의 길이를 나타낸다면, 다익스트라 알고리즘은 임의의 두 도시 사이의 최단 경로를 찾는다.

다익스트라 알고리즘은 방향이 주어진 가중 그래프(weighted graph) G와 출발점 s를 입력으로 받는다. 그래프 G의 모든 점들의 집합을 V라 하고, 그래프의 간선을 간선의 출발점 u와 도착점 v의 쌍 (u, v)로 표현한다. G의 모든 간선들의 집합을 E라 하고, 간선들의 가중치는 함수 w: E → [0, ∞]로 표현한다. 이때 가중치 w(u, v)는 점 u에서 점 v로 이동하는 데 드는 비용(시간, 거리 등)이 된다. 경로의 비용은 경로 사이의 모든 간선들의 가중치의 합이 된다. 다익스트라 알고리즘은 V의 임의의 점의 쌍 st가 있을 때 s에서 t로 가는 가장 적은 비용이 드는 경로(최단 경로)를 찾는다. 이 알고리즘은 주어진 출발점 s로부터 다른 모든 점까지의 최단 경로를 계산하는 데도 사용할 수 있다.

목차

[숨기기]

[편집] 알고리즘의 개요

다익스트라 알고리즘은 각각의 점 v에 대해 s에서 v까지의 최단 거리 d[v]를 저장하면서 작동한다. 알고리즘의 시작 시에 이 값은 s에 대해서는 0이고, (d[s]=0) 다른 모든 점에 대해서는 무한대(∞) 값으로 놓아 다른 점에 대해서는 아직 최단 경로를 모른다는 사실을 표시한다. 알고리즘이 종료되었을 때 d[v]는 s에서 v까지의 최단 경로의 거리를 나타내게 되고, 만약 경로가 존재하지 않으면 거리는 여전히 무한대로 남는다.

다익스트라 알고리즘은 이완(edge relaxation)이라고 불리는 기본 연산을 바탕으로 한다. s에서 u까지의 최단 경로(d[u])를 이미 알고 있고, u에서 v까지의 링크 (u, v)가 존재할 때, s에서 v까지의 최단경로는 u까지의 최단경로에 에 링크 (u, v)를 연장함으로써 얻을 수 있다. 이 경로의 비용은 d[u]+w(u, v)가 되며, 이 비용이 현재의 d[v] 값보다 낮으면 d[v]를 새로운 값으로 바꾼다.

이완 연산은 모든 간선 (u, v)에 대해 한번씩 이완이 적용되어 모든 d[v]가 최단 경로의 비용을 나타내게 되었을 때 끝난다.

알고리즘은 과정이 끝날 때까지 점의 집합 SQ를 저장한다. Sd[v]가 최단 경로의 비용임이 이미 알려진 점 v의 집합이고 Q는 나머지 점들의 집합을 가리킨다. S는 공집합에서 시작하여 매 단계마다 Q에서 S로 점들이 하나씩 옮겨 오며, 이때 옮겨 오는 점들은 d[u]가 가장 낮은 값을 갖는 점 u로 정해진다. uS로 옮겨 오면, 알고리즘은 u에서 시작하는 모든 간선에 대해 이완 연산을 행한다.

[편집] 수도코드

아래 알고리즘에서 u := Extract_Min(Q)는 점의 집합 Q에서 가장 작은 d[u]값을 찾은 다음 그 점 uQ에서 제거한 후 반환하는 함수를 가리킨다.

1   function Dijkstra(G, w, s)
2      for each vertex v in V[G]                        // 초기화
3            d[v] := infinity
4            previous[v] := undefined
5      d[s] := 0
6      S := empty set
7      Q := set of all vertices
8      while Q is not an empty set                      // 알고리즘의 실행
9            u := Extract_Min(Q)
10           S := S union {u}
11           for each edge (u,v) outgoing from u
12                  if d[v] > d[u] + w(u,v)             // (u,v)의 이완
13                        d[v] := d[u] + w(u,v)
14                        previous[v] := u

만약 모든 v에 대해서가 아니라 특정한 s에서 v까지의 최단 거리만을 알고 싶다면 9번째 행에서 u = t 일때 종료하면 된다.

s에서 t까지의 최단 경로는 다음과 같이 얻을 수 있다.

1 S := empty sequence 
2 u := t
3 while defined u                                        
4       insert u to the beginning of S
5       u := previous[u]

이제 Ss에서 t까지의 최단경로 상에 있는 점들의 목록이 된다.

[편집] 실행 시간

m개의 간선과 n개의 점을 가진 그래프에 대해 대문자 O 표기법으로 다익스트라 알고리즘의 실행시간을 나타낼 수 있다.

가장 간단한 구현으로, Q의 집합을 연결 리스트배열 구조로 구현하고 Extract-Min(Q) 함수를 단순한 선형 탐색으로 구현했을 때 실행 시간은 O(n2) 시간이 된다.

만약 희소 그래프(sparse graph), 즉 n2보다 훨씬 작은 개수의 간선만을 갖는 그래프에 대해서는, 인접 리스트(adjacency list)와 바이너리 또는 피보나치 힙으로 구현한 우선순위 큐(priority queue)를 이용해 다익스트라 알고리즘을 더 효율적으로 구현할 수 있다. 바이너리 힙을 이용하면 실행 시간은 O((m+n)log n) 시간이 되고, 피보나치 힙을 통해 O(m + n log n) 시간까지 개선할 수 있다.

[편집] 관련된 문제와 알고리즘

인터넷 라우팅에서 사용되는 OSPF(Open Shortest Path First) 방식의 프로토콜은 다익스트라 알고리즘이 실제 현장에서 사용되는 좋은 사례이다.

그래프의 가중치가 음수가 아니라고 가정하는 다익스트라 알고리즘과는 달리, 벨만-포드 알고리즘은 음수 가중치를 갖는 그래프에 대해서도 정확하게 동작한다. (단, 그래프에 음수 값을 갖는 순환 경로가 존재하지 않을 때)

목적지까지의 '거리'를 추정할 수 있는 방법이 있을 때, 다익스트라 알고리즘의 변형인 A* 알고리즘은 탐색해야 할 그래프의 크기를 줄이는 방법으로 더 빠르게 경로를 찾을 수 있다.




출연자소개 / 스토리
아키야카 카논 (秋山佳音) : 호리키타 마키 (堀北?希)
지방의 시골마을에서 자람. 어릴적 양친이 끔찍하게 살해당해, 오빠가 살인자로서 연행되었던 아픈 과거를 가지고 있으나, 긍정적이고 밝은 성격. 사람의 행복을 진심으로 바라는 상냥함이 있다. 청소부 일을 하다 쥰야를 만나, 사랑에 빠진다.
나가사키 준야 (長崎殉也) : 키타가와 유진 (北川悠仁)
전직 작곡가. 현재, 피아노바에서 아르바이트를 하며, 일요일에느 교회에서 아이들에게 성가를 가르치고있다. 어릴적에 양친을 잃었으나, 밝고 천진난만한 성격으로, 아이들에게도 인기인. 하지만 실은, 깊은슬픔을 품고있다. 대학시절의 동급생인 키요카와 약혼중
사쿠라이 미즈키 (?井美月) : 카시이 유우 (香椎由宇)
준야의 소꿉친구. 어릴적부터 준야를 사랑하고 있지만, 그 마음은 전해지지않고, 여동생 같은 취급을 받고 있다. 준야가 약혼자에게 휘둘리는걸 걱정하고있다. 한편 준야에게 접근하는 카논을 눈에 가시처럼 생각하며, 괴롭힌다
스가와 스바루 (?川昴) : 나리미야 히로키 (成宮?貴)
준야와 키요카의 대학시절 동급생. 디자인일을 하고있다. 준야랑은 절친한 친구지만, 그에게 조차 말할 수 없는 비밀을 품고있다. 미즈키와 같이 준야를 걱정하고있다. 한편, 좋아하는 사람에게 마음을 전하지 못한채 괴로워하고있다.
아키야마 요지 (秋山耀司) : 후쿠시 세이지 (福士誠治)
카논의 오빠. 어릴적부터 병약하여, 방안에서 지낸날이 많았던 탓에, 유일한 친구가 여동생인 카논이었다. 양친살해 죄로 소년원에 복역중. 무고함을 주장, 카논도 그렇게 믿고있다. 때로, 감정을 조절할수 없게된다.
토노 키요카 (遠野聖花) : 우치다 유키 (?田有紀)
준야의 약혼자. 제멋대로에, 억지 웃음조차 안하는, 솔직한 성격으로 언제나 준야를 휘두르고 다니지만, 그로서는 한결같이 계속 좋아한다
이케다 지로 (池田次?) : 토요하라 코스케 (豊原功補)
6년전에 일어난 카논의 양친살해사건을 쫓는 잡지기자. 카논과 요지를 집요하게 쫓고 있는 동안, 그들의 슬픈 운명에 휘말려간다.
*** 등장인물차트 ****

방송기간 : 2008.10.20 -
방송시간 : 월요일 21:00

연출 : 카토 히로마사, 마츠야마 히로아키
프로듀서 : 나카노 토시유키
각본 : 아사노 타에코
음악 : 칸노 유고
주제곡 : Eternally - by 우타다 히카루
방송국 : 후지 TV
공식 홈페이지 : http://www.fujitv.co.jp/innocentlove/

*** 스토리 ****

6년전, 어떤 지방의 작은 마을에 살고 있던 가족에게 비극이 덮쳤다. 부친과 모친이 참살된 후, 집에 방화가 되었던 것이다. 살아 남았던 13세의 소녀·카논은, 타오르는 불길 앞에서 격렬하게 울부짖었다. 5살 많은 오빠·요지는, 부모를 구하기 위해서 불길속으로 뛰어들려고 하는 카논의 몸을 필사적으로 막고 있었다--.

19세가 된 카논은, 작은 찻집에서 밝고 건강하게 아르바이트를 하고 있었다. 하지만, 6년전의 사건을 알게 된 주인 유카리는, 다음 달부터 여동생이 도와 주기로 했다, 라고 말하고, 넌지시 카논의 해고를 말한다. 다음 날, 카논은, 소년 형무소를 방문한다. 부모님을 살해한 죄로 소년 형무소에 간 오빠·요지를 면회하기 위해였다. 오빠의 무죄를 믿는 카논은, 오빠가 나올수 있도록 한번 더 변호사에게 부탁해 본다, 라고 요지를 격려했다. 하지만, 이때 카논은, 고향을 떠나 도시에 나가려는 결심을 한것에 대해 요지에게 이야기하지 않고 있었다.

음악가인 나가사키 준야는, 오래전부터 CM등의 화려한 세계에서 활약하고 있었지만, 어떠한 사정으로 일선에서 몸을 빼고, 현재는,요시미치 신부의 교회에서 아이들의 성가대를 인솔하는 등, 퍼브 레스토랑에서 피아노를 연주하는 아르바이트등을 하며 생계를 유지하고 있었다. 준야의 소꿉 친구이기도 한 사쿠라이 미즈키는, 그의 재능이 이대로 파묻혀 버리는 것을 걱정하고 있었다. 사실 미즈키는, 오래전 부터 준야를 마음속으로 좋아하고 있었다. 어느날 밤, 준야는, 대학시절부터의 친구로, 디자인의 일을 하고 있는 스가와 스바루와 만난다. 거기서 준야는, 연인인 키요카를 기쁘게 해주기 위해서, 어떤식의 크리스마스를 연출하면 좋은지를 스바루에게 상담한다. 준야, 스바루, 키요카는, 원래 같은 대학의 동료였다. 스바루는, 그런 준야를 적당히 대하며, 금년의 크리스마스 이브는 선상 파티를 하기 때문에 얼굴을 내밀어라, 라고 권했다.
아파트를 빌리고 요코하마에서 살기 시작한 카논은, 이름을 속여 청소 회사에서 아르바이트를 시작한다. 그 회사는, 주로 개인의 집을 클리닝 하는 서비스를 실시하고 있었다. 선배의 하루에는, 요즘의 젊은이와는 드물게, 불평도 말하지 않고 열심히 일하는 카논에게 감탄하고 있었다.

그렇게 있던 날, 카논은, 하루에와 함께 혼자 생활하는 음악가의 집에 파견된다. 준야의 집이었다. 카논은, 급한 볼일이 생겨 곤란해 하고 있던 하루에를 배웅하면서, 혼자서 청소를 계속했다. 거기서 카논은, 1권의 낡은 앨범을 찾아낸다. 6년전의 사건으로 앨범등도 불타 버려, 추억을 잃고 있던 카논은, 행복한 가족의 사진을 보는 것을 정말 좋아했다. 그 앨범에는, 준야의 어릴때부터의 사진이 있었다. 그때, 창으로부터 불어온 바람에 사진이 날아가 버린다. 카논이 그것을 주워 모으려 하고 있을때, 준야가 돌아온다. 준야는, 당황하며 사진을 숨기려고 하는 카논에게, 무엇을 하고 있었는지 이유를 물었다. 그러자 카논은, 사람이 웃고 있는 사진을 좋아한다고 대답했다. 살아 있으면 여러가지가 있지만, 웃는 얼굴의 사진에는 그 사람의 행복했던 때가 쭉 그곳에 있기 때문에.., 라고--. 그런 가카논의 말을 조용하게 듣고 있던 준야는, 함께 사진을 찍자, 라고 말한다. 카논의 휴대 전화를 빌린 준야는, 그녀와 함께 사진을 찍었다. 카논은, 준야와의 two shot 사진을 현상 하여, 방의 벽에 붙였다. 그 이후로, 이 사진은 카논의 보물이 되었다.

그런 어느날, 카논이 일하고 있는 회사에, 잡지 기자의 이케다 지로라고 하는 남자가 찾아 온다. 이케다는, "6년전의 사건의 이야기를 듣고 싶다" 라고 말하지만물어 카논은 딱 잘라 거절하는데….

*** 드라마 뉴스 ****

여배우 호리키타 마키(堀北?希, 19)가 10월부터 시작되는 후지TV 드라마 <이노센트 러브(イノセント ラヴ)>의 주연을 맡아, 가혹한 운명을 짊어지고도 오로지 한 남자만을 사랑하는 여성을 연기한다. 후지TV의 간판 드라마인 게츠구(月9)의 첫 주연이자 순애보 드라마에도 처음 도전하는 것이다.

호리키타가 연기하는 주인공 아키야마 카논(秋山佳音)은 어릴 때 부모님이 살해되는 비극을 겪은데다 오빠가 그 살인 용의자로 체포됐다는 설정. 동네에서는 살인범의 여동생이라고 냉대를 받아 아르바이트조차 할 수 없는 처지라 도쿄(東京)로 올라오게 되고, 겨우 찾아낸 하우스클리닝 작업장에서 운명의 남자를 만난다. 이후 역경이 차례로 닥치지만 이에 지지 않고 살아가는 현대판 신데렐라.

<이노센트 러브>는 가정 폭력(DV, domestic violence:부모나 형제, 남편, 동거 중인 연인에 의한 폭력이나 학대) 등을 소재로 젊은이들의 고독을 그려 화제를 뿌렸던 올 4월기 드라마 <라스트 프렌즈(ラスト フレンズ)>의 각본을 썼던 아사노 다에코(?野妙子) 작가, 가토 히로마사(加藤裕?) 연출에 나카노 도시유키(中野利幸) 프로듀서가 다시 만나, 이번에도 '현대의
고독'을 키워드로 한 젊은이가 고독과 싸우면서도 사랑하는 이를 생각하며 전향적으로 살아가는 모습을 그린다.

호리키타는 2007년 7월에 방영된 후지TV 드라마 <아름다운 그대에게(花ざかりの君たちへ)>에서 남장 고교생을 연기해 주목을 받는 등 다양한 역할을 소화해내고 있다. 특히 8월 17일부터는 NHK대하사극 <아츠희메(篤姬)>에 14대 쇼군 도쿠가와 이에시게(德川家茂)의 정실 부인 가즈노미야(和宮)로 등장, 9월 말 대하사극의 촬영 완료까지는 사극과 현대극을 오가며 연
기 변신해야 하는 상황이다.

출처: 일본으로 가는길 (http://tojapan.co.kr/)


public static void main(String args[]){

----------------------------------------------------------------

두번째 문장이다. HelloWorld클래스에 존재하는 유일한 메소드인 main이다. 처음 문자열부터

하나씩 알아보자


public : 클래스의 안이든 바깥이든 어디에서나 이 main메소드가 호출될 수 있음을 뜻한다. 접근 제한자에 대한 자 세한 것은 문법 메뉴를 참고하시면 많은 정보를 얻을 수 있다.


static : mian()메소드가 메모리에 인스턴스되는 공간의 주소가 모두 똑같음을 나타냅니다.

프로그래밍을 처음 시작 하시는 분들이라면 이 static이라는 키워드의 기능에 대해 이해하기가 좀 어려울 것입니다. 지금부터 제가 설명하는 것을 자세히 읽어 보시면 왠만큼 이해는 될 것입니다. static키워드는 매번 자바 언어에서 객체들 이 생성되고 이용되는 과정에서 메모리의 기억 장소를 이용합니다. 매번 객체들이 생기고 저장되고 참조하는 과정들이 무진장 일어나죠. 그래서 메모리를 많이 잡아 먹게 됩니다. 이런 메모리 점유를 조금이나마 줄이고 수행 속도의 증가를 위해 static키워드를 지정함으로서 static으로 지정된 객체나 메소드에 대해서는 메모리의 똑 같은 자리(주소)를 계속해서 사용하므로 메모리의 낭비를 막을 수 있습니다. 그러나 주의하실 점은 이런 객체나 메소드는 정적으로 이용되므로 같은 static객체나 메소드에 의해 호출이 되며, 클래스의 초기 화시 맨 처음으로 메모리에 적재됩니다.


void : C언어나 C++언어를 해보신 분들이라면 지겹도록 많이 보았을 키워드지요. 자바에서 void의 기능은 이 메소드 여기에서는 main()메소드의 안에서 작업을 처리하고 main을 호출한 호출자에게 반환한(리턴값) 결과값이 아무 것도 없다는 것을 의미합니다.


main(String args[]) : main()메소드는 모든 자바 애플리케이션 프로그램에 꼭 들어가야 하는 문장이며, 캄파일하여 실행시킬 경우 자바 런타임 인터프리터가 제일 먼저 이 main()메소드를 찾아 실행을 하는 곳입니다. main() 메소드는 "String args[]"라는 한 개의 파라미터값을 갖도록 정의되어 있습니다. args는 실행시의 클래스에 전달되는 커맨드 라인 인자로서 String의 배열형으로 정의함으로서 여러개의 문자열을 받아들일 수 있습니다.


쉽게 말해, 자바 애플리케이션 프로그램을 자바 인터프리터(java)로 실행할 경우 실행 명령뒤에 문자 열을 인자로 줄 수 있는데 이것을 받아들이는 String형 배열입니다.


위의 HelloWrold프로그램에서는 커맨드 라인 인자를 필요로 하지 않기 때문에 args인자를 주어지기 않아도 되며, args는 무시됩니다.

알고리즘에 발가락 담그기
[한빛미디어] 2005-12-02 11:42  
저자: 김대곤

* 알고리즘의 Complexity 또는 계산복잡도
* 탐욕 알고리즘(Greedy Algorithm)
* 동적 프로그래밍(Dynamic Programming) – 고급 설계 기법인가?
* Induction과 병합 정렬(Merge Sort) 알고리즘
* 거짓말 같은 Induction


다음과 같은 신탁이 주어졌다고 합시다. “1에서 n까지 출력하는 알고리즘을 개발하라”

너무 단순해 보여서 한가지 방법만 있는 듯 보입니다. 보기와는 다르게 아주 다양한 방법이 있습니다. 프로그래밍 책을 한 번이라도 본 사람들은 쉽게 다음과 같은 프로그램을 작성할 수 있을 것입니다.

public static void printUsingLoop(int N) {
    for ( int i=1 ; i <= N ; i++ ) {
        System.out.println(i);
    }
}

하지만 재귀 프로그램으로도 쉽게 구현할 수 있습니다.

public static void printUsingRecursion(int N) {
    if ( N == 1 ) {
        System.out.println(N);
    } else {
        printUsingRecursion(N-1);
        System.out.println(N);
    }
}

실행속도는 어떻게 될까요? 반복문을 사용한 경우에는 N에 비례하는 것이 분명하게 보입니다. 그러면 위의 재귀 프로그램의 속도는 어떻게 될까요? 이것도 N에 비례합니다. 재귀 프로그램의 실행속도는 재귀방정식으로 주어집니다. 즉 위의 프로그램의 수행속도는 다음과 같이 정의됩니다.



T(N)를 계속적으로 전개해 보면, N개의 1이 나옵니다. 이것들을 모두 더하면 N이므로 실행속도는 N이 됩니다. 조금 더 복잡해 보이는 프로그램을 만들어 봅시다. 다음과 재귀 프로그램도 1부터 N까지 출력합니다. 초기값은 1과 N이 되겠지요.

public static void printUsingRecursion(int i, int j) {
    if ( i == j ) {
        System.out.println(i);
    } else {
        int k = (int)((i+j)/2);
        printUsingRecursion(i,k);
        printUsingRecursion(k+1,j);
    }
}

수행속도는 어떻게 될까요? 먼저 실행속도는 재귀함수로 표현해 봅시다. 그러면 실행속도는 다음과 같이 표현됩니다.



간단히 말하기 힘들어 보입니다. T(1,5)를 전개해 봅시다.
T(1,4)=T(1,2)+T(3,4)+1={T(1,1)+T(2,2)+1}+{T(3,3)+T(4,4)+1}+1
다시 정리하면 T(1,4)=7이 됩니다. 동일하게 방법으로 T(1,8)=15가 됩니다. N에 비례한다고 말하기가 조금 주저되는 상황입니다. 결론부터 말하면 실행속도는 N에 비례합니다. 그리고 N(=j-i+1)이 2의 제곱승일 때 T(1,N)은 2N-1이 됩니다. 이것은 고등학교 수학으로 간단하게 계산이 가능합니다. 그 전에 재귀 트리(Recursion Tree)를 생각해 봅니다.



실제적인 출력은 leaf에서만 수행됩니다. 만약 leaf의 갯수가 N이고 leaf가 아닌 모든 노드들이 2개의 하위 노드를 가지고 있는 경우, 이러한 노드의 갯수는 N-1이 됩니다. 이것은 고등학교 수학으로 증명이 가능합니다. 최상위 노드는 하나이고 그 다음은 2개가 되고 그 다음은 4개 됩니다. 최상위 노드에서 Leaf 노드까지의 거리는 일정합니다. 그리고 이 거리를 h라고 합시다. Leaf가 아닌 노드의 갯수는 다음과 같이 계산됩니다. 등비수열의 합을 구하는 공식 생각나시죠.



N이 이므로 내부 노드의 갯수는 N-1이 됩니다. 전체 합은 2N-1입니다. 여기서 비례한다는 것은 알고리즘의 계산복잡도를 말하는 것입니다. 이것에 대한 간략한 설명은 “알고리즘 Complexity 또는 계산복잡도” 기사에서 찾을 수 있습니다.

알고리즘을 시작하는 사람들이 가지는 가장 일반적인 고정관념 중에 하나는 여기서 알고리즘이 끝났다고 생각하는데 있습니다. 하지만 알고리즘은 반드시 증명을 따라옵니다. 즉, 알고리즘이 목표한 결과를 가져온다는 것을 증명하지 않으면 무용지물입니다. 어떻게 그 알고리즘을 사용해서 프로그램을 할 수 있습니까 어떤 값을 나올지 모르는 상황에서. 일반적으로 알고리즘의 핵심을 알고리즘을 증명하는 과정에 있다고 할 수 있습니다. 이 과정을 연습해서 얻는 결과물은 자신의 문제에 대한 알고리즘 개발할 수 있는 것입니다. 알고리즘의 개발과 알고리즘의 증명은 동전의 양면과 같습니다.

여기서 사설은 중단하고 위에 있는 각 알고리즘을 증명해 봅시다. 먼저 첫번째 재귀 프로그램(R1이라고 합시다)을 증명해 봅시다. 만약 N=1이면, R1은 1(=N)를 출력합니다. 1에서 N(=1)까지 출력하였습니다. 만약 이 R1이 N=k일 때, 1에서 k까지 출력한다고 가정합시다. N=k+1일 때, R1(k)이 1부터 k까지 출력합니다. 그리고 나서 k+1를 출력합니다. 그러므로 1부터 k+1까지 출력합니다. 즉, 어떠한 자연수 N에 대하여 R1은 1부터 N까지 출력합니다. 이것으로 증명은 끝났습니다. 재귀 프로그램은 Induction를 이용하여 증명합니다.

그러면 처음에 있는 반복문은 어떻게 증명할까요? Loop Invariant로 이용하여 반복문을 증명합니다. Loop Invariant은 간단하게 말하면, 반복문이 시작되는 위치에서 항상 만족하는 성질입니다. 즉

각 루프의 시작점(for 과 출력문 사이), 이 때의 i의 값은 k라고 합시다. 1부터 k-1까지 출력되었다.

이것에 대하여 반복문 이전, 반복문이 수행되는 동안, 반복문이 끝난 시점에 위의 성질이 만족하는 것을 보이는 것이 반복문 증명의 방법입니다. 자 시작해 봅시다.

반복문이 시작되는 전에는 i=1입니다. 아직 아무것도 출력되지 않았습니다. 1에서 0까지는 아무것도 없으므로 Loop invariant를 만족합니다.

반복문이 i=k라고 합시다. 이 때에는 1부터 k-1까지 출력되었습니다. 그리고 k까 출력됩니다. 그리고 반복문은 i=k+1인 시작점을 통과하게 됩니다. 이 때에 1부터 k까지 출력되었습니다. 즉 1부터 (k+1)-1까지 출력되었습니다. 그러므로 모든 루프의 시작점에서 위의 성질은 만족합니다.

반복문이 끝나면, i는 N+1이 됩니다. i=N인 루프의 시작점에서 1에서 N-1까지 출력했고, 반복문을 빠져나오기 전에 N를 출력하였습니다. i=N+1일 때 1부터 N까지 출력하였습니다.

즉 반복문을 빠져 나온 시점에 우리가 예상할 수 있는 결과는 1부터 N까지 출력되었다는 것입니다. 이것으로 반복문을 사용한 알고리즘의 증명은 끝났습니다.

무슨 말 장난이냐고 생각하실 분이 계실지 모릅니다. 하지만 이 과정 없이는 스스로 알고리즘을 개발하기는 아주 힘듭니다. 이제 위의 과정을 잘 이해되었다면 쉽게 풀리는 몇가지 문제를 제시함으로써 기사를 마무리 하려고 합니다.

1. 주어진 N에 대하여 N부터 1까지 출력하는 프로그램.
2. 주어진 N(= )에 대하여 1에서 N까지의 짝수를 순서대로 출력하는 프로그램.
3. 주어진 N(= )에 대하여 1에서 N까지의 수 중에서 4로 나누었을 때 2가 남는 수를 순서대로 출력하는 프로그램.
4. 정렬된 정수의 배열 A[1…N]에서 k가 있는지 없는지 확인하는 프로그램. 예를 들어 A[1…5]가 다음과 같이 주어졌다고 하자.



k=8이면 2, k=15이면 -1를 출력해야 한다. 즉 있으면 그 위치를 출력하고 없으면 -1를 출력하는 프로그램.


path와 classpath 정확한 개념 
간단한건데 이해가 잘 안가서요...

path를 잡아주는 이유는 다른 디렉토리에서 컴파일이 가능하게끔 하려고 하는거죠?

잘못 알고 있나..

그렇다면 classpath는요...

 

어떤 파일은 classpath를 걸어줘야 하고 또 다른 문서를 그러지 않아도 되는데 정확한 개념좀 잡아주세요...

 

==================================================================

 

간단하게 생각하시면
path는 os 환경에서 필요한거구, classpath 는 자바 컴파일 할때 필요한 거라고 생각하시면 되구여

자세히 말하면
가령 우리가 윈도우 실행에서 cmd 라고 쳤을때..
command 창이 실행되는건 이것이 path에 잡혀있기 때문입니다.
사실 명령어를 실행하려면.. C:\어쩌구저쩌구\cmd.XXX 를 실행시켜야 겠죠..
이것때문에 우리는 os 환경에서 경로를 다 적을 필요없이..
간단한 명령어만 실행시켜도 실행이 되는겁니다.

하지만 classpath는 자바에서 컴파일 하기위해 classes 가 모여 있는곳을 가르키는 겁니다.
우리가 가령 com.okjsp.util 을 import 한다면..
컴파일 하는곳에선 이 경로를 알아야 합니다.
만약 이것이 c\어쩌구저쩌구\classes\com\okjsp\util 에 있다면..

이경로를 자바 컴파일 하는곳에서는 일일이 경로 지정을 해주어야 합니다.

하지만. 이런식으로
classpath = c\어쩌구저쩌구\
잡아주면 컴파일 경로를 javac에서 자기가 알수 있는겁니다.

 

돌쇠
2005-07-28 17:29:28
 


===============================================================================


1. 처음 jsk 설치시 잡아주는 환경변수 중 CLASSPATH 가 하는 역활이 뭔지요?
2. 설치시 잡아주는 환경변수 CLASSPATH 와 컴파일시 javac -classpath 와 차이점은 무엇인지요?
3. jdk 1.4 부터는 설치시 환경변수 CLASSPATH를 안잡아줘도 상관없다는데 사실인지요?
4. 만일 aaa.java 를 컴파일시 javac -classpath 를 잡아줬을경우 그 패스가 컴파일되면서 aaa.class 안 어딘가에 기억이 되는건지요?
아니면 컴퓨터를 리붓하면 사라지는 휘발성 패스인지요?
아니면 다른 java 파일을 컴파일 할때까지 기억되는 패스인가요?

뽀너스~ 질문하나만 더 드립니다. ^^*
* 클래스와 자바빈즈와 어떤차이가 있나요?
패키지 > 클래스 > 자바빈즈? 이런 의미인가요? ^^;;;


1. classpath의 역할은 class의 path입니다. class파일을 찾는 경로를 지정해주는 것이죠. 마치 path환경변수처럼.
2. javac -classpath c:/tomcat/common/lib/servlet.jar HelloServlet.java

set CLASSPATH=c:/tomcat/common/lib/servlet.jar
javac HelloServlet.java
는 같습니다.
3. 누가 그러던가요? class의 path를 지정해주지 않았는데, 어떻게 찾을 수 있을까요?
4. 클래스패스는 set 또는 env 명령어로 확인할 수 있습니다. 시스템 환경변수에 설정해 놓으면 영구적이고, command 나 cmd 창에서 지정한 경우 해당 창 내에서만 효력이 있습니다.

자바빈즈는 클래스의 형태를 갖고 있습니다.

  • kenu
  • 2003-03-19 02:42:07

     

     

    ===============================================================================

     

    • .java 는 소스 파일(혹은 원시 파일)
      .class 는 클래스 파일이라고 부릅니다.
      혹시 JRE(즉, J2SE JRE)를 설치하신 것은 아닌지...
      JDK(즉, J2SE JDK)를 설치하셨다면
      bin 디렉토리 및에 javac.exe 와 java.exe 가 있을 것입니다.
      javac.exe 는 .java ===> .class (즉, 컴파일) 과정에 쓰이는 도구이고,
      java.exe 는 컴파일된 클래스 파일(.class 파일)중에 특히
      public static void main(String[] args) 라는 메소드가
      있는 클래스 파일(즉, 자바에서 애플리케이션이라고 부르는 것)을
      실행시키는데 쓰이는 도구입니다.

      컴파일할 때는 JAVA_HOME, CLASSPATH, PATH 같은 환경변수들이 미리 설정되어 있어야 합니다.
    • javaclue
    • 2004-08-09 17:06:20
    • x
    • 리플 감사드립니다.
      JDK 설치한건 맞는데, CLASSPATH설정은 안했답니다.
      어떻게 설정해야 하는 건지 모르겠거든요.
      그래서 모든 것을 uninstalling 하고
      한단계씩 낮은 버젼의 JDK와 TOMCAT를 깔았는데
      이젠 Tomcat 자체도 실행이 안되네요.
      ㅠ.ㅠ 환경 설정도 새로 깔린 것으로 바꿔줬는데
      이게 웬 날벼락인지...혹시 os를 새로 깔아야 할까요?
    • 버들
    • 2004-08-09 17:26:56
    • x
    • 환경 변수 때문에 os새로 까는건 방이 맘에 안들어서 집을 새로 짓는 결과아닐까요..??..ㅎㅎ;;;;...
      환경설정에서..시스템 변수에서 새로만들기 클릭하시고
      변수이름 : JAVA_HOME
      변수 값 : ....\jdk

      변수이름 : CATALINA_HOME
      변수 값 : ....\tomcat

      그리고 path변수의 값으로 다음을 추가 합니다.
      (기존설정된변수값들);%JAVA_HOME%\bin;%CATALINA_HOME%\bin
    • nevermind
    • 2004-08-10 03:45:53
    • x
    • 아..글쿤요. 리플 감사 드려요.
      javaclue님,nevermind님
      무지 무지 행복하세요~~꼭이요~~
    • 버들
    • 2004-08-10 10:43:46
    • x
    • 어..저기..근데..."%"표시는 무슨 뜻인가요?
      그리고..-.-;;..CLASSPATH는 어떻게 설정해야 하나요..
      강좌를 봐도 그게 잘 안나와 있어서..
    • 버들
    • 2004-08-10 10:49:40
    • x
    • 환경설정에서 변수 값은 절대 경로 또는 %변수명%을 적어 주시면 됩니다.
      %-%는 경로에 대한 변수를 표시합니다.
      위와 같이 등록하신후 프롬프트 창에서 "c:\>cd %JAVA_HOME%"이라고 치고 엔터 치면 그 경로로 이동합니다.
    • nevermind
    • 2004-08-11 01:49:21
    • x
    • 아~~! 글쿤요~~
      감사합니다요 nevermind님. *^^*
    • 버들
    • 2004-08-11 16:25:11
    • x

     

    출처 : okjsp.pe.kr

     

     

    예)

    CLASS_PATH - %JAVA_HOME%\jre\lib\rt.jar;%JAVA_HOME%\lib\tools.jar;
    JAVA_HOME - C:\Eclipse\JDK
    Path - %JAVA_HOME%\bin;D:\oracle\product\10.2.0\client_2\bin;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;C:\Program Files\ESTsoft\ALZip

  • + Recent posts