Tải bản đầy đủ (.docx) (3 trang)

Nguyên lý vét cạn thông minh, tham lam và thứ tự

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (101.34 KB, 3 trang )

Chủ đề 2 - Nguyên lý vét cạn thông minh, tham lam và thứ tự
5 bài đăng của 3 tác giả


phương pháp Tham lam:
- Xác định cấu trúc con tối ưu.
- Xây dựng giải pháp đệ quy.
- Chứng minh: tại mỗi bước đệ qui, lựa chọn Tham lam là một trong những lựa chọn cho kết quả tối
ưu.
- Chỉ ra: sau lỗi lựa chọn Tham lam, một trong những bài toán con sẽ rỗng.
- Xây dựng giải pháp đệ quy cho chiến lược Tham lam.
- Khử đệ quy.

Hoặc có thể tổng quát như sau:
- Tìm lựa chọn sao cho các bước tiếp theo chỉ việc giải quyết một bài toán con.
- Chứng minh: Với sự lựa chọn Tham lam tại mỗi bước → luôn tìm được 1 giải pháp tối ưu (cho bài toán
ban đầu).
- Chỉ ra: Với sự lựa chọn Tham lam tại mỗi bước → giải pháp tối ưu của bài toán con còn lại kết hợp với
sự lựa chọn Tham lam này sẽ đi đến một giải pháp tối ưu (cho bài toán ban đầu).
Ví dụ: Bài toán Cây khung nhỏ nhất. (Sử dụng lý thuyết Matroid do Hasser Whitney đưa ra năm 1935)
Gọi matroid M
G
với hàm trọng số w’: w’(e) = w
0
- w(e).
Trong đó w
0
= max{w(e)} + 1
- 1 tập con A cực đại ↔ 1 cây khung của đồ thị.
- w’(A) = (|V|-1).w
0


- w(A).w(A) là độ dài của cây khung.
- Cực đại hóa w’(A) ⇔ cực tiểu hóa w(A).
- Tìm tập con tối ưu A ⇔ tìm cây khung nhỏ nhất.
*Xem đầy đủ tại *
Trọng Cả
Nguyên Lí Vét Cạn
Vét cạn là một trong những thuật toán giải bài toán tối ưu. Thuật toán
vét cạn là thuật toán tìm phương án tối ưu của bài toán bằng cách lựa
chọn một phương án trong tập hợp tất cả các phương án của bài toán để
tìm ra phương án tối ưu. Trong nhiều bài toán, không gian các phương
án quá lớn. Do vậy, khi áp dụng thuật toán vét cạn không đảm bảo về
thời gian cũng như kĩ thuật. Vấn đề đặt ra là phải cải tiến thuật toán
vét cạn như thế nào để giải quyết các yếu điểm đó. ở đây tôi giới
thiệu với các bạn phương pháp đánh giá nhánh cận. Đây là phương pháp
có thể hạn chế số phương án phải duyệt của bài toán. Trong quá trình
duyệt ta luôn giữ lại 1 phương án là phương án mẫu, phương án mẫu là
phương án có giá nhỏ nhất tại thời điểm đó. Phương pháp đánh giá nhánh
cận là phương pháp tính giá của phương án ngay trong quá trình xây
dựng các thành phần của phương án, có nghĩa là ta sẽ tính xem việc xây
dựng phương án theo hướng đó có thể có thể tốt hơn phương án mẫu hay
không. Nếu không tốt hơn ta lựa chọn hướng khác. Bằng cách này ta đã
hạn chế được nhiều phương án mà chắc rằng trong đó không chứa phương
án tối ưu. Một yêu cầu đặt ra là tính toán đặt nhánh cận như thế nào,
để có thể hạn chế tối đa các phương án phải duyệt.
Bài toán áp dụng (Bài toán người du lịch):
Cho một mạng lưới gồm n thành phố. Một người muốn đi du lịch khắp các
thành phố, mỗi thành phố đi qua đúng một lần và sau đó quay về thành
phố xuất phát. Giả sử biết chi phí đi lại giữa các thành phố
(a[i,j]>0). Hãy lập trình tìm phương án với tổng chi phí ít nhất.
Phương án của bài toán là x[1], x[2] x[n], x[1]. Trong đó x[1] là

đỉnh xuất phát, x[ i] là đỉnh thứ i trong hành trình của người du
lịch. Lúc đó tổng chi phí S được tính như sau:
S = a[x[1],x[2]]+ a[x[2],x[3]]+ + a[x[n-1],x[n]]+ a[x[n],x[1]].
Trong quá trình xây dựng các thành phần của phương án ta tiến hành đặt
nhánh cận như sau:
Xây dựng thành phần thứ i của phương án (x) ta có tổng chi phí S của
i-1 thành phần đã được xây dựng. Thành phần thứ i của phương án phải
thoả mãn biểu thức sau:
S + a[x[i-1], x]+(n-i)*Amin +X1min < Min.
Trong đó: + Amin là chí phí nhỏ nhất trong bảng chi phí a[i,j].
+ X1min là chi phí nhỏ nhất từ x[1] đến các thành phố còn lại.
+ Min là chi phí của phương án mẫu.
Chương trình.
Các biến trong chương trình:
a:array[1 100,1 100] of integer; chứa bảng chi phí.
x,y:array[1 100]of 1 100 ; chứa phương án trong quá trình duyệt
chuaxet:array[1 100]of boolean;chứa trạng thái các thành phố.
Nếu thành phố i đã nằm trong phương án đang duyệt->chuaxet=false.
ngược lại chuaxet=true.
Ban đầu các giá trị của chuaxet được khởi tạo =true.
Procedure Choice(S,i:integer);
Var j,k:integer;
Begin
for j:= 1 to n do
if (chuaxet[j]) then
begin
k:=S+ a[x[i-1],j];
if (k + (n-i)*Amin +X1min) < Min then
begin
chuaxet[j]:=false;

x:=j;
S:=S+ a[x[i-1],j];
if i = n then
begin
if S + a[x[n],x[1]]<Min then
begin
y:=x;
Min:=S+a[x[n],x[1]]
end;
end
else Choice(S,i+1);
chuaxet[j]:=true;
end;
end;
end;
Việc đặt nhánh cận như ví dụ trên tuy chưa thực sự tốt nhất, song nó
cũng mô phỏng cho chúng ta cách đặt nhánh cận là như thế nào. Việc nắm
bắt giải thuật là một chuyện, nhưng vấn đề làm sao ứng dụng giải thuật
vào các vấn đề cụ thể lại là chuyện khác. Với phương pháp "đánh giá
nhánh cận" ta phải tính toán sao cho việc đặt nhánh cận là tốt nhất,
để có thể cắt được càng nhiều trường hợp không phải xét càng tốt.

×