Bài toán quân cờ Domino

Một phần của tài liệu (LUẬN văn THẠC sĩ) cơ sở của thuật toán di truyền và ứng dụng đối với một số bài toán lớp NP (Trang 40 - 43)

2.4.2.1 Mô tả bài toán

Định nghĩa 1: Một quân bài Domino là một bộ (a,b) trong đó a là số hàng trên, b là số hàng dưới

a B

Định nghĩa 2: Phép lật quân được hiểu là một phép biến đổi bộ (a,b) thành bộ (b,a)

Bài toán:

Input: Cho n quân bài Domino (a1,b1),(a2,b2),...(an,bn) xếp thành một hàng ngang. Output: Hãy xác định các phép lật quân để sao cho độ chênh lệnh giữa tổng các số hàng trên so với tổng các số hàng dưới đạt giá trị nhỏ nhất.

a1 a2 .... an-1 An

b1 b2 bn-1 Bn

Phân tích

+ Kí hiệu một phương án lật quân là một bộ X=(x1,x2,…,xn) trong đó x(i)=1 tức là lật quân thứ i, x(i)=0 tức là không lật quân thứ i. Khi đó để tìm phương án lật quân tối ưu, chúng ta có thể sử dụng thuật toàn duyệt toàn bộ tất cả các phương án từ đó xác định phương án có độ chênh lệch nhỏ nhất. Kí hiệu hàm mục tiêu 1 ( ) x (b ) n i i i i f x a = = å -

Khi đó sử dụng thuật toán duyệt tất cả các dãy nhị phân độ dài n bằng thuật toán quay lui, ta mô tả thuật toán tìm lời giải chính xác của bài toán trên như sau:

using namespace std;

int X[N],A[N],B[N],n,fmin,Xluu[N]; void swap(int &a,int &b)

{ int tg;tg=a;a=b;b=tg;} void input()

{ int tren,duoi;

tren=0;duoi=0;

cout<<"Nhap so quan bai: ";cin>>n;

cout<<"Nhap gia tri hang duoi: ";printf("\n");

for (int i=1;i<=n;i++) {cin>>A[i];duoi=duoi+A[i];} cout<<"Nhap gia tri hang tren : ";printf("\n");

for (int i=1;i<=n;i++) { cin>>B[i];tren=tren+B[i];}

fmin=abs(tren-duoi); cout<<"Do chenh ban dau "<<fmin<<" "; }

void output()

tren=0;duoi=0;

for (int i=1;i<=n;i++) if (X[i]==1) swap(A[i],B[i]); for (int i=1;i<=n;i++) {tren=tren+B[i];duoi=duoi+A[i];} f=abs(tren-duoi);

if (f<fmin){fmin=f;for (int i=1;i<=n;i++) Xluu[i]=X[i];} }

void Try(int k) {int j;

for (j=0;j<=1;j++)

{ X[k]=j;if (k==n) output();else Try(k+1);} }

int main() { input();

Try(1);

cout<<"Phuong an lat quan toi uu: ";

for (int i=1;i<=n;i++) cout<<Xluu[i]<<" "; cout<<"do chenh be nhat= "<<fmin;

}

Hiển nhiên thuật toán trên có độ phức tạp O(2n).

+ Ta có thể sử dụng thuật toán quy hoạch động để giải bài toán trên như sau: Xây dựng mảng Wi là độ chênh lệch giữa phần trên và phần dưới của quân bài thứ i. Gọi C(i,j) là số các phép lật nhỏ nhất với các quân cờ từ 1 đến i, để hàng trên có tổng là j. Khi đó ta có công thức quy hoạch động:

C(i,j) = min {C(i-1, j-Tren(i)), C(i-1, Duoi(i))+1}.

Từ các C(i,j) ta dễ dàng tìm ra chênh lệch tối thiểu bằng thuật toán quy hoạch động xác định mảng C. Tuy nhiên thuật toán trên cần đòi hỏi số ô nhớ là rất lớn nếu số n là lớn

Có thể thấy rằng mô hình bài toán trên cũng là bài toán thuộc lớp NP.

+ Bài toán Domino có thể giải bằng thuật toán GA với cấu trúc gen là dãy nhị phân và toán tử lai ghép đa điểm hoặc lại ghép mặt nạ (Xem phụ lục)

Một phần của tài liệu (LUẬN văn THẠC sĩ) cơ sở của thuật toán di truyền và ứng dụng đối với một số bài toán lớp NP (Trang 40 - 43)

Tải bản đầy đủ (PDF)

(70 trang)