SKKN tin hoc

28 2 0
SKKN tin hoc

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Lý thuyết đồ thị là một lĩnh vực rộng, gồm nhiều mảng kiến thức, đề tài của tôi mới chỉ đề cấp đến một số nội dung cơ bản có thể áp dụng một cách hiệu quả cho học sinh Tin học 11 tham gi[r]

(1)ỨNG DỤNG LÝ THUYẾT ĐỒ THỊ TRONG VIỆC BỒI DƯỠNG HỌC SINH GIỎI TIN HỌC 11 A MỞ ĐẦU Lý chọn đề tài Đổi phương pháp dạy học là nhiệm vụ quan trọng ngành giáo dục nhằm nâng cao chất lượng đào tạo, góp phần thực công nghiệp hoá đại hóa đất nước Lý thuyết đồ thị (trong Tin học) là chuyên ngành quan trọng đã ứng dụng vào nhiều ngành khoa học, kỹ thuật khác vì lý thuyết đồ thị là phương pháp khoa học có tính khái quát cao, có tính ổn định vững để mã hóa các mối quan hệ các đối tượng nghiên cứu Đồ thị thường thể quan hệ nhị phân các đối tượng rời rạc Đó là quan hệ thường gặp nhiều bài toán thực tế Khoa học và kỷ thuật phát triển làm xuất hàng loạt bài toán thực tiển quy mô hình đồ thị Cùng với thời gian, nhiều thuật toán xây dựng cho phép giải các bài toán có kích thước liệu lớn và tốc độ thực chương trình nhanh Trong các kỳ thi học sinh gỏi Tin học THPT và các kỳ thi Olympic Tin học, bài toán lý thuyết đồ thị là nội dung quan tâm nhiều Vận dụng lý thuyết đồ thị dạy học học sinh giỏi để mô hình hóa các mối quan hệ chuyển thành phương pháp dạy học đặc thù nâng cao hiệu dạy học thúc đẩy quá trình tự học tự nghiên cứu học sinh theo hướng tối ưu hóa đặc biệt nhằm rèn luyện lực hệ thống hóa kiến thức và lực sáng tạo học sinh Nhiều bài toán thực tế đặt với yêu cầu phức tạp, chúng ta giải theo cách thông thường vất vả, chương trình dài, lủng củng và chạy thường không đúng với test lớn Việc cung cấp thêm phương pháp giải bài tập cho học sinh Tin học 11 tham gia bồi dưỡng học sinh giỏi là nhu cầu cần thiết Mặt khác việc vận dụng lý thuyết đồ thị vào giải toán giúp ta đạt hai mục tiêu: - Giải lớp bài tập - Hỗ trợ cho việc lập trình Hiện việc nghiên cứu khai thác số yếu tố lý thuyết đồ thị vào giải toán số tác giả quan tâm chưa có công bố có tính chất hệ thống, xuất phát từ lý trên tôi lựa chọn đề tài: “Ứng dụng lý thuyết đồ thị việc dạy bồi dưỡng học sinh giỏi Tin học 11” (2) Mục đích nghiên cứu Chỉ hướng vận dụng lý thuyết đồ thị vào giải các bài toán và tìm các biện pháp để giúp học sinh Tin học 11 tham gia bồi dưỡng học sinh giỏi trường THPT hình thành và phát triển lực vận dụng lý thuyết đồ thị vào giải bài tập Nhiệm vụ nghiên cứu - Tìm hiểu nội dung lý thuyết đồ thị trang bị cho học sinh Tin học - Chỉ hệ thống bài tập có thể vận dụng lý thuyết đồ thị để giải - Chỉ dấu hiệu cụ thể để nhận dạng “Bài toán” có thể khai thác lý thuyết đồ thị quá trình giải bài toán - Chỉ các phương án vận dụng lý thuyết đồ thị vào giải toán - Kiểm tra hiệu các biện pháp, phương án lý thuyết đồ thị vào giải toán thực tế Giả thuyết khoa học Nếu ta có các phương pháp giúp học sinh Tin học 11 vận dụng kiến thức lý thuyết đồ thị vào giải các bài toán thì giúp học sinh giải số lớp bài toán góp phần nâng cao chất lượng dạy học giải bài tập Phương pháp nghiên cứu a Nghiên cứu lý luận - Nghiên cứu các văn bản, tài liệu đạo Bộ GD & ĐT liên quan đến đổi phương pháp dạy học, đổi đề kiểm tra, danh mục thiết bị dạy học Tin học - SGK, phân phối chương trình, sách GV, chuẩn môn Tin trung học phổ thông, sách nâng cao, sách chuyên đề - Các tài liệu lý thuyết đồ thị và ứng dụng nó thực tiễn sống và dạy học - Các công trình nghiên cứu các vấn đề liên quan trực tiếp đến phương pháp đồ thị b Thực nghiệm sư phạm - Chỉ cho học sinh các dấu hiệu "nhận dạng"và cách thức vận dụng lý thuyết đồ thị vào giải bài tập - Biên soạn hệ thống bài tập luyện tập cho học sinh và số đề bài kiểm tra để đánh giá khả vận dụng lý thuyết đồ thị vào giải các bài toán - Tiến hành thực nghiệm và đánh giá kết thực nghiệm (3) B NỘI DUNG I CƠ SỞ LÝ LUẬN CỦA VẤN ĐỀ Đồ thị và tầm quan trọng Lý thuyết đồ thị là lĩnh vực nghiên cứu đã có từ lâu và có nhiều ứng dụng đại Các bài toán đặt đưa lý thuyết đồ thị để giải tiết kiệm nhiều thời gian, ý tưởng thuật toán rõ ràng, chương trình ngắn gọn và dễ hiểu Nếu hiểu và biết vận dụng tốt lý thuyết đồ thị giúp chúng ta giải nhiều bài toán đặt thực tế (xem phần giải vấn đề) Khoa học và kỹ thuật phát triển làm xuất hàng loạt bài toán thực tiển quy mô hình đồ thị 1.1 Định nghĩa đồ thị: Cho tập hợp X khác rỗng, E là tập hợp các cặp phần tử X xếp thứ tự không thứ tự Cặp (X, E) gọi là đồ thị Kí hiệu đồ thị là G= (X,E) đôi không gây nhầm lẫn kí hiệu tắt là G 1.2 Một số khái nhiệm - Các phần tử thuộc tập X gọi là đỉnh đồ thị G - Cho đỉnh x1, x2X, e=(x1,x2)E là cặp thứ tự thì e gọi là cung đồ thị, e là cặp không thứ tự thì e gọi là cạnh đồ thị - e=(x1,x2) là cung thì x1 là đỉnh đầu cung, x2 là đỉnh cuối cung e - e=(x1,x2) là cạnh thì x1 và x2 là đỉnh kề cạnh e đỉnh thuộc cạnh e - Hai đỉnh x1 và x2 (x1≠x2) đồ thị gọi là đỉnh kề chúng là đầu cạnh cung - Hai cạnh a, b (hoặc cung a, b) gọi là cạnh kề (hoặc cung kề nhau) chúng có đỉnh chung - Khuyên là cạnh (hoặc cung) có đầu trùng - Đỉnh treo là đỉnh thuộc cạnh cung - Đỉnh cô lập là đỉnh không thuộc cạnh cung nào 1.3 Phân loại đồ thị Cho đồ thị G=(X, E), E gồm các cạnh thì G là đồ thị vô hương Nếu E gồm các cung thì đồ thị G là đồ thị có hướng Nếu E gồm cạnh và cung thì G là đồ thị hỗn hợp Đa đồ thị: Đồ thị G=(X,E) vô hướng (hoặc có hướng) là đa đồ thị và nó là đồ thị không khuyên và có ít cặp đỉnh nối với ít cạnh (hoặc cung nối theo thứ tự cặp đỉnh) - Đơn đồ thị: Đồ thị G=(X,E) vô hướng (hoặc có hướng) là đơn đồ thị và nó là đồ thị không khuyên và cặp đỉnh nối với không quá cạnh (hoặc cung) (4) Biểu diễn đồ thị Biểu diễn đồ thị trên máy tính theo cấu trúc nào thì có giải thuật theo cấu trúc đó Với học sinh Tin học 11, biểu diễn ma trận (mảng chiều) là dễ hiểu và phù hợp Cách khai thác trên mảng chiều đã học sinh làm nhiều SGK Tin học 11 Các cách biểu diễn đồ thị: 2.1 Biểu diễn hình học Minh họa cách biểu diễn ` Đ.Nai Thanh Hoá An Giang Hà Tây TP HCM Long An Hà Nội Khánh Hoà Nam Định Huế Hình 1: Đơn đồ thị, vô hướng ` 2 4 3 5 Hình 3: Đa đồ thị, có hướng Hình 2: Đa đồ thị, vô hướng 2.2 Biểu diễn đồ thị ma trận liên thuộc (Ma trận kề) Giả sử đồ thị G=(X, E) có tập đỉnh X=(x 1,x2, x3,…,xn), tập cạnh (hoặc cung) là E Ta xây dựng ma trận vuông A cấp n cho  i,j, 1i,jn có: A[i,j]= (xi, xj)E (xi,xj)E Ma trận A là ma trận liên thuộc (ma trận kề) Nhận xét : Nếu G là độ thị vô hướng thì Ma trận A đối xứng qua đường chéo chính, Aij=Aji  i,j, 1i,jn 01000 10101 A= 01001 00001 01110 Hình 4: Đồ thị và ma trận kề (5) 2.3 Biểu diễn ma trận trọng số Trong nhiều bài toán đồ thị, cạnh (hoặc cung) e=(xi,xj) đồ thị thường gắn với số c (e) gọi là trọng số cạnh (hoặc cung) e Khi đó thường xây dựng ma trận vuông cấp n là ma trận C có phần tử C[i,j]=c (e) tồn cạnh (hoặc cung) e=(xi,xj), ngược lại không có cạnh nối xi với xj thì C[i,j]= (kí hiệu  là giá trị không xác định) Trong nhiều trường hợp, ngậm định C[i,i]=0 với đỉnh i đồ thị không khuyên Tìm kiếm trên đồ thị và tìm thành phần liên thông trên đồ thị Hiểu chất các phép tìm kiếm và tìm thành phần liên thông trên đồ thị chúng ta có thể giải nhiều các dạng bài toán đặt (thể phần áp dụng) Qua tìm kiếm trên đồ thị chúng ta có thể kết hợp tính toán, thống kê, xếp và tổng hợp các kết 3.1 Một số khái niệm Định nghĩa 1: Đường có độ dài k (k nguyên dương) từ đỉnh u tới đỉnh v trên đồ thị vô hướng G=(V, E) là dãy các đỉnh u=x 0, x1, x2, x3,…, xk=v mà các cạnh (xi, xi+1)E, i=0,1,2,…,k-1 Đường này còn có thể biểu diễn dạng dãy các cạnh: (x 0,x1), (x1,x2),….,(xk-1,xk) Đỉnh u gọi là đỉnh đầu (xuất phát), đỉnh v gọi là đỉnh cuối (đỉnh đích) đường Đường có đỉnh đầu trùng với đỉnh cuối gọi là chu trình Đường hay chu trình gọi là đơn không có cạnh nào bị lặp lại Đường hay chu trình gọi là không có đỉnh nào bị lặp lại (trừ trường hợp chu trình thì đỉnh đầu trùng đỉnh cuối là lặp lại) Định nghĩa 2: Đường có độ dài k (k nguyên dương) từ đỉnh u tới đỉnh v trên đồ thị có hướng G=(V, E) là dãy các đỉnh u=x 0, x1, x2, x3,…, xk=v mà các cung (xi, xi+1)E, i=0,1,2,…,k-1 Đường này còn có thể biểu diễn dạng dãy các cung: (x 0,x1), (x1,x2),….,(xk-1,xk) Đỉnh u gọi là đỉnh đầu (xuất phát), đỉnh v gọi là đỉnh cuối (đỉnh đích) đường Đường có đỉnh đầu trùng với đỉnh cuối gọi là chu trình (mạch vòng) Đường hay chu trình gọi là đơn không có cung nào bị lặp lại Đường hay chu trình gọi là không có đỉnh nào bị lặp lại (trừ trường hợp chu trình thì đỉnh đầu trùng đỉnh cuối là lặp lại) Định nghĩa 3: Đồ thị vô hướng G=(V,E) gọi là liên thông luôn tìm đường đỉnh nó Định nghĩa 4: Cho đồ thị vô hướng G=(V,E) và đồ thị G là đồ thị G’=(V’,E’) Đồ thị G’ gọi là vùng liên thông (hoặc thành phần liên thông) G nếu: + G’ liên thông; + Không tồn đường nào từ đỉnh thuộc G’ tới đỉnh không thuộc G’ (nói cách khác là bảo đảm tính tối đại liên thông G’) (6) VD: Trong hình xét đồ thị G và H: G có vùng liên thông nhất, H có vùng liên thông là H1, H2, H3 Định nghĩa 5: Đỉnh v gọi là đỉnh khớp (đỉnh rẻ nhánh) đồ H2thị vô hướng G=(V,E) loại bỏG đỉnh v và các cạnh liên thuộc với nó thì số thành phần liên thông G tăng thêm H1 Cạnh eE gọi là cầu loại bỏ nó khỏi đồ thị G thì số H thành phần liên H3 thông G tăng thêm đơn vị Hình 5: G liên thông, H gồm vùng liên thông 3.2 Tìm kiếm trên đồ thị Tìm kiếm trên đồ thị là duyệt (thăm) tất các đỉnh đồ thị, đỉnh đúng lần Rất nhiều thuật toán xây dựng dựa trên sở duyệt tất các đỉnh đồ thị cho đỉnh nó viếng thăm đúng lần Vì vậy, việc xây dựng thuật toán cho phép duyệt cách hệ thống tất các đỉnh đồ thị là vấn đề quan trọng Các thuật toán này giữ vai trò quan trọng việc thiết kế các thuật toán trên đồ thị Trên đồ thị có thuật toán tìm kiếm bản: - Thuật toán tìm kiếm theo chiều sâu (DFS.) - Thuật toán tìm kiếm theo chiều rộng (BFS) 3.3 Tìm đường và kiểm tra tính liên thông Tìm đường và kiểm tra tính liên thông là hình thức ứng dụng các thuật toán tìm kiếm trên đồ thị Đường tìm theo thuật toán tìm kiếm theo chiều rộng là đường ngắn (theo số cạnh) từ đỉnh s đến đỉnh t Đường ngắn trên đồ thị Trong các ứng dụng thực tế Bài toán tìm đường ngắn đỉnh đồ thị liên thông có ý nghĩa to lớn Có thể dẫn bài toán nhiều bài toán thực tế quan trọng Ví dụ, Bài toán chọn hành trình tiết kiệm (theo tiêu chuẩn khoảng cách thời gian chi phí) trên mạng giao thông đường bộ, đường thủy đường không; bài toán chọn phương pháp tiết kiệm để đưa hệ động lực từ trạng thái xuất phát đến trạng thái đích, bài toán lập lịch thi công các công đoạn công trình thi công lớn,… (7) II THỰC TRẠNG CỦA VẤN ĐỀ Thuận lợi - Lý thuyết đồ thị có thể giải nhiều bài toán đặt thực tế phù hợp với đối tượng học sinh giỏi Tin học 11, đặc biệt là bài toán thể quan hệ nhị phân các đối tượng rời rạc - Vận dụng lý thuyết đồ thị giúp học sinh có thêm luồng kiến thức để làm giàu tư thuật toán mình - Có khá nhiều tài liệu giới thiệu các vấn đề liên quan đến lý thuyết đồ thị như: sách cấu trúc liệu và giải thuật, Sách Toán rời rạc,…và các tài liệu trên mạng Internet - Giáo viên và học sinh phát huy tính động quá trình dạy - học đạt kết cao - Một số kiến thức dễ sử dụng và hiệu cao Ví dụ: phép tìm kiếm và kiểm tra vùng liên thông trên đồ thị Khó khăn - Trong việc nắm bắt và hiểu các khái niệm liên quan đến lý thuyết đồ thị - Lý thuyết đồ thị rộng và nhiều phần kiến thức khó nên không thể truyền tải hết tới học sinh và khó để đưa vào hết đề tài - Đưa các giải thuật ngôn ngữ Pascal để minh hoạ các kiến thức đưa phần sở lý luận - Đưa hệ thống các dạng bài tập có thể giải hiệu lý thuyết đồ thị và cách giải các bài tập đó Để khắc phục phần khó khăn nêu trên, đề tài tôi đề cập đến phần quan trọng lý thuyết đồ thị có ứng dụng nhiều thực tế và phù hợp với học sinh THPT, đặc biệt là học sinh Tin học 11 III THỰC TIỂN ÁP DỤNG Hai thuật toán và chương trình tìm kiếm trên đồ thị 1.1 Tìm kiếm theo chiều rộng Ý tưởng: Đỉnh xuất phát v đây thăm đầu tiên có khác với DFS chổ là: Sau đó các đỉnh chưa thăm mà là lân cận v thăm theo nhau, đến các đỉnh chưa thăm là lân cận các đỉnh này và tương tự VD: Với đồ thị hình thì thăm đến 2, 3…tiếp theo là 4, 5, và 6, 7, cuối cùng là 8 Hình (8) Quá trình duyệt theo chiều rộng có thể mô tả thủ tục đệ quy sau: Procedure BFS(v); {Tìm kiếm theo chiều rộng đỉnh v} Begin Queue:=; Queue <= v; {nạp đỉnh v vào Queue} Chuaxet[v] :=false ; While Queue <>  Begin u<= Queue; {Lấy đỉnh p từ Queue ra} Thăm_đỉnh(u); For y Ke(u) If chuaxet[y] then Begin Queue <= y; {nạp đỉnh v vào Queue} Chuaxet[y]:=false; End; End; End; BEGIN For v V Chuaxet[v]:=true; {Khởi tạo} For v V If Chuaxet[v] then BFS(v); END Chương trình duyệt đồ thị theo chiều rộng cài đặt cụ thể là: Var chuaxet:array[1 100] of boolean; A:array[1 20,1 20] of 1; Queue:array[1 20] of byte; n,y,i,j,S:integer; (*============================================*) Procedure Nhapsolieu; {Nhap so lieu cho ma tran ke} Begin Write(‘ Nhap so dinh cua thi:’); readln(n); Write(‘ Nhap so lieu ma tran ke:’); For i:=1 to n begin For j:=i+1 to n Begin Write(‘a[‘,i, ‘,’,j,’]=’);readln(a[i,j]); a[j,i]:=a[i,j]; End; (9) a[i,i]:=0; writeln; end; End; (*============================================*) Procedure BFS(i:integer);{Tìm kiếm theo chiều rộng đỉnh i} Var u, dauQ, CuoiQ:integer; Begin dauQ:=1; CuoiQ:=1; Queue[cuoiQ] :=i ; Chuaxet[i]:=fasle; While dauQ<=CuoiQ Begin u:=Queue[dauQ]; dauQ:=dauQ+1; For y :=1 to n If (a[u,y]=1) and (chuaxet[y]) then Begin cuoiQ:=cuoiQ+1; Queue[cuoiQ] :=y ; Chuaxet[y] :=false ; End ; End ; End; BEGIN Nhapsolieu; Fillchar(Chuaxet, sizeof(chuaxet), true); {khởi tạo mảng Chuaxet} For s:=1 to n if not chuaxet[s] then BFS(s); END 1.2 Tìm kiếm theo chiều sâu Ý tưởng: Đỉnh xuất phát v thăm Tiếp theo đó, đỉnh y chưa thăm, mà là lân cận v, chọn và phép tìm kiếm theo chiều sâu xuất phát từ y lại thực Khi đỉnh u đã “với tới” mà đỉnh lân cận nó đã thăm rồi, thì ta quay ngược lên đỉnh cuối cùng vừa thăm, (mà còn có đỉnh y lân cận với nó chưa Hình thăm), và phép tìm kiếm theo chiều sâu xuất phát từ y lại thực Phép tìm kiếm kết thúc không còn nút nào chưa thăm mà có thể Đầu tiên đỉnh thăm, tới (tất với tới từ nút đã thăm nhiên có thể là 3) 4, 8, 5; không có lân cận nào chưa thăm nên phải VD: Ta có đồ thị hình quay lại để thăm tiếp 3, (10) Quá trình duyệt theo chiều sâu có thể mô tả thủ tục đệ quy sau: Procedure DFS(v); {tìm theo chiều sâu đỉnh v, các biến Chuaxet, ke là cục bộ} Begin Thăm đỉnh (v); Chuaxet[v]:=false; For đỉnh y Ke( v) If chuaxet[y] then DFS(); End; Khi đó, tìm kiếm theo chiều sâu trên đồ thị thực nhờ thuật toán sau: BEGIN For vV Chuaxet[v]:=true; For vV if Chuaxet[v] then DFS(v); END Chương trình cài đặt cụ thể là: Var chuaxet:array[1 100] of boolean; A:array[1 100,1 100] of 1; S:integer; (*============================================*) Procedure Nhapsolieu; {Nhap so lieu cho ma tran ke} Begin Write(‘ Nhap so dinh cua thi:’); readln(n); Write(‘ Nhap so lieu ma tran ke:’); For i:=1 to n begin For j:=i+1 to n Begin Write(‘a[‘,i, ‘,’,j,’]=’);readln(a[i,j]); a[j,i]:=a[i,j]; End; a[i,i]:=0; writeln; end; End; (*============================================*) Procedure DFS(v:integer); {Thắm đỉnh v chưa thăm} Var y:integer; Begin Write(v, ‘ ‘); Chuaxet[v]:=false; {Đánh dấu đã thăm đỉnh v} (11) For y:=1 to n {Duyệt đỉnh y} If (a[v,y]=1) and (not chuaxet[y]) then DFS(y); {y kề với v và chưa thăm thì thăm y} End; BEGIN Nhapsolieu; Fillchar(Chuaxet, sizeof(chuaxet), true); {khởi tạo mảng Chuaxet} For s:=1 to n if not chuaxet[s] then DFS(s); END Tìm đường và kiểm tra tính liên thông a Bài toán tìm đường đỉnh Giả sử s và t là đỉnh nào đó đồ thị Hãy tìm đường từ s đến t Ý tưởng: Như trên đã phân tích, thủ tục DFS(v) (hoặc BFS(v)) cho phép thăm tất các đỉnh thuộc cùng thành phần liên thông với s Vì vậy, sau thực xong thủ tục, Chuaxet[t]=true, thì điều đó có nghĩa là không có đường từ s đến t Còn Chuaxet[t]=false thì t thuộc cùng thành phần liên thông với s, hay nói cách khác là tồn đường từ s đến t Trong trường hợp tồn đường đi, để ghi nhận đường đi, ta dùng thêm biến Truoc[v] để ghi nhận đỉnh trước đỉnh v đường tìm kiếm từ s đến v Khi đó, thủ tục DFS(v) cần sửa đổi câu lệnh if nó sau: If Chuaxet[y] then Begin Truoc[y]:=v; DFS(y) ; End ; Còn thủ tục BFS(v) cần sửa đổi câu lệnh if nó sau: If chuaxet[y] then Begin Queue <= y; {nạp đỉnh v vào Queue} Chuaxet[y]:=false; Truoc[y]:=u; End; b Tìm các thành phần liên thông đồ thị Bài toán đặt ra: Hãy cho biết đồ thị có bao nhiêu thành phần (vùng) liên thông và thành phần liên thông gồm đỉnh nào Ý tưởng: Do thủ tục DFS(v) (hoặc BFS(v)) cho phép thăm tất các đỉnh thuộc cùng thành phần liên thông với v, nên số thành phần liên thông đồ thị chính số lần gọi đến thủ tục này Nghĩa là chương trình chính gọi đến thủ tục DFS(v) lần thì kết luận có thành phần liên thông Vấn đề còn lại là ghi nhận các đỉnh thành phần liên thông Ta dùng thêm biến có tên DemLT để đếm số thành phần liên thông Khởi tạo biến này có giá trị (12) Chương trình tìm đường từ đỉnh s tới đỉnh t và tìm số thành phần liên thông đồ thị sau: Var A:array[1 20,1 20] of 1; Queue, chuaxet, Truoc:array[1 20] of byte; n,y,i,j,DemLT, s, t:integer; (*============================================*) Procedure Nhapsolieu; {Nhap so lieu cho ma tran ke} Begin Write(‘ Nhap so dinh cua thi:’); readln(n); Write(‘ Nhap so lieu ma tran ke:’); For i:=1 to n begin For j:=i+1 to n Begin Write(‘a[‘,i, ‘,’,j,’]=’);readln(a[i,j]); a[j,i]:=a[i,j]; End; a[i,i]:=0; writeln; end; End; (*============================================*) Procedure Doctep; Var f:text; fn:string; Begin Write(‘ Nhap ten tep du lieu:’) ; readln(fn) ; Assign(f, fn) ;reset(f); Readln(f, n); Write(‘ Nhap so lieu ma tran ke:’); For i:=1 to n For j:=1 to n read(f, a[i,j]); Close(f); End; (*============================================*) Procedure Insolieu; Begin Writeln(‘ Ma tran ke:’); For i:=1 to n Begin For j:=1 to n write(a[i,j]:3);writeln; (13) End; End; (*============================================*) Procedure Inketqualienthong; Begin Insolieu; If DemLT=1 then write(‘ Do thi la lien thong’ ) Else Begin Writeln(‘ So phan lien thong cua thi la:’, DemLT); For i:=1 to DemLT Begin Writeln(‘ Thanh phan lien thong thu ’, i, ‘ gom cac dinh:’); For j:=1 to n If Chuaxet[j]=i then write(j:3); writeln; End; End; End; (*============================================*) Procedure BFS(i:integer); Var u, dauQ, CuoiQ:integer; Begin dauQ:=1; CuoiQ:=1; Queue[cuoiQ] :=i ; Chuaxet[i]:=DemLT; While dauQ<=CuoiQ Begin u:=Queue[dauQ]; dauQ:=dauQ+1; For y :=1 to n If (a[u,y]=1) and (chuaxet[y]=0) then Begin cuoiQ:=cuoiQ+1; Queue[cuoiQ] :=y ; Chuaxet[y] :=DemLT ; Truoc[y]:=u; End ; End ; (*============================================*) Procedure DFS(v:integer); Var y:integer; Begin (14) Chuaxet[v]:=DemLT; For y:=1 to n If (a[v,y]=1) and (not chuaxet[y]=0) then Begin Truoc[y]:=v; DFS(y); End ; End; (*============================================*) Procedure Lienthong; Begin {Khoi tao so lieu} For j:=1 to n Chuaxet[j]:=0; DemLT:=0; For i:=1 to n If chuaxet[i]=0 then Begin demLT:=demLT+1; DFS(i); {hoac BDF(i)} End; Inketqualienthong; End; (*============================================*) Procedure Ketquaduongdi; Begin If Truoc[t]=0 then writeln(‘ Khong co duong di tu ’, s, ‘ den’, t) Else Begin Write(‘ Duong di tu’, s, ‘ den ’, t, ‘ la:’); J:=t; Write(t, ‘<==’) ; While Truoc[j]<>s Begin Write(Truoc[j], ‘<==’); J:=Truoc[j]; End; Writeln(s); End; (*============================================*) (15) Procedure Duongdi; Begin Insolieu; Write(‘ Nhap dinh xuat phat:’); readln(s); Write(‘ Nhap dinh den:’); readln(t); For j:=1 to n {khoi tao so lieu} Begin Truoc[j]:=0; Chuaxet[j]:=0 End; DemLT:=1; BFS(s); {hoac DFS(s)} Ketquaduongdi; End; (*============================================*) BEGIN {Chuong trinh chinh} CLRSCR; Writeln(‘ Nhap so lieu tu ban phim’); Writeln(‘ Nhap so lieu tu tep van ban’); Writeln(‘ Kiem tra tinh lien thong cua thi’); Writeln(‘ Tim duong di giua dinh bat ky’); Writeln(‘ Thoat khoi chuong trinh’); Writeln(‘==========================’); Writeln(‘ Hay go phim so (15) de chon chuc nang…’#7); Ch:=readkey; Writeln(ch); Repeat Case ch of ‘1’: nhapsolieu; ‘2’: doctep; ‘3’: Lienthong; ‘4’ : Duongdi ; End ; Until (ch= ‘5’) or (upcase(ch)=’Q’); END (16) Một số ví dụ áp dụng Có nhiều bài toán vận dụng thuật toán tìm kiếm trên đồ thị và thuật toán tìm số vùng liên thông để giải mà chương trình ngắn gọn, hiệu Đặc biệt là các bài toán liên quan đến duyệt, tìm kiếm mà cách lưu trữ liệu đưa dạng ma trận kề (mảng chiều) Dưới đây tôi xin trích số ví dụ để minh họa cho điều này: (Trong các ví dụ đây, tôi đưa cách giải ví dụ mà không đưa chương trình kèm theo vì đưa vào làm cho đề tài quá dài) Ví dụ 1: Miền liên thông Cho bảng chữ nhật chia thành M xN ô vuông đơn vị (M dòng đánh số từ đến M theo chiều từ trên xuống dưới, N cột đánh số từ đến N theo chiều từ trái qua phải Mỗi ô vuông ghi số Một miền bảng là tập hợp các ô chung cạnh và chứa số 0) Địa miền là toạ độ [dòng, cột] ô đầu tiên thuộc miền theo thứ tự duyệt từ trái qua phải, từ trên xuống Hãy tìm số miền bảng và tìm miền có diện tích lớn Dữ liệu vào : File Mien.INP có cấu trúc : Dòng đầu ghi số nguyên dương M và N (0<M,N100) - M dòng thể bảng số theo thứ tự từ trên xuống dưới, dòng N số theo thứ tự từ trái sang phải Dữ liệu : File Mien.Out có cấu trúc : - Dòng thứ ghi số lượng miền - Dòng thứ ghi diện tích miền có diện tích lớn - Các dòng tiếp theo, dòng ghi địa miền có diện tích lớn Cách giải : Chúng ta có thể giải theo cách thông thường không vận dụng lý thuyết đồ thị Nhưng rõ ràng, giải theo cách tìm kiếm trên đồ thị ngắn gọn, hiệu và nhanh nhiều Thuật toán thể rõ ràng, dễ hiểu Cụ thể sau :  Thực vòng lặp Tìm ô chứa số chưa thăm là ô x có toạ độ dòng và cột là (i,j) Thực thuật toán BDF (tìm kiếm theo chiều rộng) để tìm miền chứa ô x Trong quá trình duyệt tính diện tích miền (mỗi lần đến ô thì tăng diện tích lên đơn vị) Mỗi lần thực xong thủ tục BDF thì tìm miền chứa ô (i,j), lưu kết (toạ độ i, j và diện tích miền vào mảng KQ) đồng thời tăng biến đếm số miền  Hiện số lượng miền  Duyệt mảng KQ để tìm miền có diện tích lớn Hiện diện tích miền lớn  Duyệt mảng KQ lần thứ để toạ độ ô đại diện cho miền có diện tích diện tích miền lớn (17) Ví dụ 2: Hệ thống đảo cung cấp xăng Vùng Hạ Long có N hòn đảo đánh số từ đến N Toạ độ hòn đảo thứ i trên mặt phẳng toạ độ cho cặp số nguyên x i, yi Trên đảo có bể chứa xăng có khả cung cấp đầy các thiết bị chứa xăng ca nô Biết các thiết bị chứa xăng ca nô không thể chứa đủ số xăng hết M km Hãy tìm hành trình cho ca nô từ đảo U đến đảo V (0<U, VN) mà số lần ghé vào các đảo để lấy xăng là nhỏ Dữ liệu vào : File văn DAO.INP có cấu trúc - Dòng đầu ghi số nguyên dương N, M, U, V - Các dòng tiếp theo, dòng thứ i các dòng này ghi số nguyên dương xi, yi Kết : Ghi file văn DAO.OUT - Nếu có đường thì dòng đầu tiên ghi số đảo ghé vào lấy xăng (trừ U và V) - Dòng thứ ghi số hiệu các đảo đó theo thứ tự hành trình Nếu không có đường thì ghi ‘KHONG CO DUONG DI’ VD : DAO.INP DAO.OUT 12 10 12 00 2679 80 86 08 10 15 20 20 25 25 25 30 Cách giải : Áp dụng thuật toán tìm kiếm theo chiều rộng để đường qua ít đảo Điều kiện để từ đảo A sang đảo B là khoảng cách AB  M km Trong quá trình tìm kiếm theo chiều rộng tổ chức thêm mảng Truoc(N) với Truoc[i]=j có nghĩa là đảo j trước đảo i trên hành trình từ U đến V Ví dụ 3: Quét vôi khu nhà cao tầng Một quần thể nhà cao tầng xây dựng trên hình chữ nhật, trên đó chia thành M*N ô vuông (M dòng, N cột) Các dòng đánh số từ đến M và các cột đánh số từ đến N Người ta xem khu nhà tạo các khối có đáy là ô vuông với chiều cao nào đó mà người ta gọi là đơn nguyên Một đơn nguyên xác định tạo độ dòng, cột ô đáy và chiều cao tương ứng Một (18) khối nhà định nghĩa là tập hợp gồm các đơn nguyên có đáy tạo thành miền gồm ô vuông kề cạnh Thí dụ, hình vẽ mô tả quần thể gồm khối nhà : người ta đánh số các khối nhà số nguyên liên tục theo trình tự duyệt các ô đáy theo dòng từ đến M, và trên dòng, duyệt các ô đáy theo cột từ đến N Ví dụ, các khối nhà cho hình vẽ bên đánh số theo thứ tự 1 0 các ô đáy (có màu xám, số là chiều cao) : Người ta muốn quét vôi các tường xung quanh tất 1 0 0 1 các khối nhà Hãy xác định : - Số lượng các khối nhà - Tổng số diện tích quét vôi - Số nhà có diện tích quét vôi lớn và giá trị diện tích này Dữ liệu vào : từ file văn QV.INP có dạng : MN H[1,1] H[1,2] H[1,N] H[2,1] H[2,2] H[2,N] H[M,1] H[M,2] H[M,N] Trong đó H[i,j] là chiều cao đơn nguyên [i,j] với quy ước đơn nguyên này không có Giả thiết các giá trị này là số nguyên và tính theo đơn vị cạnh ô vuông Các số trên cùng dòng ghi cách ít dấu cách Ví dụ, hình vẽ trang trước mô tả 101001 khối nhà tương ứng với file liệu bảng bên 211001 Kết quả: Ghi file văn QV.OUT - Dòng đầu ghi số lượng các khối nhà 000110 - Dòng thứ ghi tổng số diện tích quét vôi - Dòng thứ ghi số hiệu khối có diện tích quét vôi lớn và giá trị diện tích này (ghi cách ít dấu cách) Ví dụ, với file liệu trên, file kết có số liệu bảng bên 50 Cách giải: Trước hết dùng thuật toán tìm kiếm theo chiều sâu theo chiều rộng để tìm các vùng liên thông (mỗi khối nhà là vùng liên thông) Trong quá trình tìm kiếm đánh số hiệu cho khối nhà Để tìm tổng diện tích cần quét vôi cho các tường xung quanh đơn nguyên khối nhà ta duyệt lại ô khối đó Xét đơn nguyên Đ nằm trên ô (i,j) có chiều cao là h Ta để ý tới đơn nguyên xung quanh Đ là các đơn nguyên Đ1, Đ2, Đ3, Đ4 tương ứng có chiều cao là h 1, h2, h3, h4 Rõ ràng là Đi (i=1,…,4) nào đó thấp Đ thì bề mặt tường đơn nguyên Đ (i,j) (19) phía đó lộ phải quét vôi Ngược lại, phía đó có đơn nguyên Đ i cao Đ thì tường đơn nguyên Đ bị che khuất đơn nguyên Đ i đó, dẫn tới mặt tường này Đ không cần quét vôi Vậy diện tích tường bao quanh đơn nguyên Đ lộ phải quét vôi là: S=Max(0, h - h1)+Max(0, h - h2)+Max(0, h - h3)+Max(0, h - h4) Tổng diện tích quét vôi khối nhà tổng diện tích tường bao quanh lộ các đơn nguyên thuộc khối nhà đó Ví dụ 4: Có số cừu trại chăn nuôi Mickey Trong Mickey ngủ say, sói đói đã vào trại và công đàn cừu Trại có dạng hình chữ nhật gồm các ô tổ chức thành hàng và cột Kí tự dấu chấm ‘.’ Là ô rỗng, kí tự ‘#’ là hàng rào, kí tự ‘o’ là cừu và kí tự ‘v’ là chó sói Chúng ta coi ô là cùng miền có thể chuyển từ ô tới ô đường gồm các đường theo chiều ngang thẳng đứng không vướng hàng rào Các ô mà từ chúng có thể thoát khỏi sân không xem là phần bất kì miền nào May thay, cừu biết tự vệ Chúng có thể chiến đấu với sói miền (húc chết sói) số lượng cừu lớn số lượng sói cùng miền Ngược lại sói ăn hết các cừu cùng miền Ban đầu các cừu và các sói đã xác định các miền trại Viết chương trình tính số lượng cừu và số lượng sói còn lại sáng hôm đó Dữ liệu vào: File văn SOICUU.INP: Dòng đầu tiên chứa số nguyên R và C (3<=R,C<=250) là số hàng và số cột trại Mỗi dòng R dòng sau gồm C kí tự Tất các kí tự này biểu diễn các vị trí có hàng rào, cừu và chó sói trại Kết quả: Ghi file SOICUU.OUT dòng gồm số: Số cừu và số sói còn lại trại Ví dụ: SOICUU.INP SOICUU.INP SOICUU.INP 66 88 12 # ###### .###.##### # # v# o # #.oo# #v# #v # # # ####.# # o#.#.#.# #.o#.# #.#v.#.# # ##o# # .###.# #.#.o#o# #.#v#o###.# .### #o.## # # #v# # #.v v.# # v#v#### .###### .####.#vv.o# .#### SOICUU.OUT SOICUU.OUT SOICUU.OUT 02 31 35 (20) Cách giải : Sử dụng thuật toán tìm kiếm các miền liên thông Trong miền liên thông đếm số cừu và số sói đó Nếu số cừu lớn số sói thì coi số sói còn lại miền này 0, ngược lại thì số cừu còn lại miền này Khi tìm tới ô nào thì xoá ô đó cách gán kí tự ‘#’ trên ô đó Đường ngắn trên đồ thị Bài toán: Cho đồ thị vô hướng, có trọng số không âm Hãy tìm đường (không có đỉnh lặp lại) ngắn từ đỉnh xuất phát x đến đỉnh đích y (y≠x) Có nhiều thuật toán để giải bài toán đặt ra, nhiên đề tài này tôi đề cập tới thuật toán có nhiều ứng dụng và hiệu quả, đó là thuật toán Dijkstra 3.1 Tổ chức liệu: Mảng A(N, N) thể ma trận trọng số Mảng V(N) là nhãn độ dài đường ngắn nhất: V[i] là độ dài đường ngắn từ đỉnh xuất phát x tới đỉnh i D(N) là mảng đánh dấu đỉnh đã có nhãn tối ưu Gán cho D[i]=True v[i] đã là độ dài tối ưu đường từ x tới i, đó đỉnh i gọi là đỉnh đã cố định nhãn D[i]=false v[i] chưa đạt giá trị tối ưu, đó đỉnh i gọi là đỉnh tự Mảng TR(N) với ý nghĩa TR[i]:=j thì đỉnh j là đỉnh trước đỉnh i trên hành trình ngắn 3.2 Thuật toán B1: Khởi trị - Khởi trị nhãn đường ngắn từ đỉnh x tới đỉnh i là V[i]:=A[x,i] (nếu không có đường trực tiếp từ x tới i thì A[x,i] vô cùng) Lưu lại đỉnh trước tới i trên hành trình ngắn là Tr[i]:=x - Đánh dấu đỉnh i là tự (nhãn V[i] chưa tối ưu) cách gán D[i]:=false - Khởi trị nhãn đỉnh x là V[x]:=0; D[x]:=True (nhãn đỉnh x đã tối ưu) B2: (Vòng lặp vô hạn) B2.1 Tìm đỉnh i0 tự có nhãn V[i0] nhỏ B2.2 Nếu không tìm i0 (i0=0), i0=y thì thoát khỏi vòng lặp còn không thì: + Đánh dấu i0 đã cố định nhãn: D[i0]:=true; + Sửa nhãn cho các đỉnh j tự kề với i0 theo công thức V[j]=Min{V[j], V[i0]+A[i0,j]} + Nếu V[j]=V[i0]+A[i0,j] thì lưu vết đỉnh trước j là i0: Tr[j]:=i0 B3: Tìm và ghi kết V[y] là độ dài đường ngắn từ đỉnh x đến y Lần ngược mảng Tr để tìm hành trình này Một số lưu ý: + Nếu khỏi lặp vô hạn với i0=0 thì không tồn đường ngắn từ x đến y + Nếu B2 cho thực lặp k lần thì nhãn đỉnh i sau thoát khỏi vòng lặp chính là độ dài đường ngắn từ x tới i qua k đỉnh (21) + Mỗi lần sửa nhãn có thêm đỉnh cố định nhãn Do đó số bước lặp B2 thuật toán trên tối đa là N Chương trình tìm đường ngắn trên đồ thị theo thuật toán Dijkstra Const fi=’dijkstra.inp’; fo=’dijkstra.out’; Max=100; Vc=100*50*maxint Type m1=array[1 max, max] of longint; m2=array [1 max] of longint; m3=array[1 max] of byte; Var a:m1;{ma tran so} V:m2; {nhan dai duong di ngan nhat} t, d:m3; {t: ghi nhan dinh truoc cua dinh, d:danh dau dinh co nhan toi uu} m:integer; n,x,y:byte; (*===============================*) Procedure Doctep; Var f:text; k.w:integer; i,j:byte; Begin Assign(f, fi);reset(f); Fillchar(a,sizeof(a),0); {mang A la ma tran so} Readln(f, n, m, x, y);{so dinh, so canh, dinh xuat phat, dinh dich} For k:=1 to m Begin Readln(f, i, j, w);{canh (i,j) co so la w} a[i,j]:=w; a[j,i]:=w; end; close(f); end; (*===============================*) Procedure khoitao; {khoi tao so bien va mang can thiet} Var i,j:byte; Begin For i:=1 to n For j:=1 to n If a[i,j]=0 then a[i,j]:=vc; Fillchar(d, sizeof(d), 0); {cac dinh chua co nhan toi uu goi la cac dinh tu do} For i :=1 to n v[i]:=a[x, i]; (22) v[x]:=0; fillchar(t, sizeof(t),0) ; {mang t dung de luu dinh truoc dinh hien tai} end ; (*===============================*) Function tim_vmin:byte;{tim dinh tu co nhan dai duong di nho nhat} Var li, i:byte; P:longint; Begin Li:=0; P:=vc;{khoi tri gia tri nho nhat can tim cac nhan v[i] voi i la dinh tu do} For i:=1 to n If d[i]=0 then {i la dinh tu do} If v[i]<p then Begin P:=v[i]; Li:=i; End; Tim_vmin:=li; End; (*===============================*) Procedure SuaNhan(j); {sua lai nhan cac dinh j tu do, ke voi dinh i} Var i:byte; Begin d[i]:=1; for j:=1 to n if d[j]= then {j la dinh tu do} if (a[i,j]>0) and (a[i,j]<>vc) then {dieu kien j la dinh ke cua i} if v[j]> v[i]+a[i,j] then {dieu kien co the sua nhan} begin v[j]:=v[i]+a[i,j]; {sua nhan} t[j]:=i; {dinh truoc dinh j hanh trinh ngan nhat la dinh i} end; end; (*===============================*) Procedure Dijkstra; Var i:byte; Begin Khoitao; Repeat i:=tim_vmin;{dinh tu co dinh nho nhat} (23) If i=0 then break; SuaNhan(i); Until (d[y]>0); End; (*===============================*) Procedure Ghiketqua; Var f:text; i,j:byte; kq:m3; Begin assign(f, fo); rewrite(f); if v[y]=vc then {khong co duong di tu x den y} begin writeln(f,-1); close(f); halt; end; writeln(f, v[y]); {do dai duong di ngan nhat tu x den y la v[y]} i :=y ; {lan nguoc hanh trinh ngan nhat bat dau tu y ve x} j :=0 ; repeat inc(j) ; kq[j]:=i; {luu hanh trinh nguoc vao mang kq} i:=t[i]; until i=0; {dieu kien da ghi nhan xong dinh truoc dinh x} for i:=j downto writeln(f, kq[i]); {dua hanh trinh ngan nhat} close(f); end; BEGIN Doctep; Khoitao; Dijkstra; Ghiketqua; END (24) Một số ví dụ áp dụng Nhiều bài toán thực tế quan trọng có thể dẫn bài toán tìm đường ngắn trên đồ thị Các bài toán dễ nhận thấy là: chọn hành trình tiết kiệm nhất, lập lịch thi công các công đoạn công trình thi công lớn, bài toán lựa chọn đường truyền tin với chi phí nhỏ mạng thông tin, bài toán tìm đường Robot….Hiện có nhiều phương pháp để giải các bài toán Thế nhưng, thông thường các thuật toán xây dựng dựa trên sở lý thuyết đồ thị tỏ là các thuật toán có hiệu cao Sau đây xin đưa vài ví dụ minh họa cho điều này (Dưới đây tôi đưa ví dụ hai bài toán khó mà giải theo thuật toán tìm đường ngắn hiệu quả) Ví dụ 1: Chọn xâu Cho số nguyên k (0=<k<=255) và N xâu kí tự có độ dài L (N nguyên, 0<N<=100, L<=255) là S1, S2, ,SN đôi khác gồm các chữ cái thường Hãy tìm xâu H nhỏ thỏa mãn tính chất sau đây : tồn k vị trí khác trên xâu H là vị trí xuất các xâu S1, S2, , SN (p là vị trí xuất xâu S H hàm Copy(H, p, L))=S) Dữ liệu vào : File XAU.INP : - Dòng đầu tiên ghi N, L, K - N dòng : dòng thứ i ghi xâu Si Kết : Ghi file XAU.OUT : - Dòng đầu ghi độ dài nhỏ - Dòng thứ ghi xâu H thỏa mãn bài toán K dòng tiếp theo, dòng thể vị trí xuất gồm số u, p cho biết xâu Su xuất vị trí p trên H VD : XAU.INP XAU.OUT 10 17 aaaaaaaxyz aaaaaaaxyzabcdefg xyzabcdefg 11 28 Cách giải : Đây là bài toán khó Nếu chúng ta giải theo cách thông thường phức tạp, chương trình dài và dễ sai thử các test khác Cách giải theo lý thuyết đồ thị sau : Trước hết xây dựng đồ thị : Mỗi đỉnh là xâu các xâu S 1, S2, , SN Để tìm trọng số cung (i, j) là a[i,j] ta làm sau : Đặt phần cuối Si trung với phần đầu Sj cho đoạn trùng chúng dài Khi đó độ dài đoạn còn lại Sj không trùng với Si chọn là a[i,j] Ví dụ : Si=’bcyaabaaaab’ và Sj=’aabaaaabhk’ thì đoạn không trùng ngắn Sj là ‘bhk’ đó a[i,j]=3 Bài toán trở thành tìm đường ngắn qua k đỉnh (độ dài đường này chính là độ dài xâu H) Để giải bài toán này, có thể tiến hành xây dựng nhãn F cho đỉnh, đó là độ dài đường ngắn (25) qua k đỉnh và kết thúc đỉnh đó Ban đầu xét các đường gồm đỉnh, đương nhiên nhãn đỉnh là độ dài xâu tương ứng với đỉnh đó Giả sử các đỉnh đã có nhãn bước trước là độ dài đường ngắn gồm t đỉnh (t<k), để xây dựng nhãn các đỉnh bước trước là độ dài đường ngắn gồm t+1 đỉnh thì cần sửa lại nhãn các đỉnh đó bước trước (qua t đỉnh) công thức : j : F[j]bước t+1 :=Min{F[i]bước t+a[i,j] | i} Ví dụ 2: K đường ngắn Vùng đất X có N thành phố (4≤N≤300) đánh số từ đến N Giữa thành phố có thể có đường nối trực tiếp không Các đường này đánh số từ đến M (1≤M<2000) Ban lãnh đạo thể dục thể thao vùng X tổ chức chạy đua tiếp sức “thông minh” theo quy luật sau: + Thành phố xuất phát là thành phố 1, thành phố đích là thành phố N + Mỗi đội thi đấu có K người dự thi Lần lượt người chạy từ thành phố thành phố N + Khi người thứ đến thành phố N thì người thứ bắt đầu rời khỏi thành phố 1,…, người thứ i đến thành phố N thì người thứ i+1 bắt đầu rời khỏi thành phố 1,…, (i<k) Người thứ K tới đích thời điểm nào thì thời điểm đó coi là thời điểm đích toàn đội + Đường chạy các đội viên không giống hoàn toàn + Có thể chạy lại đoạn đường đã chạy Hãy viết chương trình tính thời gian nhỏ để đội hoàn thành chạy đua tiếp sức nêu trên các vận động viên có tốc độ chạy Dữ liệu vào: File văn PATHK.INP - Dòng đầu tiên ghi số K, N, M - M dòng tiếp theo, dòng chứa số nguyên i, j, w thể đường trực tiếp thành phố i và j thời gian chạy là w (đơn vị thời gian, 1≤w≤9000) Kết quả: Ghi file văn PATHK.OUT: - Dòng thứ chứa số nguyên là thời gian chạy nhỏ đội - K dòng tiếp theo, dòng thể hành trình chạy vận động viên đội là dãy số hiệu các thành phố liên tiếp trên hành trình đó Cách giải: Ta xem vùng đất X là đồ thị vô hướng gồm N đỉnh Đường nối thành phố thể cạnh đồ thị Lúc đó bài toán giải theo thuật toán Dijkstra cải tiến sau: Gọi L[i,j] là độ dài đường thứ j k đường ngắn từ đỉnh đến đỉnh i (i=1, 2, …, N; j=1, 2,…, k) Khởi tạo L[i,j] vô cùng với i, j, L[1,1] - Mỗi lần tìm cặp (ii,jj) chưa đánh dấu có nhãn L[ii,jj] nhỏ - Từ (ii,jj) sửa nhãn cho (i,j) các đỉnh i kề với đỉnh ii: đường ngắn thứ j tới đỉnh i thành đường ngắn thứ j+1 tới i L[ii,jj]+ C[ii,i] > L[i,j] (*) và đường ngắn thứ j tới i thành đường qua ii trước, tới i Do đó (26) điều kiện (*) xẩy thì L[i,j+s]:=L[i,j+s-1] với s=1 đến k-j và L[i,j]:=L[ii,jj] +C[ii,i] Tương tự cập nhật lại vết đường các cặp (i,j) - Đánh dấu cặp (ii,jj) đã cố định nhãn Quá trình lặp không còn cặp (i,j) nào chưa cố định nhãn cặp (n,k) đã cố định nhãn Lưu ý: Vì chúng ta lưu trữ đồ thị ma trận kề nên bài toán chạy với số đỉnh và số cạnh không lớn (27) IV HIỆU QUẢ CỦA SÁNG KIẾN KINH NGHIỆM Tôi đã nghiên cứu đề tài này năm gần đây tiếc vận dụng dạy cho học sinh lớp 11 tham gia bồi dưỡng học sinh giỏi Tin học học kỳ II năm học 2010-2011 Sau tìm hiểu, nghiên cứu và vận dụng đề tài này vào công tác dạy học cho đội tuyển học sinh giỏi 11, tôi thấy kết thu khả quan nhiều so với cách làm củ Cụ thể: Khi chưa áp dụng đề tài: Tôi tham gia dạy bồi dương HSG năm gần đây và kết sau: - Năm 2008-2009, có học sinh dự thi HSG 11, có học sinh đạt giải 3, học sinh không đạt giải - Năm 2009-2010, có học sinh tham gia dự thi 11, có học sinh đạt giải khuyến khích, học sinh không đạt giải, Sau áp dụng đề tài: Đề tài này áp dụng cho học sinh khối 11 năm học 2010-2011 Kết HSG 11 học kỳ II vào tháng năm học 2010-2011 sau : học sinh đạt giải nhì (16 điểm) và học sinh đạt giải (14 điểm) – Đứng thứ toàn tỉnh Đề tài này đã vận dụng hiệu đội tuyển học sinh giỏi 11 và tiếp tục vận dụng để bồi dưỡng cho học sinh giỏi tin học 12 vào tháng 12 năm 2011 Tin với hỗ trợ phương pháp này đội tuyển học sinh giỏi 12 tháng 12 tới thu kết khả quan (28) C KẾT LUẬN Ứng dụng lý thuyết đồ thị vào dạy học bồi dưỡng HSG Tin học các trường THPT có ý nghĩa quan trọng việc nâng cao chất lượng, hiệu dạy học, qua đó giúp học sinh nhận thức đúng đắn vai trò, vị trí môn học Hơn việc ứng dụng lý thuyết đồ thị tạo hứng thú học tập cho học sinh, phát huy tính tích cực, chủ động, nhằm phát triển tư sáng tạo và lực giải vấn đề thực tiển sống Đề tài này đã giúp thân tôi tìm hiểu sâu kiến thức lý thuyết đồ thị và giúp học sinh tìm hiểu thêm luồng kiến thức để làm phong phú ý tưởng thuật toán mình, tạo tảng và bàn đạp để tiến xa đường lập trình Xã hội càng phát triển càng đặt nhiều yêu cầu mới, đó các bài toán đặt ngày càng thiên khuynh hướng giải lý thuyết đồ thị Lý thuyết đồ thị là lĩnh vực rộng, gồm nhiều mảng kiến thức, đề tài tôi đề cấp đến số nội dung có thể áp dụng cách hiệu cho học sinh Tin học 11 tham gia bồi dưỡng HSG đó là: vận dụng các thuật toán tìm kiếm trên đồ thị, thuật toán tìm các thành phần liên thông, thuật toán Dijkstra tìm đường ngắn trên đồ thị để giải các bài toán thực tế đặt cách hiệu Còn nhiều kiến thức đồ thị có thể áp dụng để bồi dưỡng cho học sinh, chẳng hạn vận dụng kiến thức cây, cây khung, cây khung ngắn ; chu trình, chu trình Euler và chu trình Hamilton ; đồ thị hai phía, cặp ghép Tuy nhiên, vận dụng lý thuyết đồ thị thì chưa đủ, để thành công việc bồi dưỡng học sinh giỏi cần phải biết kết hợp nhiều phương pháp khác nhau, chẳng hạn giải bài toán theo đệ quy, đệ quy quay lui, quy hoạch động Các bài toán đặt ngày càng đa dạng thì các thuật toán xây dựng phải đa dạng Mức độ thành công việc vận dụng lý thuyết đồ thị vào bồi dưỡng học sinh giỏi này phụ thuộc nhiều vào kiểu bài và đối tượng học sinh Tuy đã cố gắng tìm hiểu, nghiên cứu và vận dụng lý thuyết đồ thị vào dạy học đội tuyển học sinh giỏi tin học 11 để qua đó giúp học sinh bổ sung thêm hiểu biết mình tin học nói chung và lập trình nói riêng và để phục vụ cho thi học sinh giỏi đạt kết tốt không thể tránh khỏi thiếu sót định Kính mong Hội đồng khoa học và bạn bè đồng nghiệp góp ý, bổ sung để đề tài hoàn thiện Xin chân thành cảm ơn ! (29)

Ngày đăng: 06/06/2021, 03:16

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan