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

Chuyên đề quay lui

6 33 0

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

THÔNG TIN TÀI LIỆU

Mỗi cấu hình được xây dựng bằng cách xây dựng từng phần tử, mỗi phần tử được chọn bằng cách thử tất cả các khả năng... Liệt kê các dãy nhị phân độ dài N.[r]

(1)

THUẬT TOÁN QUAY LUI BACKTRACKING I/ Giới thiệu:

Thuật toán quay lui dùng để giải tốn liệt kê cấu hình Mỗi cấu hình xây dựng cách xây dựng phần tử, phần tử chọn cách thử tất khả Giả sử cấu hình cần liệt kê có dạng x[1 n], thuật tốn quay lui thực qua bước:

1) Xét tất giá trị x[1] nhận, thử cho x[1] nhận giá trị Với giá trị thử gán cho x[1] ta sẽ:

2) Xét tất giá trị x[2] nhận, lại thử cho x[2] nhận giá trị Với giá trị thử gán cho x[2] lại xét tiếp khả chọn x[3] … tiếp tục đến bước: …

n) Xét tất giá trị x[n] nhận, thử cho x[n] nhận giá trị đó, thơng báo cấu hình tìm <x[1], x[2], …, x[n]>

Trên phương diện quy nạp, nói thuật tốn quay lui liệt kê cấu hình n phần tử dạng x[1 n] cách thử cho x[1] nhận giá trị Với giá trị thử gán cho x[1] toán trở thành liệt kê tiếp cấu hình n - phần tử x[2 n]

II/ Mơ hình thuật tốn quay lui mơ tả sau: procedure Try(i: Integer);

begin

for <mọi giá trị V gán cho x[i]> do begin

<Thử cho x[i] := V>;

if <x[i] phần tử cuối cấu hình> then <Thơng báo cấu hình tìm được>

else

begin

<Ghi nhận việc cho x[i] nhận giá trị V (nếu cần)>;

Try(i + 1); {Gọi đệ quy để chọn tiếp x[i+1]} <Nếu cần, bỏ ghi nhận việc thử x[i] := V để thử giá trị khác>;

end; end;

end;

Thuật toán quay lui bắt đầu lời gọi Try(1) III/ Một số ví dụ:

1/ Viết chương trình in tất hoán vị n số tự nhiên (0<N<10) N nhập từ bàn phím.

Const

MaxN=100;

fi='hoanvi.inp';{chua so N}

fo='hoanvi.out';{moi dong chua mot hoan vi} Var

(2)

procedure Init; var i:integer; Begin

assign(f,fi);reset(f); read(f,n);

for i:=1 to n b[i]:=true; close(f);

assign(f,fo);rewrite(f); End;

Procedure PrintResult; var i:integer; Begin

for i:=1 to n write(f,' ',x[i]); writeln(f); End;

Procedure Try(i:integer); Var j:integer;

Begin

for j:=1 to n do if b[j] then

begin

x[i]:=j;

if i=n then PrintResult else

begin b[j]:=false; try(i+1); b[j]:=true; end;

end; End;

BEGIN Init; Try(1); Close(f); END.

2 Liệt kê dãy nhị phân độ dài N

Biểu diễn dãy nhị phân độ dài N dạng x[1 n] Ta liệt kê dãy cách thử

dùng giá trị {0, 1} gán cho x[i] Với giá trị thử gán cho x[i] lại thử giá trị gán cho x[i+1].Chương trình liệt kê thuật tốn quay lui viết:

program BinaryStrings; const

(3)

max = 30;

var x: array[1 max] of Integer; n: Integer; f: Text;

procedure PrintResult; {In cấu hình tìm được, thủ tục tìm đệ quy Try gọi tìm cấu hình}

var i: Integer; begin

for i := to n Write(f, x[i]); WriteLn(f);

end;

procedure Try(i: Integer); {Thử cách chọn x[i]} var j: Integer;

begin

for j := to {Xét giá trị gán cho x[i], với giá trị đó} begin

x[i] := j; {Thử đặt x[i]}

if i = n then PrintResult {Nếu i = n in kết quả}

else Try(i + 1); {Nếu i chưa phải phần tử cuối tìm tiếp x[i+1]} end;

end; begin

Assign(f, InputFile); Reset(f); ReadLn(f, n); {Nhập liệu} Close(f);

Assign(f, OutputFile); Rewrite(f); Try(1); {Thử cách chọn giá trị x[1]} Close(f);

end.

Vẽ ví dụ

3 Liệt kê tập k phần tử

Để liệt kê tập k phần tử tập S = {1, 2, …, n} ta đưa liệt kê cấu hình x[1 n], x[i] ∈ S x[1] < x[2] < … < x[k] Ta có nhận xét:

(4)

x[i] ≤ n - k + i …

x[1] ≤ n - k +

Từ suy x[i-1] + ≤ x[i] ≤ n - k + i (1 ≤ i ≤ k) ta giả thiết có thêm số x[0] = xét i =

Như ta xét tất cách chọn x[1] từ (=x[0] + 1) đến n - k + 1, với giá trị đó, xét tiếp tất cách chọn x[2] từ x[1] +1 đến n - k + 2, … chọn đến x[k] ta có cấu hình cần liệt kê Chương trình liệt kê thuật tốn quay lui sau:

program Combination;

const InputFile = 'SUBSET.INP';

OutputFile = 'SUBSET.OUT'; max = 30; var x: array[0 max] of Integer;

n, k: Integer; f: Text;

procedure PrintResult; (*In tập {x[1], x[2], …, x[k]}*) var i: Integer;

begin

Write(f, '{');

for i := to k - Write(f, x[i], ', '); WriteLn(f, x[k], '}');

end;

procedure Try(i: Integer); {Thử cách chọn giá trị cho x[i]} var j: Integer;

begin

for j := x[i - 1] + to n - k + i do begin

x[i] := j;

if i = k then PrintResult else Try(i + 1);

end; end; begin

Assign(f, InputFile); Reset(F); ReadLn(f, n, k); Close(f);

Assign(f, OutputFile); Rewrite(f); x[0] := 0; Try(1); Close(f);

end.

4.Bài toán cái túi (Câu đề thi cấp tỉnh V1 năm 2011-2012)

Một nhà thám hiểm cần đem theo túi có trọng lượng khơng b Có n đồ vật cần đem theo Đồ vật thứ j có trọng lượng aj giá trị sử dụng cj (j = 1, 2, 3, ,n) Hỏi nhà thám hiểm cần đem theo đồ vật tổng giá trị sử dụng đồ vật đem theo lớn nhất?

Input: Vào từ file văn CAITUI.INP:

(5)

 Dòng đầu ghi tổng giá trị đồ vật đem theo ứng với phương án tìm

 Ghi số đồ vật đem theo

CAITUI.INP CAITUI.OUT

4 8

5 4 10 6

15 1 2

uses crt;

const fi='caitui1.inp'; fo='caitui.out';

var x,a,c,bestconfig:array[1 100] of integer; n,best,sum,val,b:integer;

procedure input; var f:text; i,j,k:integer; begin

assign(f,fi);reset(f); readln(f,n,b);

for i:=1 to n read(f,a[i]); readln(f);

for i:=1 to n read(f,c[i]); close(f);

end;

procedure update; begin

if val>=best then begin

best:=val; bestconfig:=x; end;

end;

procedure try(i:integer); var j:integer;

begin

for j:= to

if sum+j*a[i]<=b then begin

x[i]:=j;

sum:=sum+x[i]*a[i]; val:=val+x[i]*c[i]; if i=n then update else try(i+1);

sum:=sum-x[i]*a[i]; val:=val-x[i]*c[i]; end;

end;

procedure init; begin

(6)

sum:=0; val:=0; end;

procedure xuat; var i:integer; begin

writeln('Gia tri lon nhat la ',best);

for i:=1 to n if bestconfig[i]=1 then write(i,' '); end;

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

Xem thêm:

TỪ KHÓA LIÊN QUAN

w