알고리듬? 알고리즘?

58
알알알알 (algorithm)? 알알알알 (algorism)? 2015 년 12 년 13 년 | 년년년 ([email protected]) 년 년년년 년년년년년 년년년년년년년 . 년년년년

Transcript of 알고리듬? 알고리즘?

Page 1: 알고리듬? 알고리즘?

알고리듬 (algorithm)? 알고리즘(algorism)?

2015 년 12 월 13 일 | 이철혁 ([email protected])

이 문서는 나눔글꼴로 작성되었습니다 . 설치하기

Page 2: 알고리듬? 알고리즘?

좋은 프로그래머가 가지고 있어야 할 능력이 무엇일까요 ?

당연히 자신이 사용하는 언어 , IDE 와 같은 툴을 다루는 능력 , 개발하는 분야 ( 비즈니스 ) 의 지식 , 혹은 커뮤니케이션 능력 등 을 꼽을 수 있습니다 .

Page 3: 알고리듬? 알고리즘?

물론 앞에서 언급한 능력들은 매우 중요합니다 .단기간에 실력 차이를 보여줄 수 있는 훌륭한

능력입니다 .

하지만 많은 프로그래머들이 가지고 싶어 하는 능력 , 많은 회사에서 채용 시에 중요하게 생각하는 능력 중

하나는 알고리듬 능력일 것 입니다 .

Page 4: 알고리듬? 알고리즘?

알고리듬은 예전에 비해 관심은 적어졌지만 ,꾸준한 관심을 받고 있는 검색어입니다 .

Page 5: 알고리듬? 알고리즘?

일부 언어 , 데이터베이스와 비교해 보면 , 시간의 흐름에 따른 등락은 있지만 꾸준함을 알 수 있습니다 .

Page 6: 알고리듬? 알고리즘?

그리고 전세계에서 우리나라가 높은 관심을 갖고 있음을

Google Trend 를 통해 알 수 있습니다 .

Page 7: 알고리듬? 알고리즘?

일부에서는 코딩인터뷰나 대회가 아니라면 크게 사용되는 경우가 없다고 생각할 수 도 있다고 오해를

받는 경우도 있지만 , 알고리듬 능력은 문제해결 능력으로 불릴 정도로 필수적인 능력임은 분명합니다 .

이제 알고리듬에 대해 쉽게 이야기 해보도록 합시다 .

Page 8: 알고리듬? 알고리즘?

알고리듬 (algorithm), 알고리즘 (algorism) 정확히 알고 계신가요 ?혹시 둘이 같은 걸로 알고 계셨나요 ?

먼저 알고리즘 (algorism) 부터 찾아 봅시다 .

Page 9: 알고리듬? 알고리즘?

알고리즘 (algorism) https://en.wikipedia.org/wiki/Algorismwikipedia 에서 찾아보면 당황할 수 있습니다 .알고리듬 (algorithm) 과 혼동 하지 말라고 바로

나와있지요 .

Page 10: 알고리듬? 알고리즘?

알고리즘 (algorism) Algorism 은 컴퓨터가 사용되기 훨씬 이전부터 사용되던 단어로 숫자를 이용한 연산을 하는 것을

뜻합니다 . 옆의 그림을 보면 어떤 상황인지 좀더 쉽게 알 수 있네요 .

출처 : https://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Gregor_Reisch%2C_Margarita_Philosophica%2C_1508_%281230x1615%29.png/375px-Gregor_Reisch%2C_Margarita_Philosophica%2C_1508_%281230x1615%29.png

Page 11: 알고리듬? 알고리즘?

알고리즘 (algorism)

알고리듬 (algorithm) 은 바로 이 단어에서 파생되었으며 ,

우리가 흔히 사용하는 그 뜻의 단어가 맞습니다 .혼동해서 사용하는 경우도 있고 , 이제는 알고리즘(algorism) 이라는 단어는 사용할 일이 거의 없기

때문에 어떤 단어를 사용하나 알고리듬 (algorithm)을 뜻한 것이겠지만

알고 사용하면 좋겠죠 ^^

Page 12: 알고리듬? 알고리즘?

알고리즘 (algorism) 사실 algorism 은 사람들이 검색도 거의 되지 않고 , Google trend 에서 검색량이 적어 비교대상 조차 되지 못하는 단어입니다 .

Page 13: 알고리듬? 알고리즘?

알고리듬 (algorithm) https://en.wikipedia.org/wiki/Algorithm

알고리듬은 짧게 표현하면 “ An algorithm is a self-contained step-by-step set of operations to be performed.”

실행될 연산들의 집합이 순서대로 포함된 것으로 보면 됩니다 .

Page 14: 알고리듬? 알고리즘?

알고리듬 (algorithm) http://

krdic.naver.com/detail.nhn?docid=25173700#FGN20122

그리고 외래어 표기법에 의해 algorithm 은 알고리듬으로

사용해야 합니다 .

Page 15: 알고리듬? 알고리즘?

알고리듬 = 수수께끼

앞에 어려운 말로 설명했는데 , 일단 알고리듬을 만들어 가는 과정은 수수께끼를 푸는 과정과 같다고 합니다 .

문제 자체의 의미를 파악하고 , 해결에 필요한 중요한 실마리를 찾아 포기하지 않고 조금씩 풀어나가는 것입니다 .

- 출처 : 누워서 읽는 알고리즘 p29 ( 한빛미디어 )

Page 16: 알고리듬? 알고리즘?

알고리듬 = 수수께끼

그럼 실제로 수수께끼 하나를 풀어 봅시다 .

옛날 어느 나라에 승려들만 모여 사는 섬이 있었다 .그들 중에서 어느 사람은 눈이 빨갛고 , 나머지는 갈색이다 . 눈이 빨간 사람은 마법에 걸려 있기 때문에 스스로 눈이 빨갛다는 사실을 깨닫게 되면 그날 밤 12 시에 섬을 떠나야 한다 . ( 원래 문제는 자살을 해야 한다는 내용인데 , 좀 바꾸었습니다 ^^;)

Page 17: 알고리듬? 알고리즘?

알고리듬 = 수수께끼

하지만 승려들은 서로의 눈 색깔에 대해 언급하지 않는다는 불문율이 있었기 때문에 눈 색깔을 알려줄 수도 없고 , 거울같이 자신의 눈 색깔을 볼 수 있는 도구도 없었다 .

그렇기에 눈이 빨간 승려도 자신이 눈이 빨갛다는 것을 모르고 함께 행복하게 함께 살아갈 수 있었다 .

Page 18: 알고리듬? 알고리즘?

알고리듬 = 수수께끼

그러던 어느 날 관광객이 찾아와서 해서는 안될 “당신들 중에서 적어도 한 명은 눈이 빨간색이로군요”라는 말을 남기고 돌아가고 말았다 .

승려들은 생전 처음 눈 색깔에 대한 말이 나왔기 때문에 크게 동요하지 않을 수 없었다 . 그리고 그 날 밤부터 그 섬에서는 일이 일어나기 시작했다 .

과연 어떤 일이 일어났겠는가 ?

Page 19: 알고리듬? 알고리즘?

알고리듬 = 수수께끼

이 수수께끼는 어떻게 보면 난센스 (non-sense) 문제 같기도 하지만 절대 그런 문제는 아닙니다 .

진지하게 논리적으로 생각을 하고 정답을 확인할 때만 다음 페이지로 진행해 봅시다 ^^

Page 20: 알고리듬? 알고리즘?

알고리듬 = 수수께끼

먼저 앞에 이야기 한대로 , 문제 자체의 의미를 파악하는 것이 중요합니다 . 우리에게 이 수수께끼가 요구하는 것은 무슨 일이 일어 났겠느냐는 것 입니다 .

다만 주어진 조건이 정확하지 않습니다 .승려가 몇 명인지 주어지지 않았고 , 그중 한 명 이상의 눈이 빨간 것만 알고 있습니다 . 그러면 승려는 최소한 한 명 이상일 것입니다 .

Page 21: 알고리듬? 알고리즘?

알고리듬 = 수수께끼

그러면 승려가 1 명이라고 가정해 봅시다 .이 경우는 1 명 이상의 승려가 눈이 빨갛다고 했으니 , 이 승려는 눈이 빨간 승려라는 사실을 알았을 것이고 , 다음 날이 오기 전에 섬을 떠날 것 입니다 .

Page 22: 알고리듬? 알고리즘?

알고리듬 = 수수께끼

이제 승려가 2 명이라고 가정해 봅시다 .이 경우부터는 다른 경우의 수가 생깁니다 .눈이 빨간 승려가 1 명이거나 2 명일 수 있습니다 .

Page 23: 알고리듬? 알고리즘?

알고리듬 = 수수께끼

먼저 눈이 빨간 승려가 1 명일 경우…눈이 빨간 승려는 다른 승려의 눈이 갈색인 것을 보고 있으므로 , 자신이 눈이 빨간 승려라는 사실을 깨닫고 다음날이 되기 전에 섬을 떠나게 될 것입니다 .

Page 24: 알고리듬? 알고리즘?

알고리듬 = 수수께끼

하지만 눈이 빨간 승려가 2 명일 경우…눈이 빨간 승려들은 서로의 눈이 빨간색인 것을 보고 있으므로 , 자신이 눈이 빨간 승려라는 사실을 깨닫지 못합니다 . 그렇기에 상대방이 섬을 떠나리라 생각하고 , 섬을 떠나지 않은 채로 다음 날을 맞이 하게 될 것 입니다 .

Page 25: 알고리듬? 알고리즘?

알고리듬 = 수수께끼

다음날이 되고 나서야 서로가 섬에서 떠나지 않았다는 것으로 서로가 눈이 빨간 승려라는 것을 깨닫게 되고 섬을 떠나게 될 것입니다 . 따라서 눈이 빨간 승려가 2 명 일 때는 2 일째 섬을 떠나게 될 것입니다 .

Page 26: 알고리듬? 알고리즘?

알고리듬 = 수수께끼

마지막으로 승려가 3 명이라고 가정하면 또 빨간 승려는 각각 1 명 , 2 명 , 3 명일 경우가 발생합니다 .1 명일 때 , 2 명일 때는 앞에 경우와 같으므로 , 3명일 때만 생각해봅시다 .

Page 27: 알고리듬? 알고리즘?

알고리듬 = 수수께끼

모든 승려는 자기를 제외한 두 사람이 눈이 빨간 승려라고 생각할 것 입니다 . 그렇기에 첫 날은 아무도 섬을 떠나지 않고 다음 날을 맞이할 것 입니다 .

Page 28: 알고리듬? 알고리즘?

알고리듬 = 수수께끼

2 일째가 되어도 자신이 눈이 빨간 승려인줄 모르고 , 남은 두 승려가 자신이 빨간 승려인지 모르고 섬을 떠나지 않은 것으로 생각하고 , 2 명의 승려가 눈이 빨간 경우와 마찬가지로 깨닫게 되어 떠날 것으로 생각할 것 입니다 .

Page 29: 알고리듬? 알고리즘?

알고리듬 = 수수께끼

다음날이 되어도 자신이 눈이 빨간 승려인줄 모르고 , 남은 두 승려가 자신이 빨간 승려인지 몰라서 섬을 떠나지 않은 것으로 생각하고 , 이제 서로 깨닫게 되어 떠날 것으로 생각할 것 입니다 .( 2 명의 승려 중 2 명이 빨간 눈의 승려일 때 와 같은 상황 )

Page 30: 알고리듬? 알고리즘?

알고리듬 = 수수께끼

이제 4 명 , 5 명 , 6 명 등을 해보면 모두 아래와 같은 결과를 얻게 될 것입니다 . 수수께끼에서 말한 일어날 일은 m 명의 승려 중에 n 명의 빨간 승려가 있다면 결국 n 일이 될 때 함께 떠난 다는 것입니다 .

Page 31: 알고리듬? 알고리즘?

알고리듬 ≠ 수수께끼

앞에서 수수께끼를 해결하기 위해 논리적으로 생각 해보고 , 상황을 가정하고 차근차근 풀어가는 모습은 알고리듬을 만들어갈 때와 같을 수 있지만 , 이 자체가 완벽한 알고리듬은 아닙니다 .

몇 개의 값 만 입력해서 규칙적인 답이 나왔다고 그 것을 답으로 확정하면 , 다른 입력 값에 의해 다른 결과가 발생할 수 있기 때문에 주의해야 합니다 .

Page 32: 알고리듬? 알고리즘?

잘못된 명제

“ 모든 소수 p 에 대해서 2^p – 1 은 소수다” 라는 잘못된 가설이 오랫동안 사실로 받아들여지고 있었습니다 .

소수인 2, 3, 5, 7 의 값을 대입해보면 결과가 소수이기 때문에 맞는 말로 생각되었지만 , 11 을 대입하고 얻은 2047 이 23 과 89 의 곱을 표현될 수 있다는 사실이 발견되어 잘못된 것임으로 드러났습니다 .

Page 33: 알고리듬? 알고리즘?

잘못된 명제

앞에서와 마찬가지로 절대 몇 개의 값만 테스트 해서는 절대 완벽한 알고리듬이 탄생할 수 없음을 한 번 더 강조합니다 ! ^^

Page 34: 알고리듬? 알고리즘?

남은 수 찾기…

이번엔 좀 더 프로그래밍 같은 문제를 생각해 봅시다 .

작업의 결과로 itemList 와 selectedItemList 2개의 배열을 받게 되었습니다 .

- itemList 배열 : 1 부터 100 까지 숫자가 100개가 들어 있습니다 .- selectedItemList : itemList 배열에서

무작위로 하나씩 뽑아 99 개를 담았습니다 .

Page 35: 알고리듬? 알고리즘?

남은 수 찾기…

즉 selectedItemList 배열에는 itemList 에서 1 개의 숫자만 모자란 배열입니다 .selectedItemList 에서 없는 숫자는 무엇일까요 ?

Page 36: 알고리듬? 알고리즘?

남은 수 찾기…

처음에 떠올릴 수 있는 생각 ,가장 쉽게 생각할 수 있는 것은

itemList 배열에서 하나씩 꺼내서 selectedItemList 배열에 있는지 찾는 것 입니다 .

Page 37: 알고리듬? 알고리즘?

남은 수 찾기…

java 로 구현한다면 아래와 같을 방식일 것 입니다 .

Page 38: 알고리듬? 알고리즘?

남은 수 찾기…

for 를 2번 이용해서 모든 배열을 값을 비교하게 됩니다 .for 안에서 총 몇 번의 비교를 하게 될까요 ?

Page 39: 알고리듬? 알고리즘?

남은 수 찾기…

운이 좋은 경우 itemList 의 첫 번째 값이 se-lectedItemList 에 안 들어 있는 경우라면 ,

첫 번째 for 1번 * 두 번째 for 99번 = 99번

Page 40: 알고리듬? 알고리즘?

남은 수 찾기…

운이 안 좋은 경우 itemList 의 마지막 값이라면 ..

첫 번째 for 100번 * 두 번째 for 99번 = 9900번

itemList 배열이 100 개라서 이렇지만 , 만약 10,000 개라면 최악의 경우에는 어떻게 될까요 ?

첫 번째 for 10,000번 * 두 번째 for 9,999번 = 99,990,000번…

Page 41: 알고리듬? 알고리즘?

남은 수 찾기…

10,000 개의 경우를 100번씩 연속 계산을 15번 돌리면…

개인용 컴퓨터에서 7000~8000ms

정도의 성능이 나옵니다 . 이보다 더 빠르게 할 수 있는 방법은 없을까요 ?

Page 42: 알고리듬? 알고리즘?

남은 수 찾기…

for 를 2번 쓰기에 비교 횟수가 곱하기로 늘어나고 있습니다 . for 를 한 번만 쓸 방법은 없을까요 ?

for 를 중복으로 겹쳐서 쓰는 이유는 selecte-dItemList 가 무작위로 정렬이 되어 있어서 그런 것임을 파악해야 합니다 .

만약 selectedItemList 를 정렬하고 비교를 한다면 ?한번의 for 문으로 충분 합니다 .

Page 43: 알고리듬? 알고리즘?

남은 수 찾기…

java 로 구현한다면 아래와 같을 방식일 것 입니다 .

Page 44: 알고리듬? 알고리즘?

남은 수 찾기…

여기서는 별도의 정렬 로직을 만들지 않고 Collections.sort 를 이용하였습니다 .

주의 해야 할 점은 어떤 정렬 방식을 사용하느냐에 따라 오히려 더 늦어지는 결과를 얻을 수도 있게 됩니다 .

참고로 Collections.sort 는 merge sort 라는 방식으로 진행됩니다 .

Page 45: 알고리듬? 알고리즘?

남은 수 찾기…

10,000 개의 경우를 100번씩 연속 계산을 15번 돌리면…

개인용 컴퓨터에서 224~316ms

정도의 성능이 나옵니다 . 이전 알고리듬 보다 무려 20~30배나 빨라진 것이 보입니다 .

만족할 수도 있지만 이보다 더 빠르게 할 수 있는 방법은 없을까요 ?

Page 46: 알고리듬? 알고리즘?

남은 수 찾기…

정렬도 큰 비용입니다 . 정렬을 하지 않고 for 문을 중복해서 사용하지 않는 다면 더 빠를 수 있지 않을까요 ?

Page 47: 알고리듬? 알고리즘?

남은 수 찾기…

수학적인 사고를 동원하면 더 빠르게 계산할 수 있는 방법을 찾아낼 수 있습니다 .

사실 우리가 찾으려는 숫자는

itemList 배열의 모든 값을 합한 값- selectedItemList 배열의 모든 값을 합한 값

입니다 .

Page 48: 알고리듬? 알고리즘?

남은 수 찾기…

java 로 구현한다면 아래와 같을 방식일 것 입니다 .

Page 49: 알고리듬? 알고리즘?

남은 수 찾기…

10,000 개의 경우를 100번씩 연속 계산을 15번 돌리면…

개인용 컴퓨터에서 49~67ms 정도의 성능이 나옵니다 .

이전 알고리듬 보다 무려 3.2~6배나 빨라진 것이 보입니다 .

만족할 수도 있지만 이보다 더 빠르게 할 수 있는 방법은 없을까요 ?

Page 50: 알고리듬? 알고리즘?

남은 수 찾기…

앞에서는 for 문을 2번 이용하였습니다 .이 두 개의 for 문이 모두 필요한 걸까요 ?

하나의 for 문을 줄이면 조금 더 성능 향상이 일어날 것 같습니다 .

Page 51: 알고리듬? 알고리즘?

남은 수 찾기…

앞의 for 문이 단순히 1 부터 100 까지의 숫자의 합을구하는데 사용됐다는 것을 주목해야 합니다 .

1 부터 100 까지 숫자를 더하는데 for 문을 이용할필요가 없기 때문입니다 .

바로 가우스가 어렸을 때 알아낸 1 부터 100 은 (1 + 100 ) + ( 2 + 99 ) + ( 3 + 98 ) + … ( 50 + 51 )즉 101 * 50 = 5,050 이라는 것을 이용하면 됩니다 .

Page 52: 알고리듬? 알고리즘?

남은 수 찾기…

java 로 구현한다면 아래와 같을 방식일 것 입니다 .

Page 53: 알고리듬? 알고리즘?

남은 수 찾기…

10,000 개의 경우를 100번씩 연속 계산을 15번 돌리면…

개인용 컴퓨터에서 45~49ms 정도의 성능이 나옵니다 .

이전 알고리듬 보다 아주 조금이지만 빨라진 것이 보입니다 .

만족할 수도 있지만 이보다 더 빠르게 할 수 있는 방법은 없을까요 ?

Page 54: 알고리듬? 알고리즘?

남은 수 찾기…

코드적으로 본다면 , for 문 안에 비교를 위해 .size() 함수가 매번 호출되는 것이나…ArrayList 대신 Arrays 를 사용하는 것…

여러가지가 있을 수 있습니다 ^^

더 빠르게 하는 방법이 아니더라도 다른 방법에 대한이제 고민을 해보시길 바랍니다 ~

Page 55: 알고리듬? 알고리즘?

남은 수 찾기…

참고로 문제를 만드는 짧은 코드를 공유합니다 .

Page 56: 알고리듬? 알고리즘?

남은 숙제…

앞의 예제들은 어떤 문제에 대해 해결하는 방법… 즉 알고리듬에 따라 얼마나 큰 차이가 있는 보여주는 작은 예일 뿐입니다 .

간단한 문제와 몇 줄의 소스만으로도 큰 차이가 있는 것에 알게 되어 다른 좋은 책들과 연습을 통해 도움이 되는 계기가 되길 바랍니다…

Page 57: 알고리듬? 알고리즘?

이 슬라이드에 나온 문제와 일부 내용은 누워서 읽는 알고리즘을 이용하였습니다 .http://book.naver.com/bookdb/book_detail.nhn?bid=9685856

Page 58: 알고리듬? 알고리즘?

이 문서는 나눔글꼴로 작성되었습니다 . 설치하기