Thực hành Lý thuyết đồ thị Chu trình, Đường đi Euler, Haminton

Chu trì nh, Đườ ng đi Hamilton

I. Chu trình Hamilton, Đường đi Hamilton, Đồ thị Hamilton

1. Các khái niệm:

 Chu trình Hamilton là chu trình xuất phát từ 1 đỉnh đi thăm tất cả những đỉnh còn lại

mỗi đỉnh đúng 1 lần, cuối cùng quay trở lại đỉnh xuất phát.

 Đường đi Hamilton là đường đi qua tất cả các đỉnh của đồ thị, mỗi đỉnh đúng 1 lần.

2. Ví dụ 1:

b

a

c

e

d

 Chu trình Hamilton: baedcb  Đường đi Hamilton (nhưng không phải là chu trình Hamilton): baecd

3. Ví dụ 2: Xét 3 đơn đồ thị G1, G2, G3 sau:

a

b

e

e

m

f

c

d

G1

G2

G3

Trang 1

GVHD: Lương Trần Hy Hiến

Thực hành Lý thuyết đồ thị Chu trình, Đường đi Euler, Haminton

 G1 có chu trình Hamilton (a, b, c, d, e, a).  G2 không có chu trình Hamilton vì deg(a) = 1 nhưng có đường đi Hamilton (a,

b, c, d).

 G3 không có cả chu trình Hamilton lẫn đường đi Hamilton.

II. Thuật toán

Dưới đây là phần hướng dẫn cài đặt thuật toán liệt kê tất cả các chu trình Hamilton xuất phát từ đỉnh 0, các chu trình Hamilton khác có thể có được bằng cách hoán vị vòng quanh. Lưu ý rằng cho tới nay, người ta vẫn chưa tìm ra một phương pháp nào thực sự hiệu quả hơn phương pháp đệ qui quay lui để tìm dù chỉ một chu trình Hamilton cũng như đường đi Hamilton trong trường hợp đồ thị tổng quát.

1. Tìm chu trình Hamilton

Thuật toán gọi đệ qui hàm tìm trong đó thực hiện những công việc sau:

 B1: Kiểm tra nếu số lần gọi đệ qui > số đỉnh của đồ thị và tồn tại cạnh nối từ x tới đỉnh đầu tiên trong đường đi thì kết luận có chu trình Hamilon. Ngược lại làm tiếp B2

 B2: Duyệt qua tất cả các đỉnh i (chưa xét) kề với đỉnh x  B3: Lưu lại đỉnh i trong đường đi và đánh dấu i đã xét. Gọi đệ qui tìm tiếp.  B4: Bỏ đánh dấu i đã xét.

Lưu ý: ban đầu đỉnh 0 được đánh dấu đã xét và được lưu trong đường đi.

2. Tìm đường đi Hamilton Cũng làm tương tự như tìm chu trình chỉ khác trong điều kiện kiểm tra ở B1. Chỉ cần

kiểm tra số lần gọi đệ qui == số đỉnh của đồ thị là được.

III. Nội dung thực hành

Cho một tập tin văn bản chứa số đỉnh và ma trận kề biểu diễn đồ thị. Viết chương trình tìm chu

trình Hamilton trong đồ thị đó.

Ví dụ:

Cho đồ thị gồm 4 đỉnh. Tìm một chu trình Hamilton trong đồ thị đó. Ví dụ: 0 1 2 3 0 là một chu trình Hamilton trong đồ thị

Nội dung tập tin văn bản Ý nghĩa và yêu cầu 4 0 1 1 1

1 1 1 0

1 1 0 1

1 0 1 1

Trang 2

GVHD: Lương Trần Hy Hiến

Thực hành Lý thuyết đồ thị Chu trình, Đường đi Euler, Haminton

Khai báo CTDL cần thiết:

int sodinh; int a[MAX][MAX];

#include using namespace std; #define MAX 20 #define FOUND 1 //1: cho biết ý nghĩa của các hằng số này #define NOT_FOUND 0 struct GRAPH { };

Hàm tìm chu trình Hamilton, kết quả trả về cho biết có tìm được chu trình Hamilton hay không.

int start = 0; int flag = NOT_FOUND; //2: cho biết ý nghĩa của biến flag int visited[MAX]; //3: cho biết ý nghĩa của mảng visited

visited[i] = 0;

for(int i = 0; i < g.sodinh; i++) { }

count = 0; //đếm số lượng đỉnh trong chu trình Hamilton đang tìm path[count] = start; count++; visited[start] = 1;

flag = visit(start,visited,count,flag,path,g);

if(flag) return FOUND; return

NOT_FOUND;

visited[v] = 1; path[count] = v; count++; if(count == g.sodinh && g.a[v][path[0]] == 1) //4: cho

flag = FOUND;

visit(v,visited,count,flag,path, g);

int dfsHamilton(int path[], GRAPH g) { } Hàm visit cài tương tự thuật toán duyệt theo chiều sâu DFS int visit(int u, int visited[],int&count,int&flag, int path[], GRAPH g) { if(flag == FOUND) return flag; for(int v = 0; v < g.sodinh; v++) if(visited[v] == 0 && g.a[u][v] != 0) {//nếu u kề v, v chưa thăm biết ý nghĩa }

Trang 3

GVHD: Lương Trần Hy Hiến

Thực hành Lý thuyết đồ thị Chu trình, Đường đi Euler, Haminton

visited[u] = 0;

if(flag == NOT_FOUND) {//5: cho biết ý nghĩa của đoạn chtr này count--; } return flag;

}

// Tìm cách in ra chu trình Hamilton dựa vào mảng path

cout<<"Khong tim thay chu trinh Hamilton";

GRAPH g; readGRAPH("dothi.txt", g); //Sinh viên tự viết hàm đọc đồ thị int path[MAX]; if(dfsHamilton(path, g) == FOUND) { } else system("pause");

void main() { }

Hàm main

IV. Bài tập

1. Trả lời 5 câu hỏi trong đoạn chương trình mẫu trên. 2. Hãy khử đệ quy cho hàm visit bằng cách dùng stack. 3. Hãy sửa đoạn chương trình trên sao cho chương trình tìm được 1 đường đi

Hamilton (không nhất thiết là chu trình Hamilton).

4. Bài tập tự luyện

Trên bàn cờ n×n (3 ≤ n) có một số ô bị đục thủng, một con mã muốn đi khắp các ô còn lại mà không có bước đi nào lặp lại 2 lần, các bước đi nối tiếp nhau. Viết chương trình xuất ra một đường đi có thể của con mã này. Chương trình được viết dưới dạng Console với 2 tham số dòng lệnh lần lượt là đường dẫn tập tin đầu vào và đường dẫn tập tin đầu ra:

Ví dụ tham số dòng lệnh:

MSSV.exe input.txt Output.txt Hoặc MSSV.exe C:\input.txt D:\Output.txt

Lưu ý: đường dẫn/tên tập tin đầu vào và đầu ra có thể thay đổi (không cố định) Cấu trúc file dữ liệu đầu vào:

Biểu diễn bàn cờ quốc tế n×n bằng một đồ thị có n×n = N đỉnh. Các ô trên bàn cờ được đánh số bắt đầu từ 0, theo thứ tự từ trái sang phải và từ trên xuống dưới.

Trang 4

GVHD: Lương Trần Hy Hiến

• Dòng đầu tiên: số đỉnh đồ thị (N) • N dòng tiếp theo: ma trận kề của đồ thị với quy ước:

Thực hành Lý thuyết đồ thị Chu trình, Đường đi Euler, Haminton

 A[i][j] = 1: con mã đi được từ i đến j  A[i][j] = 0: con mã không đi được từ i đến j

Các đỉnh được đánh chỉ số từ 0 Cấu trúc file dữ liệu đầu ra:

Nếu tìm được đường đi thì lần lượt xuất ra các đỉnh trên đường đi đó (cách nhau bởi khoảng trắng).

Bàn cờ

Tập tin đầu ra 0 7 2 3 8 1 6 5

0 1 2

3 4 5

6 7 8

Nếu không tìm được ghi là 0 Ví dụ: Tập tin đầu vào 9 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 Đường màu xanh biểu diễn đường đi của con mã. Ô số 4 (màu xám) bị đục thủng .

V. Tài liệu tham khảo

[1]. Bài tập thực hành Lý thuyết đồ thị, Khoa CNTT, ĐH Khoa học Tự Nhiên, ĐHQG TpHCM.

Trang 5

GVHD: Lương Trần Hy Hiến