1. Trang chủ
  2. » Giáo án - Bài giảng

THUẬT TOÁN CHƯƠNG 3 QUY HOẠCH ĐỘNG SLIDE GIẢNG DẠY

67 937 3

Đ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

Thông tin cơ bản

Định dạng
Số trang 67
Dung lượng 1,12 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Bài toán thực hiện dãy phép nhân ma trậnBài toán tìm đường đi ngắn nhất - thuật toán Floy QUY HOẠCH ĐỘNG Bài toán dãy con lớn nhất 2.2.3... 3.1 Thuật toán quy hoạch động tổng quát Để

Trang 1

TRƯỜNG CAO ĐẲNG CNTT HỮU NGHỊ ViỆT - HÀN

KHOA KHOA HỌC MÁY TÍNH

-*** -THUẬT TOÁN

(Algorithms)

Trang 3

QUY HOẠCH ĐỘNG

 Chia để trị là thiết kế thuật toán theo kiểu từ trên xuống (top-down)

 Quy hoạch động là quá trình tiếp cận thuật toán

theo quá trình ngược lại, đó là thiết kế theo kiểu từ dưới lên (bottom-up).

 Điểm khác cơ bản của quy hoạch động với phương pháp chia để trị đó là:

 các bài toán con không độc lập với nhau,

 nghĩa là các bài toán con cùng có chung các bài toán con nhỏ hơn

 Trong tình huống đó, phương pháp chia để trị sẽ tỏ ra

không hiệu quả, khi nó phải lặp đi lặp lại việc giải các bài toán con chung đó

 Quy hoạch động sẽ giải một bài toán con một lần và lời giải

Trang 4

QUY HOẠCH ĐỘNG

động là một phương pháp giảm thời gian

chạy của các thuật toán thể hiện các tính

chất của các bài toán con gối nhau

(overlapping subproblem) và cấu trúc con tối

ưu (optimal substructure).

phương pháp quy hoạch động vào năm

1953.

Trang 5

Bài toán thực hiện dãy phép nhân ma trận

Bài toán tìm đường đi ngắn nhất - thuật toán Floy

QUY HOẠCH ĐỘNG

Bài toán dãy con lớn nhất

2.2.3

Trang 6

3.1 Thuật toán quy hoạch động tổng quát

 Để giải một bài toán bằng quy hoạch động, chúng

ta cần tiến hành những công việc sau:

Tìm nghiệm của các bài toán con (các trường hợp riêng) đơn giản nhất.

Tìm ra các công thức (hoặc quy tắc) xây dựng

nghiệm của bài toán con thông qua nghiệm của các bài toán con cỡ nhỏ hơn.

Tạo ra một bảng để lưu giữ các nghiệm của các bài toán con Sau đó tính nghiệm của các bài toán con theo các công thức đã tìm ra và lưu vào bảng.

Từ bảng đã làm đầy, tìm cách xây dựng nghiệm của bài toán đã cho

Trang 7

3.1 Thuật toán quy hoạch động tổng quát

Việc phát triển giải thuật dựa trên quy hoạch động có

thể chia làm 3 giai đoạn:

Phân rã: Chia bài toán cần giải thành những bài toán con nhỏ hơn

có cùng dạng với bài toán ban đầu sao cho bài toán con kích thước nhỏ nhất có thể giải một cách trực tiếp Bản thân bài toán xuất

phát có thể coi là bài toán con có kích thước lớn nhất trong họ các bài toán con này.

Ghi nhận lời giải: Lưu trữ lời giải của các bài toán con vào một

bảng Việc làm này là cần thiết vì lời giải của các bài toán con

thường được sử dụng lại rất nhiều lần, và điều đó nâng cao hiệu quả của giải thuật do không phải giải lặp lại cùng một bài toán

nhiều lần.

Tổng hợp lời giải: Lần lượt từ lời giải của các bài toán con kích

thước nhỏ hơn tìm cách xây dựng lời giải của bài toán kích thước lớn hơn, cho đến khi thu được lời giải của bài toán xuất phát (là bài

Trang 8

3.1 Thuật toán quy hoạch động tổng quát

 Có hai tính chất quan trọng mà một bài toán tối ưu cần phải thoả mãn để có thể áp dụng quy hoạch

động để giải nó là:

Cấu trúc con tối ưu: Để giải được bài toán đặt ra một cách

tối ưu, mỗi bài toán con cũng phải được giải một cách tối ưu

Số lượng các bài toán con phải không quá lớn Rất nhiều

các bài toán NP (xem [1] trang 234) – khó có thể giải được nhờ quy hoạch động, nhưng việc làm này là không hiệu quả

do số lượng các bài toán con tăng theo hàm mũ Một đòi hỏi quan trọng đối với quy hoạch động là tổng số các bài toán con cần giải là không quá lớn, cùng lắm phải bị chặn bởi một

Trang 9

Bài toán thực hiện dãy phép nhân ma trận

Bài toán tìm đường đi ngắn nhất - thuật toán Floy

QUY HOẠCH ĐỘNG

Bài toán dãy con lớn nhất

2.2.3

Trang 10

3.2.2

Bài toán thực hiện dãy phép nhân ma trận

Bài toán tìm đường đi ngắn nhất - thuật toán Floy

Trang 11

3.2.1 Bài toán thực hiện dãy phép nhân ma trận

 Tích của ma trận A = (aik) kích thước p x q với ma trận B = (bkj) kích thước q x r là ma trận C = (cij) kích thước p x r với các phần

tử của C được tính theo công thức:

Trang 12

3.2.1 Bài toán thực hiện dãy phép nhân ma trận

 Chúng ta có thể sử dụng đoạn chương trình sau đây

 Rõ ràng, đoạn chương trình trên đòi hỏi thực hiện tất

cả p.q.r phép nhân vô hướng để tính tích của hai ma trận.

Trang 13

3.2.1 Bài toán thực hiện dãy phép nhân ma trận

sau:1×7 + 2×2 + 3×6 = 29 nên nó có 3 phép nhân

vô hướng.

35 nên cũng có 3 phép nhân vô hướng,…

trận A và B là: 2×3×4 = 24 phép nhân.

Trang 14

3.2.1 Bài toán thực hiện dãy phép nhân ma trận

trước lần lượt như sau:

A × B × C × D (*)

[20×2] [2×30] [30×12] [12×8]

ma trận ở trên, đòi hỏi chúng phải tương thích với

nhau Tức là số cột của A phải đúng bằng số dòng của

B, số cột của B phải đúng bằng số dòng của C,…

Trang 15

3.2.1 Bài toán thực hiện dãy phép nhân ma trận

nhưng lại có tính chất kết hợp nên tích của 4 ma trận trên có thể được tính bằng nhiều cách như sau:

Trang 16

3.2.1 Bài toán thực hiện dãy phép nhân ma trận

hưởng lớn tới phí tổn để thực hiện dãy phép nhân của các ma trận Bài toán đặt ra là tính số phí tổn ít nhất

có thể được, khi thực hiện dãy phép nhân của n ma trận.

Trang 17

3.2.1 Bài toán thực hiện dãy phép nhân ma trận

Áp dụng phương pháp quy hoạch động chúng ta sẽ giải quyết bài toán theo kiểu “bottom-up”:

Gọi F[i, j] là số phép nhân tối thiểu cần thực hiện để nhân đoạn

ma trận liên tiếp: M i *M i+1 *…*M j (1 <= i <= j <= n)

Khi đó F[i, i] = 0 với mọi i.

Để tính M i *M i+1 *…*M j ta có thể có nhiều cách kết hợp: M i *M i+1 *…

*M j = (M i *M i+1 *…*M k )*(M k+1 *…*M j-1 *M j ) với i<= k <j Với mỗi

cách kết hợp (phụ thuộc vào cách chọn vị trí k), chi phí tối thiểu phải thực hiện bằng:

Chi phí thực hiện phép nhân: M i *M i+1 *…*M k = F[i, k]

Cộng với chi phí thực hiện phép nhân: M k+1 *…*M j-1 *M j = F[k+1, j]

Trang 18

3.2.1 Bài toán thực hiện dãy phép nhân ma trận

nhân Mk+1*…*Mj-1*Mj có kích thước ak+1×aj+1, vậy chi phí này là : ai×ak+1×aj+1.

chọn cách kết hợp để có chi phí ít nhất nên ta sẽ cực tiểu hóa F[i, j] theo công thức:

F[i, j] = min(F[i, k] + F[k+1,j] + ai*ak+1*aj+1) mọi

i<= k <j (3.1)

Trang 19

3.2.1 Bài toán thực hiện dãy phép nhân ma trận

Trang 20

3.2.1 Bài toán thực hiện dãy phép nhân ma trận

ra cách kết hợp tối ưu để nhân đoạn Mi*Mi+1*…*Mk

và cách kết hợp tối ưu để nhân đoạn

Mk+1*…*Mj-1*Mj (có kèm theo dấu mở ngoặc) đồng thời viết

thêm dấu “*” vào giữa hai biểu thức đó.

Trang 21

3.2.1 Bài toán thực hiện dãy phép nhân ma trận

Ta có hàm:

int Minmult(int n, const int a[], index P[][]) //a[] kích thước của các ma trận

{ //P[][] là ma trận lưu vị trí kết hơp k tối ưu

F[i][j] = min(F[i][k] + F[k+1][j] + ai*ak+1*aj+1);

P[i][j] = k sao cho F[i][j] dat min

}

return M[1][n];

Trang 22

3.2.1 Bài toán thực hiện dãy phép nhân ma trận

Trang 23

3.2.1 Bài toán thực hiện dãy phép nhân ma trận

Trang 24

3.2.1 Bài toán thực hiện dãy phép nhân ma trận

cách đặt dấu ngoặc tách đầu tiên cho giá trị F[i][j]

Cùng với việc tính các giá trị F[i][j], ta sẽ tính P[i][j] theo quy tắc:

d = 1: F[i][i+1] = ai×ak+1×aj+1

P[i][i+1] = i+1

1< d < n: F[i][i+d] = min(F[i][k] + F[k+1][i+d] + a i a k a i+d )

P[i][i+d] = k

Trang 25

3.2.1 Bài toán thực hiện dãy phép nhân ma trận

Thí dụ 3: Các giá trị của P[i, j] theo (*) được cho

trong bảng dưới đây:

Trang 26

3.2.1 Bài toán thực hiện dãy phép nhân ma trận

Ta có số phép nhân cần thực hiện là F[1,4] = 1232 Dấu ngoặc đầu tiên cần đặt sau vị trí P[1,4] = 1, tức là M = A(BCD) Ta tìm cách đặt dấu ngoặc đầu tiên để có F[2,4] tương ứng với tích

BCD Ta có P[2,4] = 2, tức là tích BCD được tính tối ưu theo

cách: BCD = (BC)D Từ đó suy ra, lời giải tối ưu là: M =

A((BC)D).

Bây giờ, ta tính số phép toán cần thực hiện theo thuật toán vừa trình bày Với mỗi d > 0, có n – d phần tử trên đường chéo cần tính, để tính mỗi phần tử đó ta cần so sánh d giá trị số tương ứng với các giá trị có thể của k Từ đó suy ra số phép toán cần thực hiện theo thuật toán là cỡ

6 / ) (

6 / ) 1 2 )(

1 ( 2 / ) 1 (

) (

3 2

1 1

1 1

1 1 2

n n

n n

n n

n

d d

n d d n

n d

n s

n d

Trang 27

3.2.1 Bài toán thực hiện dãy phép nhân ma trận

sau:

/* F[i,j] - chi phí tối ưu thực hiện nhân dãy Mi Mj;

P[i,j] - ghi nhận vị trí đặt dấu ngoặc đầu tiên trong cách thực hiện nhân dãy Mi Mj */

{for (i = 1;i<= n;i++) F[i,i] = 0; //khởi tạo

for (d = 1 ;d<= n;d++) // d = chỉ số của đường chéo for (i = 1;i<= n – d;i++)

{ j = i + d - 1; F[i,j] = +;

for (k = i;k<= j – 1;k++)

{ q = F[i,k] + F[k+1,j] + a[i]*a[k+1]*a[j+1]; if(q <F[i,j]) then

{ F[i,j] = q; P[i,j] = k; }

Trang 28

3.2.1 Bài toán thực hiện dãy phép nhân ma trận

đưa ra trình tự nhân tối ưu

Trang 29

3.2.1 Bài toán thực hiện dãy phép nhân ma trận

Như đã trình bày ở trên một trong những điều kiện để áp dụng được quy hoạch động để giải bài toán tối ưu là số lượng các bài toán con phải không quá lớn, nghĩa là thuật toán đệ quy để giải bài toán phải giải đi, giải lại cùng một bài toán con chứ không

phải luôn giải các bài toán con mới Khi một thuật toán đệ quy phải giải đi, giải lại cùng một bài toán con ta sẽ nói là bài toán tối

ưu có các bài toán con trùng lặp Để minh họa cho tính chất này,

ta sẽ tìm hiểu bài toán nhân dãy ma trận

Xét thuật toán đệ quy sau đây để tính F[i,j] là số phép nhân ít

nhất cần thực hiện để tính tích dãy ma trận MiMi+1 … Mj

RMat(a,i,j);

{ If( i == j) return 0;

F[i,j] = ;

for (k = I;k<= j – 1;k++)

{ q = RMat(a,i,k) + RMat(a, k+1,j) + d[i]*d[k+1]*d[j+1];

if q < F[i,j] then F[i,j]: = q;

}

Trang 30

3.2.1 Bài toán thực hiện dãy phép nhân ma trận

Trang 31

3.2.1 Bài toán thực hiện dãy phép nhân ma trận

Hình vẽ dưới đây cho thấy cây đệ quy thực hiện lệnh gọi RMat(a,1,4) Mỗi đỉnh của cây được đánh dấu bởi giá trị của hai tham số i, j.

Trang 32

3.2.1 Bài toán thực hiện dãy phép nhân ma trận

RMat(a,1,n) thực hiện thủ tục đệ quy trên để tính m[1,n] tăng theo hàm mũ của n Thật vậy, ta có:

) 1 ) (

) ((

1 ) (

1 ) 1 (

n k

k n T k

n T T

)(2

1

)1)(

)((1

)(

n

n i

n k

n k

i T n

i T k

k n T k

T n

T

Trang 33

3.2.2

Bài toán thực hiện dãy phép nhân ma trận

Bài toán tìm đường đi ngắn nhất - thuật toán Floy

Trang 34

3.2.2 Bài toán tìm đường đi ngắn nhất - thuật toán Floy

 nhắc lại sơ lược về lý thuyết đồ thị Hình 3.2 ở dưới là một đồ thị

Trang 35

3.2.2 Bài toán tìm đường đi ngắn nhất - thuật toán Floy

 ví dụ trong hình 3.2 để đi từ v1 đến v3 ta có 3 đơn

đường đi là: [v1, v2, v3], [v1, v4, v3], [v1, v2, v4, v3] Vì thế độ dài của các đường đi này là:

Trang 36

3.2.2 Bài toán tìm đường đi ngắn nhất - thuật toán Floy

 Để tìm đường đi ngắn nhất từ đỉnh u đến đỉnh v, ta liệt kê tất cả các đường đi từ u đến v (có thể có) Sau

đó chọn đường đi ngắn Tuy nhiên thuật toán này là không khả thi vì có độ phức tạp lớn hơn là thời gian hàm mũ

 Nếu gọi T(n) là thời gian thực hiện thuật toán trên thì

ta có T(n) = (n-2)! nên suy ra T(n) = O(n!), điều này

là tồi hơn thời gian hàm mũ Mục đích của chúng ta là tìm ra một thuật toán có hiệu quả hơn.

Trang 37

3.2.2 Bài toán tìm đường đi ngắn nhất - thuật toán Floy

toán tìm đường đi ngắn nhất, chúng ta có thể thực hiện như sau:

0 , nếu i = j

W[i][j]= trọng số trên cạnh , nếu có cung từ vi đến vj

∞ , nếu không có cung từ vi đến vj

Bảng 3.3 dưới đây là ma trận trọng số của đồ thị ở hình 3.2

Trang 38

3.2.2 Bài toán tìm đường đi ngắn nhất - thuật toán Floy

Trang 39

3.2.2 Bài toán tìm đường đi ngắn nhất - thuật toán Floy

 Bảng 3.4 Ma trận D chứa đường đi ngắn nhất giữa các cặp đỉnh trên đồ thị hình

Trang 40

3.2.2 Bài toán tìm đường đi ngắn nhất - thuật toán Floy

sẽ tính một vài giá trị mẫu của D(k)[i][j] cho đồ thị ở hình 3.2

 D3[2][5] = D2[2][5] = 14 (vì không có đường đi từ v3 đến v5)

 D4[2][5] = min(D3[2][5], length[v2, v4 ,v5]) = min(14, 5) = 5

 Và cuối cùng giá trị tính toán D5[2][5] = 5 là chiều dài của

đường đi ngắn nhất từ v2 đến v5 đã đi qua các đỉnh trung gian Điều này có nghĩa nó là chiều dài của đường đi ngắn nhất

 Như vậy D(n)[i][j] là chiều dài của đường đi ngắn nhất từ vi đến

vj vượt qua các đỉnh trung gian, và D(0)[i][j] là chiều dài của

đường đi ngắn nhất không vượt qua các đỉnh còn lại, nó là trọng

số từ vi đến vj chúng ta đã thiết lập D(0) = W và D(n) = D

Trang 41

3.2.2 Bài toán tìm đường đi ngắn nhất - thuật toán Floy

 Sử dụng phương pháp quy hoạch động ta có thể thực hiện như sau:

 Cho k chạy từ 1 đến n, tính D(k) thông qua D(k-1) Như vậy ta đã tao ra một dãy

Trang 42

3.2.2 Bài toán tìm đường đi ngắn nhất - thuật toán Floy

[3] = 3 bởi vì khi chúng ta chọn đỉnh v5 làm đỉnh trung gian trên

đường đi chỉ còn [v1, v4, v3]

trung gian trong [v1, v2, , vk] và sử dụng vk trong trường hợp này thì đường đi ngắn nhất là:

 D(k)[i][j] = D(k-1)[i][k] + D(k-1)[k][j] (3.2)

 D(2)[5][3] = 7 = 4 + 3 = D(1)[5][2] + D(1)[2][3]

của D(k)[i][j] là min của các giá trị bên phải của biểu thức 3.3 và 3.4 điều này có nghĩa là chúng ta xác định D(k) từ D(k-1) theo công thức sau:

 D(k)[i][j] = min(D(k-1)[i][j], D(k-1)[i][k] + D(k-1)[k][j])

Trang 43

3.2.2 Bài toán tìm đường đi ngắn nhất - thuật toán Floy

Ví dụ:

ở bảng 3.3, một vài tính toán đơn giản như sau (với D(0) = W):

Trang 44

3.2.2 Bài toán tìm đường đi ngắn nhất - thuật toán Floy

Thuật toán Floyd tìm đường đi ngắn nhất

thị có trọng số đến các đỉnh còn lại (trọng số không âm)

Trang 45

3.2.2 Bài toán tìm đường đi ngắn nhất - thuật toán Floy

 Phân tích thuật toán:

 Vòng lặp bên trong j chạy từ 1 đến n, có 3 vòng for lồng nhau nên:

 T(n)=n×n×n=O(n3).

 Để lưu lại các đường đi ta đưa vào mảng P[][]

 P[i][j] = một đỉnh trung gian trên đường đi ngắn

nhất, hoặc bằng 0 nếu không có đỉnh trung gian

Trang 46

3.2.2 Bài toán tìm đường đi ngắn nhất - thuật toán Floy

Trang 47

3.2.2 Bài toán tìm đường đi ngắn nhất - thuật toán Floy

 Dưới đây là mảng P lưu lại vết các đường đi của bảng 3.4

Trang 48

3.2.2 Bài toán tìm đường đi ngắn nhất - thuật toán Floy

 Để in đường đi ngắn nhất ta có thuật toán sau:

 void path (index q, r)

Trang 49

3.2.2

Bài toán thực hiện dãy phép nhân ma trận

Bài toán tìm đường đi ngắn nhất - thuật toán Floy

Trang 50

3.2.3 Bài toán dãy con lớn nhất

 Trong chương 2 ta đã trình bày thuật toán chia để trị

để giả bài toán dãy con lớn nhất với thời gian tính

Trang 51

3.2.3 Bài toán dãy con lớn nhất

Phân rã Gọi si là tổng thứ i của dãy con lớn nhất

Tổng hợp lời giải Trước hết, ta có sn = a1 Bây

giờ giả sử i > 1 và ta đã tính được si-1 Ở bước thứ i

để tính si là tổng của dãy con lớn nhất của dãy a1,

a2, …, ai-1, ai.

Trang 52

3.2.3 Bài toán dãy con lớn nhất

 Rõ ràng dãy con lớn nhất của dãy này hoặc là có chứa

phần tử ai hoặc là không chứa phần tử ai, vì thế chỉ

có thể là một trong hai dãy sau đây:

· Dãy con lớn nhất của dãy a1, a2, …, ai-1.

· Dãy con lớn nhất của dãy a1, a2, …, ai kết thúc tại ai.

 Từ đó suy ra Si = max {si-1, ei },

Trong đó ei là tổng của dãy con lớn nhất của dãy a1,

a2, …, ai kết thúc tại ai.

Trang 53

3.2.3 Bài toán dãy con lớn nhất

 Lưu ý rằng để tính ei, i = 1, 2, …, n, ta cũng có thể sử dụng công thức đệ quy sau:

e1 = a1;

ei = max {ai, ei-1 + ai }, i > 1.

 Ví dụ: cho dãy a = (3, 2, -7, 3, -5, 5, 3) thì dãy con lớn nhất là dãy b = (3,-5,5,3)

 Từ đó, ta có thuật toán sau để giải bài toán đặt ra:

Trang 54

3.2.3 Bài toán dãy con lớn nhất

{

smax = a[1]; // smax - tổng của dãy con lớn nhất

maxendhere = a[1];

s=1; //vị trí đầu của dãy

imax = 1; // imax - vị trí kết thúc của dãy con lớn nhất for( i = 2;i<= n;i++)

Trang 55

3.2.2

Bài toán thực hiện dãy phép nhân ma trận

Bài toán tìm đường đi ngắn nhất - thuật toán Floy

Trang 56

3.2.4 Bài toán dãy con chung dài nhất

Trang 57

3.2.4 Bài toán dãy con chung dài nhất

Thiết kế thuật toán:

Thuật toán đơn giản:

Duyệt tất cả các dãy con của dãy a và

kiểm tra mỗi dãy như vậy có phải là dãy con của b, và giữ lại dãy con dài nhất

 Mỗi dãy con của a tương ứng với dãy chỉ số <i1, i2, …,

ik> là tập con k phần tử của tập chỉ số {1, 2, …, m},

vì thế có tất cả 2m dãy con của a

Ngày đăng: 23/06/2017, 16:02

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w