Trên thực tế có nhiều bài toán liên quan tới một tập các đối tượng và những mối liên hệ giữa chúng, đòi hỏi toán học phải đặt ra một mô hình biểu diễn một cách chặt chẽ và tổng quát bằng ngôn ngữ ký hiệu, đó là đồ thị. Những ý tưởng cơ bản của nó được đưa ra từ thế kỷ thứ XVIII bởi nhà toán học Thuỵ Sĩ Leonhard Euler, ông đã dùng mô hình đồ thị để giải bài toán về những cây cầu Konigsberg nổi tiếng. Mặc dù Lý thuyết đồ thị đã được khoa học phát triển từ rất lâu nhưng lại có nhiều ứng dụng hiện đại. Đặc biệt trong khoảng vài mươi năm trở lại đây, cùng với sự ra đời của máy tính điện tử và sự phát triển nhanh chóng của Tin học, Lý thuyết đồ thị càng được quan tâm đến nhiều hơn. Đặc biệt là các thuật toán trên đồ thị đã có nhiều ứng dụng trong nhiều lĩnh vực khác nhau như: Mạng máy tính, Lý thuyết mã, Tối ưu hoá, Kinh tế học v.v... Chẳng hạn như trả lời câu hỏi: Hai máy tính trong mạng có thể liên hệ được với nhau hay không ?; hay vấn đề phân biệt hai hợp chất hoá học có cùng công thức phân tử nhưng lại khác nhau về công thức cấu tạo cũng được giải quyết nhờ mô hình đồ thị. Hiện nay, môn học này là một trong những kiến thức cơ sở của bộ môn khoa học máy tính. Trong phạm vi một chuyên đề, không thể nói kỹ và nói hết những vấn đề của lý thuyết đồ thị. Tập bài giảng này sẽ xem xét lý thuyết đồ thị dưới góc độ người lập trình, tức là khảo sát những thuật toán cơ bản nhất có thể dễ dàng cài đặt trên máy tính một số ứng dụng của nó. Các khái niệm trừu tượng và các phép chứng minh sẽ được diễn giải một cách hình thức cho đơn giản và dễ hiểu chứ không phải là những chứng minh chặt chẽ dành cho người làm toán. Công việc của người lập trình là đọc hiểu được ý tưởng cơ bản của thuật toán và cài đặt được chương trình trong bài toán tổng quát cũng như trong trường hợp cụ thể. Thông thường sau quá trình rèn luyện, hầu hết những người lập trình gần như phải thuộc lòng các mô hình cài đặt, để khi áp dụng có thể cài đặt đúng ngay và hiệu quả, không bị mất thời giờ vào các công việc gỡ rối. Bởi việc gỡ rối một thuật toán tức là phải dò lại từng bước tiến hành và tự trả lời câu hỏi: Tại bước đó nếu đúng thì phải như thế nào?, đó thực ra là tiêu phí thời gian vô ích để chứng minh lại tính đúng đắn của thuật toán trong trường hợp cụ thể, với một bộ dữ liệu cụ thể.
MỤC LỤC Chương TỔNG QUAN 1.1 Mở đầu Trên thực tế có nhiều toán liên quan tới tập đối tượng mối liên hệ chúng, đòi hỏi toán học phải đặt mô hình biểu diễn cách chặt chẽ tổng quát ngôn ngữ ký hiệu, đồ thị Những ý tưởng đưa từ kỷ thứ XVIII nhà toán học Thuỵ Sĩ Leonhard Euler, ông dùng mô hình đồ thị để giải toán cầu Konigsberg tiếng Mặc dù Lý thuyết đồ thị khoa học phát triển từ lâu lại có nhiều ứng dụng đại Đặc biệt khoảng vài mươi năm trở lại đây, với đời máy tính điện tử phát triển nhanh chóng Tin học, Lý thuyết đồ thị quan tâm đến nhiều Đặc biệt thuật toán đồ thị có nhiều ứng dụng nhiều lĩnh vực khác như: Mạng máy tính, Lý thuyết mã, Tối ưu hoá, Kinh tế học v.v Chẳng hạn trả lời câu hỏi: Hai máy tính mạng liên hệ với hay không ?; hay vấn đề phân biệt hai hợp chất hoá học có công thức phân tử lại khác công thức cấu tạo giải nhờ mô hình đồ thị Hiện nay, môn học kiến thức sở môn khoa học máy tính Trong phạm vi chuyên đề, nói kỹ nói hết vấn đề lý thuyết đồ thị Tập giảng xem xét lý thuyết đồ thị góc độ người lập trình, tức khảo sát thuật toán dễ dàng cài đặt máy tính số ứng dụng Các khái niệm trừu tượng phép chứng minh diễn giải cách hình thức cho đơn giản dễ hiểu chứng minh chặt chẽ dành cho người làm toán Công việc người lập trình đọc hiểu ý tưởng thuật toán cài đặt chương trình toán tổng quát trường hợp cụ thể Thông thường sau trình rèn luyện, hầu hết người lập trình gần phải thuộc lòng mô hình cài đặt, để áp dụng cài đặt hiệu quả, không bị thời vào công việc gỡ rối Bởi việc gỡ rối thuật toán tức phải dò lại bước tiến hành tự trả lời câu hỏi: "Tại bước phải nào?", thực tiêu phí thời gian vô ích để chứng minh lại tính đắn thuật toán trường hợp cụ thể, với liệu cụ thể Trước tìm hiểu vấn đề lý thuyết đồ thị, bạn phải có kỹ thuật lập trình tốt, có tìm hiểu trước kỹ thuật vét cạn, quay lui, số phương pháp tối ưu hoá, toán quy hoạch động giúp ích nhiều cho việc đọc hiểu giảng 1.2 Các khái niệm 1.2.1 Đồ thị Đồ thị mô hình toán học diễn tả cách tường minh mối quan hệ hai (một chiều hai chiều) đối tượng cần xem xét Lý thuyết đồ thị ngành toán học đại có ứng dụng quan trọng vào nhiều ngành khoa học, kỹ thuật đại: vật lý, hoá học, sinh học, tin học, điều khiển học, v.v Một kết lí thuyết đồ thị xuất báo nhà toán học Thuỵ Sĩ Leonhard Euler Bảy cầu Königsberg, xuất năm 1736 Thành phố Konigsberg (nay gọi Kaliningrad thuộc Cộng hoà Nga) chia thành bốn vùng nhánh sông Pregel Các vùng gồm hai vùng bên bờ sông, đảo Kneiphof miền nằm hai nhánh sông Pregel Vào kỷ 18 ngưòi ta xây cầu nối vùng lại với nhaunhư (Hình 1.1) Vào Chủ Nhật dân chúng thường dạo chơi quanh thành phố nêu thắc mắc: dạo chơi qua khắp cầu, cầu lần thôi, trở điểm xuất phát không? Hình 1-1 Để chứng minh kết quả, Euler phát biểu toán thuật ngữ lý thuyết đồ thị Ông loại bỏ tất chi tiết ngoại trừ vùng đất cầu, sau thay vùng đất điểm, gọi đỉnh nút, thay cầu đoạn nối, gọi cạnh liên kết Cấu trúc toán học thu được gọi đồ thị (Hình 1.3) Hình 1-2 Hình 1-3 Khi thắc mắc dân thành phố là: khắp đường sơ đồ (Hình 1.3), đường qua lần không? Nói cách khác: vẽ sơ đồ (Hình 1.3) nét bút liên tục (tức không nhấc bút khỏi trang giấy không vẽ trùng hai lần đoạn nào) không? Euler công bố lời giải toán vào năm 1736, ứng dụng lý thuyết đồ thị Euler trả lời: không khẳng định rằng: Muốn qua khắp cạnh sơ đồ (rồi quay trở chỗ cũ) mà cạnh qua lần, sơ đồ phải liên thông điểm bậc lẻ Đồ thị cầu Königsberg có bốn nút bậc lẻ Năm 1852 Francis Guthrie đưa toán bốn màu vấn đề liệu với bốn màu tô màu đồ cho hai nước biên giới tô màu Bài toán giải sau kỉ vào năm 1976 Kenneth Appel Wolfgang Haken Trong cố gắng giải toán này, nhà toán học phát minh nhiều thuật ngữ khái niệm tảng cho lí thuyết đồ thị Đồ thị dùng để giải toán nhiều lĩnh vực khác Ví dụ: Xác định xem thực mạch điện bảng điện phẳng không Xác định xem hai máy tính có nối với đường truyền thông hay không dùng mô hình đồ thị mạng máy tính Tìm đường ngắn hai thành phố mạng giao thông Lập lịch thi phân chia kênh cho đài truyền hình Điều lí thú nhiều toán mà phát biểu ban đầu, ta không thấy “bóng dáng” đồ thị sau phân tích, việc giải toán đưa việc giải toán đồ thị xây dựng thích hợp 1.2.2 Các khái niệm Như định nghĩa đồ thị G = (V, E) cấu trúc rời rạc, tức tập V E tập hữu hạn, tập đếm được, có nghĩa ta đánh số thứ tự 1, 2, cho phần tử tập V E Hơn nữa, đứng phương diện người lập trình cho máy tính ta quan tâm đến đồ thị hữu hạn (V E tập hữu hạn) mà thôi, từ sau, không thích thêm nói tới đồ thị, ta hiểu đồ thị hữu hạn Cạnh liên thuộc, đỉnh kề, bậc • Đối với đồ thị vô hướng G = (V, E) Xét cạnh e ∈ E, e = (u, v) ta nói hai đỉnh u v kề (adjacent) cạnh e liên thuộc (incident) với đỉnh u đỉnh v • Với đỉnh v đồ thị, ta định nghĩa bậc (degree) v, ký hiệu deg(v) số cạnh liên thuộc với v Dễ thấy đơn đồ thị số cạnh liên thuộc với v số đỉnh kề với v Định lý: Giả sử G = (V, E) đồ thị vô hướng với m cạnh, tổng tất bậc đỉnh V 2m: Chứng minh: Khi lấy tổng tất bậc đỉnh tức cạnh e = (u, v) tính lần deg(u) lần deg(v) Từ suy kết Hệ quả: Trong đồ thị vô hướng, số đỉnh bậc lẻ số chẵn • Đối với đồ thị có hướng G = (V, E) Xét cung e ∈ E, e = (u, v) ta nói u nối tới v v nối từ u, cung e khỏi đỉnh u vào đỉnh v Đỉnh u gọi đỉnh đầu, đỉnh v gọi đỉnh cuối cung e • + Với đỉnh v đồ thị có hướng, ta định nghĩa: Bán bậc v ký hiệu deg (v) - số cung khỏi nó; bán bậc vào ký hiệu deg (v) số cung vào đỉnh Định lý: Giả sử G = (V, E) đồ thị có hướng với m cung, tổng tất bán bậc đỉnh tổng tất bán bậc vào m: Chứng minh: Khi lấy tổng tất bán bậc hay bán bậc vào, cung (u, v) tính lần deg+(u) tính lần deg-(v) Từ suy kết Một số tính chất đồ thị có hướng không phụ thuộc vào hướng cung Do để tiện trình bày, số trường hợp ta không quan tâm đến hướng cung coi cung cạnh đồ thị vô hướng Và đồ thị vô hướng gọi đồ thị vô hướng đồ thị có hướng ban đầu Chương BÀI TOÁN GHÉP CẶP TRONG ĐỒ THI 2.1 Bài toán ghép cặp cực đại 2.1.1 Các khái niệm Xét đồ thị G = (V, E), ghép đồ thị G tập cạnh đôi đỉnh chung Bài toán tìm ghép cực đại đồ thị tổng quát phát biểu sau: Cho đồ thị G, phải tìm ghép cực đại G (bộ ghép có hiều nh nhất) Với ghép M đồ thị G, ta gọi: • Những cạnh thuộc M gọi cạnh ghép hay cạnh đậm • Những cạnh không thuộc M gọi cạnh chưa ghép hay cạnh nhạt • Những đỉnh đầu mút cạnh đậm gọi đỉnh ghép, đỉnh lại gọi đỉnh chưa ghép • Một đường (đường đỉnh lặp lại) gọi đường pha bắt đầu cạnh nhạt cạnh đậm, nhạt nằm nối tiếp xen kẽ • Một chu trình (chu trình đỉnh lặp lại) gọi Blossom qua đỉnh, bắt đầu kết thúc cạnh nhạt dọc chu trình, cạnh đậm, nhạt nằm nối tiếp xen kẽ Đỉnh xuất phát chu trình (cũng đỉnh kết thúc) gọi đỉnh sở (base) Blossom • Đường mở đường pha bắt đầu đỉnh chưa ghép kết thúc đỉnh chưa ghép Ví dụ: Với đồ thị G ghép M đây: match edge unmatch edge Hình 2-4 Đồ thị G ghép M • Đường (8, 1, 2, 5, 6, 4) đường pha • Chu trình (2, 3, 4, 6, 5, 2) Blossom • Đường (8, 1, 2, 3, 4, 6, 5, 7) đường mở • Đường (8, 1, 2, 3, 4, 6, 5, 2, 1, 9) có cạnh đậm/nhạt xen kẽ đường pha (và tất nhiên đường mở) đường Ta dễ dàng suy tính chất sau: • Đường mở Blossom đường độ dài lẻ với số cạnh nhạt nhiều số cạnh đậm cạnh • Trong Blossom, đỉnh đỉnh sở đỉnh ghép đỉnh ghép với đỉnh phải thuộc Blossom • Vì Blossom chu trình nên Blossom, đỉnh đỉnh sở tồn hai đường pha từ đỉnh sở đến nó, đường kết thúc cạnh đậm đường kết thúc cạnh nhạt, hai đường pha hình thành cách dọc theo chu trình theo hai hướng ngược Như ví dụ trên, đỉnh có hai đường pha đỉnh sở tới: (2, 3, 4) đường pha kết thúc cạnh đậm (2, 5, 6, 4) đường pha kết thúc cạnh nhạt 2.1.2 Thuật toán EDMONDS(1965) Cơ sở thuật toán định lý (C.Berge): Một ghép M đồ thị G cực đại không tồn đường mở M Thuật toán Edmonds: M := ∅; for ( đỉnh u chưa ghép) if then < Dọc đường mở: Loại bỏ cạnh đậm khỏi M; Thêm vào M cạnh nhạt; > Result: M ghép cực đại G Điều khó thuật toán Edmonds phải xây dựng thuật toán tìm đường mở xuất phát từ đỉnh chưa ghép Thuật toán xây dựng cách kết hợp thuật toán tìm kiếm đồ thị với phép chập Blossom Xét đường pha xuất phát từ đỉnh x chưa ghép Những đỉnh đến từ x đường pha kết thúc cạnh nhạt gán nhãn "nhạt", đỉnh đến từ x đường pha kết thúc cạnh đậm gán nhãn "đậm" Với Blossom, ta định nghĩa phép chập (shrink) phép thay đỉnh Blossom đỉnh Những cạnh nối đỉnh thuộc Blossom tới đỉnh v không thuộc Blossom thay cạnh nối đỉnh chập với v giữ nguyên tính đậm/nhạt Dễ thấy sau phép chập, cạnh đậm đảm bảo ghép đồ thị mới: Hình 2-5 Phép chập Blosson Thuật toán tìm đường mở phát biểu sau: • Trước hết đỉnh xuất phát x gán nhãn đậm • Tiếp theo thuật toán tìm kiếm đồ thị x, theo nguyên tắc: từ đỉnh đậm phép cạnh nhạt từ đỉnh nhạt cạnh đậm Mỗi thăm tới đỉnh, ta gán nhãn đậm/nhạt cho đỉnh tiếp tục thao tác tìm kiếm đồ thị bình thường Cũng trình tìm kiếm, phát thấy cạnh nhạt nối hai đỉnh đậm, ta dừng lại gán nhãn tiếp gặp tình trạng đỉnh có hai nhãn đậm/nhạt, trường hợp này, Blossom phát (xem tính chất Blossom) bị chập thành đỉnh, thuật toán bắt đầu lại với đồ thị trả lời câu hỏi: "có tồn đường mở xuất phát từ x hay không?" • Nếu đường mở tìm không qua đỉnh chập ta việc tăng cặp dọc theo đường mở Nếu đường mở có qua đỉnh chập ta lại nở đỉnh chập thành Blossom để thay đỉnh chập đường mở đoạn đường xuyên qua Blossom: Hình 2-6 Nở Blossom để dò thương xuyên qua Blosson Lưu ý Blossom bị chập, Blossom ảnh hưởng tới trình tìm đường mở phải chập để đảm bảo đường mở tìm đường Tuy nhiên việc cài đặt trực tiếp phép chập Blossom 0_cạnh (x, y) với x∈VisitedX y∉VisitedY Vì x* đến x đường pha (x, y) 0_cạnh nên x* đến y đường pha, dẫn tới y ∈ VisitedY, điều vô lý Biến đổi đồ thị G sau: Với ∀x ∈ VisitedX, trừ ∆ vào trọng số cạnh liên thuộc với x, Với ∀ y ∈ VisitedY, cộng ∆ vào trọng số cạnh liên thuộc với y * Lặp lại thủ tục tìm kiếm đồ thị thử tìm đường mở xuất phát x tìm đường mở Bước 3: Sau bước X_đỉnh ghép, in kết ghép tìm Mô hình cài đặt thuật toán viết sau: ; for (x*∈X) begin repeat ; if then ; until ; ; end; ; Ví dụ minh hoạ: Để không bị rối hình, ta hiểu cạnh không ghi trọng số 0_cạnh, cạnh không vẽ mang trọng số lớn trường hợp không cần thiết phải tính đến Những cạnh nét đậm cạnh ghép, cạnh nét cạnh chưa ghép Ta thấy không tìm thấy đường mở xuất phát x * trình * tìm kiếm đồ thị cho ta pha gốc x Giá trị xoay ∆ thực chất trọng số nhỏ cạnh nối X_đỉnh pha với Y_đỉnh pha (cạnh ngoài) Việc trừ ∆ vào cạnh liên thuộc với X_đỉnh pha cộng ∆ vào cạnh liên thuộc với Y_đỉnh pha làm cho cạnh nói trở thành 0_cạnh, cạnh khác có trọng số ≥ Nhưng quan trọng tất cạnh pha 0_cạnh Điều đảm bảo cho trình tìm kiếm đồ thị lần sau xây dựng pha lớn pha cũ (Thể chỗ: tập VisitedY rộng trước phần tử) Vì tập Y_ đỉnh ghép hữu hạn nên sau không k bước, có Y_đỉnh chưa ghép ∈ VisitedY, tức tìm đường mở Trên thực tế, để chương trình hoạt động nhanh hơn, bước khởi tạo, người ta thêm thao tác: o Với đỉnh x ∈ X, xác định trọng số nhỏ cạnh liên thuộc với x, sau trừ tất trọng số cạnh liên thuộc với x trọng số nhỏ Làm tương tự với Y_đỉnh Điều tương đương với việc trừ tất phần tử hàng ma trận C giá trị nhỏ hàng đó, lại trừ tất phần tử cột ma trận C phần tử nhỏ cột Khi số 0_cạnh đồ thị nhiều, chứa ghép đầy đủ cần qua bước biến đổi chứa ghép đầy đủ k cạnh o Để tưởng nhớ hai nhà toán học König Egervary, người đặt sở lý thuyết cho phương pháp, người ta lấy tên đất nước sinh hai nhà toán học để đặt tên cho thuật toán Mặc dù sau có số cải tiến tên gọi Thuật toán Hungari (Hungarian Algorithm) dùng phổ biến Chương ỨNG DỤNG CỦA BÀI TOÁN GHÉP CẶP 3.1 Phát biểu toán Bài toán phân công công việc Có M người thợ N công việc, người có khả thực số công việc định Cần phân công cho thợ việc việc thợ thực cho số công việc thực nhiều có phương án thực nhiều công việc phương án chi phí Khả làm việc thợ cho ma trận Cij với Cij = thợ i biết làm việc j, Cij = thợ i làm việc j - 3.2 Phương pháp giải Dựng đồ thị hai phía G = (X Y, E) với X tập m người thợ, Y tập n công việc (u, v) E với trọng số c[u,v] người u làm công việc v Bài toán đưa - tìm ghép nhiều cạnh G có trọng số nhỏ Gọi k = max(m,n) Gọi M số dương lớn chi phí phép phân công Với cặp đỉnh (u, v): u X v Y Nếu (u,v) E ta bổ sung cạnh (u, v) vào E với - trọng số M Khi ta G đồ thị hai phía đầy đủ (đồ thị hai phía mà đỉnh bất kỳ X Y có cạnh nối) Nếu tìm ghép đầy đủ k cạnh có trọng số nhỏ ta cần loại bỏ khỏi ghép cạnh mang trọng số M vừa thêm vào kế hoạch phân công người tương ứng với việc cần tìm 3.3 Phân tích toán Do đồ thị hai phía G không thiết phải đầy đủ nên giải toán cách riêng dễ dàng - Tập cặp ghép M (có thể không đầy đủ ) cực đại không tìm đường đỉnh tự thuộc X kết thúc đỉnh tự thuộc Y đồ thị G’ = (X Y, E’) Đường gọi đường tăng cặp ghép, G’ nhận từ G cách định hướng lại cạnh G theo quy tắc: o Những cạnh (x, y) thuộc M đồ thị G định hướng ngược lại trở thành cung (y, x) đồ thị G’ o Những cạnh (x, y) thuộc M đồ thị G định hướng trở thành cung (x, y) đồ thị G’ o Như vậy, ta có nhận xét sau đây: giả sử xây dựng tập cặp ghép M có đường tăng cặp ghép từ đỉnh tự x X đến đỉnh tự y0 Y X y x1 y2 … x n y - Input: đồ thị hai phía đầy đủ G = (X Y, E) với | X | = | Y | = k Được cho bơir ma trận vuông C, kích thước k x k, C[i,j] = trọng số cạnh nối đỉnh X i với Yj, C[i,j] 0, với i - , j Output: ghép đầy đủ trọng số nhỏ 3.4 Thuật toán Bước 1: Khởi tạo tập cặp ghép M rỗng Bước 2: Tìm đường cặp ghép từ đỉnh x tự thuộc X đến đỉnh y tự - thuộc Y Nếu tìm chuyển sang bước Nếu không tìm tập cặp ghép thời cực đại kết thúc thuật toán Bước 3: Tăng cặp ghép: W = {c[x, y] – Tho[x] – Viec[y]} Với x VisitedX: Tho[x] = Tho[x] + W; Với y VisitedY: : Viec[y] = Viec[y] - W; Lặp lại tìm đường mở Xuất W; 3.5 Chương trình cài đặt: - Nhập liẹu từ file văn Input.inp o Dòng ghi hai số m, n tương ứng số thợ số việc o Dòng tiếp theo, dòng ghi ba số i, j, c[i, j] thể thợ i làm việc j chi phí c[i, j] để làm công việc Input.inp Output.out Tho[1] - Viec[1] 1 Tho[2] - Viec[4] Tho[3] - Viec[2] 2 Tho[1] - Viec[1] Trong So: 2 3 4 12 - Dạng đồ thị sau: - Chương trình cài đặt: program GhepCapCucDai User Crt; Const input = 'input.inp'; output = 'output.out'; MaxN = 200; // tap cac nguoi tho MaxM = 200; // tap cac cong viec Var C: array[1 max, max] of Integer; Tho: array[1 MaxN] of Integer; Viec: array[1 MaxM] of Integer; N, M of Integer; xo, yo of Integer; PathFound = Boolean; /*Đọc liệu đầu vào*/ procedure ReadInput; Var f: text; i, x: byte; Begin Fillchar(C, SizeOf(C), 0); /* trả về mảng với C[i] = */ Assign (f, input); reset (f); Readln (f, N, M); For (i = 1; i [...]... sở và thoát ra khỏi Blossom bằng một cạnh nhạt 2.2 Bài toán ghép cặp trong đồ thị hai phần 2.2.1 Đồ thị hai phía(Bipartite Graph) 2.2.1.1 Khái niệm Các tên gọi đồ thị hai phía, đồ thị lưỡng phân, đồ thị phân đôi, đồ thị đối sánh hai phần v.v là để chỉ chung một dạng đơn đồ thị vô hướng G = (V, E) mà tập đỉnh của nó có thể chia làm hai tập con X, Y rời nhau sao cho bất kỳ cạnh nào của đồ thị cũng nối... một đỉnh tự do thuộc X và kết thúc tại một đỉnh tự do thuộc Y trên đồ thị G’ = (X Y, E’) Đường đi đó gọi là đường tăng cặp ghép, và G’ nhận được từ G bằng cách định hướng lại các cạnh của G theo quy tắc: o Những cạnh (x, y) thuộc M trong đồ thị G được định hướng ngược lại trở thành cung (y, x) trong đồ thị G’ o Những cạnh (x, y) thuộc M trong đồ thị G được định hướng trở thành cung (x, y) trong đồ thị... ta được G là một đồ thị hai phía đầy đủ (đồ thị hai phía mà giữa một đỉnh bất kỳ của X và Y đều có cạnh nối) Nếu như tìm được bộ ghép đầy đủ k cạnh có trọng số nhỏ nhất thì ta chỉ cần loại bỏ khỏi bộ ghép đó những cạnh mang trọng số M vừa thêm vào thì sẽ được kế hoạch phân công 1 người tương ứng với 1 việc cần tìm 3.3 Phân tích bài toán Do đồ thị hai phía G ở đây không nhất thi t phải đầy đủ nên chúng... Không phải đồ thị hai phía > else ; Đồ thị hai phía gặp rất nhiều mô hình trong thực tế Chẳng hạn quan hệ hôn nhân giữa tập những người đàn ông và tập những người đàn bà, việc sinh viên chọn trường, thầy giáo chọn tiết dạy trong thời khoá biểu... kết quả về bộ ghép tìm được Dừng Chương 4 TỔNG KẾT, ĐÁNH GIÁ Mặc dù vẫn còn nhiếu thi u sót trong quá trình thực hiện báo cáo, qua bài cáo giúp chúng ta nắm được cái khai niệm về lý thuyết đồ thị, khái niệm đồ thị,… Bái báo cáo cũng cho chúng ta nắm được bài toán ghép cặp trong đồ thị, ứng dụng của bài toán trong thực tế, cũng như các bước cài đặt bài toán bằng ngôn ngữ lập trình Pascal TÀI... Queue Sau mỗi lần thăm, chú ý việc lưu vết (hai nhãn S và T) • Nếu v đã thăm: Nếu v là đỉnh nhạt hoặc b[v] = b[u] ∼ bỏ qua Nếu v là đỉnh đậm và b[v] ≠ b[u] ta phát hiện được blossom mới chứa u và v, khi đó: o Phát hiện đỉnh cơ sở: Truy vết đường đi ngược từ hai đỉnh đậm u và v theo hai đường pha về nút gốc, chọn lấy đỉnh a là đỉnh đậm chung gặp đầu tiên trong quá trình truy vết ngược Khi đó Blossom... tự do x 0 X đến đỉnh tự do y0 Y X 0 y 1 x1 y2 … x n y 0 - Input: đồ thị hai phía đầy đủ G = (X Y, E) với | X | = | Y | = k Được cho bơir ma trận vuông C, kích thước k x k, C[i,j] = trọng số cạnh nối đỉnh X i với Yj, C[i,j] 0, với mọi i - , j Output: bộ ghép đầy đủ trọng số nhỏ nhất 3.4 Thuật toán Bước 1: Khởi tạo tập cặp ghép M là rỗng Bước 2: Tìm đường cặp ghép từ một đỉnh x 0 tự do thuộc... 1 ghi hai chỉ số m, n tương ứng là số thợ và số việc o Dòng tiếp theo, mỗi dòng ghi ba số i, j, c[i, j] thể hiện thợ i làm việc j và chi phí c[i, j] để làm công việc đó Input.inp Output.out 5 6 Tho[1] - Viec[1] 0 1 1 Tho[2] - Viec[4] 3 0 1 2 0 Tho[3] - Viec[2] 2 2 1 0 Tho[1] - Viec[1] 0 2 4 3 Trong So: 5 3 2 2 3 3 0 4 3 0 4 4 7 5 4 12 - Dạng đồ thị như sau: - Chương trình cài đặt: program GhepCapCucDai... gọi một tập (chẳng hạn tập X) là tập các đỉnh trái và tập còn lại là tập các đỉnh phải của đồ thị hai phía G Các đỉnh thuộc X còn gọi là các X_đỉnh, các đỉnh thuộc Y gọi là các Y_đỉnh Hình 2-7 Đồ thị hai phía 2.2.1.2 Thuật toán kiểm tra đồ thị hai phía Để kiểm tra một đồ thị liên thông có phải là đồ thị hai phía hay không, ta có thể áp dụng thuật toán sau: X := {v}; Y := ∅; repeat Y := Y ∪ Kề(X); X... BFS để tìm đường qua ít cạnh nhất) có hai khả năng xảy ra: • Hoặc tìm được đường mở thì dọc theo đường mở, ta loại bỏ những cạnh đã ghép khỏi M và thêm vào M những cạnh chưa ghép, ta được một bộ ghép mới * nhiều hơn bộ ghép cũ 1 cạnh và đỉnh x trở thành đã ghép • Hoặc không tìm được đường mở thì do ta sử dụng thuật toán tìm kiếm trên đồ thị nên có thể xác định được hai tập: VisitedX = {Tập những X_đỉnh