깊이 우선 탐색(Depth First Algorithm)
그래프를 인접 행렬로 표현 [C++ 소스]
"본문 내용"은 언제나 휴일 본 사이트에 있습니다.
//Graph.h
#pragma once
#include <iostream>
#include <vector>
using namespace std;
typedef vector<int> Neighbors;
class Graph
{
const int vn;//정점의 개수
int **matrix;//인접 행렬
public:
Graph(int vn);
~Graph(void);
void AddEdge(int start, int goal);//간선 추가
void ViewNeighbors()const;
void ViewNeighbor(int vt)const;
Neighbors FindNeighbors(int vt);
};
//Graph.cpp
#include "Graph.h"
#include <string.h>
Graph::Graph(int vn):vn(vn)
{
matrix = new int *[vn];//매트릭스 메모리 할당
for (int i = 0; i < vn; i++)
{
matrix[i] = new int[vn];//매트릭스 [i-row] 메모리 할당
memset(matrix[i], 0, sizeof(int)*vn);//메모리 0으로 초기화
}
}
Graph::~Graph(void)
{
for (int i = 0; i < vn; i++)
{
delete[] matrix[i];//매트릭스 [i-row] 메모리 소멸
}
delete[] matrix;//매트릭스 메모리 해제
}
void Graph::AddEdge(int start, int goal)//간선 추가
{
matrix[start][goal] = 1;//간선 설정
//아래 코드를 주석 처리하면 방향성 있는 그래프입니다.
matrix[goal][start] = 1;//간선 설정
}
void Graph::ViewNeighbors()const
{
cout<<"=== 이웃 정점 ==="<<endl;
for (int i = 0; i < vn; i++)
{
cout<<i<<"의 이웃: ";
ViewNeighbor(i);//i정점의 이웃 보여주기
}
cout<<endl;
}
void Graph::ViewNeighbor(int vt)const
{
for (int i = 0; i < vn; i++)
{
if(matrix[vt][i])
{
cout<<i<<" ";
}
}
cout<<endl;
}
Neighbors Graph::FindNeighbors(int vt)
{
Neighbors neighbors;
for (int i = 0; i < vn; i++)
{
if(matrix[vt][i])
{
neighbors.push_back(i);
}
}
return neighbors;
}
//Heuristic.h
#pragma once
#include "Graph.h"
#include <vector>
using namespace std;
typedef vector<int> Foots;
typedef Foots::iterator FIter;
typedef Foots::const_iterator CFIter;
class Heuristic;
typedef vector<Heuristic *> Heues;
typedef Heues::iterator HIter;
typedef Heues::const_iterator CHIter;
class Heuristic
{
Graph *graph;
int goal;
Foots foots;
public:
Heuristic(Graph *graph, int start,int goal);
Heues EnumNext();
bool IsGoal()const;
void View()const;
private:
Heuristic(const Heuristic *bheu,int vt);
};
//Heuristic.cpp
#include "Heuristic.h"
#include <algorithm>
Heuristic::Heuristic(Graph *graph,int start,int goal)
{
this->graph = graph;
foots.push_back(start);
this->goal = goal;
}
Heues Heuristic::EnumNext()
{
Heues nheues;
int last_foot = (*foots.rbegin());//가장 최근에 방문한 정점
Neighbors neighbors = graph->FindNeighbors(last_foot);//마지막 방문 정점의 이웃하는 정점을 구함
FIter seek = neighbors.begin();
FIter last = neighbors.end();
for( ;seek != last; ++seek)
{
if(find(foots.begin(), foots.end(),*seek) == foots.end())//방문한 적이 없으면
{
nheues.push_back(new Heuristic(this,*seek));//*seek를 추가 방문하는 새로운 경험을 생성
}
}
return nheues;
}
bool Heuristic::IsGoal()const
{
return (*foots.rbegin()) == goal;
}
void Heuristic::View()const
{
cout<<"Foots: ";
CFIter seek = foots.begin();
CFIter last = foots.end();
for( ;seek != last; ++seek)
{
cout<<(*seek)<<" ";
}
cout<<endl;
}
Heuristic::Heuristic(const Heuristic *bheu,int vt)
{
this->graph = bheu->graph;
foots = bheu->foots;
this->goal = bheu->goal;
foots.push_back(vt);//vt를 방문한 행적에 추가
}
//Program.cpp
#include "Heuristic.h"
#include <stack>
using namespace std;
int main()
{
Graph *graph = new Graph(9);//그래프 동적 생성
graph->AddEdge(0, 1);//간선 추가
graph->AddEdge(0, 2);//간선 추가
graph->AddEdge(1, 2);//간선 추가
graph->AddEdge(1, 3);//간선 추가
graph->AddEdge(2, 4);//간선 추가
graph->AddEdge(3, 6);//간선 추가
graph->AddEdge(4, 5);//간선 추가
graph->AddEdge(4, 6);//간선 추가
graph->AddEdge(4, 7);//간선 추가
graph->AddEdge(6, 8);//간선 추가
graph->ViewNeighbors();
stack<Heuristic *> hs;
Heuristic *heu = new Heuristic(graph,0,8);//초기 경험 정보를 생성
hs.push(heu);//스택에 보관
while(hs.empty() == false) //반복(스택이 비어 있지 않다면)
{
heu = hs.top();//스택에서 경험 정보 꺼내옮
hs.pop();
heu->View();
Heues nheues = heu->EnumNext();//스택에서 꺼내온 경험 정보에서 다음 경험 목록 조사
HIter seek = nheues.begin();
HIter last = nheues.end();
for( ;seek != last; ++seek)//반복(다음 경험 목록을 순차적으로 반복)
{
if((*seek)->IsGoal())//목적지에 도달하면
{
cout<<"솔루션 ";
(*seek)->View();//결과 출력
delete (*seek);
}
else//그렇지 않다면
{
hs.push(*seek);//스택에 보관
}
}
delete heu;
}
return 0;
}
다음은 방향성있는 그래프에서 실행한 결과입니다.
▷ 실행 결과
=== 이웃 정점 ===
0의 이웃: 1 2
1의 이웃: 2 3
2의 이웃: 4
3의 이웃: 6
4의 이웃: 5 6 7
5의 이웃:
6의 이웃: 8
7의 이웃:
8의 이웃:
Foots: 0
Foots: 0 2
Foots: 0 2 4
Foots: 0 2 4 7
Foots: 0 2 4 6
솔루션 Foots: 0 2 4 6 8
Foots: 0 2 4 5
Foots: 0 1
Foots: 0 1 3
Foots: 0 1 3 6
솔루션 Foots: 0 1 3 6 8
Foots: 0 1 2
Foots: 0 1 2 4
Foots: 0 1 2 4 7
Foots: 0 1 2 4 6
솔루션 Foots: 0 1 2 4 6 8
Foots: 0 1 2 4 5
다음은 방향성없는 그래프에서 실행한 결과입니다.
▷ 실행 결과
▷ 실행 결과
=== 이웃 정점 ===
0의 이웃: 1 2
1의 이웃: 0 2 3
2의 이웃: 0 1 4
3의 이웃: 1 6
4의 이웃: 2 5 6 7
5의 이웃: 4
6의 이웃: 3 4 8
7의 이웃: 4
8의 이웃: 6
Foots: 0
Foots: 0 2
Foots: 0 2 4
Foots: 0 2 4 7
Foots: 0 2 4 6
솔루션 Foots: 0 2 4 6 8
Foots: 0 2 4 6 3
Foots: 0 2 4 6 3 1
Foots: 0 2 4 5
Foots: 0 2 1
Foots: 0 2 1 3
Foots: 0 2 1 3 6
솔루션 Foots: 0 2 1 3 6 8
Foots: 0 2 1 3 6 4
Foots: 0 2 1 3 6 4 7
Foots: 0 2 1 3 6 4 5
Foots: 0 1
Foots: 0 1 3
Foots: 0 1 3 6
솔루션 Foots: 0 1 3 6 8
Foots: 0 1 3 6 4
Foots: 0 1 3 6 4 7
Foots: 0 1 3 6 4 5
Foots: 0 1 3 6 4 2
Foots: 0 1 2
Foots: 0 1 2 4
Foots: 0 1 2 4 7
Foots: 0 1 2 4 6
솔루션 Foots: 0 1 2 4 6 8
Foots: 0 1 2 4 6 3
Foots: 0 1 2 4 5
프로그래밍 언어 및 기술 학습, 무료 동영상 강의 언제나 휴일
'C++ > 디딤돌 자료구조와 알고리즘 with C++' 카테고리의 다른 글
너비 우선 탐색(Breath First Search) 그래프를 인접 행렬 표현 [C++ 소스] (0) | 2016.06.12 |
---|---|
깊이 우선 탐색(Depth First Algorithm) 그래프를 정점과 간선 집합으로 표현 [C++ 소스] (0) | 2016.06.12 |
방향성 있는 그래프를 인접 행렬로 표현 [C++ 소스] (0) | 2016.06.12 |
방향성 없는 그래프를 인접 행렬로 표현 [C++ 소스] (0) | 2016.06.12 |
동적 프로그래밍(Dynamic Programming) 순열 문제 [C++ 소스] (0) | 2016.06.12 |