1. Trang chủ
  2. » Công Nghệ Thông Tin

CHUYEN DE 2 THUAT TOAN DUYET p1

17 154 0

Đ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 17
Dung lượng 514,5 KB
File đính kèm CHUYEN DE 2 THUAT TOAN DUYET P1.rar (200 KB)

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

Nội dung

Các thuật tốn duyệt: Duyệt tồn bộ: Một trong những phương pháp hiển nhiên nhất để giải bài tốn tối ưu tổ hợp đặt ra là: trên cơ sở các thuật tốn liệt kê tổ hợp ta tiến hành duyệt từng p

Trang 1

BÀI TOÁN TỐI ƯU :

Bài tốn tối ưu tổ hợp là bài tốn tìm phương án tối ưu trên tập các cấu hình tổ hợp Nghiệm của bài tốn cũng là một vector x gồm n thành phần sao cho:

1 x = (x1,x2,…xn)

2 xi lấy giá trị trong tập Si

3 x thoả mãn các ràng buộc cho bởi hàm G(x)

4 F(x)  min/max (hàm F(x) được gọi là hàm mục tiêu)

Khi đĩ x gọi là một phương án tối ưu, F(x) là giá trị tối ưu.

1 Các thuật tốn duyệt:

Duyệt tồn bộ:

Một trong những phương pháp hiển nhiên nhất để giải bài tốn tối ưu tổ hợp đặt ra là: trên cơ sở các thuật tốn liệt kê tổ hợp ta tiến hành duyệt từng phương án của bài tốn, đối với mỗi phương án ta điều tính giá trị hàm mục tiêu tại đĩ, sau đĩ so sánh giá trị hàm mục tiêu tại tất cả các phương án được liệt kê để tìm ra phương án tối ưu

Thuật tốn nhánh cận:

Trang 2

Trong thủ tục trên, BestSolution là nghiệm tốt nhất đã biết ở thời điểm đĩ Thủ tục <cập nhật BestSolution> sẽ xác định “độ tốt” của nghiệm mới tìm thấy, nếu nghiệm mới tìm thấy tốt hơn BestSolution thì BestSolution sẽ được cập nhật lại là nghiệm mới tìm được

2 Một số ví dụ

BÀI TỐN NGƯỜI DU LỊCH

1 Bài tốn

Cho n thành phố đánh số từ 1 đến N và các tuyến đường giao thơng hai chiều giữa chúng, mạng lưới giao thơng này được cho bởi bảng C[1 n,1 n], ở đây Cij = Cji là chi phí đi đoạn đường trực tiếp từ thành phố i đến thành phố j Một người du lịch xuất phát từ thành phố 1, muốn đi thăm tất cả các thành phố cịn lại mỗi thành phố đúng 1 lần và cuối cùng quay lại thành phố 1 Hãy chỉ ra cho người đĩ hành trình với chi phí ít nhất Bài tốn đĩ gọi là bài tốn người du lịch hay bài tốn hành trình của một thương

gia (Travelling Salesman Problem-TSP)

* Input: file TOURISM.INP cĩ dạng:

- Dịng đầu chứa số thành phố n (1<n100)

- n dịng tiếp theo, mỗi dịng n số mơ tả mảng C (chi phí này là số nguyên dương ≤10000)

* Output: file TOURISM.OUT cĩ dạng:

- Dịng đầu là chi phí ít nhất

- Dịng thứ hai mơ tả hành trình

Procedure BranchBound(i); // xây dựng thành phần thứ i

Begin

<Đánh giá các nghiệm mở rộng>;

If<các nghiệm mở rộng đều không tốt hơn BestSolution> then exit;

<Xác định Si>;

for xi ∈ Si do

begin

<ghi nhận thành phần thứ i>;

if (tìm thấy nghiệm “i=n”) then < Cập nhật BestSolution>

else BranchBound(i+1);

<Loại thành phần i >;

end;

end;

Trang 3

Ví dụ:

4

0 20 35 42

20 0 34 30

35 34 0 12

42 30 12 0

97 1->2->4->3->1

2 Cách giải

1) Hành trình cần tìm cĩ dạng (x1 = 1, x2, , xn, xn+1 = 1), ở đây giữa xi và xi+1: hai thành phố liên tiếp trong hành trình phải cĩ đường đi trực tiếp; trừ thành phố 1, khơng thành phố nào được lặp lại hai lần

Cĩ nghĩa là dãy (x1, x2, , xn) lập thành 1 hốn vị của (1, 2, , n)

2) Duyệt quay lui: x2 cĩ thể chọn một trong các thành phố mà x1 cĩ đường đi tới (trực tiếp), với mỗi cách thử chọn x2 như vậy thì x3 cĩ thể chọn một trong các thành phố mà x2 cĩ đường đi tới (ngồi x1) Tổng quát: xi cĩ thể chọn 1 trong các thành phố chưa đi qua mà từ x i-1 cĩ đường đi trực tiếp tới (1  i  n)

3) Nhánh cận: Khởi tạo cấu hình BestConfig cĩ chi phí = + Với mỗi bước thử chọn xi xem chi phí đường đi cho tới lúc đĩ cĩ < Chi phí của cấu hình BestConfig?, nếu khơng nhỏ hơn thì thử giá trị khác ngay bởi cĩ đi tiếp cũng chỉ tốn thêm Khi thử được một giá trị xn ta kiểm tra xem xn cĩ đường đi trực tiếp về 1 khơng ? Nếu cĩ đánh giá chi phí đi từ thành phố 1 đến thành phố xn cộng với chi phí từ xn đi trực tiếp về 1, nếu nhỏ hơn chi phí của đường đi BestConfig thì cập nhật lại BestConfig bằng cách đi mới

Chương trình giải bài tóan người du lịch bằng PP nhánh cận (tham khảo):

Trang 4

Program Nguoi_dulich;

{TT: ky thuat nhanh can}

Const MAX =100; oo =1000000;

fi ='Tourism.INP'; fo ='Tourism.OUT';

Var

C :array[1 max,1 max]of integer;

x,bestway:array[1 max]of integer;

d : array[1 max] of boolean;

n,m :integer;

sum,best : longint;

Procedure input;

var

i, j, k: Integer; f: Text;

begin

Assign(f,fi); Reset(f);

ReadLn(f, n);

for i :=1 to n do

for j := 1 to n do

Read(f,C[i, j]);

Close(f);

end;

procedure update;

begin

if sum+C[x[n],x[1]]<best then

begin

best:=sum+C[x[n],x[1]];

bestway:=x;

end;

end;

procedure branchBound(i:longint);

var j :longint;

begin

if sum>=best then exit;

for j:=1 to n do

if d[j] then

begin

x[i]:=j;

d[j]:=false;

sum:=sum + C[x[i-1],j];

if i=n then update

else branchBound(i+1);

sum:=sum - C[x[i-1],j];

d[j]:=true;

end;

end;

procedure init;

begin

fillchar(d,sizeof(d),true);

d[1]:=false;

x[1]:=1;

best:=oo;

Trang 5

procedure output;

var f:text; i:longint;

begin

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

writeln(f,best);

for i:=1 to n do

write(f,bestway[i],'->');

write(f,bestway[1]);

close(f);

end;

BEGIN

input; init;

BranchBound(2);output;

END

Trang 6

BÀI TẬP PHƯƠNG PHÁP DUYỆT TỒN BỘ, NHÁNH CẬN

Bài 1 BÀI TỐN MÁY RÚT TIỀN TỰ ĐỘNG ATM:

Chương trình giải bài tóan ATM (tham khảo):

Program ATM_PP_NhanhCan;

Const MAX =20; fi ='ATM.INP';

fo ='ATM.OUT';

Type vector =array[1 MAX] of longint;

Var t, tmax :array[1 MAX] of longint;

x,xbest :vector;

c,cbest :longint;

n,s,sum :longint;

Procedure input;

var f :text;

i :longint;

begin

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

readln(f,n, s);

for i:=1 to n do read(f,t[i]);

close(f);

end;

Trang 7

Procedure init;

var i :longint;

begin

tmax[n]:=t[n];

for i:=n-1 downto 1 do begin

tmax[i]:=tmax[i+1];

if tmax[i]<t[i] then tmax[i]:=t[i];

end;

sum:=0; c:=0; cbest:=n+1;

end;

Procedure update;

var i :longint;

f :text;

begin

if (sum = s) and (c<cbest) then begin

xbest:=x; cbest:=c;

end;

end;

Procedure OUTPUT;

var i :longint;

f :text;

begin

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

if cbest<n+1 then begin

writeln(f,cbest);

for i:=1 to n do

if xbest[i]=1 then write(f,t[i],' ');

end

else write(f,'-1');

close(f);

end;

Procedure BranchBound(i:longint);

var j :longint;

begin

if c + (s-sum)/tmax[i] >= cbest then exit;

for j:=0 to 1 do begin

x[i]:=j;

sum:=sum + x[i]*t[i];

c:=c + j;

if (i=n) then update

else if sum<=s then branchBound(i+1);

sum:=sum - x[i]*t[i];

c:=c - j;

end; end;

BEGIN

Input;

Init;

BranchBound(1);

Output;

END

Trang 8

Bài 2: Trong một Hội chợ triển lãm có các gian hàng được bố trí trong một khung gồm NxN ô, mỗi ô

một gian hàng chứa các mặt hàng khác nhau Từ một gian hàng muốn đi qua gian hàng khác ta có thể

đi theo 4 hướng: lên, xuống, trái, phải Một người xuất phát từ ô [1,1] muốn đi xem tất cả các gian hàng, mỗi gian hàng không quá 1 lần và không bỏ gian hàng nào, sau đó ra cửa ở ô [n,1]

Yêu cầu tìm các đường đi mà người đó có thể thực hiện được

Input : số nguyên n (n<=10) Output: gồm nhiều dòng, mỗi dòng là 1 đường đi

Bài 3: Mã đi tuần: Cho bàn cờ có N x N ô Một quân Mã được phép đi theo luật cờ Vua, đầu tiên

được đặt ở ô có tọa độ (x,y) Lập chương trình tìm tất cả các đường đi của quân Mã sao cho mọi ô trên bàn cờ đều được quân Mã đi qua đúng 1 lần

Bài 4: Truyền tin

Người ta cần truyền n gói tin được đánh số từ 1 đến n từ một điểm phát đến một điểm thu Để thực hiện việc truyền tin có thể sử dụng m đường truyền được đánh số từ 1 đến m Biết rằng nếu truyền j gói tin theo đường truyền tin I thì chi phí phải trả là Sij (Sij là số nguyên dương, Sij≤32767, i=1,2,…,m, j=1,2,…,n)

Yêu cầu: Hãy xác định số lượng gói tin cần truyền theo mỗi đường truyền tin để việc truyền n gói tin được thực hiện với tổng chi phí là nhỏ nhất

Dữ liệu: vào từ file TTIN.INP:

+Dòng đầu tiên chứa hai số nguyên dương n va m (n,m<100)

+Dòng thứ i trong số m dòng tiếp theo chứa n số nguyên dương Si1, Si2,…,Sin, i=1,2,…,m

Kết quả: Đưa ra file TTIN.OUT:

+Dòng đầu tiên chứa S là tổng chi phí phải trả theo cách tuyền tin tìm được

+ Dòng thứ hai chứa m số nguyên không âm q1,q2,…,qm, trong đó qi là số gói tin cần truyền theo đường truyền tin i

Ví dụ:

Hướng dẫn:

Mỗi đường truyền i có thể truyền j gói tin (j=0,1,2,…,n-t, t là tổng các gói tin đã truyền trên i-1 đường truyền trước)

Do đó, mỗi một phương án truềyn tin là một chỉnh hợp lặp chặp m của n-t+1 phần tử {0,1,2,…,n-t} có dạng q=(q1,q2,…,qm)

Giá của phương án là

Bài 5: Thuê máy

Một trung tâm có n máy tính (cấu hình giống nhau) dùng để cho thuê trong tháng (từ ngày 1 đến ngày 31), thời gian thuê tính theo đơn vị ngày Đầu tháng, trung tâm nhận được yêu cầu của m khách hàng (đánh số từ 1 đến m), mỗi khách hàng cần thuê một máy trong một số ngày nào đấy thuộc tháng Giả thiết rằng, đối với mỗi khách hàng, hoặc trung tâm từ chối, hoặc trung tâm đồng ý cho thuê theo

đúng như yêu cầu của khách Với mỗi ngày, gọi tần số sử dụng máy là số máy tính được sử dụng trong

ngày đó Hãy lập một phương án cho thuê máy để tổng tần số sử dụng máy trong tháng là lớn nhất

* Dữ liệu: vào từ file THUEMAY.INP:

+Dòng đầu ghi các giá trị n,m

3 3

20 20 20

4 3 10

1 3 20

4

0 2 1

1

( ) m [ , ]i

i



Trang 9

+m dòng tiếp theo, theo thứ tự 1,2, ,m mỗi dòng ghi yêu cầu của một khách : bắt đầu là số ngày

mà khách cần thuê, tiếp theo là các ngày trong tháng mà khách cần thuê

* Kết quả: Đưa ra file TTIN.OUT:

+ Dòng đầu ghi số khách được thuê

+ Dòng tiếp theo ghi các số hiệu khách được thuê, các số hiệu này phân cách nhau ít nhất một dấu cách

+ Dòng cuối cùng ghi tổng tần số sử dụng máy

Hạn chế kích thước: số máy, số khách không quá 30

* Hướng dẫn:

- Mỗi phương án cho thuê máy tính là một dãy nhị phân độ

dài m, x=(x1,x2,…,xm) xi{0,1}

- Điều kiện chấp nhận x là

- Giá của phương án là :

Duyệt các dãy nhị phân độ dài m, kiểm tra các dãy là

phương án của bài toán, so sánh giá của các phương án với nhau để tìm phương án có giá lớn nhất

3 10

5 1 3 4 6 7

1 1

2 3 6

3 2 4 5

6 1 2 3 4 5 6

2 2 3

5 1 3 4 6 7

5 2 4 5 6 7

4 1 2 4 5

3 3 5 6

6

2 6 7 8 9 10 20

1 [ , ]* [ ] , 1, 31

m

i

ngay i j x i n j

1

( ) m [ ]* [ ]

i



Trang 10

Program HoiCho;

Const

max = 100;

fi='HOICHO.INP';

fo='HOICHO.OUT';

Hx : Array[1 4] of integer=(0,0,-1,1);

Hy : Array[1 4] of integer=(-1,1,0,0);

Var

Dd : Array[1 Max,1 max] of integer;

n, x, y, sn :integer;

f :text;

{+ + + + + ++ + + + + + + + + + + + + + + +}

Procedure input;

begin

Assign(f,fi);Reset(f);

Readln(f,n);

Fillchar(Dd,sizeof(Dd),0);

x:=1; y:=1;

DD[x,y]:=1;

close(f);

end;

{+ + + + + ++ + + + + + + + + + + + + + + +}

Procedure ghinghiem;

var i,j : longint;

begin

if dd[n,1]=n*n then begin

sn:=sn+1;writeln(f,'Nghiem thu :',sn);

for i:=1 to n do begin

for j := 1 to n do write(f,dd[i,j]:5);

writeln(f);

end;

end;

end;

{+ + + + + ++ + + + + + + + + + + + + + + +}

Procedure Tim(t:integer);

var i, u, v : longint;

begin

for i := 1 to 4 do begin

u := x + Hx[i]; v := y + Hy[i];

if ((u>=1) and (u<=n)) and ((v>=1) and (v<=n)) then

if (dd[u,v]=0) then

begin

dd[u,v] := t; x := u; y := v;

if t=n*n then ghinghiem

else

Tim(t+1);

x := u - Hx[i]; y := v - Hy[i];

dd[u,v]:=0;

end;

end;

Trang 11

end;

{+ + + + + ++ + + + + + + + + + + + + + + +}

BEGIN

input;

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

tim(2);

if sn=0 then writeln(f,'Bai toan vo nghiem')

else writeln(f,'Bai toan co ', sn,' nghiem');

close(f); END

HD Bài 3

Program Ma_di_tuan;

Const max = 20; fi='MADITUAN.INP';

fo='MADITUAN.OUT';

Hx :Array[1 8] of integer=(2,1,-1,-2,-2,-1,1,2);

Hy : Array[1 8] of integer=(1,2,2,1,-1,-2,-2,-1);

Var

DD : Array[1 Max,1 max] of integer;

n, x, y, sn :integer; s : Set of 1 Max;

f : text;

Procedure input;

var i:integer;

begin Assign(f,fi);Reset(f); Readln(f,n,x,y);

Fillchar(Dd,sizeof(Dd),0); DD[x,y]:=1;

s:=[]; for i:=1 to n do S:=S+[i];

close(f);

end;

{===============================}

Procedure ghinghiem;

var i,j : longint;

begin

sn:=sn+1;writeln(f,'Nghiem thu :',sn);

for i:=1 to n do begin

for j := 1 to n do write(f,dd[i,j]:5);

writeln(f); end;

end;

{===============================}

Procedure Tim(t:integer);

var i, u, v : longint;

begin

for i := 1 to 8 do begin

u := x + Hx[i]; v := y + Hy[i];

if (u In S) and (v In S) then

if (dd[u,v]=0) then

begin

dd[u,v] := t; x := u; y := v;

if t=n*n then ghinghiem

else

Trang 12

Tim(t+1);

x := u - Hx[i]; y := v - Hy[i];

dd[u,v]:=0;

end;

end;

end;

{===============================}

BEGIN

input;

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

tim(2);

if sn=0 then writeln(f,'Bai toan vo nghiem')

else writeln(f,'Bai toan co ', sn,' nghiem');

close(f);

END

Giải Bài 4: DI DAO

Const fi='DIDAO2.INP';fo='DIDAO2.OUT';

Type Dao=Record

x,y:integer;

end;

mangso=Array[1 100] of integer;

Var a:array[1 100] of Dao;

b,c:mangso;

DD:array[1 100] of Boolean;

i,j, DDmin,dem,d, dau,dich,n,sn:integer;

nhoi, m:real; Good:Boolean;

f,g:text;

Procedure input;

Var k:integer;

begin

readln(f,n);

For k:=1 to n do Read(f,a[k].x,a[k].y);

Readln(f); Readln(f,dau,dich);

Read(f,m);

Fillchar(b,sizeof(b),0);

Fillchar(c,sizeof(c),0);

Fillchar(DD,sizeof(DD),False);

DDMin:=maxint;

end;

Procedure Print(x:mangso;sl:integer);

var k:integer;

begin

sn:=sn+1;

for k:=1 to sl-1 do write(g,x[k],' -> ');

writeln(g,x[sl]);

end;

Function kc(i,j:integer):real;

begin

kc:=sqrt(sqr(a[i].x-a[j].x)+sqr(a[i].y-a[j].y));

Trang 13

Procedure thu(i:integer);

var j,k:integer;

begin

if d=dich then

begin

print(b,dem);

if (Sn=1) Or (dem<DDMin) then

begin

ddmin:=dem;

fillchar(c,sizeof(c),0);

for k:=1 to dem do c[k]:=b[k];

end;

end;

For j:=1 to n do

Begin

if (j<>i) and (Not DD[j]) then

begin

Good:=true;

for k:=1 to dem do

if (a[j].x=a[k].x) and (a[j].y=a[k].y) then Good:=false;

if Good and (kc(i,j)<=m) then

begin

dem:=dem+1;

b[dem]:=j;

DD[j]:=true;

d:=j;

thu(d);

b[dem]:=0;

dem:=dem-1;

DD[j]:=False;

end; end; end; end;

Procedure xuli;

begin

sn:=0; dem:=1; b[1]:=dau;

thu(dau);

if sn=0 then

writeln(g,'Khong co DD tu ', dau ,' den ',dich)

else {if (DDmin>0) and (ddmin<maxint) then}

begin

writeln(g,'Tong so duong di : ',sn);

writeln(g,'Duong di toi uu : ');

print(c,DDmin);

end

end;

Begin

openf;

input; nhoi:=maxint;

xuli;

closef;

Trang 14

Program TRUYENTIN;

const { t la tong goi tin da truyen tren i-1 duong truyen truoc}

Fi = 'TTIN.INP';

Fo = 'TTIN.OUT';

max = 100;

Type vector=array[1 max,0 max] of integer;

var

s: vector;

f: Text;

n,m: integer;

q,qc:array[1 max] of integer;

min, tongcp, sn:longint;

procedure Nhap;

var i,j:integer;

begin

Assign(f, Fi); Reset(f);

ReadLn(f, n,m);

for i:=1 to m do begin

for j:=1 to n do read(f,s[i,j]);

readln(f);

end;

Close(f);

for i:=1 to m do s[i,0]:=0;

end;

{ -}

Procedure chon_min;

var i:integer;

begin

if (tongcp<>0) and (sn=n) then

if tongcp<min then begin

min:=tongcp;

qc:=q;

end;

end;

{ -}

procedure Tim(i: Integer); { moi duong truyen i co the truyen j goi tin}

var j, t, k : Integer; { j=0,1,2, ,n-t, t la tong cac goi tin da truyen tren i-1 duong truyen truoc}

begin

t:=0;

for k:=1 to i-1 do

t:=t+q[k];

for j:=0 to n-t do begin

Ngày đăng: 13/01/2019, 10:28

TỪ KHÓA LIÊN QUAN

w