Hotline: 024.62511017

024.62511081

  Trang chủ   Sản phẩm   Phần mềm Dành cho nhà trường   Phần mềm Hỗ trợ học tập   Kho phần mềm   Liên hệ   Đăng nhập | Đăng ký

Tìm kiếm

School@net
 
Xem bài viết theo các chủ đề hiện có
  • Hoạt động của công ty (726 bài viết)
  • Hỗ trợ khách hàng (498 bài viết)
  • Thông tin tuyển dụng (57 bài viết)
  • Thông tin khuyến mại (80 bài viết)
  • Sản phẩm mới (216 bài viết)
  • Dành cho Giáo viên (549 bài viết)
  • Lập trình Scratch (3 bài viết)
  • Mô hình & Giải pháp (156 bài viết)
  • IQB và mô hình Ngân hàng đề kiểm tra (127 bài viết)
  • TKB và bài toán xếp Thời khóa biểu (242 bài viết)
  • Học tiếng Việt (183 bài viết)
  • Download - Archive- Update (289 bài viết)
  • Các Website hữu ích (70 bài viết)
  • Cùng học (92 bài viết)
  • Learning Math: Tin học hỗ trợ học Toán trong nhà trường (78 bài viết)
  • School@net 15 năm (154 bài viết)
  • Mỗi ngày một phần mềm (7 bài viết)
  • Dành cho cha mẹ học sinh (124 bài viết)
  • Khám phá phần mềm (122 bài viết)
  • GeoMath: Giải pháp hỗ trợ học dạy môn Toán trong trường phổ thông (36 bài viết)
  • Phần mềm cho em (13 bài viết)
  • ĐỐ VUI - THƯ GIÃN (363 bài viết)
  • Các vấn đề giáo dục (1210 bài viết)
  • Bài học trực tuyến (1037 bài viết)
  • Hoàng Sa - Trường Sa (17 bài viết)
  • Vui học đường (275 bài viết)
  • Tin học và Toán học (220 bài viết)
  • Truyện cổ tích - Truyện thiếu nhi (180 bài viết)
  • Việt Nam - 4000 năm lịch sử (97 bài viết)
  • Xem toàn bộ bài viết (8223 bài viết)
  •  
    Đăng nhập/Đăng ký
    Bí danh
    Mật khẩu
    Mã kiểm traMã kiểm tra
    Lặp lại mã kiểm tra
    Ghi nhớ
     
    Quên mật khẩu | Đăng ký mới
     
    Thành viên có mặt
    Khách: 8
    Thành viên: 0
    Tổng cộng: 8
     
    Số người truy cập
    Hiện đã có 89585090 lượt người đến thăm trang Web của chúng tôi.

    SẮP XẾP TOPO - MỘT BÀI TOÁN CỔ ĐIỂN

    Ngày gửi bài: 12/02/2008
    Số lượt đọc: 5041

    1. Sắp xếp topo:

    Sắp xếp topo (topological sorting) là một trong những bài toán có tính ứng dụng cao cả trong Tin học lẫn Toán học và đời sống thường ngày. Đây là quá trình sắp xếp một dãy các phần tử sao cho thứ tự mới vẫn đảm bảo được thứ tự cục bộ (một cách nôm na có nghĩa là thứ tự được xác định đối với một vài cặp phần tử chứ không phải là tất cả các phần tử) vốn có của chúng. Một số ví dụ sẽ minh hoạ điều này

    Ví dụ 1:

    i) Một đề án có thể được chia thành nhiều nhiều công việc nhỏ khác nhau, tuy nhiên trong đó có những công việc chỉ có thể thực hiện được sau khi một số công việc khác đã hoàn thành. Nếu việc v buộc phải hoàn thành trước việc w (khi ấy việc w mới có thể thực hiện), ta kí hiệu v w. Sắp xếp topo trong trường hợp này nghĩa là đưa ra một thứ tự thực hiện các công việc hợp lý để có thể hoàn thành đề án.

    ii) Trong một số trường ĐH ở VN hiện nay, có những học phần gọi là học phần tiên quyết mà sinh viên buộc phải hoàn thành trước khi học các học phần khác. Nếu học phần v là học phần tiên quyết đối với học phần w, ta viết v w. Sắp xếp topo ở đây có nghĩa là đưa ra thứ tự học các học phần sao cho mọi học phần phải được học sau các học phần tiên quyết của nó.

    Một thứ tự cục bộ trên tập S thực chất là một quan hệ giữa các phần tử trên tập S, và khi đó S được gọi là tập được sắp xếp cục bộ (1). Thông thường thứ tự cục bộ được kí hiệu là (2), và phải thoả các tính chất (xem như tiên đề) sau với mọi x, y, z S:

    i) Tính phản xạ: x ≤ x,
    ii) Tính phản xứng: nếu x ≤ y và y ≤ x thì x=y, và
    iii) Tính bắc cầu: nếu x ≤ y, y ≤ z thì x ≤ z.

    Ví dụ 2:

    i) Quan hệ chia hết trên Z+ là một thứ tự cục bộ.
    ii) Quan hệ “nhỏ hơn hay bằng” (≤) trên tập các số nguyên là một thứ tự cục bộ.
    iii) Quan hệ “nhỏ hơn” (<) trên Z không phải là thứ tự cục bộ, vì nó phản xứng, bắc cầu nhưng không phản xạ. (bạn đọc có thể tự kiểm chứng một cách dễ dàng).

    Trong một tập được sắp xếp cục bộ, kí hiệu x y cũng được dùng để chỉ x ≤ y mà x ≠ y.

    Một cách hiển nhiên, ta giả sử tập S cần sắp xếp topo là tập hữu hạn. Do đó một thứ tự cục bộ có thể được biểu diễn bởi một đồ thị có hướng mà các đỉnh của đồ thị biểu diễn các phần tử của S, đồng thời các cạnh có hướng biểu diễn thứ tự giữa các phần tử.

    Để tiện theo dõi, giả sử có 10 công việc cần thực hiện (đây chính là tập S) được đánh số từ 1 đến 10, với thứ tự cục bộ như sau:

    Khi đó, đồ thị biểu diễn của tập S có dạng như hình 1:

    Sắp xếp topo phải xây dựng được thứ tự toàn bộ từ thứ tự cục bộ đã cho (3). Một cách trực quan, đó là quá trình vẽ lại đồ thị ở hình 1 thành một đồ thị mới sao cho tất cả các đỉnh đều nằm trên một hàng và tất cả các cạnh đều hướng sang phải (xem hình 2)

    Từ đồ thị trong hình 2, dễ dàng đưa ra một thứ tự thích hợp để thực hiện các công việc mà vẫn đảm bảo thứ tự cục bộ giữa chúng. Tất nhiên, vấn đề quan trọng là làm sao để “vẽ lại” đồ thị ở hình 1 thành đồ thị trong hình 2. Việc này khá đơn giản. Ta bắt đầu từ đỉnh mà không có cạnh nào lấy nó làm đỉnh cuối (tức là bậc vào của nó bằng 0). Luôn tồn tại ít nhất một đỉnh như thế(4). Đặt đỉnh này vào đầu danh sách mới (đồ thị mới) đồng thời loại bỏ nó khỏi đồ thị cũ. Đồ thị cũ vẫn còn là một tập được sắp cục bộ nên lặp lại quá trình cho đến khi hết tất cả các đỉnh. Do giả sử S là tập hữu hạn nên công việc sẽ kết thúc sau một số hữu hạn bước.

    Mọi việc sẽ rõ ràng hơn khi ta nghiên cứu việc tổ chức dữ liệu và cài đặt thuật toán. Bài viết này sử dụng ngôn ngữ C++ để cài đặt, nhưng đương nhiên các đoạn mã đều có thể chuyển sang các ngôn ngữ khác một cách dễ dàng.

    2. Cài đặt:

    Để dễ trình bày, ta xem mỗi phần tử trong S là một công việc (như trong ví dụ 1i, mặc dù thuật toán trình bày ở đây có thể được áp dụng cho bất kì tập hợp nào cần sắp xếp topo). Nhận xét rằng mỗi một công việc trong S cần quản lý 3 thông tin, gồm: số hiệu công việc, số lượng công việc cần được thực hiện trước công việc ấy, và tập các công việc có thể thực hiện sau công việc ấy. Những thông tin này được tổ chức trong một cấu trúc tên là leader (xem hình 3). Để quản lí S, ta dùng một danh sách liên kết các leader, do đó mỗi leader sẽ có thêm một trường next để chỉ tới phần tử kế tiếp nó trong danh sách. Ngoài ra để quản lí các công việc có thể được thực hiện sau mỗi leader, ta dùng một danh sách liên kết các trailer (hình 4). Mỗi trailer đại diện cho một leader có thể thực hiện. Sau đây là mô tả cụ thể:

    Trong leader, trường key là số hiệu công việc mà ta sẽ giả sử là được đánh số thứ tự theo kiểu nguyên (nhưng không nhất thiết liên tục từ 1 đến n), trường count dùng để chỉ số lượng công việc phải được hoàn thành trước khi thực hiện công việc này. Nếu count = 0 thì có nghĩa là công việc này có thể được thực hiện ngay mà không cần phải chờ. Chẳng hạn trong đồ thị ở hình 1, trường count của nút 4 có giá trị là 2, của nút 7 có giá trị là 0... Trường next của leader có kiểu là một con trỏ trỏ đến leader kế tiếp trong danh sách S. “Kế tiếp” ở đây chỉ đơn thuần mang nghĩa là phần tử tiếp theo trong S, để quản lí S một cách dễ dàng. Tiếp theo, trường trail có kiểu là con trỏ trỏ đến 1 danh sách liên kết đơn các trailer. Mỗi một trailer trong danh sách này đại diện cho một công việc phải thực hiện sau công việc này. Chẳng hạn trong hình 1, danh sách liên kết trail của nút 9 có 2 phần tử trailer, của nút 10 là danh sách rỗng (không có phần tử trailer nào).

    Trong trailer, trường id có kiểu con trỏ trỏ đến 1 leader, đó chính là công việc tiếp theo mà trailer này đại diện. Trường next trong trailer trỏ đến phần tử trailer tiếp theo trong danh sách.

    Chẳng hạn trong hình 1, leader số 1 (có trường key = 1) sẽ có 2 trailer, một trailer trỏ đến leader số 2, trailer còn lại trỏ đến leader số 3.

    Sau đây là khai báo của các cấu trúc này:

    Công việc sắp xếp topo sẽ trải qua hai giai đoạn. Đầu tiên là nhập dữ liệu từ thứ tự bộ phận của tập S. Việc này được thực hiện bằng cách nhập các cặp giá trị x, y với x, y là số hiệu công việc mà công việc x phải thực hiện trước công việc y (x y). Mỗi lần nhập một cặp x, y ta cũng đưa ngay vào danh sách liên kết S, đồng thời thiết lập các trailer phù hợp.

    Ví dụ, với thứ tự bộ phận như lúc đầu, sau khi nhập x=1, y=2 ta được như hình 5:

    Ở hình 6 là kết quả sau khi nhập tiếp x = 2, y = 4. Và cuối cùng hình 7 là kết quả sau khi nhập toàn bộ tất cả các cặp x, y.

    Ở đây do thường xuyên phải duyệt, tìm kiếm trên toàn bộ danh sách nên tail được sử dụng như lính canh nhằm giảm số phép so sánh. Việc xây dựng danh sách S khá đơn giản. Giả sử dữ liệu cần sắp xếp chứa trong file topo.inp. File này có n dòng, mỗi dòng chứa 2 giá trị x, y cách nhau bởi khoảng trắng. Việc đọc dữ liệu sẽ được thực hiện thông qua hàm readData có mã giả như sau:

    Danh sách S được trỏ bởi con trỏ head, phần tử lính canh trỏ bởi con trỏ tail, z là số lượng các leader trong toàn bộ danh sách. Việc thêm 2 leader có key là x, y được thực hiện bởi hàm addList một cách khá đơn giản. Do dùng tail làm lính canh nên chỉ cần duyệt trên danh sách và tạo các leader mới nếu các phần tử này chưa có trong danh sách. Để rõ hơn, xin xem code đầy đủ ở phần sau.

    Công việc thứ 2 là từ danh sách liên kết đã có (hình 7), đưa ra thứ tự toàn bộ khải dĩ cho các công việc, tức là tiến hành sắp xếp topo trên danh sách. Để làm việc này, cần duyệt qua tất cả các leader, tách các leader có trường count = 0 ra thành 1 danh sách riêng (đây là những công việc có thể được thực hiện trước tiên mà không cần phải chờ), sau đó duyệt qua các trailer tương ứng để cập nhật lại trường count cho các leader trong danh sách trail. Cụ thể mã giả của hàm sắp xếp topo như sau:

    Trong hàm topoSort, cứ mỗi khi in ra 1 key (ngụ ý rằng sẽ thực hiện việc có khoá key) thì hàm lại giảm z đi 1, mang nghĩa số công việc còn lại cần thực hiện trong S đã giảm đi 1. Tuy nhiên, ở cuối hàm này, nếu z không thể giảm về 0 (tức là sau khi thực hiện cả 2 vòng while mà vẫn chưa hết danh sách S) thì có nghĩa rằng không thể đưa ra một thứ tự toàn bộ để thực hiện các công việc.

    Mọi chuyện sẽ trở nên rõ ràng khi xem xét mã lệnh đầy đủ ở phía dưới. Đây là toàn văn chương trình viết bằng C++, biên dịch trong môi trường VC++ 2005 (windows console application). Ngoài ra tác giả cũng đã chuyển chương trình này sang ngôn ngữ Pascal và VB mà độc giả quan tâm có thể download cả 3 chương trình ở http://www.mediafire.com/?ect33zgmzon. Mọi ý kiến góp ý xin gửi về địa chỉ mail của tác giả.


    (1) Những vấn đề chi tiết về quan hệ, thứ tự... nằm ngoài phạm vi của bài viết này. Bạn đọc quan tâm có thể tham khảo trong những cuốn sách về Toán rời rạc, chẳng hạn “Discrete Mathematics and its applications” của Kenneth H. Rosen (đã có bản dịch tiếng Việt là “Toán học rời rạc ứng dụng trong Tin học” của Bùi Xuân Toại), hay quyển “Toán rời rạc” của GS. Nguyễn Hữu Anh...

    (2) lưu ý rằng kí hiệu ≤ trong ngữ cảnh này được dùng để chỉ chung cho thứ tự cục bộ bất kì, chứ không phải là chỉ riêng quan hệ “nhỏ hơn hoặc bằng”.

    (3) Một cách đầy đủ, sắp xếp topo trên một tập được định nghĩa là “quá trình thiết lập một thứ tự toàn cục từ thứ tự cục bộ của nó”.

    (4) Việc chứng minh khá đơn giản. Trước hết nhận xét rằng đây là đồ thị cho một tập được sắp xếp cục bộ nên tính chất ii) và iii) của thứ tự cục bộ đảm bảo rằng đồ thị không có chu trình nào. Suy ra tồn tại ít nhất một đỉnh mà bậc vào của nó bằng 0.

    Địa chỉ liên hệ: Phạm Hoài Vũ, 571/1/17A Phạm Văn Bạch, P. 15, Q. Tân Bình, Tp. HCM

    Email: classical_boy1988@yahoo.com

    School@net



     Bản để in  Lưu dạng file  Gửi tin qua email


    Những bài viết khác:



    Lên đầu trang

     
    CÔNG TY CÔNG NGHỆ TIN HỌC NHÀ TRƯỜNG
     
    Phòng 804 - Nhà 17T1 - Khu Trung Hoà Nhân Chính - Quận Cầu Giấy - Hà Nội
    Phone: 024.62511017 - 024.62511081
    Email: kinhdoanh@schoolnet.vn


    Bản quyền thông tin trên trang điện tử này thuộc về công ty School@net
    Ghi rõ nguồn www.vnschool.net khi bạn phát hành lại thông tin từ website này
    Site xây dựng trên cơ sở hệ thống NukeViet - phát triển từ PHP-Nuke, lưu hành theo giấy phép của GNU/GPL.