Nhánh và cận

Một phần của tài liệu Giải thuật di truyền giải bài toán phủ đỉnh nhỏ nhất (Trang 44 - 50)

Mô hình nhánh và cận là một trong các công cụ chính để xây dựng các thuật toán hiệu quả giải các bài toán NP – khó. Thuật toán nhánh và cận thực hiện tìm kiếm toàn bộ không gian lời giải của bài toán để tìm ra lời giải tốt nhất. Tuy nhiên, thuật toán này không liệt kê tất cả các lời giải vì không gian lời giải có thể tăng lên đến hàm mũ. Thay vào đó, người ta sử dụng các cận cho hàm cần tối ưu kết hợp với giá trị lời giải tốt nhất hiện tại để cho phép thuật toán chỉ khảo sát một phần không gian lời giải.

Thuật toán nhánh cận này có thể áp dụng cho dạng (P2) của bài toán phủ đỉnh. Về cơ bản ý tưởng của thuật toán này là xây dựng một cây đầy đủ các hình trạng của các lời giải. Trong hình trạng của cây, một nút sẽ mô tả trạng thái hiện tại của tất cả các đỉnh trong đồ thị. Thuật toán thực hiện khảo sát toàn bộ không gian hình trạng đầy đủ và tại mỗi bước đệ quy quyết định xem một nút có thuộc phủ đỉnh hay không và thực hiện giải đệ quy bài toán cho các đỉnh còn lại. Cây không gian hình trạng là cây đầy đủ, trong đó mỗi nút có hai nhánh có thể; một nhánh tương ứng với việc lựa chọn nút vào phủ và nhánh kia tương ứng với việc loại bỏ nút ra khỏi phủ. Vì mục đích là tìm một phủ đỉnh có kích thước lớn nhất bằng k. Do đó, thuật toán thực hiện duyệt đệ quy cây hình trạng và quay lui nếu đã sử dụng hết k đỉnh mà vẫn chưa tìm được phủ hoặc gặp điều kiện cận. Thuật toán kết thúc khi tìm được một phủ đỉnh thỏa mãn hoặc đã duyệt hết tất cả các hình trạng có thể. Như vậy, có thể dễ dàng thấy trong tình huống tồi nhất, độ phức tạp của thuật toán nhánh và cận có cận trên là số nút trong cây đệ quy và xấp xỉ bằng 2n, tức là độ phức tạp là của thuật toán là O(2n).

Ban đầu, tất cả các đỉnh được đánh dấu là tự do. Thuật toán thực hiện đánh dấu một đỉnh tự do nào đó là được phủ nếu nó có một đỉnh kề là tự do hoặc chưa được phủ.

Nếu số đỉnh được phủ vẫn nhỏ hơn k thì thuật toán tiếp tục duyệt cây, ngược lại sẽ thực hiện quay lui. Nếu thuật toán trả về một nút bằng cách quay lui thì đỉnh là không được

phủ và những nhánh khác của hình trạng được xử lý. Nếu tất cả đỉnh kề với đỉnh đang xét là được phủ thì đỉnh đó được đánh dấu là không được phủ. Thuật toán sử dụng biên

để “chặt” hình trạng cây: “không đánh dấu một đỉnh là không được phủ nếu nó có đỉnh kề nào đó là không được phủ”.

Thuật toán có thể tóm tắt lại như sau: Mỗi đỉnh có ba trạng thái: tự do (free), được phủ (covered) và không được phủ (uncovered). Thuật toán bắt đầu từ các đỉnh tự do.

Nhánh:

1. Phủ một đỉnh tự do nào đó nếu tồn tại một đỉnh kề của nó ở trạng thái tự do

hoặc không được phủ.

2. Quay lui nếu vượt quá số đỉnh k. 3. Ngược lại không phủ đỉnh tự do đó.

Cận:

Không đánh dấu một đỉnh là không được phủ nếu như tồn tại một đỉnh kề nào đó của nó là không được phủ.

Cận áp dụng trong thuật toán dưới đây sử dụng bậc hiện tại d(i) là số đỉnh kề không

được phủ tại một thời điểm tính toán nào đó của đỉnh i đang xét. Khi một đỉnh i được

phủ thì số cạnh chưa được phủ của đồ thị sẽ giảm đi đúng bằng d(i). Nếu có nhiều đỉnh

v1, v2, ..., vk được phủ thì số cạnh không được phủ có thể giảm nhiều nhất là d(v1) +

d(v2) + ...+d(vk). Giả sử, tại một bước nào đó trong cây quay lui, có uncov cạnh chưa được phủ và vẫn còn k đỉnh để phủ.

Khi đó biên dưới M cho số cạnh nhỏ nhất chưa được phủ trong cây con được cho bởi công thức:

1 2

1 2 , ,...,

max[0, cov max ( ( ) ( ) ... ( ))]

k

k

v v v

Mund vd v  d v

Thuật toán sẽ không rẽ nhánh vào cây con nếu M thực sự lớn hơn số cạnh chưa được phủ opt trong lời giải tốt nhất hiện tại. Thứ tự các đỉnh được lựa chọn là được hay

không được phủ trong thuật toán phụ thuộc vào bậc hiện tại của chúng.

Dưới đây là tóm tắt của thuật toán liệt kê tất cả các hình trạng để đưa ra số cạnh chưa được phủ nhỏ nhất. Gọi G( , )V E là một đồ thị có |V| = n, k là số đỉnh để phủ,

unco là số cạnh cần phủ. Khởi tạo, k = nunco = |E|. Biến opt khởi tạo bằng|E| chứa số cạnh nhỏ nhất chưa được phủ trong lời giải tốt nhất hiện thời. Giá trị của opt được truyền thông qua lời gọi bằng tham chiếu. Ban đầu, tất cả các đỉnh i thuộc V đều đánh dấu là free.

algorithmmin-cover (G, k, uncov, opt) (adsbygoogle = window.adsbygoogle || []).push({});

begin

if k = 0 then {chạm tới lá cây}

begin

if uncov < optthen {tìm thấy giá trị nhỏ nhất mới}

begin

opt := uncov;

xóa tập các hình trạng được lưu trữ;

end

lưu hình trạng;

end;

if điều_kiện_cận_đúng then return;

gọi i V là một đỉnh được đánh dấu là free có bậc hiện tại lớn nhất; đánh dấu icovered; {đưa đỉnh i vào tập phủ đỉnh}

k := k – 1;

hiệu chỉnh bậc của tất cả các đỉnh kề j của i: d(j) := d(j) – 1;

min-cover(G, k, uncovd(i), opt)

{rẽ nhánh sang cây con bên “trái”, tương ứng với i được đưa vào phủ đỉnh} đánh dấu iuncovered;

k := k +1;

hiệu chỉnh (lại) bậc của các đỉnh kề j của i : d(j) := d(j) +1;

{rẽ nhánh sang cây con phải, tương ứng với i không được đưa vào phủ đỉnh} đánh dấu ifree;

end

Trong các cài đặt thực tế, thuật toán không đi xuống sâu trong cây khi không còn cạnh chưa được phủ. Trong trường hợp này, các phủ đỉnh của cây con tương ứng bao gồm các đỉnh đã được phủ và tất cả các cách chọn k đỉnh trong số các đỉnh chưa được phủ. Ngoài ra, thuật toán này cũng có thể dùng phương pháp chọn đỉnh ngẫu nhiên để thực hiện thay vì việc chọn đỉnh dựa vào bậc của đỉnh. Điều này có thể làm cho thuật toán chạy tốt hơn nhờ có đặc tính của thuật toán xác suất.

Dưới đây là một số kết quả thực nghiệm khi áp dụng thuật toán chính xác để giải bài toán phủ đỉnh được thực hiện bởi Alexander K Hartmann and Martin Weigt[1].

Với N là số đỉnh của đồ thị G ban đầu, số δ= 2*|E|/N là số kết nối trung bình của các đỉnh trong đồ thị (một cạnh được tính là hai kết nối). Gọi X là số đỉnh dùng để phủ đồ thị G. Đặt x=X/N , như vậy x là tỉ lệ số đỉnh dùng để phủ các cạnh đồ thị. Với một giá trị x nhỏ tức là chúng ta dùng một số lượng nhỏ các đỉnh để phủ thì rất khó có thể phủ hết các cạnh của đồ thị G với X=xN đỉnh. Sau đây là một số kết quả thực nghiệm đạt được nhờ áp dụng các thuật toán trên. Pcov(x) là xác suất có thể phủ được với với

Hình 3.1. Kết quả thực nghiệm giải chính xác bài toán phủ đỉnh

Với N =100 thì A.K.Hartmann và M.Weigt thử với 1000 bộ dữ liệu và N = 25 và 50 thì thử với 104 bộ dữ liệu.

Các bộ dữ liệu được sinh ngẫu nhiên căn cứ vào N và δ. Đồ thị là kết quả khi chạy với δ =2 nhưng với δ lớn hơn thì kết quả cũng gần như thế. Trong đồ thị chúng ta thấy

Pcov(x) tăng khi x tăng. Khi kích thước đồ thị tăng thì đường cong cũng trở nên dốc hơn. Điều đó chứng tỏ rằng khi N   thì ngưỡng nét hơn x = xδ 0.39 xuất hiện và đồ thì có khả năng phủ xấp xỉ 1 với số đỉnh phủ xN.

Với x < xδ thì xác suất phủ được sẽ nhỏ và khả năng phủ được gần như là không thể.Ta gọi xδ là giá trị chuyển trạng thái. Ở đây xδ là một hàm phụ thuộc vào δ.Vấn đề xác định hàm này ta sẽ không trình bày ở đây.

Thời gian chạy trung bình của thuật toán nhánh cận là một hàm đối với x. Thời gian chạy được tính dựa vào số nút được thăm trong cây quay lui. Xét trường hợp δ = 2, khi x < xc thì thời gian chạy tăng lên hàm mũ, như trong hình dưới đây.

Hình 3.2. Thời gian của thuật toán nhánh cận (adsbygoogle = window.adsbygoogle || []).push({});

Nhìn biểu đồ này chúng ta dẽ thấy thời gian chạy của thuật toán là gần tuyến tính khi giá trị của x lớn hơn đáng kể so với giá trị tới hạn xδ. Và tăng rất nhanh khi x <

xδ và tiến gần đến xδ. Với các giá trị x nhỏ trong miền không phủ được, thời gian chạy nhanh hơn nhiều so với khi x gần tới xδ nhưng vẫn là hàm mũ. Nếu bài toán chỉ yêu cầu trả lời câu hỏi “có tồn tại hay không một phủ đỉnh” thì thuật toán có thể được cải tiến sao cho với các giá trị x nhỏ có thể thu được lời giải trong thời gian đa thức.

Một phần của tài liệu Giải thuật di truyền giải bài toán phủ đỉnh nhỏ nhất (Trang 44 - 50)