초보자를 위해서 써봅니다. (사실 저도 알고리즘 책 1권밖에 공부 안한 초보자입니다만 ^^;;)
이해에 관련된 민감한 오타등은 댓글 달아주심 고치도록 하겠습니다. 글자가 많아서 지루할수도 있지만 열심히 쓸테니 차근차근 읽어 주시면 감사하겠습니다. 문단은 글이 좀 길어질 경우 내용이 계속 이어지더라도 보기편하시라고 중간중간 띄어놓도록 하겠습니다.
FOUNDATIONS of USING C++ PSEUDOCODE
저자 : Richard Neapolitan / Kumarss Naimipour
위의 책을 참고하였음을 밝힙니다. ^^
사실 어떻게 보면 알고리즘 공부 전에 자료구조에서 그래프를 미리 접하는 경우가 있기 때문에...
알고리즘에서 굳이 인접행렬에 대해 설명 할 필요는 없습니다만... 앞에서와 같이 초보자를 위한 글이므로...
또한 자료구조를 공부하셨다고 해도 기억이 가물가물 할 수 도 있으므로... 자료구조와 알고리즘의 영역에 대해 논하는 것은 민감한 사항이기도... 뭐 어떻게 딱 나눌수가 없다는 ㅎㅎ C와 C++간의 관계와 비슷하다고 할 수 있는건가... 글쎄...
아래에서 사용하는 용어는 다른책에선 좀 다르게 말할 수도 있습니다. 그래도 거의 비슷하기때문에 아래 용어를 기억하나면 별 문제는 없을 듯 싶습니다. 한글로는 용어가 다르더라도 영어로는 거의 같을겁니다. 내용을 자세히 들어가면 더 많은 내용과 용어들이 있으나 앞에서 밝히바와 같이 초보자용임을 잊지 말아 주시길... ^^
제목엔 인접행렬을 강조하기 위해서 앞에 뒀지만 사실은 그래프(Graph)를 먼저 알아야 인접행렬(Adjacent matrix)을 알 수 있습니다.
따라서 그래프를 먼저 보도록하겠습니다. 그래프는 경로에 관련되 문제에 많이 사용 됩니다.
용어들을 알기에 앞서서 일단 그래프란 녀석이 뭔지 그림으로 보도록 합시다.
보시면 아시겠지만 뭐 별거 없습니다. 동그라미 있구 화살표 찍찍 화살표에 숫자 써있고 제가 설명안해도 감으로 뭘 말하는지 때려 잡으시는 분들이 많을거 같군요. 대강 예상을 하셨다면 제가 설명할 내용과 큰 차이 없을 겁니다. 그럼 하나 하나 보도록 하죠. 우선 원을 '정점(vertex, node)'이라고 합니다. 정점이란 개념은 계속 설명을 듣다보면 이해가 가실테지만 지금 대충 둘러대자면 땅? 위치? 뭐 그정도로 가능하겠군요. 원에 써있는 글자는 그 정점의 이름이구요. 원과 원을 잇고있는 선은 '이음선(edge, arc)'이라고 합니다. 한 정점에서 다른 정점으로 연결이 되어 있다는것은 이동가능하다라는 것을 의미한다고 할 수도 있겠군요.(제가 앞에서 계속 무엇은 무엇이다라고 정확히 말하지않고 무엇은 무엇이라고 할 수 있다 정도로 설명하는 것은 그래프가 다양한 용도에 쓰이기때문에 꼭 뭐라고 말 할 수 없기 때문입니다.) 하지만 이해의 편의를 위해서 정점을 섬이라고 생각하도 이음선을 다리라고 생각해도 좋겠습니다. 아래에선 이걸 활용하여 설명하겠습니다.
말 그대로 비방향 그래프입니다. 방향이 없는거죠... 방향이 없다면 더 말이안될수... 정리해서 다시말하면 양방향이라는 겁니다. 양방향이니 굳이 방향을 표시할 필요없다는 겁니다.(이음선 하나 하나가 양쪽으로 화살표를 지닌다고 보면 됩니다.) 센스있으신 분이면 이그래프의 정확한 이름을 지으실수 있습니다. 가중치 포함 비방향 그래프 이 이름을 지었다면 정말 휼륭하십니다 ^^ 앞의내용을 차근차근 읽으신 분이겠죠? 아님 이미 알고계시거나... 좀더 정확히 표현 하자면 '연결된, 가중치가 있는, 비방향 그래프'라고 말 할 수 있습니다. 연결된 이란... 따로 고립되어있는 정점이 없는것을 말합니다. 만약 v1,v3사이의 이음선과 v1,v2사이의 이음선을 제거하면 이 그래프는 연결된것이 아닙니다. 다른 노드에서 v1으로 갈 방법이 없기 때문입니다. 만약 v1,v2사이의 이음선과 v2,v3사이의 이음선 그리고 v3,v4사이의 이음선 이렇게 3개를 모두 제거해도 서로 이동이 모두 가능하기때문에 연결되어있다고 봅니다. 트리라는 개념도 있는데... 여기에선 본격적인 알고리즘 설명을 하기보단 그래프를 알기위함이었으므로 생략하도록 합니다.
지금까지 그래프의 설명을 잘 읽어 오셨습니다. 그렇다면 이제 인접행렬을 알아보도록하죠!!
그래프를 이용해서 각종 문제를 해결 할 수 있습니다. 하지만 그 그래프를 컴퓨터로 표현하지 못한다면 물거품이겠죠?
그래프를 컴퓨터로 표현하기위해 사용하는 것이 바로 인접행렬 입니다. 행렬이라... 뭐가 떠오르시나요...??
그렇습니다. 2차원 배열입니다 ㅎㅎ 감동(?) 아닌가... 이내용을 처음 접하고 감도을 받으셨다면 당신은 프로그래머적 감수성(?)이 풍부하신 분일 겁니다 *^^*
저는 설명의 편의를 위해 그냥 행렬로 나타냅니다. 여러분들도 그냥 행렬로 이해하시고 써먹을땐 2차원배열에 적용하시면됩니다. 계속 말하지만 이건 초보자용이므로 그냥 설명만하고 적용까지는 하지 않습니다. 적용은 몇몇분이 지금 강좌를 쓰고계신듯 합니다. 전 그냥 한번 써보는 정도라... ㅎㅎ 또 언제 필 충만하면 작성할지는 모르겠으나... 헐... 인접행렬도 방향있는 그래프를 가지고 먼저 설명하겠습니다. 그래야 비방향은 쉽게 끝납니다. ㅎㅎ
앞의 내용을 이해 하셨다면 이또한 이해되실겁니다. 여기서 주목할 만한 점은 비방향그래프는 양방향이기때문에(앞에서 말했지만 비방향 그래프는 이음선 양끝에 화살표가 있는것이라고 했습니다 ^^) 행렬값이 0으로 이루어진 대각선을 기준으로 대칭이라는 것이죠.. 흥미롭지 않으신가요? 이를 적용하는것은 다른분들이 이미 강좌를 쓰고계신것 같네요. 최소비용신장트리를 구하는 알고리즘에 이 기본지식은 튼튼한 버팀목이 될겁니다. 플로이드, 프림, 다익스트라, 크루스칼 알고리즘등의 이해를 위해서 이 내용들은 반드시 숙지하셔야 합니다. 이 알고리즘이 사용될만한 우리생활에서 접할수있는 예를 들자면 지하철 두개 역의 최단경로를 구하는 프로그램을 들 수 있겠네요 ㅎㅎ 설명은 약간 길었지만 별 내용은 없습니다. 제대로 이해했는지 확인 하는 가장 좋은 방법은 그래프를 아무렇게나 그려놓고 인접행렬로 옮겨 보시는 겁니다. 지금까지 읽으시느라 수고 많으셨습니다. 다음에 또 기회가 되면 나름대로(매우 중요한 단어)쉽고 자세한 강좌를 쓰도록 하겠습니다. 감사합니다~!