2.2.1 Thuật toán Fleury
* Đầu vào: Đồ thị G , không có đỉnh cô lập.
* Đầu ra: Chu trình Euler C của G, hoặc kết luận G không có chu trình Euler. * Phương pháp:
(1) Chọn đỉnh xuất phát bất kỳ v0. đặt v1 := v0 , C := (v0) , H := G. (2) Nếu H = , thì kết luận C là chu trình Euler, kết thúc.
Ngược lại sang bước (3) (3) Chọn cạnh đi tiếp :
- Trường hợp đỉnh v1 là đỉnh treo : tồn tại duy nhất đỉnh v2 kề v1 Chọn cạnh (v1, v2). Sang bước (4).
- Trường hợp đỉnh v1 không là đỉnh treo:
Nếu mọi cạnh liên thuộc v1 là cầu, thì không có chu trình Euler,kết thúc.
Ngược lại chọn cạnh (v1, v2) bất kì không phải là cầu trong H. Thêm vào đường đi C đỉnh v2. Sang bước (4)
(4) Xóa cạnh vừa đi qua, và xóa đỉnh cô lập
Loại khỏi H cạnh (v1, v2). Nếu H có đỉnh cô lập thì loại chúng khỏi H. Đặt v1:= v2 sang bước (2). [1]
Thí dụ 2.2.1
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/ Hình 2.2 Đồ thị vô hướng G với 6 đỉnh bậc chẵn
Đồ thị liên thông và có các đỉnh bậc chẵn, thực hiện các bước tìm chu trình Euler như sau :
(1) : chọn đỉnh xuất phát là đỉnh 1, đặt v1=1, C := (1), H := {(1, 2) ; (1, 6) ; (2, 3) ; (2, 5) ; (2, 6) ; (3, 4) ; (3, 5) ; (3, 6) ; (4, 5) ; (5, 6)}
(2) : H ≠ sang bước (3)
(3) : Chọn cạnh đi kế tiếp là cạnh (1, 2) hoặc (1, 6) (cả hai không là cầu), ta chọn cạnh (1, 2) khi đó C = {1, 2} sang bước (4)
(4) : xóa cạnh vừa qua và xóa đỉnh cô lập
Loại cạnh (1, 2) khỏi H, khi đó H = {(1, 6) ; (2, 3) ; (2, 5) ; (2, 6) ; (3, 4) ; (3, 5) ; (3, 6) ; (4, 5) ; (5, 6)} 1 4 3 5 2 6
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/ Hình 2.3 Đồ thị G sau khi xóa cạnh (1,2)
đỉnh v1=2 quay lại bước (2) (2) : H ≠ sang bước (3)
(3) : Chọn cạnh đi kế tiếp là cạnh (2, 3) khi đó C = {1, 2, 3} sang bước (4) (4) : xóa cạnh vừa qua và xóa đỉnh cô lập
Loại cạnh (2, 3) khỏi H, khi đó H = {(1, 6) ; (2, 5) ; (2, 6) ; (3, 4) ; (3, 5) ; (3, 6) ; (4, 5) ; (5, 6)} 1 4 3 5 2 6
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/ Hình 2.4 Đồ thị G sau khi xóa cạnh (1,2), (2,3)
đỉnh v1=3 quay lại bước (2) (2) : H ≠ sang bước (3)
(3) : Chọn cạnh đi kế tiếp là cạnh (3, 4) khi đó C = {1, 2, 3, 4} sang bước (4) (4) : xóa cạnh vừa qua và xóa đỉnh cô lập
Loại cạnh (2, 3) khỏi H, khi đó H = {(1, 6) ; (2, 5) ; (2, 6) ; (3, 5) ; (3, 6) ; (4, 5) ; (5, 6)} 1 4 3 5 2 6
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/ Hình 2.5 Đồ thị G sau khi xóa cạnh (1,2), (2,3), (3,4)
đỉnh v1=4 quay lại bước (2) (2) : H ≠ sang bước (3)
(3) : Chọn cạnh đi kế tiếp là cạnh (4, 5) khi đó C = {1, 2, 3, 4, 5} sang bước (4) (4) : xóa cạnh vừa qua và xóa đỉnh cô lập
Loại cạnh (4, 5) khỏi H, xóa đỉnh cô lập 4, khi đó H = {(1, 6) ; (2, 5); (2, 6); (3, 5); (3, 6); (5, 6)} 1 4 3 5 2 6
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/ Hình 2.6 Đồ thị G sau khi xóa cạnh (1,2), (2,3), (3,4), (4, 5) và đỉnh 4
đỉnh v1=5 quay lại bước (2) (2) : H ≠ sang bước (3)
(3) : Chọn cạnh đi kế tiếp là cạnh (5, 6) khi đó C = {1, 2, 3, 4, 5, 6} sang bước (4) (4) : xóa cạnh vừa qua và xóa đỉnh cô lập
Loại cạnh (5, 6) khỏi H, khi đó H = {(1, 6) ; (2, 5); (2, 6); (3, 5); (3, 6)} Hình 2.7
Hình 2.7 Đồ thị G sau khi xóa cạnh (1,2), (2,3), (3,4), (4,5), (5,6) và đỉnh 4
1 3 5 2 6 1 3 5 2 6
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/
đỉnh v1=6 quay lại bước (2) (2) : H ≠ sang bước (3)
(3) : Chọn cạnh đi kế tiếp là cạnh (6, 2) hoặc (6, 3) vì cạnh (6, 1) là cầu, ta chọn cạnh (6, 2) khi đó C = {1, 2, 3, 4, 5, 6, 2} sang bước (4)
(4) : xóa cạnh vừa qua và xóa đỉnh cô lập
Loại cạnh (6, 2) khỏi H, khi đó H = {(1, 6) ; (2, 5); (3, 5); (3, 6)} Hình 2.8
Hình 2.8 Đồ thị G sau khi xóa cạnh (1,2), (2,3), (3,4), (4,5), (5,6),(6,2) và đỉnh 4
đỉnh v1=2 quay lại bước (2) (2) : H ≠ sang bước (3)
(3) : Chọn cạnh đi kế tiếp là cạnh (2, 5) khi đó C = {1, 2, 3, 4, 5, 6, 2, 5} sang bước (4)
(4) : xóa cạnh vừa qua và xóa đỉnh cô lập
Loại cạnh (2, 5) và đỉnh cô lập 2 khỏi H, khi đó H = {(1, 6); (3, 5); (3, 6)} Hình 2.9
1
3 5
2 6
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/ Hình 2.9 Đồ thị G sau khi xóa cạnh (1,2), (2,3), (3,4), (4,5), (5,6),(6,2),(2,5) và
xóa đỉnh 4, 2
đỉnh v1=5 quay lại bước (2) (2) : H ≠ sang bước (3)
(3) : Chọn cạnh đi kế tiếp là cạnh (5, 3) khi đó C = {1, 2, 3, 4, 5, 6, 2, 5, 3} sang bước (4)
(4) : xóa cạnh vừa qua và xóa đỉnh cô lập
Loại cạnh (5, 3) và đỉnh cô lập 5 khỏi H, khi đó H = {(1, 6); (3, 6)} Hình 2.10
1
3 5
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/ Hình 2.10 Đồ thị G sau khi xóa cạnh (1,2), (2,3), (3,4), (4,5),
(5,6),(6,2),(2,5),(5,3) và xóa đỉnh 4, 2, 5
đỉnh v1=3 quay lại bước (2) (2) : H ≠ sang bước (3)
(3) : Chọn cạnh đi kế tiếp là cạnh (3, 6) khi đó C = {1, 2, 3, 4, 5, 6, 2, 5, 3, 6} sang bước (4)
(4) : xóa cạnh vừa qua và xóa đỉnh cô lập
Loại cạnh (3, 6) và đỉnh cô lập 3 khỏi H, khi đó H = {(1, 6)} Hình 2.11
Hình 2..11 Đồ thị G sau khi xóa cạnh (1,2), (2,3), (3,4), (4,5), (5,6),(6,2),(2,5),(5,3), (3,6) và xóa đỉnh 4, 2, 5, 3
đỉnh v1=6 quay lại bước (2) (2) : H ≠ sang bước (3) 1 6 1 3 6
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/
(3) : Chọn cạnh đi kế tiếp là cạnh (6, 1) khi đó C = {1, 2, 3, 4, 5, 6, 2, 5, 3, 6, 1} sang bước (4)
(4) : xóa cạnh vừa qua và xóa đỉnh cô lập
Loại cạnh (6, 1) và đỉnh cô lập 6 và 1 khỏi H, khi đó H = (thuật toán dừng) Kết luận ta có chu trình Euler là :
C = {1, 2, 3, 4, 5, 6, 2, 5, 3, 6, 1}
2.2.2 Thuật toán Hierholzer
Năm 1873 Hierholzer đề xuất một thuật toán tìm chu trình : Đầu vào : đồ thị G liên thông và không có đỉnh bậc lẻ Đầu ra : chu trình Euler
(1). (Khởi động) Chọn đỉnh s tuỳ ý làm đỉnh xuất phát.
(2). (Tiến) Đi theo các cạnh mới (cạnh chưa thăm) đến mức tối đa. Lần lượt ghi nhận đường đi thể hiện qua các đỉnh đầu mút vào một ngăn xếp p.
(3). (Kiểm tra) Nếu mọi cạnh đều đã thăm: thực hiện bước 5 để kết thúc; nếu không: thực hiện bước 4.
(4). (Lùi) Dỡ dần ngăn xếp p, tức là bạn quay lui, để tìm một đỉnh đầu tiên w (tính từ thời điểm gặp đỉnh s) nơi từ đó có khả năng đi tiếp theo một cạnh chưa thăm. Hãy ghi nhận lại các đỉnh đã dỡ từ ngăn xếp vào một mảng r rồi lặp lại bước 2 để đi tiếp từ đỉnh w này theo các cạnh chưa thăm giống như đã làm với đỉnh v.
(5). (Kết) Ghép tiếp mảng r chứa các đỉnh đã dỡ từ ngăn xếp p vào cuối p để nhận được chu trình Euler. [4]
Thí dụ 2.2.2
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/ Hình 2.12 Đồ thị vô hướng G liên thông với 6 đỉnh 11 cạnh
Đồ thị G : Đồ thị gồm 6 đỉnh bậc chẵn V={1, 2, 3, 4, 5, 6} ; tập cạnh E={a, b, c, d, e, f, g, h, i, j}
Các bước thực hiện thuật toán Hierholzer cho kết quả sau
Bước Giá trị trong Stack P Giá trị trong mảng R Cạnh còn lại
1 1 a, b, c, d, e, f, g, h, i, j 2 1, 2 b, c, d, e, f, g, h, i, j 3 1, 2, 3 b, d, e, f, g, h, i, j 4 1, 2, 3, 1 d, e, f, g, h, i, j 5 1, 2, 3 1 d, e, f, g, h, i, j 6 1, 2, 3, 4 1 d, f, g, h, i, j 7 1, 2, 3, 4, 2 1 f, g, h, i, j 8 1, 2, 3, 4, 2, 5 1 g, h, i, j 9 1, 2, 3, 4, 2, 5, 3 1 h, i, j 10 1, 2, 3, 4, 2, 5 1, 3 h, i, j 11 1, 2, 3, 4, 2, 5, 4 1, 3 i, j 4 1 3 5 6 2 a b c d f h j i g e
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/
12 1, 2, 3, 4, 2, 5, 4, 5 1, 3 i
13 1, 2, 3, 4, 2, 5, 4, 5, 6 1, 3 14 1, 2, 3, 4, 2, 5, 4, 5, 6, 3 1 15 1, 2, 3, 4, 2, 5, 4, 5, 6, 3, 1
Bảng 2.1 Các bước thực hiện thuật toán Hierholzer để tìm chu trình Euler
Kết quả : 1, 2, 3, 4, 2, 5, 4, 5, 6, 3, 1
Thuật toán tìm đường đi Euler
Đầu vào : đồ thị G liên thông và chỉ có hai đỉnh bậc lẻ Đầu ra : đường đi Euler
(1). (Khởi động) Chọn 1 trong 2 đỉnh lẻ làm đỉnh xuất phát.
(2). (Tiến) Đi theo các cạnh mới (cạnh chưa thăm) đến mức tối đa. Lần lượt ghi nhận đường đi thể hiện qua các đỉnh đầu mút vào một ngăn xếp p.
(3). (Kiểm tra) Nếu mọi cạnh đều đã thăm: thực hiện bước 5 để kết thúc; nếu không: thực hiện bước 4.
(4). (Lùi) Dỡ dần ngăn xếp p, tức là bạn quay lui, để tìm một đỉnh đầu tiên w (tính từ thời điểm gặp đỉnh s) nơi từ đó có khả năng đi tiếp theo một cạnh chưa thăm. Hãy ghi nhận lại các đỉnh đã dỡ từ ngăn xếp vào một mảng r rồi lặp lại bước 2 để đi tiếp từ đỉnh w này theo các cạnh chưa thăm giống như đã làm với đỉnh v.
(5). (Kết) Ghép tiếp mảng r chứa các đỉnh đã dỡ từ ngăn xếp p vào cuối p để nhận được chu trình Euler. [4]
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/ Thí dụ 2.2.3
Cho đồ thị vô hướng như hình 2.13
Hình 2.13 Đồ thị vô hướng G liên thông có 2 đỉnh bậc lẻ
Đồ thị G : tập đỉnh V={1, 2, 3, 4, 5} trong đó có 3 đỉnh bậc chẵn {2, 4, 5} và 2 đỉnh bậc lẻ {1, 3}; tập cạnh E={a, b, c, d, e, f, g, h}
Đồ thị có đường đi euler, áp dụng thuật toán Hierholzer với đỉnh xuất phát là đỉnh 1. Các bước thực hiện thuật toán Hierholzer cho kết quả sau
Bước Giá trị trong Stack P Giá trị trong mảng R Cạnh còn lại
1 1 a, b, c, d, e, f, g, h 2 1, 2 a, b, c, e, f, g, h 3 1, 2, 3 a, c, e, f, g, h 4 1, 2, 3, 1 a, e, f, g, h 5 1, 2, 3, 1, 4 e, f, g, h 6 1, 2, 3, 1, 4, 3 f, g, h 7 1, 2, 3, 1, 4, 3 f, g, h 8 1, 2, 3, 1, 4, 2 3 g, h 9 1, 2, 3, 1, 4, 2, 5 3 10 1, 2, 3, 1, 4, 2, 5, 4 3 11 1, 2, 3, 1, 4, 2, 5, 4, 3
Bảng 2.2 Các bước thực hiện thuật toán Hierholzer để tìm đường đi Euler
c d a f g h e b 1 3 4 5 2
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/
Đường đi euler : 1, 2, 3, 1, 4, 2, 5, 4, 3. Chương trình dưới đây:
Đọc dữ liệu mô tả đồ thị liên thông G gồm n đỉnh và m cạnh. Đếm số đỉnh lẻ k và quyết định:
Nếu k > 2: Ghi kết quả 0 với ý nghĩa: G không có đường (và dĩ nhiên là không có chu trình) Euler.
Nếu k = 2: Hiển thị một đường Euler. Nếu k = 0: Hiển thị một chu trình Euler.
Chương trình hiển thị kết quả trung gian tại mỗi bước quay lui. Sơ đồ chính của chương trình sẽ như sau:
Đọc dữ liệu;
int Euler(int s){ while(1) {
Tien và ghi nhận các bước tiến vào stack p; Nếu Đã duyệt hết cạnh: thoát lặp; Nếu chưa duyệt hết cạnh:
- Quay lui chuyển các đỉnh lui về cuối p; - Nếu không quay lui được: thoát lặp; } // end while;
- Thông báo kết quả; }
Thủ tục Tiến sẽ xuất phát từ đỉnh s và thêm dần các đỉnh đến vào stack p, từ p[k] đến p[e].
Thủ tục Lui sẽ chạy ngược từ e đến k để tìm một đỉnh i trên đường lùi thoả điều kiện: từ i có cạnh chưa thăm.
Trường họp dồ thị có 2 đỉnh bậc lẻ thì chỉ có đường đi euler và đỉnh xuất phát là một trong hai đỉnh bậc lẻ, đỉnh kết thúc là đỉnh bậc lẻ còn lại.