2018.11.12 오전 01:30 (KR) Emirates Stadium


라인업





 

 Match Stats

 

Arsenal


Wolverhampton Wanderers F.C.

71.7

점유율%

28.3

10

슛팅

13

3

유효슛팅

5

734

패스시도

291

4

클리어런스

26

11

코너킥

2

1

오프사이드

2

9

파울

16



다소간 향상된 그의 퍼포먼스에도 불구하고, 울브스전에 보여준 자꾸 정줄 놓는 모습은 자카가 가진 기본적 결함을 잘 드러내준다.


그라니트 자카는 아스널의 수수께끼다. 분데스리가 역사상 최연소 주장에 걸맞은 £30M의 이적료로 보루시아 묀헨글라드바흐로부터 이적해온 자카는, 때로는 열렬한 박수갈채를 받은 플레이를, 때로는 팬들을 크게 좌절시키는 플레이를 선보여왔다.

이를 극명하게 드러낸 것이 지난 일요일 울브스와의 경기였다. 26세의 자카는 거너스 유니폼을 입은 후 가히 최고의 퍼포먼스를 보여줬던 지난 라운드 리버풀전 이후 아주 높은 기대를 받으며 경기에 나섰다.

루카스 토레이라의 합류는 자카에게 더 많은 자유를 주었고, 잠깐 동안 레프트백 자리에서 땜빵을 뛴(이는 복합적 결과를 낳았다) 이후에 리버풀을 상대로 보여준 자카의 모든 플레이는 드디어 이 선수가 북런던에서 완전히 자신에 맞는 역할을 찾은 것처럼 보였다.

그는 피치 위의 어느 누구보다 많은 패스를 성공시켰고, 가장 많은 볼 탈취와 태클을 기록했으며, 지난 시즌 챔피언스리그 결승 진출팀 리버풀이 평상시와 같은 자유로운 플레이를 할 수 없도록 만드는 데 있어서 (토레이라와 함께) 핵심적 역할을 했다.

허나 승격팀 울브스와의 경기에선, 모든 좋지 않은 이유로 관심 집중의 대상이 되어버리고 만 자카였다.

울브스전 89%의 패스성공률에도 불구하고, 물론 그가 경기 초반에 받은 세아드 콜라시나츠의 패스가 굉장히 나쁘긴 했지만, 어쨌든 집중력을 잃어버린 자카는, 원정팀 울브스의 이반 카바예로가 선제골을 넣도록 찬스를 헌납해버렸다. 정규시간 종료 4분 전 터진 헨리크 미키타리안의 동점골이 아니었다면 이 실수가 경기 결과를 결정해버렸을 것이다.

울브스전 자카가 소유권을 잃어버린 상황은 29차례 나왔고, 이는 다른 어떤 선수가 기록한 것보다 많았다. 2016년 아스널에서의 데뷔 이후 자카는 이제 리그에서 실점으로 직결된 실수를 5회나 저질렀고, 이는 같은 기간 리그의 모든 선수를 통틀어 가장 많다.

우나이 에메리: (자카의 실수에 대해 질문받자)

"그는 아주 헌신적이고 개성이 있습니다. 그의 퍼포먼스와 퀄리티는 좋습니다. 우리는 팀원 모두를 필요로 합니다. 저도 그렇고 팀도 그렇고, 우린 더욱 꾸준해야만 합니다. 제 생각엔 가장 작은 부분부터 하나하나 만들어가며 자신감을 얻고 더 큰 일도 이뤄내는 것이 중요한 것 같습니다. 우리는 그걸 해내고 있고 자카 역시 그러고 있다고 생각합니다."

물론 에메리 체제에서의 아스널이 아주 인상적이긴 하지만, 자카의 기복은 아스널의 팀적 시스템 차원의 문제이며 계속해서 그들의 발등을 스스로 찍는 것과 다름이 없다.

지난 시즌 시작부터 지금까지를 기준으로, 상대의 실점으로 이어진 개인 실수를 아스널보다(17회) 더 많이 저지른 상위권[*역자 주: 빅6를 뜻하는 듯] 팀은 없으며, 16연속 무패행진은 분명 박수갈채를 받아 마땅하지만, 아스널이 앞으로도 저러한 실수를 더 저지르지 말란 법도 없다.

에메리가 앞으로 얼마나 더 자카를 참을성 있게 기다려줄 수 있을 것인지에 대해서는 지켜봐야 한다. 파이널 써드 지역으로 공을 연결해주는 자카의 능력은 리그 최상위권 수준이지만, 최근 크리스탈 팰리스전에 나온 그의 프리킥은 그가 무에서 유를 창조할 수 있으면서도, 탑 4에 들 수 있을지 없을지를 결정해버릴 수도 있는 차이가 돼버릴 수도 있다는 점을 강조해줄 뿐이다. [*역자 주: 정확한 해석인지 모르겠네요. 도와주세요 영잘알분들. 원문 - His ability to provide a link into the final third is up there with the very best in the league while his recent free-kick against Crystal Palace only serves to highlight that he is a player capable of providing a moment out of nothing who could yet be the difference between a place in the top four or outside come to the final knockings.]

에메리가 끝내 자카에 대한 인내심을 완전히 잃어버린다면, 벌써 국가대표로 국제대회를 3차례나 나선 자카보다 경험은 많이 부족하긴 해도, 마테오 귀엔두지와 에인슬리 메이틀랜드-나일스가 대체자로서 가능하다. 심지어 에메리에겐 아론 램지를 토레이라 옆자리에 세운다는 선택지도 있다. 비록 램지는 내년 여름 자유계약으로 팀을 떠날 것이 확실시되고, 에메리는 그를 메수트 외질의 후보로 더 앞선에 쓰고 싶은 것처럼 보이기에 그가 투미드필더의 한 축으로서 3선에 기용될 가능성은 적어보이긴 하지만 말이다.

에미레이츠 스타디움의 열혈 팬들은 드디어 그들이 알던 아스널이 돌아왔다며 찬가를 부르고 있을 수도 있지만, 아르센 벵거의 말년을 힘들게 만들었고 끝내 그를 쫓아낸 수비 문제는 여전히 존재하며, 자카도 여전히 그 문제의 주요 제공자이다. 에메리는 축복인지 저주인지 모를 이 선수를 어떻게 할지에 대해 이른 시일 내에 결단을 내려야만 할 것이다.

번역 : https://www.fmkorea.com/best/1382277555 


블로그 이미지

벵거빠돌이

,

해쉬테이블 (Hashtable)

C# 2018. 11. 8. 11:12

해쉬 테이블의 이해와 구현 (Hashtable)


조대협 (http://bcho.tistory.com)


기본적인 해쉬 테이블에 대한 이해


해쉬 테이블은 Key Value를 저장하는 데이타 구조로, value := get(key)에 대한 기능이 매우매우 빠르게 작동한다. 개발자라면 자주 쓰는 데이타 구조지만, 실제로 어떻게 작동하는지에 대해서 정확하게 알고 있지는 모르는 경우가 많다. 이 글에서는 해쉬 테이블에 대한 기본적인 구조와, 구현 방식에 대해서 설명 하도록 한다.

 

해쉬 테이블의 기본적인 개념은 다음과 같다.

이름을 키로, 전화 번호를 저장하는 해쉬 테이블 구조를 만든다고 하자.  전체 데이타 양을 16명이라고 가정하면

 

John Smith의 데이타를 저장할때, index = hash_function(John Smith) % 16  를 통해서 index 값을 구해내고, array[16] = John Smith의 전화 번호 521-8976”을 저장한다.



(출처 :https://en.wikipedia.org/wiki/Hash_table )

 

이런 형식으로 데이타를 저장하면, key에 대한 데이타를 찾을때, hash_function을 한번만 수행하면 array내에 저장된 index 위치를 찾아낼 수 있기 때문에, 데이타의 저장과 삭제가 매우매우 빠르다.

 

충돌 처리 방식에 따른 알고리즘 분류

 

그런데, 이 해쉬 테이블 문제는 근본적인 문제가 따르는데, hash_function(key) / size_of_array의 값이 중복이 될 수 가 있다.

 

예를 들어 저장하고자 하는 key가 정수라고 하고, hash_function key%10 이라고 하자. 그리고 size_of_array 10일때, key 1,11,21,31은 같은 index 값을 가지게 된다. 이를 collision (충돌)이라고 하는데, 이 충돌을 해결하는 방법에 따라서 여러가지 구현 방식이 존재한다.

 

1. Separate chaining 방식

 

JDK내부에서도 사용하고 있는 충돌 처리 방식인데, Linked List를 이용하는 방식이다.

index에 데이타를 저장하는 Linked list 에 대한 포인터를 가지는 방식이다.



(출처 :https://en.wikipedia.org/wiki/Hash_table )

 

만약에 동일  index로 인해서 충돌이 발생하면 그 index가 가리키고 있는 Linked list에 노드를 추가하여 값을 추가한다.  이렇게 함으로써 충돌이 발생하더라도 데이타를 삽입하는 데 문제가 없다.

 

데이타를 추출을 하고자할때는 key에 대한 index를 구한후, index가 가리키고 있는 Linked list를 선형 검색하여, 해당 key에 대한 데이타가 있는지를 검색하여 리턴하면 된다. 

삭제 처리


key를 삭제하는 것 역시 간단한데, key에 대한 index가 가리키고 있는 linked list에서, 그 노드를 삭제하면 된다.

Separate changing  방식은 Linked List 구조를 사용하고 있기 때문에, 추가할 수 있는 데이타 수의 제약이 작다.

 

참고 : 동일 index에 대해서 데이타를 저장하는 자료 구조는 Linked List 뿐 아니라, Tree를 이용하여 저장함으로써, select의 성능을 높일 수 있다. 실제로, JDK 1.8의 경우에는 index에 노드가 8개 이하일 경우에는 Linked List를 사용하며, 8개 이상으로 늘어날때는 Tree 구조로 데이타 저장 구조를 바꾸도록 되어 있다.

 

2. Open addressing 방식

 

Open addressing  방식은 index에 대한 충돌 처리에 대해서 Linked List와 같은 추가적인 메모리 공간을 사용하지 않고, hash table array의 빈공간을 사용하는 방법으로, Separate chaining 방식에 비해서 메모리를 덜 사용한다. Open addressing  방식도 여러가지 구현 방식이 있는데, 가장 간단한 Linear probing 방식을 살펴보자

 

Linear Probing

 

Linear Probing 방식은 index에 대해서 충돌이 발생했을 때, index 뒤에 있는 버킷중에 빈 버킷을 찾아서 데이타를 넣는 방식이다. 그림에서 key % 10 해쉬 함수를 사용하는  Hashtable이 있을때, 그림에서는 충돌이 발생하지 않았다.

 

 


아래 그림을 보자, 그런데, 여기에 11을 키로 하는 데이타를 그림과 같이 넣으면 1이 키인 데이타와 충돌이 발생한다. (이미 index1인 버킷에는 데이타가 들어가 있다.) Linear Probing에서는 아래 그림과 같이 충돌이 발생한 index (1) 뒤의 버킷에 빈 버킷이 있는지를 검색한다. 2번 버킷은 이미 index2인 값이 들어가 있고, 3번 버킷이 비어있기 3번에 값을 넣으면 된다.


검색을 할때, key 11에 대해서 검색을 하면, index1이기 때문에, array[1]에서 검색을 하는데, key가 일치하지 않기 때문에 뒤의 index를 검색해서 같은 키가 나오거나 또는 Key가 없을때 까지 검색을 진행한다. 


삭제  처리


이러한 Open Addressing의 단점은 삭제가 어렵다는 것인데, 삭제를 했을 경우 충돌에 의해서 뒤로 저장된 데이타는 검색이 안될 수 있다. 아래에서 좌측 그림을 보자,  2index를 삭제했을때, key 11에 대해서 검색하면, index1이기 때문에 1부터 검색을 시작하지만 앞에서 2index가 삭제되었기 때문에, 2 index까지만 검색이 진행되고 정작 데이타가 들어 있는 3index까지 검색이 진행되지 않는다.

그래서 이런 문제를 방지하기 위해서 우측과 같이 데이타를 삭제한 후에, Dummy node를 삽입한다. Dummy node는 실제 값을 가지지 않지만, 검색할때 다음 Index까지 검색을 연결해주는 역할을 한다.


Linear probing에 대한 샘플 코드는

http://www.cs.rmit.edu.au/online/blackboard/chapter/05/documents/contribute/chapter/05/linear-probing.html

http://www.tutorialspoint.com/data_structures_algorithms/hash_data_structure.htm

를 참고하기 바란다.

Dummy Node를 이용해서 삭제를 할때, 삭제가 빈번하게 발생을 하면, 실제 데이타가 없더라도 검색을 할때, Dummy Node에 의해서, 많은 Bucket을 연속적으로 검색을 해야 하기 때문에, Dummy Node의 개수가 일정 수를 넘었을때는 새로운 array를 만들어서, 다시 hash를 리빌딩 함으로써, Dummy Node를 주기적으로 없애 줘야 성능을 유지할 수 있다.


Resizing

Open addressing의 경우, 고정 크기 배열을 사용하기 때문에 데이타를 더 넣기 위해서는 배열을 확장해야 한다. 또한 Separate changing에 경우에도 버킷이 일정 수준으로 차 버리면 각 버킷에 연결되어 있는 List의 길이가 늘어나기 때문에, 검색 성능이 떨어지기 때문에 버킷의 개수를 늘려줘야 한다. 이를 Resizing이라고 하는데, Resizing은 별다른 기법이 없다. 더 큰 버킷을 가지는 array를 새로 만든 다음에, 다시 새로운 arrayhash를 다시 계산해서 복사해줘야 한다.


해쉬 함수


해쉬 테이블 데이타 구조에서 중요한 것중 하나가 해쉬 함수(hash function)인데, 좋은 해쉬 함수란, 데이타를 되도록이면 고르게 분포하여, 충돌을 최소화할 수 있는 함수이다. 수학적으로 증명된 여러가지 함수가 있겠지만, 간단하게 사용할 수 있는 함수를 하나 소개하고자 한다. 배경에 대해서는 http://d2.naver.com/helloworld/831311 에 잘 설명되어 있으니 참고하기 바란다. (필요하면 그냥 외워서 쓰자)

String key

char[] ch = key.toChar();

int hash = 0;

for(int i=0;i<key.length;i++)

 hash = hash*31 + char[i]

 

Cache를 이용한 성능 향상


해쉬테이블에 대한 성능 향상 방법은 여러가지가 있지만, 눈에 띄는 쉬운 방식이 하나 있어서 마지막으로 간략하게 짚고 넘어가자. 해쉬테이블의 get(key)put(key)에 간단하게, 캐쉬 로직을 추가하게 되면, 자주 hit 하는 데이타에 대해서 바로 데이타를 찾게 함으로써, 성능을 간단하게 향상 시킬 수 있다.  




'C#' 카테고리의 다른 글

Label 투명하게!  (0) 2018.12.10
DLL을 C#에서 사용하기  (0) 2018.10.25
c#에서 비관리코드를 호출하는 방법  (0) 2018.10.24
[MFC] LPSTR,LPCSTR,LPCTSTR .. 과연 무엇인가?  (0) 2018.10.23
opos visual studio 적용....  (0) 2018.10.15
블로그 이미지

벵거빠돌이

,

2018.11.04 오전 02:30 (KR) Emirates Stadium


이날 레스터의 비극을 추모하는 뜻으로 검은 완장을 착용하였습니다. 

#TogetherForLeicester


라인업





 

 Match Stats

 

Arsenal


Liverpool

61.8

점유율%

38.2

12

슛팅

13

4

유효슛팅

4

586

패스시도

356

28

클리어런스

29

5

코너킥

8

7

오프사이드

1

7

파울

7




775249930_SM_2079_ED53694F8EA732D397340A130898EEB6.jpg [공홈] 리버풀전 이후 에메리 프레스 컨퍼런스


리버풀을 상대로 포인트를 획득하려고 분투했던 알렉상드르 라카제트의 동점골 이후 우나이 에메리는 기뻐 보였다. 

무승부가 합당한 경기였는지..

"잘 모르겠습니다. 우리의 경기력에 기쁘고, 90분동안의 밸런스는 우리 쪽이 긍정적으로 우위했다고 생각합니다. 하지만 그들에게 기회를 허용하지 않는 것도 매우 까다로웠습니다.
우리는 몇몇 상황에서 약간의 운이 필요했습니다. 우리가 공격할 때도 득점하기 위해 운이 필요했습니다.
실점 이후에도 우리가 90분동안 해온 것들을 고려하면, 끝내 1-1이 괜찮은 결과라고 생각합니다. 우리가 절반만 기쁜 이유이기도 합니다.
두 번째로, 우리에겐 패배할 상황이 있었고, 우리 또한 90분 동안 균형을 깨뜨릴 상황이 있었습니다."

관중에 대해..

"리버풀의 한 특징은 그들의 강렬함과 빅 플레이어들입니다. 따라서 오늘은 우리에게 좋은 시험이었죠.
우리의 작업과 전술적인 부분에 발전이 더 필요하지만, 우리가 원했던 스피릿이 있었고, 오늘의 분위기는 90분 동안 응원하는 서포터들과 함께 정말 뜨거웠습니다.
오늘은 우리에게나, 그들에게나 정말 스펙타클했습니다."

믿음이 상승하는 것에 대해..

"우리의 과정은 많은 시간이 필요합니다. 축구에 있어서 많은 시간을 요구함은 정말 어렵지만, 필요합니다.
좋은 예는 맨시티전, 첼시전 그리고 오늘의 리버풀전까지, 우리가 여러 경기를 치르면서 경기력이 얼마나 달라졌는지입니다.
이 세 경기 중 오늘의 경기는 우리에게 더 경쟁적인 경기였다고 생각합니다."

이워비의 임팩트에 대해..

"우리는 모든 선수가 필요하고, 그가 가지고 있는 재능은 중요합니다. 그를 벤치에 앉히고 경기를 시작했을 때 또한, 이워비는 경기에 큰 임팩트를 줄 수 있습니다.
오늘 그는 오른쪽에서 뛰었지만, 왼쪽에서 더 좋은 모습을 보였습니다. 몇몇 상황에선 우리의 득점 과정처럼, 임팩트도 있었습니다.
그의 에너지와 재능은 중요합니다. 더불어 그는 더 발전할 수 있습니다. 많은 경기를 치르면서도, 첼시를 상대로 득점했습니다. 
득점을 위해, 박스에 그가 더 밀접히 플레이하길 바라고, 그는 할 수 있다고 생각합니다.
그는 젊고, 나아지고 있지만, 그는 더욱더 발전할 수 있으므로 그에 대해 야망이 있습니다."

상위권 팀들을 상대로 경기에 대해..

"첫 번째로, PL이 우리에게 최우선 경쟁입니다. 한 시즌 38경기 동안, 우리에게 큰 꾸준함을 부여하기 때문입니다. 시티와 첼시, 리버풀과 같은 팀을 상대할 때도 매우 중요합니다.
승리한다면 좋지만, 리버풀을 상대로 3포인트와 크리스탈 팰리스를 상대로 3포인트는 같은 3포인트이기 때문에 모든 경기가 매우 중요합니다. 오늘은 시티, 첼시를 상대한 이후, 어떻게 변화했는지를 알아보기 위한 한 시험이었습니다.
오늘은 경기력에 있어서, 더 나아졌다고 생각합니다. 매 경기와 홈에서 치를 다음 울버햄튼전에도 또한 꾸준함이 필요하고, 중요한 경기입니다."

슈퍼리그에 대해..

"정확히는 잘 모르겠습니다. 무엇이 최고의 경쟁인지, 축구계 그리고 사람들과 함께 많은 시간을 들여 얘기를 나눠야 할 것입니다. 많은 지식을 함께한 긴 대화 말입니다."

늦은 득점과 우리의 공격수들에 대해..

"우리에겐 오바메양같은 정상급 득점자가 있고, 라카제트 또한 많이 득점할 수 있으며 다른 선수들도 있습니다. 이 통계는 중요합니다. 이번 골은 우리와 라카에게 있어 중요합니다.
계속 기회를 창출하고, 득점하는 것은 중요합니다. 오늘 우리는 많은 찬스가 있었습니다. 이러한 방면을 이어가는 것은 우리에게 중요합니다."


블로그 이미지

벵거빠돌이

,