Thuật toán biểu diển đồ thị theo Forward Star

11 890 1
Thuật toán biểu diển đồ thị theo Forward Star

Đ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

TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN CHƯƠNG TRÌNH ĐÀO TẠC THẠC SĨ CNTT QUA MẠNG LẬP TRÌNH SYMBOLIC TRONG MAPLE Bộ môn: Lập trình Symbolic và ứng dụng Giáo viên hướng dẫn: PGS.TS. Đỗ Văn Nhơn Sinh viên: Trần Hoài Phong MSSV: CH1101027 Niên khóa 2011 - 2013 Mục lục Lời mở đầu Có ba thành phần có thể được lập trình: lôgic – đây là quá trình mô tả ở cấp độ cao của việc làm thế nào để có thể giải quyết một vấn đề, điều khiển – làm sao để thao tác với máy tính ở cấp độ thấp để có được giải pháp, và trừu tượng – xác định các đối tượng phức tạp bằng các thuộc tính có liên quan để giải quyết một vấn đề. Khó khăn thực sự trong việc giải quyết một vấn đề sẽ có liên quan đến hai phần: lôgic và trừu tượng. Với nhu cầu hiện nay, các phần mềm đã ngày càng phát triển và trở nên lớn hơn. Trí tuệ nhân tạo là một lĩnh vực như vậy với các ứng dụng được đặc trưng bằng cách sử dụng các tính toán hình thức hơn là tính toán số học. Loại ứng dụng này đôi khi đòi hỏi phải linh hoạt hơn các lĩnh vực ứng dụng khác. Các ngôn ngữ lập trình Symbolic hỗ trợ lập trình ở cấp độ cao bằng cách nhấn mạnh vào lôgic và trừu tượng: mọi thao tác phức tạp đều được ẩn trong ngôn ngữ do đó việc lập trình rất biểu cảm, ngắn ngọn, dễ hiểu và do đó có thể được duy trì dễ dàng. Và đặc biệt trong các lĩnh vực liên quan đến tính toán đến các phương trình đại số và vi phân… thì maple đã nổi lên thành một công cụ phổ biến vô cùng hữu ích cho các nhà lập trình cấp cao. Trong bài tiểu luận này em sẽ đưa ra một số kiến thức tổng quát về lập trình symbolic nói chung cũng như maple nói riêng để phần nào biết được một cách lập trình khác biệt so với những gì thông thường chúng ta lập trình đồng thời đưa ra một ví dụ minh hoạ dùng trực tiếp maple để thực hiện các tính toán hình thức. Vì thời gian và kiến thức có hạn nên bài tiểu luận vẫn còn nhiều hạn chế rất mong được sự đóng góp ý kiến từ thầy. Niên khóa 2011 - 2013 2 Cuối cùng em xin cám ơn thầy đã rất nhiệt tình hướng dẫn trong quá trình giảng dạy. Thầy đã cung cấp cho em nhiều kiến thức quý giá đặc biệt trong lĩnh vực tính toán hình thức cũng như lập trình trong lĩnh vực trí tuệ nhân tạo qua đó giúp em có thể nghiên cứu sâu hơn trong lĩnh vực này đồng thời giải quyết những vấn đề mà nếu dùng các ngôn ngữ lập trình thông thường là rất phức tạp. 1. Lập trình symbolic 1.1. Khái niệm Lập trình symbolic là ngôn ngữ lập trình mà trong đó các chương trình có thể tự xử lý, hoặc lập trình với các dữ liệu cấp cao. Không chỉ gồm một chuỗi kí tự hoặc văn bản mà là các dữ liệu thực sự có cấu trúc trong đó chương trình có thể thao tác được. Nói chung, trong ngôn ngữ lập trình symbolic, các cấu trúc dữ liệu phức tạp có thể dễ dàng tạo ra – người dùng có thể dễ dàng tạo ra nó đơn giản chỉ bằng cách viết trực tiếp chúng và sau đó có thể mở rộng nó bằng một vài phép toán đơn giản. Nhờ lập trình symbolic mà thay vì được tạo một chương trình trong ngôn ngữ bình thường đòi hỏi những xử lý rất phức tạp thì có thể dễ dàng được khai báo trong symbolic. Thực tế, sự hấp dẫn của các ngôn ngữ lập trình symbolic phần lớn đến từ sự dễ dàng trong việc tạo và thao tác trên các dữ liệu có cấu trúc phức tạp. 1.2. So sánh lập trình symbolic với lập trình hàm và lập trình lô gíc Lập trình hàm là lập trình bằng cách xác định các hàm (ví dụ nghịch đảo của X là 1 chia cho X) hơn là nói với máy tính cần phải làm cái gì (đưa 1 vào trong bộ nhớ, chia nó cho X, lưu kết quả lại). Lập trình hàm thường xuyên có rất nhiều hàm ngắn được định nghĩa hơn là một chuỗi mã dài. Tiêu biểu là LISP. Lập trình logic là lập trình điều khiển thông qua một mô hình lý luận nguyên nhân kết quả (ví dụ tôi có thể kết luận Y là đối xừng của X nếu tôi có thể làm điều này …). Tiêu biểu là prolog. 2. Maple Niên khóa 2011 - 2013 3 Maple là một ứng dụng giúp chúng ta có thể giải quyết các phương trình đại số và vi phân. Maple có khả năng thực hiện các phép toán dưới dạng hình thức và do đó nó có thể dùng để phân tích các giải pháp cho các phương trình đại số và vi phân. Với khả năng tính đạo hàm, tích phân và các tính toán đại số cũng như các biểu thức toán học dưới dạng hình thức đây là một giải pháp vô cùng mạnh mẽ và giúp chúng ta giải quyết được rất nhiều vấn đề phức tạp mà nếu chúng ta dùng một ngôn ngữ lập trình bình thường để giải thì sẽ vô cùng kì công. Ngoài ra maple còn cung cấp rất nhiều tài liệu tham khảo hữu ích trong toán học. Ví dụ trong trường hợp người dùng quên đạo hàm của sin là cosin thì có thể dễ dàng dùng Maple để nhanh chóng tìm kiếm thông tin này. Maple có thể thay thế rất nhiều công thức toán học qua đó có thể giúp chúng ta giải quyết rất nhiều vấn đề về khoa học kỹ thuật. 3. Ứng dụng trong maple 3.1. Phân tích yêu cầu Thuật toán Dijkstra được hình hành bởi Edsger Dijkstra vào năm 1956 và được công bố vào năm 1959. Đây là một thuật toán để giải quyết vấn đề tìm đường đi ngắn nhất cho một đồ thị mà không có cạnh nào có trọng số âm. Thuật toán này thường dùng cho việc định tuyến và như là một thủ tục con trong các thuật toán về đồ thị khác. Cho trước một đỉnh gốc trong một đồ thị, thuật toán sẽ tìm đường đi với chi phí nhỏ nhất (tức là đường đi ngắn nhất) giữa đỉnh nguồn này với tất cả các đỉnh. Nó cũng có thể được dùng để tìm kiếm chi phí của đường đi ngắn nhất từ một đỉnh tới một đỉnh khác bằng cách dừng thuật toán khi đường đi ngắn nhất tới đỉnh đích đã được xác định. Hiệu suất hoạt động của một thuật toán về đồ thị phụ thuộc vào: thuật toán và cấu trúc dữ liệu. Để biểu diễn một đồ thị chúng ta cần phải lưu trữ hai thông tin: một là các đỉnh các cạnh, hai là các dữ liệu về chi phí, cung cầu, có liên quan đến các đỉnh và các cạnh. Ở đây ta dùng cấu trúc Forward và Reverse Star. Cấu trúc này sẽ được đề cập trong phần sau. Niên khóa 2011 - 2013 4 3.2. Cấu trúc dữ liệu 1.1.1. Cấu trúc đầu vào Một đồ thị sẽ được xác định thông qua một danh sách gồm các danh sách con với một dãy các con số dùng để xác định đồ thị 1) Danh sách con đầu tiên chứa số đỉnh trong đồ thị, số cạnh và đỉnh gốc. 2) Các danh sách con còn lại xác định các cạnh trong đồ thị. Mỗi danh sách chứa đỉnh bắt đầu, kết thúc và chi phí của cạnh. Ví dụ: dothi := [ [4, 6, 1], // 4 đỉnh, 6 cạnh, đỉnh gốc là 1 [1, 2, 1], // cạnh từ 1 đến 2 với chi phí là 1 [1, 3, 3], [2, 3, 2], [3, 2, 4], [2, 4, 5], [3, 4, 9] ]; 1.1.2. Biểu diễn theo kiểu Forward Star Một đồ thị sẽ được xác định thông qua một danh sách gồm các danh sách con với một dãy các con số dùng để xác định được một đồ thị. Đồ thị sẽ lưu trữ một danh sách các đỉnh liền kề nhau theo dạng mảng qua đó cung cấp cho chúng ta một cách để có thể xác định hiệu quả tập hợp các cạnh đi ra từ bất kỳ đỉnh nào trong đồ thị. Chúng ta thực hiện sắp xếp các cạnh lại theo thứ tự sau: đầu tiên là các cạnh từ đỉnh 1 và sau đó là các cạnh từ đỉnh 2 và cứ tiếp tục như vậy. Với mỗi cạnh chúng ta Niên khóa 2011 - 2013 5 đánh một số theo thứ tự. Sau đó lần lượt lưu trữ các thông tin về mỗi cạnh trong danh sách cạnh. Chúng ta lưu trữ đỉnh gốc, đỉnh kết thúc, chi phí trong ba mảng khác nhau. Ngoài ra còn lưu 1 con trỏ cho mỗi đỉnh i, được kí hiệu là point(i) chỉ ra cạnh nhỏ nhất trong danh sách cạnh mà xuất phát từ đỉnh i, nếu đỉnh i ko có cạnh nào đi ra thì point(i) bằng với point(i+1). Vì vậy tất cả các cạnh đi ra từ đỉnh i tại các vị trí từ point(i) đến point(i+1)-1. Ví dụ: Từ dothi ở trên ta tạo ra các mảng như sau FS_tail = [1 1 2 2 3 3]; FS_head = [2 3 3 4 2 4]; FS_cost = [1 3 2 5 4 9]; FS_point = [1 3 5 7 7]; Ba mảng trên có thể được hiểu như sau phần tử đầu là cạnh từ đỉnh 1 đến đỉnh 3 với chi phí là 1, phần tử 2 là từ cạnh 1 đến cạnh 3 với chi phí là 3 và tương tự như vậy với các phần tử sau. point(1) = 1, point(2) = 3 tức là đỉnh 1 có cạnh 1 và 2 đi ra, đỉnh 2 có cạnh 3 và cạnh 4, 1.1.3. Biểu diễn theo kiểu Reverse Star Giúp xác định tập hợp các cạnh đi vào bấy kì đỉnh nào. Tương tự như Forward Star ta cũng được một tập hợp các mảng nhưng thứ tự như sau: Ví dụ: FS_tail = [1 31 2 2 3]; FS_head = [2 2 3 3 4 4]; FS_cost = [1 4 3 2 5 9]; FS_rpoint = [1 1 3 5 7]; -> Thay vì lưu các cạnh đi ra thì ta lưu các cạnh đi vào. Niên khóa 2011 - 2013 6 Tuy nhiên thay vì lưu lại tất cả các mãng tail, head, cost lặp lại như trên từ đó làm hao tốn tài nguyên và bộ nhớ, ta chỉ cần lưu lại số cạnh và có thể dùng các thông tin tương tự từ các mảng đã lưu trong Forward Star bằng cách lưu các con số cạnh trong một mãng gọi là trace. FS_Trace = [1 5 2 3 4 6]; trong đó cạnh 1 trong kiểu reverse star sẽ tương ứng với cạnh 1 trong forward star, cạnh 2 trong reverse star sẽ tương ứng với cạnh 5 trong forward star v.v 3.3. Thuật giải 1.1.4. Thuật toán biểu diển đồ thị theo Forward Star - Bước 1: Với mọi cạnh u, ta lần lượt gán đỉnh xuất phát, đỉnh kết thúc, chi phí vào ba mảng raw_tail, raw_head, raw_cost - Bước 2: Với mọi đỉnh v ta lặp tất cả các cạnh u xem cạnh nào có đỉnh xuất phát từ v Nếu tìm thấy ta lưu cách thông tin trong raw_tail, raw_head, raw_cost vào FS_tail, FS_head, FS_cost đồng thời lưu lại thông tin thứ tự cạnh trong FS_point 1.1.5. Thuật toán dijkstra - Bước 1: Với mọi đỉnh v ∈ S, trọng số(v) := ∞ S := {} i := Đỉnh gốc, trọng số(i)=0 - Bước 2: Tìm tất cả đỉnh v có trọng số nhỏ nhất và chưa có trong s Gán i = đỉnh vừa tìm được, trường hợp đầu tiên là đỉnh gốc Niên khóa 2011 - 2013 7 Với mọi v S và kề với i∈ trọng số(v) := trọng số(i) + w(i) - Bước 3: Nếu chưa quá số đỉnh cho trong đồ thị Lặp lại bước 2. Nếu quá số đỉnh dừng thuật toán 3.4. Code dữ liệu Vui lòng tham khảo file maple đính kèm. 3.5. Dữ liệu thử nghiệm Ví dụ 1:  Đầu vào: dothi := [ [4, 6, 1], # 4 đỉnh, 6 cạnh, đỉnh gốc: 1 [1, 2, 1], # cạnh 1 - từ đỉnh 1 tới đỉnh 2, trọng số = 1 [1, 3, 3],[2, 3, 2],[3, 2, 4],[2, 4, 5],[3, 4, 9] ]: ThuatToan_Dijkstras(dothi); # không vẽ đồ thị  Đầu ra: Đường đi ngắn nhất từ đỉnh nguồn 1: Tới Đỉnh Trọng số Đỉnh trước 2 1 1 3 3 1 4 6 2 Ví dụ 2:  Đầu vào: dothi := [ Niên khóa 2011 - 2013 8 [9,36,1], # 9 đỉnh, 36 cạnh, đỉnh gốc 1 [1,2,5], # cạnh 1 - từ đỉnh 1 tới đỉnh 2, trọng số = 5 [1,3,9],[1,4,20],[1,5,4],[1,8,14],[1,9,15], [2,1,5],[2,3,6],[3,1,9],[3,2,6],[3,4,15], [3,5,10],[4,1,20],[4,3,15],[4,5,20],[4,6,7], [4,7,12],[5,1,4],[5,3,10],[5,4,20],[5,6,3], [5,7,5],[5,8,13],[5,9,6],[6,4,7],[6,5,3], [7,4,12],[7,5,5],[7,8,7],[8,1,14],[8,5,13], [8,7,7],[8,9,5],[9,1,15],[9,5,6],[9,8,5] ]: ThuatToan_Dijkstras(net, true); //Vẽ đồ thị  Đầu ra: Đường đi ngắn nhất từ đỉnh nguồn 1: Tới Đỉnh Trọng số Đỉnh trước 2 5 1 3 9 1 4 14 6 5 4 1 6 7 5 7 9 5 8 14 1 9 10 5 Niên khóa 2011 - 2013 9 4. Kết luận Trong bài tiểu luận này em đã trình bày một số cái nhìn tổng quát về lập trình symbolic nói chung cũng như maple nói riêng. Bài tiểu luận này chỉ đi vào một phần tương đối nhỏ, tổng quát nhất. Đồng thời trong bài tiểu luận cũng có thêm một ví dụ về cách ứng dụng maple để tìm được đường đi ngắn nhất bằng cách sử dụng thuật toán Dijkstras. Qua ví dụ này ta có thể thấy được cách thức maple xử lý với các mảng, đồ thị, qua đó phần nào thấy được cách làm thế nào để có thể giải quyết được một vấn đề trong maple. Các nghiên cứu này đã giúp cho em có được những kiến thức rất hữu ích. Qua nó em có thể thấy được những hướng đi rất tốt mà sau này có thể áp dụng được sau này. Các tri thức hiện tại của con người hiện giờ là rất khổng lồ. Nếu có thể áp dụng được những gì vừa nghiên cứu được và mở rộng sâu hơn sẽ có thể tạo ra những sản phẩm vô cùng hữu ích trong cuộc sống. Hiện nay việc phát triển sáng tạo trong các phần mềm vẫn còn rất nhiều hạn chế. Phần lớn đều dựa trên các ngôn ngữ lập trình thông thường. Do đó mọi người thường gặp khó khăn khi yêu cầu phải làm ra các phần mềm đòi hỏi tính sáng tạo trong giải quyết một vấn đề của bài toán. Do đó việc nghiên cứu một ngôn ngữ lập trình mới như maple là rất cần thiết. Nó giúp chúng ta mở rộng thêm tư duy sáng tạo qua đó có thể tạo ra những phần mềm để phục vụ tốt hơn cho cuộc sống cũng như cho xã hội. Niên khóa 2011 - 2013 10 [...]... Shortest Path Algorithm http://www.maplesoft.com/applications/view.aspx?SID=4969&view=html [3] Dr Masoud Yaghini , Network Flows Network Representations http://www.google.com.vn/url? sa=t&rct=j&q =Forward+ Star+ Reverse +Star+ &source=web&cd=1&ved=0CC0 QFjAA&url=http%3A%2F%2Fwebpages.iust.ac.ir%2Fyaghini%2FCourses %2FNetwork_891%2F01_3_Representations.pdf&ei=1eAFUd2SEKfriAewp4A I&usg=AFQjCNGdZ_uOturDfWi8VnyHiyFTUiYJg&bvm=bv.41524429,d.aGc . trong forward star, cạnh 2 trong reverse star sẽ tương ứng với cạnh 5 trong forward star v.v 3.3. Thuật giải 1.1.4. Thuật toán biểu diển đồ thị theo Forward Star - Bước 1: Với mọi cạnh u, ta lần. dừng thuật toán khi đường đi ngắn nhất tới đỉnh đích đã được xác định. Hiệu suất hoạt động của một thuật toán về đồ thị phụ thuộc vào: thuật toán và cấu trúc dữ liệu. Để biểu diễn một đồ thị. 9] ]; 1.1.2. Biểu diễn theo kiểu Forward Star Một đồ thị sẽ được xác định thông qua một danh sách gồm các danh sách con với một dãy các con số dùng để xác định được một đồ thị. Đồ thị sẽ lưu trữ

Ngày đăng: 10/04/2015, 00:50

Từ khóa liên quan

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

Tài liệu liên quan