1. Trang chủ
  2. » Trung học cơ sở - phổ thông

Tài liệu ôn tập tin học lớp 12 kiểm tra, thi bồi dưỡng học sinh tham khảo (4).DOC

139 2,5K 1

Đ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 139
Dung lượng 659 KB

Nội dung

I / ý nghĩa : Trong nhiều trờng hợp , nghiệm của bài toán là dãy các phần tử đợc xác định không theo một luật tính toán nhất định, muốn tìmnghiệm phải thực hiện từng bớc ,tìm kiếm dần

Trang 1

A / Khái niệm chung

I / Khái niệm về đệ qui :

Một đối tợng gọi là có tính đệ qui nếu nó đợc định nghĩa thôngqua chính nó

Một hàm , một thủ tục có tính đệ qui nếu trong thân chơngtrình của hàm , thủ tục này lại có lời gọi tới chính nó

Giả sử có 1 hoán vị là S (A1 ,A 2 , A i-1 ,Ai , An-1 ,An ), sau

đó đổi chỗ 2 phần tử S[i] và S[j] của hoán vị đó ta sẽ đợc một hoán vịmới Sau đây là sơ đồ hình thành dần các hoán vị tiếp theo nhau củahoán vị S(1,2,3)

123

Trang 2

tử ,do đó nếu phần tử thứ i nhận giá trị cao nhất là (N-K)+i thì cácphần tử tiếp theo vẫn còn khả năng nhận các giá trị : (N-K)+i +1 ,(N-K)+i +2 , , (N-K)+i + (K-i) = N

Vậy để xây dựng phần tử thứ i của 1 tổ hợp , ta phải dựa vàokết quả đã xây dựng tới phần tử thứ i-1 Tất nhiên để xây dựng phần

tử thứ 1 , ta phải dựa vào ‘phần tử hàng rào ‘ là phần tử ở vị trí thứ

‘0’ ,ta gán cho phần tử này giá trị nào cho phù hợp qui luật nêutrên ? rõ ràng đó là giá trị 0 ,nhằm cho nó quyền đợc bình đẳng nhmọi phần tử khác Phần tử 0 này chịu một trách nhiệm rất nặng

nề ,bắt đầu từ nó mới xây dựng dần đợc các phần tử tiếp theo củamọi tổ hợp , song ta cũng đừng quên nó phải ‘ngậm ngùi’ vì ‘không

đợc đứng trong tổ hợp ‘

Sau đây là sơ đồ minh hoạ việc xây dựng tổ hợp chập 3 của 5 phần

tử 1,2,3,4,5

0 * * *

Trang 3

i=1 ; n-k+i = 3 0 1 * * 0 2 * *

0 3 * *

i=2 ; n-k+i = 4 012* 013* 014* 023* 024* 034*

Trang 4

==> Fibonaci(3) = Fibonaci(2)+ Fibonaci(1) = 1+1 =2.

L

u ý 2 Thủ tục và hàm đệ qui phải thể hiện tính đệ qui : Nó gọi tới

chính nó

Trong 2 thí dụ nêu trên các lệnh

Giaithua := N*Giaithua(N-1); { Thí dụ 1 }

Bài 5 : Tạo xâu kí tự có độ dài không quá 20 , chỉ chứa 3 kí tự A,B,C

có tính chất : Không có 2 xâu con liền nhau bằng nhau

Bài 6 :

Lập trình thể hiện trò chơi Tháp Hà Nội : Trên cọc 1 có N đĩa

và xếp đĩa nhỏ ở trên đĩa lớn ; cọc 2 và cọc 3 cha có đĩa Hãychuyển hết đĩa ở cọc 1 sang cọc 3 theo qui luật sau :

Trang 5

Chuyển từng đĩa ở trên cùng của một trong 3 cọc sang cọc khác saocho đĩa lớn không đặt trên đĩa nhỏ

Gợi ý :

+ Nếu cọc 1 chỉ có 1 đĩa thì chuyển nó sang cọc 3

+ Giả sử đã giải đợc bài toán trong trờng hợp có N-1 đĩa ;không mất tính chất tổng quát ,ta giả sử cọc 2 chứa N-1 đĩa ( đĩa nhỏtrên đĩa lớn ) và sẽ chuyển hết đợc sang cọc 3 nhờ cọc trung gian làcọc 1 Ta sẽ chứng minh bài toán cho N đĩa xếp ở cọc 1 , chuyểnsang cọc 3 nhờ cọc trung gian là cọc 2 sẽ giải đợc Thật vậy :

a) Tìm cách chuyển N-1 đĩa từ cọc 1 sang cọc 2 ( cọcphụ : 3 );

b) Chuyển 1 đĩa còn lại (đĩa lớn nhất ) ở cọc 1 sang cọc 3

c) Tìm cách chuyển N-1 đĩa từ cọc 2 sang cọc 3 (cọc phụ làcọc 1 )

+ Nếu số ngời N=0 thì không thể chia đợc

+ Nếu 0<M<N thì trong mọi cách chia , luôn có ít nhất N-Mngời không đợc chia , do vậy các cách chia khác nhau ở chỗ : chia

có khác nhau cho M ngời còn lại hay không ? Nói cách khác số cáchchia trong trờng hợp này bằng số cách chia của bài toán chia M vậtcho M ngời

+ Nếu M>=N>0 thì các cách chia thuộc 2 loại :

Loại 1 : Mọi ngời đều có phần , vậy mọi cách chia

có chỗ giống nhau là mọi ngời đều có ít nhất 1 vật , các cách chia chỉ khác nhau ở chỗ phân chia M-N vật còn lại cho N ngời nh thế nào ?

Loại 2 : Có 1 ngời không đợc chia vật nào Nghĩa là chỉ

Trang 6

Bài 8 : Vẽ các đờng HilBert cấp 5 , biết các đờng HilBert cấp 1, cấp

2, cấp 3 nh hình vẽ dới đây :

Các đ ờng cấp 1

Các đ - ờng cấp

B2

D2

Trang 7

êng A5

Trang 12

Function Kt(S : String) : Boolean;

Var i,j : Byte;

Begin

Kt := True;

For i:=1 to Length(S) div 2 do

For j:=1 to Length(S)- 2*i+1 do

Trang 13

Var Sodia,i,h1,h2,h3 : Byte;

A,B,C : Array[1 100] of Byte;

Trang 14

'2' : Begin

Inc(h2);B[h2] :=A[h1];

Gotoxy(50,24-h2); Write(B[h2]:2); End;

'3' : Begin

Inc(h3);C[h3] := A[h1];

Gotoxy(60,24-h3); Write(C[h3]:2); End;

'1': Begin

Inc(h1);A[h1] := B[h2];

Gotoxy(40,24-h1); Write(A[h1]:2); End;

'3' : Begin

Inc(h3);C[h3] := B[h2];

Gotoxy(60,24-h3); Write(C[h3]:2); End;

Trang 15

'1': Begin

Inc(h1);A[h1] := C[h3];

Gotoxy(40,24-h1); Write(A[h1]:2); End;

'2' : Begin

Inc(h2);B[h2] :=C[h3];

Gotoxy(50,24-h2); Write(B[h2]:2); End;

Trang 18

A(i-1); y:=y-h; lineto(x,y);

Gd := Detect; InitGraph(Gd, Gm, 'C:\tp97\tp\bgi');

If GraphResult <> grOk then Halt(1);

Thủ tục B gọi tới các thủ tục C và A ở dới nó

Ngoài ra , để dùng các lệnh vẽ ( chế độ đồ hoạ ) ta sử dụng Unit Graph

Trang 19

B / Quay lui + vÐt c¹n + lùa chän tèi u

Trang 20

I /

ý nghĩa :

Trong nhiều trờng hợp , nghiệm của bài toán là dãy các phần tử

đợc xác định không theo một luật tính toán nhất định, muốn tìmnghiệm phải thực hiện từng bớc ,tìm kiếm dần từng phần tử củanghiệm Để tìm mỗi phần tử ,phải kiểm tra “đúng,sai” các khả năng

có thể chấp nhận của phần tử này

+ Nếu khả năng nào đó không dẫn tới giá trị chấp nhận đợc củaphần tử đang xét thì phải loại bỏ khả năng đó , chuyển sang chọnkhả năng khác ( cha đợc chọn ) Chú ý : mỗi khi chọn một khả năngcho một phần tử thì thông thờng trạng thái bài toán sẽ thay đổi vìthế khi chuyển sang chọn khả năng khác , phải trả lại trạng thái nhtrớc khi chọn khả năng vừa loại bỏ (nghĩa là phải quay lui lại trạngthái cũ )

+ Nếu có 1 khả năng chấp nhận đợc ( nghĩa là gán đợc giá trịcho phần tử đang xét của nghiệm ) và cha là phần tử cuối cùng thìtìm tiếp phần tử tiếp theo

+ Nếu bài toán yêu cầu chỉ tìm 1 nghiệm thì sau khi chọn đợc 1khả năng cho 1 phần tử của nghiệm , ta kiểm tra phần tử này đã là

phần tử cuối cùng của 1 nghiệm hay cha ( gọi là lệnh kiểm tra kết

thúc 1 nghiệm ) Nếu đúng là phần tử cuối cùng của nghiệm thì :

Hiện nghiệm và thoát hẳn khỏi thủ tục đệ qui bằng lệnh Halt;

Nếu bài toán yêu cầu tìm tất cả các nghiệm thì không có lệnhkiểm tra kết thúc 1 nghiệm

+ Trong việc thử mọi khả năng của 1 phần tử của nghiệm , nếubiết tìm những điều kiện để nhanh chóng loại bỏ những khả năngkhông thể chấp nhận đợc thì việc thử sẽ nhanh chóng hơn Việc thửmọi khả năng của 1 phần tử của nghiệm cũng giống nh một ngời đi

đờng , mỗi khi đến ngã N-đờng , lần lợt chọn 1 đờng thích hợp trongcác con đờng của ngã N-đờng đó , nếu biết chắc chắn những đờngnào đó trong các đờng của ngã N-đờng là đờng “cụt” không thể đitới đích thì ngời đi đờng sẽ loại ngay những đờng đó ; hoặc ngợc lạinếu nhìn thấy trớc những điều kiện cho phép chỉ cần đi theo một sốcon đờng nhất định trong N đờng mà vẫn tới đích nhanh chóng thìngời đi đờng sẽ dùng những điều kiện ấy nh “la bàn “ chỉ phơng h-ớng đi của mình Tất nhiên khi khẳng định điều này là “đúng” ,điềukia là “sai” phải hết sức thận trọng.Nếu những khẳng định” chắcchắn” chỉ là điều “ngộ nhận” thì có thể bỏ sót một số con đờng tới

đích, hoặc chệch hớng không thể tới đích Một trí khôn vừa “táobạo” vừa “chắc chắn” là trí khôn của một chơng trình sáng giá !

Trang 21

+ Nếu tìm 1 nghiệm tốt nhất ( theo điều kiện ) thì mỗi khi tìm

đợc 1 nghiệm , ta so sánh với nghiệm tốt nhất đã tìm đợc cho đến lúcnày( gọi là nghiệm tối u ) Nếu nghiệm vừa tìm đợc tốt hơn nghiệmtối u thì gán lại nghiệm tối u là nghiệm mới

Quá trình tiếp diễn cho đến khi duyệt hết các nghiệm của bài toán ta

sẽ đợc nghiệm tối u của bài toán

Tóm lại thuật toán “duyệt trên cơ sở tìm kiếm và quay lui ” Thuật toán BackTracking - có chứa các nội dung sau :

-+ Vét cạn mọi nghiệm bằng tìm kiếm tiến dần về đích đồngthời biết quay lui khi không thể tiến

+ Có thể đặt các “mắt lọc” để việc tìm kiếm nhanh chóng hơn :hoặc loại bỏ hoặc chỉ chọn một số hớng

+ Có thể so sánh các nghiệm để có nghiệm tối u

+ Tuỳ theo yêu cầu , có thể chỉ tìm 1 nghiệm , cũng có thể tìmmọi nghiệm

Do thuật toán BackTracking xây dựng trên cơ sở tìm kiếmdần ,kết quả sau hình thành từ kết quả trớc, nên có thể dùng cáchàm, thủ tục đệ qui để thực hiện thuật toán Cụ thể có 3 dạng dàn bàithờng gặp sau đây :

II / Ba dạng đệ qui th ờng gặp để thực hiện thuật toán BackTracking

+ Nếu đề cử này chấp nhận đợc thì

Begin

Trang 22

* Nếu cha phải bớc cuối cùng thìTim(K+1)

Else {là bớc cuối cùng} thì HiệnNghiệm;

* Trả lại trạng thái của bài toán tr ớc khi

đề cử;

End;

End;

End;

Cũng có thể viết dới dạng sau :

Procedure Tim(k : Integer);

Begin

Nếu bớc k là bớc sau bớc cuối cùng thì Hiện nghiệm ;

Vòng lặp đề cử mọi khả năng của bớc thứ k trong tìmkiếm 1 nghiệm

Begin + Thử chọn 1 đề cử cho bớc k

+ Nếu đề cử này thoả mãn bài toán thì

Trang 23

C : Array [1 8] of -2 2 = (-1,1,2,2,1,-1,-2,-2); Var

Procedure Try(k:Integer;x,y: Integer);

Var i,j,u,v : Integer;

Begin

If k > nsq then Hien Else

For i:=1 to 8 do

Begin

Trang 25

Var i,j : Integer;

Trang 26

HoÆc cã thÓ viÕt díi d¹ng sau :

Procedure Tim(k : Integer);

Trang 27

Tạo vòng lặp đề cử mọi khả năng của bớc thứ k trong tìmkiếm 1 nghiệm

Begin + Thử chọn 1 đề cử

+ Nếu đề cử này thoả mãn bài toán thì

Begin

* Ghi nhận giá trị đề cử

* Lu trạng thái mới của bài toán sau đề cử

* Nếu cha phải bớc cuối cùng thìTim(K+1)

* Trả lại trạng thái của bài toán tr ớc khi

đề cử

End;

End;

End;

Trong bài toán tìm 1 nghiệm , ngời ta thờng đa thêm vào các điều

kiện đối với các khả năng đề cử để bỏ bớt đi 1 số khả năng đề cử hoặc làm cho khả năng đề cử thu hẹp lại

Thí dụ :

+ Điều kiện cần để một khả năng đợc chấp nhận ở bớc thứ i là bớci+1 cũng có khả năng chấp nhận một đề cử của nó và bớc thứ i chaphải bớc cuối cùng Vì vậy có thể nhanh chóng tới đích nếu đa raqui luật chọn đề cử của bớc thứ i nh sau :

ở bớc thứ i ta sẽ chọn đề cử nào mà theo nó đa ta tới bớc i+1

có ít khả năng chấp nhận nhất ( nghĩa là bớc thứ i+1 vẫn có khả năng

đề cử của nó , nhng số đề cử ít )

+ Một cách khác : Khi chấp nhận một khả năng đề cử cho bớc thứ i ,

có thể sẽ tác động tới trạng thái bài toán Vì vậy ta tính toán trớcnếu chọn đề cử này thì trạng thái bài toán có thay đổi quá mức giớihạn cho phép hay không ?.Nghĩa là có vợt qua cận trên hoặc cận dớicủa bài toán hay không ? Nếu vợt qua thì ta không chọn đề cử ấyTrong nhiều bài toán những cận này cũng thu hẹp dần theo từng b-

ớc , nếu ta tìm đợc sự thay đổi của cận theo từng bớc thì các khả

Trang 28

Trë l¹i bµi to¸n con m· ®i tuÇn nh ng víi yªu cÇu chØ hiÖn 1 nghiÖm

Trang 29

Procedure Try(k:Integer;x,y: Integer);

Var i,j,u,v : Integer;

Trang 31

Var i,j : Integer;

Function Bac(x,y:integer) : Integer;

Var i,dem : Byte;

Trang 32

Lời bình : Ngoài việc sử dụng đệ qui kết hợp quay lui , chơng trình

còn dựa trên thuật toán “Háu ăn ‘ : có lợi thì làm để nhanh chóng

đạt đích Cụ thể là ở mỗi bớc SO sẽ chọn ô của bớc (S0+1) tiếp theo nếu từ ô ấy có ít hớng đi tiếp tới ô kháccủa bớc (S0+2) Cây phân nhánh sẽ ít nhánh đi đáng kể Tất nhiên phải chứng minh rằng, với cách thức đi nh thế vẫn bảo đảm có ít nhất 1 nghiệm.

Ta thấy :Bằng cách chọn ô có bậc thấp và phải xuất phát từ ô (1,1) nên cứ đi vòng quanh bàn cờ dần vào trong luôn có đờng đi vào trong ruột bàn cờ , vì bậc các ô bên ngoài lớn hơn bậc các ô bên trong, và bậc các ô bên trong còn lớn hơn 1 khi mã cha vào sâu trongbàn cờ Chỉ khi gần kết thúc mới nảy sinh vấn đề : có đờng

đi tiếp nữa hay không ( còn ô có bậc lớn hơn 1 hay không ) , nghĩa

là khi đó ta mới biết cách đi này có đúng đắn không ? ( Các em hãy

tự chứng minh , hoặc ít nhất hãy thử nghiệm với các giá trị N=5,6,7,8, 20 nếu vẫn có nghiệm thì rõ ràng cách đi nh thế đã

đúng với các trờng hợp này ) và nh thế kết quả thu đợc cũng đã quá bất ngờ so với lập trình bình thờng Vậy ‘Háu ăn’ nhiều khi cũng có lợi lắm đấy

*

Một khó khăn khác của loại toán hiện 1 nghiệm là : trờng hợp bàitoán vô nghiệm cần viết chơng trình nh thế nào ? Phải duyệt hết mọikhả năng mới rõ kết luận vô nghiệm hay không vô nghiệm Nghĩa là

Trang 33

đã đi theo mọi nhánh nhng nhánh nào cũng đều không tới đích ,do

đó theo quy luật cứ quay lui mãi để tìm kiếm thì đến lúc nào đó dẫn

đến tình trạng phải trở về ô xuất phát Vậy khi gặp ô đề cử mớitrùng với ô xuất phát thì bài toán vô nghiệm (xem lại bài giải trang330)

Ta chỉ cần thêm vào mẫu 1 (Dạng tìm mọi nghiệm ) một chút

“gia vị” là có ngay dạng tơng ứng với bài toán vô nghiệm :

Procedure Tim(k : Integer);

Begin

Vòng lặp đề cử mọi khả năng của bớc thứ k trong tìm kiếm

1 nghiệm

Begin + Thử chọn 1 đề cử cho bớc k

+ Nếu đề cử này chấp nhận đợc thì

End;

End;

Cũng có thể viết dới dạng sau :

Procedure Tim(k : Integer);

Begin

Nếu bớc k là bớc sau bớc cuối cùng thì Hiện nghiệm ;

Vòng lặp đề cử mọi khả năng của bớc thứ k trong tìm

Trang 34

Procedure Try(i:integer;x,y:index;Var q:Boolean);

Var k,u,v : Integer;

Trang 35

Do đó nếu sau khi đã vét cạn mọi khả năng vẫn không đi tới bớc cuối cùng , tham biến q sau khi thoát khỏi thủ tục đệ qui Try sẽ có giá trị FALSE ban đầu Vậy sau thủ tục đệ qui Try , nếu q=TRUE thì có nghiệm , nếu q =FALSE là vô nghiệm Nhiệm vụ của q nh cái gậy dò dẫm tìm đờng vậy ! Có thể tăng độ dài của gậy lên không, để

nó thông báo kết thúc sớm hơn không ? ( Các em hãy chạy chơng trình với N=4 )

Trang 36

Nếu tìm đợc nghiệm mới thì So sánh nghiệm mới

+ Nếu đề cử này thoả mãn bài toán thì

Trang 37

Thí dụ trong bài toán du lịch : Tìm đờng đi qua N thành phố ,mỗi thành phố chỉ qua 1 lần , sao cho tốn ít chi phí vận chuyển nhất Mỗi nghiệm của bài toán là 1 véc tơ N thành phần đó là dãy tên cóthứ tự chọn của N thành phố Giả sử đã tìm đợc 1 số nghiệm , vàtrong đó nghiệm tốt nhất có chí phí tơng ứng là CPMax đồng , bâygiờ tìm tiếp các nghiệm còn lại Đặt tình huống ta đang xây dựng tớithành phần thứ i (i<N) của nghiệm tiếp theo ,gọi CP2 là tổng chi phítối thiểu của N-i thành phố còn lại , CP1 là tổng chi phí qua i thànhphố đã chọn

Nếu một đề cử nào đó của bớc i mà CP1+CP2 > CPMax thì đề

cử này bị loại

Nh vậy biết kết hợp với nghiệm tối u của các nghiệm trớc đó thì việctìm kiếm nghiệm tiếp theo đợc nhanh chóng hơn

Cách 2 :

Trang 38

Cách 3 : Thờng dùng trong các bài toán chọn một số phần tử trong

N phần tử cho trớc để tạo thành 1 nghiệm Thủ tục dới đây thực hiệnthử chọn dần phần tử i cho nghiệm tốt nhất , S : điều kiện chấp nhậncủa các phần tử i sẽ chọn , F là cận trên của hàm mục tiêu cần tối u( Xem lời giải bài toán cái túi - Trang 343 )

Procedure Tim(k : Integer);

+ Nếu đề cử này chấp nhận đợc thì

So sánh nghiệm mới với

Trang 39

Bài toán 1:

Bài toán ngời du lịch : Cho N thành phố , giá cớc phí vận chuyển từthành phố i tới thành phố j là C ij Yêu cầu :

File dữ liệu vào là ‘DULICH.INP’ nh sau

Dòng đầu là N , XP , Dich ( N số thành phố , XP : th/ phố xuất phát, Dich : th/phố đích )

N dòng tiếp theo :

Số đầu dòng là i , các cặp số tiếp theo là j và C ij của ma trậnC(N,N)

File dữ liệu ra là ‘DULICH.OUT’

Dòng đầu : Liệt kê hành trình tốn ít chi phí nhất , lần lợt qua N thànhphố ( Mỗi thành phố chỉ 1 lần )

Dòng tiếp theo : Tổng chi phí

+ Ghi phần tử thứ i vào tập nghiệm

+ Nếu i cha phải phần tử cuối cùng then Tim(i+1,S_mới ,F)

Còn không :

Nếu cận trên còn lớn hơn so với Lu cận là LF thì

Begin LF := F; LuNghiệm := Nghiệm ; End;

+ Trả lại trạng thái cũ : Loại bỏ phần tử i khỏi tậpnghiệm

Trang 40

ReWrite(F);

Trang 42

If (Not D[j]) and (i<>j) then

If (C[i,j]>0) and (Ltong-Tong>=C[i,j]) then

Begin

Inc(cs);

KQ[cs] := j;

D[j] := True;

Tong := Tong + C[i,j];

If (j<>dich) then Tim(j,Tong)

Ngày đăng: 08/07/2015, 16:43

TỪ KHÓA LIÊN QUAN

w