192892436 case-study

17
I. Get Homework/Assignment Done II. Homeworkping.com III. IV. Homework Help V. https://www.homeworkping.com/ VI. VII. Research Paper help VIII. https://www.homeworkping.com/ IX. X. Online Tutoring XI. https://www.homeworkping.com/ XII. XIII. click here for freelancing tutoring sites 1

Upload: homeworkping2

Post on 17-Feb-2017

191 views

Category:

Education


2 download

TRANSCRIPT

Page 1: 192892436 case-study

I. Get Homework/Assignment Done II. Homeworkping.com

III.IV. Homework Help V. https://www.homeworkping.com/

VI.VII. Research Paper help

VIII. https://www.homeworkping.com/ IX.

X. Online Tutoring XI. https://www.homeworkping.com/

XII.XIII. click here for freelancing tutoring sites XIV. Bài tập 1. Bài toán cái túi.

Một nhà thám hiểm cần đem theo một cái túi trọng lượng không quá B. Có N đồ vật cần đem theo. Đồ vật thứ i có trọng lượng ai, có giá trị sử dụng ci (i=1, 2, .., N; ai, ciZ+). Hãy tìm cách đưa đồ vật vào túi cho nhà thám hiểm sao cho tổng giá trị sử dụng các đồ vật trong túi là lớn nhất

Tập phương án của bài toán: Mỗi phương án của bài toán là một xâu nhị phân có độ dài N. Trong đó, xi =1 tương ứng với đồ vật i được đưa vào túi, xi =0 tương ứng với đồ vật i không được đưa vào túi. Tập các xâu nhị phân X =(x1,..,xN) còn phải thỏa mãn điều kiện tổng trọng lượng không vượt quá B. Nói cách khác, tập phương án D của bài toán được xác định như công thức dưới đây.

Hàm mục tiêu của bài toán: Ứng với mỗi phương án X =(x1,..,xN)D, ta cần tìm phương án X* =(x*1,..,x*N ) sao cho tổng giá trị sử dụng các đồ vật trong túi là lớn nhất. Do vậy, hàm mục tiêu của bài toán được xác định như sau:

a) Thuật toán sinh

void Next_Bit_String(void) {

int i = n;

while(i > 0 && X[i]) {

X[i] = 0;

1

Page 2: 192892436 case-study

i--;

}

if (i > 0) X[i] = 1;

else OK = 0;

}

int Test(void) {

int i, s = 0, p = 0;

for(i = 1; i <= n; i++) {

s = s + A[i]*X[i];

p = p + C[i]*X[i];

}

if (s <= B) return(p);

return(0);

}

void Update_Test(void) {

int p = Test(), i;

if (p > FOPT) {

FOPT = p;

for (i = 1; i <= n; i++)

{ XOPT[i] = X[i];}

}

}

b) Thuật toán quay lui

void update(){

int i;

if(cost>fopt) {

fopt=cost;

for(i=1; i<=n; i++) xopt[i]=x[i];

}

}

void Try(int i){

2

Page 3: 192892436 case-study

int j,t;

t=(int) ((w-weight)/a[i]);

for(j=t; j>=0; j--){

x[i]=j;

weight=weight+a[i]*x[i];

cost=cost+c[i]*x[i];

if (i==n) update();

else Try(i+1);

weight=weight-a[i]*x[i];

cost=cost-c[i]*x[i];

}

}

c) Thuật toán nhánh cận

void update(){

int i;

if(cost>fopt) {

fopt=cost;

for(i=1; i<=n; i++) xopt[i]=x[i];

}

}

void nhanhcan(int i){

int j,t;

t=(int) ((w-weight)/a[i]);

for(j=t; j>=0; j--){

x[i]=j;

weight=weight+a[i]*x[i];

cost=cost+c[i]*x[i];

if (i==n) update();

else if (cost+c[i+1]*(w-weight)/a[i+1]>fopt) nhanhcan(i+1);

weight=weight-a[i]*x[i];

cost=cost-c[i]*x[i];

3

Page 4: 192892436 case-study

}

}

XV. Bài tập 2. Bài toán người du lịch.

Một người du lịch muốn đi tham quan N thành phố T1, T2,..,TN. Xuất phát tại một thành phố nào đó, người du lịch muốn qua tất cả các thành phố còn lại mỗi thành phố đúng một lần rồi trở lại thành phố ban đầu. Biết cij là chi phí đi lại từ thành phố Ti đến thành phố Tj. Hãy tìm một hành trình cho người đi du lịch có tổng chi phí là nhỏ nhất.

Tập phương án của bài toán: Không hạn chế tính tổng quát của bài toán, ta cố định xuất phát là thành phố T1= 1. Khi đó, mỗi hành trình của người du lịch T1T2..TNT1 được xem như một hoán vị của 2,.., N là X =(x1, x2,..,xN), trong đó x1 =1. Như vậy, tập phương án D của bài toán là tập các hoán vị X = (x 1, x2,..,xN) với x1=1.

Hàm mục tiêu của bài toán: Ứng với mỗi phương án X =(x1,..,xN)D, chi phí đi lại từ thành phố thứ i đến thành phố j là C[X[i]][X[i+1] (i=1, 2,.., N-1). Sau đó ta quay lại thành phố ban đầu với chi phí là C[X[N]][X[1]]. Như vậy, hàm mục tiêu của bài toán được xác định như sau:

a) Thuật toán sinh

void Next_Permutation(void) {

int j = N - 1, k, t, r, S;

while(j > 0 && X[j] > X[j + 1]) j--;

if (j > 0) { k = N;

while(X[j] > X[k]) k--;

t = X[j]; X[j] = X[k]; X[k] = t;

r = j + 1, S = N;

while(r <= S) {

t = X[r]; X[r] = X[S]; X[S] = t;

r++;S--;

}

}

else OK = 0;

4

Page 5: 192892436 case-study

}

void Test(void) {

int i, S = 0;

if (xp == X[1]) {

for (i = 1; i <= N; i++) S = S + T[X[i]][X[i + 1]];

S = S + T[X[N]][xp];

if (S < Min) {

Min = S;

for (i = 1; i <= N; i++)

MinX[i] = X[i];

}

}

}

b) Thuật toán quay lui

void ghi_nhan(){

int sum;

sum=can+c[x[n]][x[1]]; // hanh trinh phai quay ve dinh xuat phat

if (sum<fopt)

{

fopt=sum;

for (int j=1;j<=n;j++) xopt[j]=x[j];

}

} // end of ghi_nhan

void thu(int i){ // xac dinh thanh pho thu i trong hanh trinh cua nguoi du lich

for (int j=1;j<=n;j++)

if (chua_xet[j])

{

x[i]=j;

if(c[x[i-1]][x[i]]>0){

5

Page 6: 192892436 case-study

chua_xet[j]=0;

can += c[x[i-1]][x[i]];

if (i==n) ghi_nhan();

else thu(i+1);

// tra lai trang thai cu

chua_xet[j]=1;

can -= c[x[i-1]][x[i]];

}

} // end of for

} // end of thu

void init() {

fopt=INT_MAX;

for (int j=1;j<=n;j++) chua_xet[j]=1;

can=0;

x[1]=1; // co dinh dinh xuat phat la 4

chua_xet[x[1]]=0;

}

c) Thuật toán nhánh cận

void ghi_nhan(){

int sum;

sum = can+c[x[n]][x[1]]; // hanh trinh phai quay ve dinh xuat phat

if (sum < fopt)

{

fopt=sum;

for (int j=1;j<=n;j++) xopt[j]=x[j];

}

} // end of ghi_nhan

void thu(int i){ // xac dinh thanh pho thu i trong hanh trinh cua nguoi du lich

6

Page 7: 192892436 case-study

for (int j=1;j<=n;j++)

if (chua_xet[j])

{

x[i]=j;

if(c[x[i-1]][x[i]]>0){

chua_xet[j]=0;

can += c[x[i-1]][x[i]];

if (i==n) ghi_nhan();

else

if ((can+(n-i+1)*cmin) < fopt ) thu(i+1);

// tra lai trang thai cu

chua_xet[j]=1;

can -= c[x[i-1]][x[i]];

}

} // end of for

}

XVI. Bài tập 3. Bài toán cho thuê máy.

Một ông củ có một chiếc máy cho thuê.Đầu tháng ông nhận được yêu cầu của M khách hàng thuê máy cho N ngày kế tiếp.Mỗi khách hàng i cho biết tập N i ngày họ cần thuê máy. Ông chỉ có quyền hoặc từ chối yêu cầu của khách hàng, hoặc nếu chấp nhận yêu cầu của khách ông phải bố trí máy theo đúng những ngày mà khách yêu cầu. Hãy tìm phương án thuê máy giúp ông chủ sao cho tổng số ngày thuê máy là nhiều nhất.

Tập phương án của bài toán: Gọi I = { 1, 2, .., M} là tập chỉ số khách hàng, S là tập của tất các tập con của I. Khi đó, tập các phương án cho thuê máy là:

Hàm mục tiêu: Ứng với mỗi phương ánJD, tổng số ngày cho thuê máy là:

a) Thuật toán sinh

void Next_Bit_String(){

7

Page 8: 192892436 case-study

int i=m;

while(i>0&&x[i])

{

x[i]=0;

i--;

}

if(i>0) x[i]=1;

else OK=0;

}

void XuLy(){

int S=0,d=0;

int cot[100];

for(int j=1;j<=n;j++) cot[j]=0;

for(int i=1; i<=m; i++)

{

if(x[i])

for(int j=1;j<=n;j++)

{

if(cot[j]&&a[i][j]) d++;

if(a[i][j]) cot[j] = 1;

}

}

for(int j=1;j<=n;j++)

if(cot[j]) S++;

if(S>MAX && d==0){

MAX=S;

for(int i=1;i<=m;i++) xopt[i]=x[i];

}

cout<<endl;

for(int i=1; i<=m; i++) cout<<x[i]<<" ";

}

8

Page 9: 192892436 case-study

XVII. Bài tập 4. Bài toán phân công công việc.Một hệ gồm có N quá trình thực hiện N việc song hành.Biết mỗi quá trình đều có

thể thực hiện được N việc kể trên nhưng với chi phí thời gian khác nhau. Biết cij là thời gian quá trình i thực hiện việc j. Hãy tìm phương án giao việc cho mỗi quá trình sao cho tổng thời gian thực hiện N việc kể trên là ít nhất.

Tập phương án của bài toán: Gọi X =(x1,x2,..,xN) là một hoán vị của 1, 2,..,N. Nếu xi = j thì ta xem quá trình thứ i được thực hiện việc j. Như vậy, tập phương án của bài toán chính là tập các hoán vị của 1, 2, .., N.

Hàm mục tiêu của bài toán: Ứng với mỗi phương ánXD, thời gian thực hiện của mỗi phương án là:

a) Thuật toán sinh

void Generation()

{

int j, k, r, s, temp;

j=n-1;

while(j>0 && X[j]>X[j+1]) j--;

if (j==0) OK=0;

else

{

k=n;

while (X[j]>X[k]) k--;

temp = X[j]; X[j] = X[k]; X[k] = temp;

r = j+1; s=n;

while(r<s)

{

temp = X[r]; X[r] = X[s]; X[s] = temp;

r++; s--;

}

}

}

void Test()

9

Page 10: 192892436 case-study

{

int T=0;

for(int i=1; i<=n; i++)

T=T+A[i][X[i]];

if (T<min) //Ghi nhan ket qua tam thoi tai moi buoc sinh

{

min=T;

for(int i=1;i<=n; i++)

{

cot[i]=X[i];

GT[i]=A[i][X[i]];

}

}

}

b) Thuật toán quay lui

void Test(){

int T=0;

for(int i=1; i<=n; i++)

T=T+A[i][X[i]];

printf("\nVong lap-------T=%d ------ min=%d\n",T,min);

if (T<min) //Ghi nhan ket qua tam thoi tai moi buoc sinh

{

min=T;

for(int i=1;i<=n; i++)

{

cot[i]=X[i];

GT[i]=A[i][X[i]];

}

}

}

void Back_Track(int i){

10

Page 11: 192892436 case-study

for(int j=1; j<=n; j++)

{

if(chuaxet[j]){

X[i]=j; chuaxet[j]=0;

if(i==n) Test();

else Back_Track(i+1);

chuaxet[j]=1;

}

}

}

c) Thuật toán nhánh cận

void ghi_nhan(){

if (TGian < fopt){

fopt=TGian;

for (int j=1;j<=n;j++) xopt[j]=x[j];

}

}

void Nhanhcan(int i){

for (int j=1;j<=n;j++){

if (chuaxet[j]){

x[i]=j;

chuaxet[j]=0;

TGian += c[i][x[i]];

if (i==n) ghi_nhan();

else if ((TGian+(n-i+1)*cmin) < fopt )

Nhanhcan(i+1);

// tra lai trang thai cu

chuaxet[j]=1;

TGian -= c[i][x[i]];

}

} // end of for

11

Page 12: 192892436 case-study

}

XVIII. Sử dụng tài liệu trên Internet, hãy cho biết những kết quả nghiên cứu tiếp theo của các bài toán trên và ứng dụng của nó?

1. Kết quả nghiên cứu a) Nhánh cận: - Bài toán tối ưu, bài toán yêu cầu tìm ra một phương án tốt nhất thỏa mãn một số

yêu cầu ràng buộc nào đó. - Nghiệm của bài toán đạt giá trị max/min trong không gian nghiệm. - Thuộc lĩnh vực Tối ưu toán học hoặc Quy hoạch toán học. Lời giải toán có thể

khó => Sự vào cuộc của Tin học.- Hai hướng tiếp cận tìm lời giải tối ưu cho bài toán:

Tìm từng lời giải, khi hoàn tất một lời giải thì so sánh của nó với chi phí tốt nhất hiện có. Nếu tốt hơn thì cập nhật chi phí tốt nhất mới.

Với mỗi lời giải, khi xây dựng các thành phần nghiệm luôn kiểm tra điều kiện nếu đi tiếp theo hướng này thì có khả năng nhận được lời giải tốt hơn lời giải hiện có không? Nếu không thì thôi không đi theo hướng này nữa. => Nguyên lí nhánh cận (Branch and Bound)

b) Quay lui: - Các bài toán thỏa mãn ràng buộc là các bài toán có một lời giải đầy đủ, trong đó

thứ tự của các phần tử không quan trọng. Các bài toán này bao gồm một tập các biến mà mỗi biến cần được gán một giá trị tùy theo các ràng buộc cụ thể của bài toán. Việc quay lui là để thử tất cả các tổ hợp để tìm được một lời giải. Thế mạnh của phương pháp này là nhiều cài đặt tránh được việc phải thử nhiều tổ hợp chưa hoàn chỉnh, và nhờ đó giảm thời gian chạy.

- Phương pháp quay lui có quan hệ chặt chẽ với tìm kiếm tổ hợpc) Sinh: - Thuật toán sinh kế tiếp dùng để giải quyết các bái toán thỏa mãn các điều kiện: - Xác định được trật tự các nghiệm.Biết được nghiệm đầu và nghiệm cuối cùng. - Xây dựng được thuật toán tử một nghiệm (cấu hình) chưa phải là nghiệm cuối

cùng ta đều sinh ra một cấu hình đứng sau nó.(Next generation).2. Ý tưởng: a) Nhánh cận: - Nhánh cận (Branch and Bound): Thuật toán tìm lời giải cho các bài toán tối ưu

dạng liệt kê cấu hình dựa trên nguyên lí đánh giá nhánh cận. - Nguyên lí đánh giá nhánh cận: Sử dụng các thông tin đã tìm được trong lời giải

của bài toán để loại bỏ sớm phương án không dẫn tới lời giải tối ưu.- Bản chất:

Sử dụng phương pháp quay lui nhưng tại mỗi bước đưa thêm thao tác đánh giá giá trị phương án hiện có.

12

Page 13: 192892436 case-study

Nếu đó là phương án tối ưu hoặc có hy vọng trở thành phương án tối ưu (tức là tốt hơn phương án hiện có) thì cập nhật lại phương án tối ưu hoặc đi tiếp theo hướng đó.

Trong trường hợp ngược lại thì bỏ qua hướng đang xét. b) Quay lui: - Về bản chất, tư tưởng của phương pháp là thử từng khả năng cho đến khi tìm

thấy lời giải đúng. Đó là một quá trình tìm kiếm theo độ sâu trong một tập hợp các lời giải. Trong quá trình tìm kiếm, nếu ta gặp một hướng lựa chọn không thỏa mãn, ta quay lui về điểm lựa chọn nơi có các hướng khác và thử hướng lựa chọn tiếp theo. Khi đã thử hết các lựa chọn xuất phát từ điểm lựa chọn đó, ta quay lại điểm lựa chọn trước đó và thử hướng lựa chọn tiếp theo tại đó. Quá trình tìm kiếm thất bại khi không còn điểm lựa chọn nào nữa.

- Quy trình đó thường được cài đặt bằng một hàm đệ quy mà trong đó mỗi thể hiện của hàm lấy thêm một biến và lần lượt gán tất cả các giá trị có thể cho biến đó, với mỗi lần gán trị lại gọi chuỗi đệ quy tiếp theo để thử các biến tiếp theo. Chiến lược quay lui tương tự với tìm kiếm theo độ sâu nhưng sử dụng ít không gian bộ nhớ hơn, nó chỉ lưu giữ trạng thái của một lời giải hiện tại và cập nhật nó.

- Để tăng tốc quá trình tìm kiếm, khi một giá trị được chọn, trước khi thực hiện lời gọi đệ quy, thuật toán thường xóa bỏ giá trị đó khỏi miền xác định của các biến có mâu thuẫn chưa được gán (kiểm tra tiến - forward checking) và kiểm tra tất cả các hằng số để tìm các giá trị khác đã bị loại trừ bởi giá trị vừa được gán (lan truyền ràng buộc - constraint propagation).

3. Ứng dụnga) Nhánh cận:- Xếp balo(Knapsack problem)- Quy hoạch nguyên (Integer programming)- Quy hoạch phi tuyến (Nonlinear programming).- Người bán hàng (Traveling salesman problem - TSP)- Quadratic assignment problem (QAP)- Bài toán thỏa được cực đại (Maximum satisfiability problem – MAX – SAT).- Tìm kiếm láng giềng gần nhất (Nearest neighbor search - NNS).- Cutting stock problem.- False noise analysis (FNA).b) Quay lui:- Xếp hậu - Sinh dãy số nhị phân, k phân có độ dài n - Sinh hoán vị của n phần tử - Sinh tổ hợp chập k của n phần tử - Biểu thức Zero - Phân tích số c) Sinh:

13

Page 14: 192892436 case-study

- Sinh dãy số nhị phân, k phân có độ dài n - Sinh hoán vị của n phần tử - Sinh tổ hợp chập k của n phần tử

14