<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Holik in everything! &#187; Algorithm</title>
	<atom:link href="http://holik.org/tag/algorithm/feed/" rel="self" type="application/rss+xml" />
	<link>http://holik.org</link>
	<description>Jihoon&#039;s Life story.</description>
	<lastBuildDate>Tue, 02 Nov 2010 02:26:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>NP 문제</title>
		<link>http://holik.org/2009/10/18/np-%eb%ac%b8%ec%a0%9c/</link>
		<comments>http://holik.org/2009/10/18/np-%eb%ac%b8%ec%a0%9c/#comments</comments>
		<pubDate>Sat, 17 Oct 2009 17:26:21 +0000</pubDate>
		<dc:creator>Jihoon</dc:creator>
				<category><![CDATA[Research]]></category>
		<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[NP-complete]]></category>

		<guid isPermaLink="false">http://holik.org/?p=318</guid>
		<description><![CDATA[살면서 여러가지 문제들에 마주치다보면 어떤 것은 매우 쉽고 빠르게 해결할 수 있는 반면에, 해결하기가 매우 어렵고 오래 걸리는 일도 있습니다. 컴퓨터학에서는 문제의 어려움을 계산 복잡도를 사용하여 나타냅니다. 쉽고 빠르게 해결할 수 있는 문제들은 계산 복잡도가 낮다고 하며, 해결하기 어렵고 복잡한 문제일수록 계산 복잡도가 높다고 합니다. 그런데, 어떤 문제들은 적절한 시간 내에 풀 수 있을지 없을지조차 모르는 [...]]]></description>
			<content:encoded><![CDATA[<p>살면서 여러가지 문제들에 마주치다보면 어떤 것은 매우 쉽고 빠르게 해결할 수 있는 반면에, 해결하기가 매우 어렵고 오래 걸리는 일도 있습니다. 컴퓨터학에서는 문제의 어려움을 <a href="http://en.wikipedia.org/wiki/Computational_complexity_theory" target="_blank">계산 복잡도</a>를 사용하여 나타냅니다. 쉽고 빠르게 해결할 수 있는 문제들은 계산 복잡도가 낮다고 하며, 해결하기 어렵고 복잡한 문제일수록 계산 복잡도가 높다고 합니다. 그런데, 어떤 문제들은 적절한 시간 내에 풀 수 있을지 없을지조차 모르는 것들도 있습니다. 다음의 문제를 하나 봅시다.</p>
<blockquote><p>당신은 휴가를 맞아 여행을 가기로 하였습니다. 비록 휴가는 일주일 밖에 안되지만, 욕심이 많은 당신은 이집트, 스페인, 네덜란드 3개국의 카이로, 알렉산드리아, 바르셀로나, 그라나다, 마드리드, 암스테르담, 헤이그 7개 도시를 방문하려고 합니다. 각 도시들 사이에는 직행 비행기로 이동할 수 있다고 할 때, 쾌적한 여행을 즐길 수 있도록 도시를 중복 방문하는 일 없이 최단 거리 여행 계획을 짜보세요!</p></blockquote>
<p>당신은 지도를 펴놓고 고민하기 시작합니다. 당신은 한 도시에서 다른 도시로 넘어갈 때 근처에 있는 도시를 먼저 방문하는 것이 최단 경로를 줄이는 방법이라는 것을 알고 있습니다. 따라서 도시들을 어떤 순서로 방문해야 쾌적한 여행을 즐길 수 있는지 그다지 고민하지 않고 결정할 수 있습니다. <span style="background-color: #ffffff;">하지만 이 문제를 컴퓨터에게 풀게 한다면, 컴퓨터는 한 도시를 방문한 후 어떤 도시를 방문해야 쾌적한 여행이 될지 결정할 수 없습니다. 따라서 도시를 중복 방문하지 않는 수많은 여행 코스<sup><a href="http://holik.org/2009/10/18/np-%eb%ac%b8%ec%a0%9c/#footnote_0_318" id="identifier_0_318" class="footnote-link footnote-identifier-link" title="7개의 도시를 중복되지 않게 방문하므로, 총 방법의 수는 6! = 720개가 됩니다.">1</a></sup> 를 모두 비교하여 최단 코스가 무엇인지 찾아내야 할 겁니다. </span></p>
<p>이와 같이, 어떤 알고리즘을 수행하는데 있어 한 단계에서 다음 단계로 진행할 때 여러 선택권을 가질 수 있는 문제들을 <span style="background-color: #ffffff;">NP (Non-deterministic in Polynomial time) 문제라고 합니다<sup><a href="http://holik.org/2009/10/18/np-%eb%ac%b8%ec%a0%9c/#footnote_1_318" id="identifier_1_318" class="footnote-link footnote-identifier-link" title="NP 문제의 정의는 비결정적인 알고리즘(non-deterministic algorithm)을 사용하여 적절한 시간(polynomial time) 내에 해결이 가능한 문제입니다.">2</a></sup>.</span></p>
<p><a href="http://en.wikipedia.org/wiki/NP_%28complexity%29" target="_blank"><img class=" aligncenter" title="NP problems" src="http://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Complexity_classes.svg/414px-Complexity_classes.svg.png" alt="NP problems" width="414" height="255" /></a></p>
<p>위의 그림처럼, NP 문제는 크게 P 문제와 NP-Complete 문제로 나눌 수 있습니다. P 문제는 결정적인(deterministic) 알고리즘을 사용하여 적절한 시간 (polynomial time) 안에 해결할 수 있는 문제입니다. 반면에 NP-Complete 문제들은 비결정적인(non-deterministic) 알고리즘으로는 적절한 시간 내에 해결할 수 있지만, 결정적인 알고리즘으로는 적절한 시간 안에 해답을 얻을 수 있는 방법을 찾지 못한 문제들 입니다. NP-Compete 문제들의 특징은 해결 방법이 없는 것이 아니라, 해결 방법이 있지만 입력의 크기가 커질수록 계산복잡도가 엄청나게 커진다는 것입니다<sup><a href="http://holik.org/2009/10/18/np-%eb%ac%b8%ec%a0%9c/#footnote_2_318" id="identifier_2_318" class="footnote-link footnote-identifier-link" title="일반적으로 NP-Complete 문제들의 계산복잡도는 sn 에 비례합니다. 여기서&nbsp;s는 상수, n은 입력의 크기">3</a></sup>. 그래서 NP-Complete 문제들은 보통 다음의 세 접근 방법을 통해 해결합니다.</p>
<ul>
<li>Approximate algorithm: 적절한 범위 내에서 차선의(suboptimal) 해결책을 구하는 알고리즘입니다.</li>
<li>Probabilistic algorithm: 문제의 입력의 확률 분포에 대하여 평균적으로 좋은 성능을 보이는 알고리즘입니다.</li>
<li>Heuristic algorithm: 대부분의 경우에 잘 동작하지만, 항상 최선의 결과를 얻는다는 보장은 없는 알고리즘입니다.</li>
</ul>
<p>NP 문제에서 단연 최고의 이슈가 되고 있는 것은 &#8216;<span style="background-color: #ffffff;">P=NP?&#8217; 입니다. (이 문제는 용의자 X의 헌신에도 나왔었죠.) 즉, &#8216;NP에 속하는 모든 문제는 결정적인 알고리즘을 사용하여 적절한 시간 내에 해결할 수 있다.&#8217; 라는 명제가 참인지 거짓인지를 판명하는 것입니다. 만약 이 명제가 참이 된다면, 모든 NP-Complete 문제들은 쉽게 해결할 수 있는 방법이 있다는 것이 되므로 엄청난 센세이션을 불러일으키게 되겠죠. 현재는 &#8216;P 문제는 NP 문제가 될 수 있다.&#8217; 라는 명제가 참이라는 것까지 증명된 상태입니다. (Denis Shasha, 1995)</span></p>
<p>NP-Complete 문제들은 정말 상당히 흥미로운 것들이 많습니다. 그 중에서도, 그래프는 본연의 구조적 특성 때문에 일반적으로 연산이 굉장히 복잡해서, 상당히 많은 NP-Complete 문제들이 있습니다. 다음엔 그래프에서의 NP-Complete 문제들에 대해 포스팅해보겠습니다.</p>
<p>NP 문제와 관련된 추천 사이트</p>
<ul>
<li><span style="background-color: #ffffff;"><a href="http://page.mi.fu-berlin.de/aneumann/npc.html" target="_blank">Graph of NP-Complete Problems</a>: NP-Complete 문제들을 그래프로 보여줍니다.</span></li>
<li><span style="background-color: #ffffff;"><a href="http://page.mi.fu-berlin.de/aneumann/npc.html" target="_blank"></a><a href="http://rjlipton.wordpress.com/" target="_blank">Gödel’s Lost Letter and P=NP</a>: 조지아 텍 교수인 Dick Lipton의 블로그입니다. 알고리즘에 관한 흥미로운 글이 많이 올라옵니다.</span></li>
</ul>
<p><br class="spacer_" /></p>
<ol class="footnotes"><li id="footnote_0_318" class="footnote">7개의 도시를 중복되지 않게 방문하므로, 총 방법의 수는 6! = 720개가 됩니다.</li><li id="footnote_1_318" class="footnote">NP 문제의 정의는 비결정적인 알고리즘(non-deterministic algorithm)을 사용하여 적절한 시간(polynomial time) 내에 해결이 가능한 문제입니다.</li><li id="footnote_2_318" class="footnote">일반적으로 NP-Complete 문제들의 계산복잡도는 <em>s</em><sup><em>n</em></sup> 에 비례합니다. 여기서 <em>s</em>는 상수, <em>n</em>은 입력의 크기</li></ol><p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://holik.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://holik.org/2009/10/18/np-%eb%ac%b8%ec%a0%9c/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Database에서 사용되는 join 기법들</title>
		<link>http://holik.org/2009/06/16/database%ec%97%90%ec%84%9c-%ec%82%ac%ec%9a%a9%eb%90%98%eb%8a%94-join-%ea%b8%b0%eb%b2%95%eb%93%a4/</link>
		<comments>http://holik.org/2009/06/16/database%ec%97%90%ec%84%9c-%ec%82%ac%ec%9a%a9%eb%90%98%eb%8a%94-join-%ea%b8%b0%eb%b2%95%eb%93%a4/#comments</comments>
		<pubDate>Tue, 16 Jun 2009 13:17:19 +0000</pubDate>
		<dc:creator>Jihoon</dc:creator>
				<category><![CDATA[Research]]></category>
		<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Join]]></category>

		<guid isPermaLink="false">http://holik.org/?p=148</guid>
		<description><![CDATA[이 글은 Sachin Arora의 Nested loops, Hash join and Sort Merge joins – difference? 라는 글에 기초하여 약간의 수정을 가한 것입니다. 1. Nested loop join (loop over loop) 이 알고리즘은 외부 루프와 내부 루프로 구성된다. 외부 루프는 몇몇의 엔트리로 구성되며, 외부 루프의 각 엔트리마다 내부 루프가 수행된다. 예) Select tab1.*, tab2.* from tabl, tab2 where [...]]]></description>
			<content:encoded><![CDATA[<p>이 글은 Sachin Arora의 <a href="http://oracle-online-help.blogspot.com/2007/03/nested-loops-hash-join-and-sort-merge.html">Nested loops, Hash join and Sort Merge joins – difference?</a> 라는 글에 기초하여 약간의 수정을 가한 것입니다.<br />
<span style="font-weight: bold;"><br />
1. Nested loop join (loop over loop)</span></p>
<p>이 알고리즘은 외부 루프와 내부 루프로 구성된다. 외부 루프는 몇몇의 엔트리로 구성되며, 외부 루프의 각 엔트리마다 내부 루프가 수행된다.</p>
<p class="MsoNormal"><o:p></o:p>예)</p>
<p class="MsoNormal">
<div style="border: 1px solid rgb(203, 203, 203); padding: 10px; background-color: rgb(132, 132, 132); color: rgb(255, 255, 255);" class="txc-textbox">
Select tab1.*, tab2.* from tabl, tab2 where tabl.col1=tab2.col2;</div>
<p>
이 SQL문은 다음과 같이 수행된다.</p>
<div style="border: 1px solid rgb(203, 203, 203); padding: 10px; background-color: rgb(132, 132, 132); color: rgb(255, 255, 255);" class="txc-textbox">
For i in (select * from tab1) loop</p>
<div style="margin-left: 4em;">
For j in (select * from tab2 where col2=i.col1) loop
</div>
<div style="margin-left: 8em;">
Display results;
</div>
<div style="margin-left: 4em;">
End loop;
</div>
<div>
End loop;</div>
</div>
<p></p>
<p class="MsoNormal" style="margin-left: 0.5in; text-indent: -0.25in;"><o:p></o:p>Nested loop join의 수행에 포함되는 단계들은 다음과 같다.
</p>
<p class="MsoNormal" style="margin-left: 0.5in; text-indent: -0.25in;">1) 외부 테이블 확인한다 (identify).
</p>
<p class="MsoNormal" style="margin-left: 0.5in; text-indent: -0.25in;">2) 내부 테이블을 외부 테이블에 할당한다.
</p>
<p class="MsoNormal" style="margin-left: 0.5in; text-indent: -0.25in;">3) 외부 테이블의 각 행마다 내부 테이블의 전체 행들을 접근한다.
</p>
<p><span style="font-style: italic;">Optimizer는 언제 nested loop join을 사용하는가?</span></p>
<p>효율적인 join 조건으로 적은 수의 행을 담고 있는 테이블을 조인할 때 optimizer가 nested loop join을 사용한다. 외부 테이블의 각 행 마다 매번 내부 테이블의 전체 행을 확인하기 때문에 내부 테이블을 색인하는 것이 중요하다.</p>
<p>다음의 경우에는 nested loop join을 사용하지 않는다.</p>
<ol style="list-style-type: decimal;">
<li>조인하려는 테이블들의 크기가 클 때</li>
<li>내부 질의가 항상 같은 결과를 낼 때
</li>
<li>내부 테이블의 접근 경로가 외부 테이블의 데이터에 독립적일 때
</li>
</ol>
<p><!--[endif]--> <i style=""><u></u></i><br />
<span style="font-weight: bold;">2. Hash join</span></p>
<p>Hash join은 큰 데이블을 조인할 때 사용된다. Optimizer는 2개의 테이블 중 더 작은 테이블을 사용하여 메모리에 해쉬 테이블을 생성하고, 큰 테이블 전체를 스캔하면서 해쉬 값을 비교한다.</p>
<p>Hash join 알고리즘은 다음의 두 단계로 구성된다.</p>
<ol style="list-style-type: decimal;">
<li><span style="font-weight: bold;">Build</span> 단계: 두 테이블 중 더 작은 테이블로 해쉬 테이블을 메모리에 생성한다.</li>
<li><span style="font-weight: bold;">Probe</span> 단계: 큰 테이블을 스캔하면서 해쉬 값을 비교하여 join 되는 행을 찾는다.
</li>
</ol>
<p>간단하게 알고리즘을 적으면 다음과 같다.</p>
<p class="MsoNormal"><i style=""><u>Build 단계<o:p></o:p></u></i></p>
<p class="MsoNormal">
<div style="border: 1px solid rgb(203, 203, 203); padding: 10px; background-color: rgb(132, 132, 132); color: rgb(255, 255, 255);" class="txc-textbox">
For each row RW1 in small (left/build) table loop</p>
<div style="margin-left: 4em;">
Calculate hash value on RW1 join key
</div>
<div style="margin-left: 4em;">
Insert RW1 in appropriate hash bucket.
</div>
<div>
End loop;</div>
</div>
<p></p>
<p class="MsoNormal">
<p class="MsoNormal"><i style=""><u>Probe 단계</u></i></p>
<p class="MsoNormal">
<div style="border: 1px solid rgb(203, 203, 203); padding: 10px; background-color: rgb(132, 132, 132); color: rgb(255, 255, 255);" class="txc-textbox">
For each row RW2 in big (right/probe) table loop</p>
<div style="margin-left: 4em;">
<span style="">            </span>    Calculate the hash value on RW2 join key
</div>
<div style="margin-left: 4em;">
<span style="">            </span>    For each row RW1 in hash table loop
</div>
<div style="margin-left: 8em;">
  If RW1 joins with RW2
</div>
<div style="margin-left: 12em;">
  output (RW1, RW2)
</div>
<div style="margin-left: 4em;">
End loop;
</div>
<div>
End loop;</div>
</div>
<p style="font-style: italic;" class="MsoNormal">Optimizer는 언제 hash join을 사용하는가?</p>
<p class="MsoNormal">Optimizer는 조인하려는 테이블의 크기가 큰 경우에 사용한다. Nested loop와 다르게, hash join은 해쉬 테이블 생성 후에 join이 이루어지기 때문에 결과가 즉시 나오지 않는다.<br />
<i style=""><u><o:p></o:p></u></i></p>
<p class="MsoNormal">
<p>
<span style="font-weight: bold;">3. Sort merge join</span></p>
<p>Sort merge join은 두 개의 독립적인 데이터 소스를 조인하는 경우에 사용된다. 이 방법은 일반적으로 데이터의 크기가 큰 경우에 nested loop보다 성능이 좋지만 hash join만큼 좋지는 않다.</p>
<p>이 방법이 hash join보다 좋을 때는 join 조건으로 사용되는 열이 이미 정렬되어 있거나 정렬될 필요가 없을 때이다.</p>
<p>알고리즘은 다음과 같다.</p>
<p class="MsoNormal" style="margin-left: 0.5in;"><o:p></o:p></p>
<div style="border: 1px solid rgb(203, 203, 203); padding: 10px; background-color: rgb(132, 132, 132); color: rgb(255, 255, 255);" class="txc-textbox">
While not at the end of either input loop</p>
<div style="margin-left: 4em;">
<span style="">        </span>    If RW1 key == RW2 key
</div>
<div style="margin-left: 8em;">
Output (RW1, RW2)</div>
<div style="margin-left: 8em;">
Get next row R1 from input 1
</div>
<div style="margin-left: 8em;">
<span style="">                </span>    Get next row R2 from input 2
</div>
<div style="margin-left: 4em;">
<span style="">        </span>    Else if RW1 key &lt; RW2 key
</div>
<div style="margin-left: 8em;">
Get next row RW1 from input 1
</div>
<div style="margin-left: 4em;">
<span style="">        </span>    Else
</div>
<div style="margin-left: 8em;">
Get next row RW2 from input 2
</div>
<div>
<span style=""> </span>End loop;</div>
</div>
<p class="MsoNormal" style="margin-left: 0.5in;">
<p>
중요한 점은 외부 테이블의 행의 개수만큼 내부 테이블에 접근하여야 하는 nested loop join과는 다르게, sort merge join 알고리즘은 테이블의 각 행을 단 한 번씩만 접근한다. 따라서 데이터의 크기가 클 때 nested loop join보다 더 좋은 성능을 보인다.</p>
<p>Optimizer는 언제 sort merge join을 사용하는가?</p>
<ol style="list-style-type: upper-alpha;">
<li>join 조건이 부등 조건일 경우 (&lt;, &lt;=, &gt;=)에 사용한다. hash join은 부등 조건에 사용될 수 없고, 데이터의 크기가 큰 경우 nested loop join은 고려의 대상이 아니다.</li>
<li>&#8220;order by&#8221;와 같이, 만약 어떤 속성에 대하여 항상 정렬해야하는 경우, hash join보다 sort merge join이 더 좋은 성능을 보이기 때문에 optimizer는 sort merge join을 사용한다.
</li>
</ol>
<p><i style=""></i></p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://holik.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://holik.org/2009/06/16/database%ec%97%90%ec%84%9c-%ec%82%ac%ec%9a%a9%eb%90%98%eb%8a%94-join-%ea%b8%b0%eb%b2%95%eb%93%a4/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

