Tải bản đầy đủ (.docx) (5 trang)

Một số bài hướng dẫn thực hành lý thuyết đồ thị

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (97.04 KB, 5 trang )

Một số bài hướng dẫn thực hành Lý thuyết đồ thị
Created by NgoHung

Vấn đề 1: Biểu diễn đồ thị và duyệt đồ thị
1. Biểu diễn đồ thị
Xây dựng các hàm phục vụ cho việc tạo ma trận kề của đồ thị cần biễu diễn, gồm có:
Nhập ma trận kề: Cho phép nhập thông tin về đồ thị bằng tay gồm số đỉnh N, các giá
trị Ai,j của ma trận kề
Đọc ma trận kề từ file: Cho phép nhập thông tin về đồ thị từ file chứa các giá trị của
ma trận kề gồm số đỉnh N, các giá trị Ai,j.
Xuất ma trận kề: In thông tin về đồ thị ở dạng ma trận kề gồm các giá trị A i,j .
Source code :
#define MaxV 20 //Define su dung cho so dinh cuc dai cua do thi
int A[MaxV][MaxV];
int V = 0;
int ChuaXet[MaxV];

//Ma tran ke
//So dinh cua do thi

//Thu tuc nhap matran ke bang ban phim.
void NhapMTKe(int A[][MaxV], int &V)
{
printf("Nhap V:");
scanf("%d", &V);
for (int i=0; i{
for (int j=0; j{
printf("A[%d,%d] = ", i+1, j+1);
scanf("%d", &(A[i][j]));


}
}
}
// Xuat ket qua ma tran ke cua do thi ra man hinh.
void XuatMTKe(int A[][MaxV], int V)
{
printf("\nMa tran ke:\n");
for (int i=0; i{
for (int j=0; jprintf("%3d ", A[i][j]);
printf("\n");
}
}
//Doc du lieu ma tran ke cua do thi da duoc tao thanh file text luu san tren dia.
int DocMTKe(char *fileName, int A[][MaxV], int &V)
{


FILE *f = fopen(fileName, "rt");
if (f == NULL)
{
printf("Doc file loi !!!");
return 0;
}
fscanf(f, "%d", &V);
for (int i=0; i{
for (int j=0; j{

fscanf(f, "%d", &(A[i][j]));
}
}
return 1;
}

2. Duyệt đồ thị
Sử dụng các phương pháp duyệt đồ thị để cài đặt thành các hàm duyệt đồ thị:
Duyệt theo chiều sâu có sử dụng đệ quy
Duyệt theo chiều sâu không sử dụng đệ quy, sử dụng STACK thay thế
Duyệt theo chiều rộng sử dụng cấu trúc QUEUE
Source code các hàm
//Thu tuc duyet DFS, duyet theo chieu sau su dung ky thuat de quy.
void DFS(int v)
{
ChuaXet[v] = 1;
for ( int u=0; uif ( A[v][u]!=0 )
//The hien u la dinh ke cua v
if ( ChuaXet[u]==0 )
DFS( u );
//Dinh u chua duoc duyet qua==> Duyet u
}
//Thu tuc duyet DFS, duyet theo chieu sau su dung STACK de khu de quy.
void DFS0DeQuy(int v)
{
int STACK[MaxV], topS = 0;
//Khoi tao STACK voi mot STACT rong
STACK[topS++] = v;
ChuaXet[v] = 0;

while(topS > 0)
{
v = STACK[--topS];

//Dua dinh v vao dinh STACK
//Xem nhu da duyet dinh v
//Lap trong khi STACK khac rong
//Lay mot dinh v tu dinh cua STACK ra

for (int u=V-1; u>=0; u--)
if (A[v][u] != 0)
//Xet dinh u ke voi dinh v
if ( ChuaXet[u]==0 )
{
STACK[topS++] = u; //Dua u vao dinh STACK


ChuaXet[u] = 1;

//Xem dinh nay la da xet.

}
}
}
//Thu tuc duyet DFS, duyet theo chieu rong su dung QUEUE de chay khong de quy.
void BFS0DeQuy(int v)
{
int QUEUE[MaxV], topQ=0, bottomQ=0; //Khoi dau voi mot QUEUE rong
QUEUE[topQ++] = v;
ChuaXet[v] = 1;


//Dua dinh v vao QUEUE, xem no nhu la da xet

while ( bottomQ < topQ )
//Lap trong khi QUEUE khac rong
{
v = QUEUE[bottomQ++]; //Lay dinh v tu day cua QUEUE
for (int u=0; uif ( A[v][u] != 0 )
if ( ChuaXet[u]==0 )
{
QUEUE[topQ++] = u;
ChuaXet[u] = 1;
}

//The hien u ke voi dinh v

// Dua u vao dinh cua QUEUE

}
}
Xây dựng hàm main( ) tiến hành gọi thuật toán duyệt đồ thị:
+ Gọi hàm đọc, xuất ma trận kề của đồ thị
+ Gọi hàm duyệt đồ thị với đỉnh bất kỳ, ví dụ như đỉnh đầu tiên ( đỉnh 0 )
+ In ra các thành phần đã duyệt được trong đồ thị bơi
Source code hàm main( )
int main(int argc, char* argv[])
{
DocMTKe("D:\\Dothi_1.txt", A, V);
XuatMTKe(A, V);

memset(ChuaXet, 0, sizeof(ChuaXet) );
DFS0DeQuy(v);
printf( "Các dinh da duyet: " );
if (ChuaXet[j] == tp)
printf( "%d ", v+1 );
getch ( );
}
Tạo mới file đồ thị D:\\Graph_1.TXT ở dạng ma trận kề, ví dụ:
13
0 1 0 1 0 0 0 0 0 0 0 1 0
1 0 0 1 0 0 0 0 0 0 0 0 0


0
1
0
0
0
0
0
0
0
1
0

0
1
0
0
0

0
0
0
0
0
0

0
0
0
0
1
0
0
0
0
0
0

0
0
0
0
1
0
0
0
0
0
0


0
0
0
1
0
1
1
0
0
0
0

0
1
1
0
1
0
0
0
0
0
1

1
1
0
1
0

0
0
0
0
0
0

0
0
1
0
0
0
1
0
0
0
0

0
0
1
0
0
1
0
0
0
0
0


0
0
0
0
0
0
0
0
1
1
0

0
0
0
0
0
0
0
1
0
1
0

0
0
0
0
0

0
0
1
1
0
0

0
0
0
1
0
0
0
0
0
0
0

3. Thành phần liên thông
Để tìm số thành phần liên thông, thì mỗi lầ duyệt hãy gán cho mỗi thành phần liên thông một chỉ
số vào giá trị của mảng ChuaXet, thay vì luôn ghi giá trị là 1. Các đỉnh của cùng thành phần liên
thông sẽ có giá trị lưu trong ChuaXet giống nhau.
Các bước tiến hành:
1. Truyền tham so nSoTPLT ve thành phần liên thông đang duyệt cho các hàm duyệt, cụ
thể là:
void DFS0DeQuy(int v, int nSoTPLT)
void BFS0DeQuy(int v, int nSoTPLT)
void DFS0DeQuy(int v, int nSoTPLT)
2. Thay thế chỉ số index cho các thành phần liên thông trong các hàm duyệt:

Thay thế các dòng gán ChuaXeti = 0 thành ChuaXet[i ] = nSoTPLT.
Ví dụ:
ChuaXet[v] = nSoTPLT;
//Xem dinh nay la da xet.
Chỉnh sửa lại hàm main ( ) để in ra tất cả các đỉnh của từng thành phần liên thông
int main(int argc, char* argv[])
{
int nSoTPLT = 0;
DocMTKe("D:\\Graph_1.TXT", A, V);
XuatMTKe(A, V);
for (int v=0; vif (ChuaXet[v] == 0)
DFS0DeQuy(v, ++nSoTPLT);
for (int tp=1; tp<=nSoTPLT; tp++)
{
cout<<"\nTPLT thu "<for (v=0; vif (ChuaXet[v] == tp)
cout<cout<<"\n";
}
}

1.

Tìm đường đi
+ Khai báo mảng lưu vết :


int DinhTruoc[MaxV];

+ Bổ sung để hàm duyệt DFS lưu vết tìm đường đi:
//Thu tuc duyet DFS, duyet theo chieu sau su dung ky thuat de quy.
void DFS(int v)
{
ChuaXet[v] = nSoTPLT;
for ( int u=0; uif ( A[v][u]!=0 )
//The hien u la dinh ke cua v
if ( ChuaXet[u]==0 )
{
DinhTruoc[u] = v;
DFS( u );
//Dinh u chua duoc duyet qua==> Duyet u
}
}
+ Hoàn thiện hàm main ( ) để tìm đường đi từ s đến t.
int main(int argc, char* argv[])
{
int nSoTPLT = 0;
DocMTKe("D:\\1.TXT", A, V);
XuatMTKe(A, V);
int s, t;
cout<<"Nhap dinh bat dau, dinh ket thuc:"; cin>>s>>t;
s--; t--;
DFS(s);
int DuongDi[MaxV], k = 0;
DuongDi[k++] = t;
while ( DinhTruoc[ DuongDi[k-1] ] != s)
DuongDi[k++] = DinhTruoc[ DuongDi[k-1] ];
DuongDi[k++] = s;

cout<<"\nDuong di tu "<for ( int i=k-1; i>=0; i-- )
cout<getch( );
}



×