BÀI TẬP LỚN MÔN Cấu trúc dữ liệu và giải thuật ĐƯỜNG ĐI NGẮN NHẤT

11 1.2K 5
BÀI TẬP LỚN MÔN Cấu trúc dữ liệu và giải thuật   ĐƯỜNG ĐI NGẮN NHẤT

Đ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

I.BÀI TOÁN ĐƯỜNG ĐI NGẮN NHẤT. 1.Phát biểu bài toán. Trong các ứng dụng thực tế bài toán tìm đường đi ngắn nhất giữa hai đỉnh của một đồ thị có ý nghĩa to lớn. Có thể dẫn về bài toán như vậy nhiều bài toán thực tế quan trọng. Ví dụ: ỉBài toán chọn một hành trình tiết kiệm nhất (theo tiêu chuẩn khoảng cách hoặc thời gian, chi phí ...) trên một bản đồ đường giao thông. ỉBài toán chọn một phương pháp tiết kiệm nhất để đưa một hệ động lực từ trạng thái này sang trạng thái khác. ỉĐặc biệt, bài toán tìm hành trình trong nhiều công đoạn nào đó thuộc một qui trình công nghệ sản xuất tự động. Ví dụ trong công đoạn khoan mạch in, hàn chân các linh kiện điện tử trong các nhà máy sản xuất, lắp ráp mạch điện tử, hành trình làm việc của các máy khoan tự động, robot hàn thường gồm rất nhiều đỉnh: hàng nghìn, hàng chục nghìn đỉnh. Vậy nênviệc thực hiện được hành trình ngắn nhất cho các robot đem lại lợi ích to lớn: tăng năng suất, giảm chi phí... (có thể trong trường hợp này bài toán biến đổi đi một chút, ví dụ cần phải tìm hành trình ngắn nhất qua tất cả các đỉnh, mỗi đỉnh đúng một lần...) ỉVà nhiều bài toán thực tế khác ... Hiện nay có rất nhiều phương pháp để giải các bài toán như vậy. Thế nhưng thông thường các phương pháp dựa trên lý thuyết đồ thị tỏ ra là các phương pháp có hiêụ quả cao nhất. Bài toán tìm đường đi ngắn nhất dưới dạng tổng quát có thể phát biểu như sau: Cho một đồ thị G(V, E), một hàm trọng số w(e) cho các cung e của G. Bài toán đặt ra là cần tìm một đường đi ngắn nhất từ một đỉnh xuất phát sG đến đỉnh cuối dG. Các trọng số w(e) có thể là dương, âm hoặc bằng 0. Một điều duy nhất là G không chứa chu trình với tổng trọng số âm. Vì rằng nếu như G có một chu trình H như vậy thì xuất phát từ S, ta đi đến vH và sau đó đi vòng quanh chu trình H một số đủ lớn lần rồi đến d ta sẽ thu được một đường đi có trọng lượng đủ nhỏ . Vì vậy trong trường hợp này đường đi ngắn nhất là không tồn tại. Tuy nhiên, việc giải bài toán tổng quát trên là nằm ngoài khuôn khổ bài tập lớn này, vì vậy chúng ta chỉ giải bài toán đặt ra trong trường hợp các trọng số w(e) 0, G là đồ thị định hướng. Ta xét một thuật toán đơn giản, hiệu quả để giải bài toán trong trường hợp này.

Bài tập lớn môn Cấu trúc liệu giải thuật Đờng ngắn I Bài toán đờng ngắn Phát biểu toán Trong ứng dụng thực tế toán tìm đờng ngắn hai đỉnh đồ thị có ý nghĩa to lớn Có thể dẫn toán nh nhiều 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í ) đồ đờng giao thô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 sang trạng thái khác Đặc biệt, toán tìm hành trình nhiều công đoạn thuộc qui trình công nghệ sản xuất tự động Ví dụ công đoạn khoan mạch in, hàn chân linh kiện điện tử nhà máy sản xuất, lắp ráp mạch điện tử, hành trình làm việc máy khoan tự động, robot hàn thờng gồm nhiều đỉnh: hàng nghìn, hàng chục nghìn đỉnh Vậy nênviệc thực đợc hành trình ngắn cho robot đem lại lợi ích to lớn: tăng suất, giảm chi phí (có thể trờng hợp toán biến đổi chút, ví dụ cần phải tìm hành trình ngắn qua tất đỉnh, đỉnh lần ) Và nhiều toán thực tế khác Hiện có nhiều phơng pháp để giải toán nh Thế nhng thông thờng phơng pháp dựa lý thuyết đồ thị tỏ phơng pháp có hiêụ cao Bài toán tìm đờng ngắn dới dạng tổng quát phát biểu nh sau: Cho đồ thị G(V, E), hàm trọng số w(e) cho cung e G Bài toán đặt cần tìm đờng ngắn từ đỉnh xuất phát s G đến đỉnh cuối d G Các trọng số w(e) dơng, âm Một điều G không chứa chu trình với tổng trọng số âm Vì nh G có chu trình H nh xuất phát từ S, ta đến v H sau vòng quanh chu trình H số đủ lớn lần đến d ta thu đợc đờng có trọng lợng đủ nhỏ Vì trờng hợp đờng ngắn không tồn Tuy nhiên, việc giải toán tổng quát nằm khuôn khổ tập lớn này, giải toán đặt trờng hợp trọng số w(e) 0, G đồ thị định hớng Ta xét thuật toán đơn giản, hiệu để giải toán trờng hợp Giải toán với trọng số không âm thuật toán Dijkstra Dijkstra ngời đề nghị thuật toán hữu hiệu giải toán tìm đờng ngắn từ s tới d Phơng pháp đơc xây dựng dựa sở dán nhãn tạm thời cho đỉnh Nhãn đỉnh cho biết cận độ dài đờng ngắn từ s đến Các nhãn đợc biến đổi theo thủ tục lặp, mà bớc lặp lại có nhãn tạm thời trở thành nhãn cố định Nếu nhãn đỉnh trở thành cố định cho ta cận mà độ dài đờng ngắn từ s đến Ta mô tả cụ thể thuật toán Thuật toán Dijkstra (w(e) 0): Ký hiệu val(i), val(s) nhãn đỉnh v(i), s Bớc Gán nhãn tạm thời cho tất đỉnh Tất val đỉnh + trừ val(s) = Bớc Trong tất đỉnh có nhãn tạm thời khác + , tìm đỉnh có val nhỏ Nếu tìm thấy, gọi đỉnh vmin Nếu không tìm thấy đờng từ s đến d, thoát Thay đổi nhãn vmin thành cố định Nếu vmin d tìm đợc đờng ngắn nhất, độ dài đờng val(vmin), thoát Bớc Với đỉnh v(i) có nhãn tạm thời kề với vmin (có cạnh hớng từ vmin sang v(i), nói cách khác w(vmin, v(i)) < + ) ta thay đổi val(i) theo qui tắc sau: val(i) := min{val(i), val(vmin) + w(vmin, v(i))} Quay lại bớc Phần chứng minh thuật toán thấy nhiều tài liệu nên để khỏi dài dòng, ta không cần nêu II Chơng trình viết ngôn ngữ Turbo Pascal Cách tổ chức chơng trình a Cấu trúc liệu Trong chơng trình biến dùng để lu trọng số cạnh chiếm nhiều nhớ Ta dùng biến kiểu real (6 bytes) để lu trọng số Nếu ta lu trữ trọng số vào ma trận kề chơng trình xử lý cho số lợng đỉnh tối đa xấp xỉ 100 đỉnh, số lợng cho toán thực tế Vì việc chọn cấu trúc liệu thích hợp cho chơng trình quan trọng Ta dùng cấu trúc danh sách kề để biểu diễn đồ thị Ta dùng mảng chiều mà phần tử mảng danh sách móc nối Mỗi đỉnh G có danh sách tơng ứng Các nút danh sách i biểu diễn đỉnh lân cận đỉnh v(i) Mỗi nút danh sách thứ i gồm trờng: index, long link Trờng index cho biết số đỉnh kề với đỉnh v(i) Trờng long cho biết trọng số cạnh nối từ nút v(i) đến nút có số index Trờng link trỏ tới nút danh sách nil nút cuối danh sách Ta thấy dùng cách biểu diễn đồ thị có phức tạp dùng ma trận kề song chơng trình dễ dàng giải toán có số đỉnh số cạnh cỡ nghìn, đủ lớn cho nhiều ứng dụng thực tế Ta khai báo chơng trình nh sau: const nmax=1001; type nn=1 nmax; vertexPtr=^vertexNode; vertexNode=record index: word; long: real; link: vertexPtr; end; var adj: array[nn] of vertexPtr; Nmax số đỉnh tối đa mà chơng trình xử lý Adj mảng danh sách kề b Cấu trúc chơng trình Ta chia nhỏ chơng trình thành module, module có chức riêng thành viên nhóm thiết kế Sau cấu trúc chơng trình program Find_The_Shortest_Way; uses crt; const declaration; type declaration; var declaration; Procedure insert(i1, i2: integer; val: real); Function check(a, b, n: integer): boolean; Procedure inputFromFile; Call insert, check; Procedure showData; Procedure inputFromKeyboard; Call check; Procedure dijkstra; Procedure output; Begin Call inputFromFile, showData, inputFromKeyBoard, Dijkstra, output, check; end Chức module Procedure insert(i1, i2: integer; val: real) Thêm đỉnh v(i2) vào danh sách đỉnh kề v(i1), val trọng số cạnh (v(i1), v(i2)) Function check(a, b, n: integer): boolean; Nếu a, b n check trả giá trị true, không trả false Procedure inputFromFile; Thủ tục nhập số liệu đồ thị từ file text dijkstra.inp Ta đề cập cấu trúc file Tất số liệu G, trừ s d đợc nhập từ bàn phím, đợc ghi file Đầu tiên thủ tục đọc số đỉnh G vào biến toàn cục n có kiểu integer Trong file liệu, n đợc ghi sau dấu : Xuống dòng, dòng hớng dẫn Sau đến n dòng ghi số, tên đỉnh ứng với số Các dòng tên đỉnh ghi theo thứ tự Biến mảng name toàn cục chứa tên đỉnh, tên có không 15 ký tự Dành tiếp dòng cho hớng dẫn Mỗi dòng cho thông tin cạnh đồ thị Mỗi dòng gồm số đỉnh i1, i2 trọng số cạnh hớng từ v(i1) đến v(i2) Trọng số số thực để áp dụng tốt số nguyên cho toán thực tế Kết thúc file Procedure showData; Thủ tục hiển thị phần thông tin G hình nhằm giúp ngời sử dụng kiểm tra thêm tính đắn liệu (chỉ dùng cho đồ thị bé) Các thông tin đợc hiển thị bao gồm: số đỉnh, số cạnh, tên đỉnh, danh sách kề (không có thông tin độ lớn cạnh) Procedure inputFromKeyboard; Thủ tục lấy số đỉnh nguồn, đỉnh đích ngời sử dụng nhập từ bàn phím đa vào biến toàn cục nguyên: source dest Nó đơc chơng trình sử dụng kết hợp với hàm check tạo nên vòng lặp sử dụng chơng trình Khi ngời dùng nhập vào số không nằm [1, n] chơng trình kết thúc Procedure dijkstra; Đây thủ tục chính, hạt nhân chơng trình Chúng ta mô tả kỹ thủ tục Thủ tục dùng biến mảng val, dad, mark, adj Chúng ta biết adj mảng danh sách kề lu trữ thông tin cạnh đồ thị có hớng G, val (viết tắt value) lu nhãn đỉnh Ta định nghĩa maxreal = 1e38 đủ lớn để đại diện cho đại lợng + Mảng mark cho biết trạng thái nhãn đỉnh Mark[i] cho biết nhãn đỉnh v(i) tạm thời hay cố định Còn mảng dad dùng để lu trữ thông tin đờng để sau tìm đợc đờng ngắn nhất, ta dùng để tìm lại đờng từ s đến d Trong bớc lặp, val[i] đợc thay đổi, dad[i] chứa đỉnh đứng trớc v(i) đờng tìm đợc thời điểm Nếu nhãn v(i) cố định, dad[i] số đỉnh đứng trớc đỉnh i đờng ngắn từ s đến v(i) Biến imin, vmin số giá trị nhãn đỉnh vmin ta đề cập bớc thuật toán Biến toàn cục found kiểu boolean cho biết gặp đỉnh đích gán nhãn cố định cho hay cha Thực tế có nhiều cách tổ chức lu trữ cho biến adj, name, dad, mark, val để tiết kiệm nhớ nữa, song với chơng trình tập lớn ta thấy điều không cần thiết làm tăng độ phức tạp chơng trình lên mà hiệu không tăng nhiều Do ta chọn kiểu mảng chiều đơn giản cho biến Vì thủ tục đơc thiết kế trung thành với ý tởng thuật toán đề đoạn mã ngắn, dễ hiểu nên hiệu quả, nhanh chóng bỏ qua phần thiết kế thủ tục ngôn ngữ tựa Pascal Procedure output; Thủ tục xuất kết file text dijkstra.out, đồng thời đa kết hình để ngời sử dụng dễ theo dõi đồ thị cỡ nhỏ Nếu nh tìm đợc đờng đi, thủ tục kiêm chức dò lại đờng đi, lu vào mảng way Văn chơng trình Xin xem chơng trình dijkstra.pas đĩa kèm theo program Find_The_Shortest_Way; uses crt; const nmax=1001; maxreal=1e38; fi='dijkstra.inp'; fo='dijkstra.out'; type nn=1 nmax; vertexPtr=^vertexNode; vertexNode=record index: word; long: real; link: vertexPtr; end; var f: text; n, e, start, dest: integer; name: array[nn] of string[15]; val: array[nn] of real; dad, way: array[nn] of word; mark: array[nn] of byte; adj: array[nn] of vertexPtr; found: boolean; Procedure insert(i1, i2: integer; val: real); var v: vertexPtr; begin new(v); v^.index:=i2; v^.long:=val; v^.link:=adj[i1]; adj[i1]:=v; end; Function check(a, b, n: integer): boolean; begin check:=(a>=1)and(a=1)and(b=1)and(i1=1)and(i2

Ngày đăng: 09/05/2016, 22:30

Từ khóa liên quan

Mục lục

  • Bài tập lớn môn

  • Dijkstra là người đầu tiên đề nghị thuật toán hữu hiệu giải bài toán tìm đường đi ngắn nhất từ s tới d. Phương pháp này đươc xây dựng dựa trên cơ sở dán các nhãn tạm thời cho các đỉnh. Nhãn của mỗi đỉnh cho biết cận trên của độ dài đường đi ngắn nhất từ s đến nó. Các nhãn này được biến đổi theo các thủ tục lặp, mà ở mỗi bước lặp lại có một nhãn tạm thời trở thành nhãn cố định. Nếu nhãn của một đỉnh nào đó trở thành cố định thì nó cho ta không phải là cận trên mà là độ dài của đường đi ngắn nhất từ s đến nó. Ta sẽ mô tả cụ thể thuật toán này.

  • Thuật toán Dijkstra (w(e) 0):

  • Ký hiệu val(i), val(s) là nhãn của đỉnh v(i), s.

  • Bước 1. Gán nhãn tạm thời cho tất cả các đỉnh. Tất cả val của các đỉnh bằng trừ val(s) = 0.

    • Index of source vertex:

      • Can not go from Hong Kong to Ha Noi

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

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

Tài liệu liên quan