Phương pháp tìm trực tiếp (không qua giai đọan tính gradient)

Một phần của tài liệu Tự động hóa tính toán, thiết kế và đóng tàu (Trang 152 - 157)

TÍNH NỔI VÀ TÍNH ỔN ĐỊNH TÀU

Chương 5 QUI HOẠCH TUYẾN TÍNH VÀ QUI HOẠCH PHI TUYẾN

5.2 QUI HOẠCH PHI TUYẾN

5.2.5. Phương pháp tìm trực tiếp (không qua giai đọan tính gradient)

Ý tưởng phương pháp hết sức đơn giản, cố gắng bằng mọi cách thử nghiệm tìm điểm xk, tại đó thỏa mãn điều kiện || xk+1 - xk || < ε. Bước tiến hành đầu tiên của phương pháp là chọn vector d1, d2,..., dn, cùng điểm xuất phát x1, và hãy đặt y1 = x1, k = j = 1, sau đó bắt tay vào tính lặp.

Gia đoạn tính lặp ∗:

∗ Phương pháp tính dùng cho phần này đề nghị tìm trong các tài liệu sau:

(1) Giả sử λj là hằng số Lagrange thỏa mãn lời giải tối ưu f(yj+ λdj). Tìm tiếp giá trị yj+1 = yj + λjdj . Nếu j < n hãy thay j thành j + 1 và quay lại bước đầu. Nếu j = n hãy tiến đến bước (2).

(2) Đặt xk+1 = yn+1. Nếu || xk+1 - xk || < ε dừng các phép tính. Trường hợp ngược lại, hãy đặt y1 = xk+1, j=1, thay k thành k+1 và quay về bước (1).

Những phương pháp chính trong phần này gồm:

- Phương pháp Hooke-Jeeves,

- Phương pháp Neldel-Mead, hay còn gọi phương pháp Simplex công bố trong “A Simplex Method for Function Minimisation”, Comp. Jour.,1965.

- Phương pháp của Rosenbrock,

- Phương pháp của Box hay còn gọi phương pháp Complex.

Trong các thủ tục tính nêu trên, khi xử lý những bài toán trong miền hạn chế chúng ta thường gặp khái niệm hằng số Lagrange và khái niệm lồi, lõm hàm đa biến. Trong tài liệu này sẽ không trình bày cách xác định λj cũng như điều kiện Kuhn-Tucker. Về hàm Lagrange và điều kiện của Kuhn-Tucker liên quan miền lồi hàm đa biến được tìm thấy trong các tài liệu chuyên ngành sau:

“ A new derivation of the Kuhn-Tucker conditions”, Operations Research, 12, 1964.

H.W. Kuhn and A.W. Tucker, “Non linear Programming”, hội thảo khoa học tại trường đại học Berkeley, 1951.

Phương pháp Hooke-Jeeves,

Phương pháp này được giới thiệu lần đầu năm 1961, còn giá trị đến ngày nay. Quá trình tìm gồm nhiều bước, quanh quẩn điểm cơ bản. Thủ tục tiến hành như sau:

(a) Chọn điểm cơ bản b1 và bước hj cho mỗibiến xj, j =1,2,3,..., n.

(b) Tính f(x) tại điểm cơ bản b1 và xác định hướng tìm kiếm.

1. Tính f(b1),

2. Tính f(b1 +h1e1 ). Nếu động tác này làm cho hàm f() nhỏ hơn, thay b1 bằng b1 +h1e1. Ngược lại, thực hiện phép tính theo f(b1 - h1e1), và nếu giá trị của f() nhỏ hơn sẽ thay b1 thành b1 - h1e1. nếu các động tác trên không mang lại hiệu quả làm nhỏ hơn hàm f(), điểm chuẩn b1 sẽ được giữ nguyên giá trị ban đầu và chuyển hướng sang tìm trên trục x2. Thay vì bước tính f(b1 +h1e1 ) như đã làm ở trên, lần này tính f(b1 + h2e2 ). Cần thiết khảo sát cho tất cả n biến, nếu công việc đòi hỏi, sau đó sẽ chuyển qua điểm cơ bản mới b2.

3. Nếu b2 = b1, có nghĩa là không làm cho f() giảm, phải làm lại từ đầu, cũng quanh quẩn điểm cơ bản ban đầu b1 song bước phải nhỏ hơn. Kinh nghiệm tính cho thấy, nên giảm bước chừng 10 lần.

4. Trường hợp b2 b1, tiến hành các bước nêu dưới đây quanh điểm cơ bản sau.

(c) Sử dụng đầy đủ thông tin thu nhận từ phần trên để tiến hành công việc theo hướng tốt nhất. Thủ tục làm như sau:

M.J. Box, D.Davies and W.H. Swann, “Non-linear Optimisation Techniques”, 1969.

H.H. Rosenbrock, “An Automatic Method for Fiding the Greatest or Least Value of a Function”, Comp. Jour., 3, 1960.

1. Theo hướng b2 - b1 để tiếp tục công việc. Tính giá trị hàm f() tại điểm P1 = b1 + 2(b2 - b1). Trường hợp tổng quát tính theo:

Trường hợp tổng quát tính theo: Pi = bi + 2(bi+1 - bi).

2. Khảo sát hàm chung quanh điểm P1 (Pi).

3. Thực hiện các động tác nêu trên cho điểm cơ bản b3 nếu cần.

(d) Thực hiện các động tác trên cho đến khi bước trở thành quá nhỏ, đạt giới hạn cho phép, nếu cần.

Chương trình tính sau đây được soạn để tìm điểm cực tiểu hàm Rosenbroke, theo phương pháp Simplex của Neldr-Mead:

#include <stdio.h>

/* example for opt. */

#include <stdlib.h>

#include <math.h>

#define sqr(X) (X) * (X) #define IMAX 20

int k,m,N;

double xb[IMAX], xh[IMAX], xl[IMAX], stp[IMAX];

double fb;

double funceval( double xb[] ) {

return 100.0*sqr( xb[1] - xb[0]*xb[0] ) + sqr(1.0 - xb[0]) ; }

void DirectSearch( int N, double *xb, double fb, double *xh, double *xl, double *stp, int flag, int ifns, int conv )

/* Direct Search procedure in C Coded in Ho Chi Minh City 1992

by Dr. Tran Cong Nghi */

{

register int i, j ;

int fns, iexp, minfal, rvs[IMAX];

double stor, temp, pat, fbp, fp;

double a, b, tol, tol1;

double bp[IMAX];

for (i=0; i < IMAX; i++) { rvs[i] =0;

bp[i] = 0.0;

} conv =0;

iexp = 0;

a = 1.20; b = 0.10; tol = 1.0e-06; tol1 = 1.0e-08;

for ( i = 0; i < N; i++){

if ( xb[i] > xh[i] ) xb[i] = xh[i];

if ( xb[i] < xh[i] ) xb[i] = xl[i];

if ( xh[i] == xl[i] ) stp[i] = 0.0;

bp[i] = xb[i];

} fns = 1;

fp = fbp = fb;

L2: minfal = 0;

if ( fns > ifns ) goto L21;

if ( flag > 0 ) {

printf ("fns = %d fbp = %20.5lf\n", fns,fbp);

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

printf("%20.5lf %20.5lf\n", bp[i], stp[i]);

}

/* start the exploratory loop */

for ( i = 0 ; i < N; i++) {

rvs[i] = 0;

if ( stp[i] == 0.0e+0 ) goto L10;

stor = xb[i];

xb[i] += stp[i];

if ( (xb[i] > xh[i]) || (xb[i] < xl[i]) ) goto L4;

++fns;

fb= funceval( xb );

if ( flag > 1 ) {

printf("i= %d fb = %20.5lf\n", i, fb);

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

printf("%d %25.6lf\n", j, xb[j] );

}

if ( fb >= fp - tol1 * fabs(fp) ) goto L4;

if ( iexp == 0 ) stp[i] *= a;

L3: fp = fb;

goto L11;

L4:

xb[i] = stor - stp[i];

if ( (xb[i] > xh[i]) || (xb[i] < xl[i]) ) goto L5;

++fns;

fb=funceval( xb );

if ( flag > 1) {

printf("i = %d fb = %20.5lf\n", i, fb);

for (j=0; j < N; j++) printf("%d %25.6lf\n",j, xb[j]);

}

if ( fb >= fp - tol1*fabs(fp) ) goto L5;

if (iexp == 0 ) stp[i] *= a;

rvs[i] =1; goto L3;

L5:

xb[i] = stor;

if ( iexp == 1) goto L10;

stp[i] *= b;

temp = fabs(xb[i]/stp[i])* tol;

if ( 1.0 < temp ) stp[i] *= temp;

else

if (1.0 == temp ) goto L7; else goto L9;

L7: temp = 1.0 - 10 / fabs(stp[i]);

if ( 1.0 >= temp ) goto L10;

L8: stp[i] *= temp; goto L10;

L9: temp = 1.0- 16 / fabs( stp[i]);

if ( 1.0 == temp ) goto L10;

else

if ( 1.0 < temp ) goto L8;

else goto L11;

L10: ++minfal;

L11: j = 0;

}

if ( (fbp-fp) <= (tol * fabs(fbp)) ) goto L14;

if ( flag > 2) printf("%d", fns);

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

if ( rvs[i] != 0 ) stp[i] = - stp[i];

fbp = fp;

for ( i =0; i < N; i++) {

pat = bp[i];

bp[i] = xb[i];

xb[i] = 2.0* bp[i] - pat;

xb[i] = ( xb[i] > xl[i] ) ? xb[i]: xl[i];

xb[i] = ( xb[i] < xh[i] ) ? xb[i]: xh[i];

} ++fns;

fb=funceval(xb);

if (flag > 2 ) {

printf("fp = %25.6lf\n", fp);

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

printf("% 25.6lf\n", xb[i]);

} iexp =1;

goto L2;

L14: if ( iexp ==1 ) goto L16;

if ( minfal >= N ) goto L18;

if (flag > 2 ) printf(" base point exploratory mode failure\n");

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

if ( rvs[i] != 0 ) stp[i] = - stp[i];

goto L2;

L16: iexp =0;

fp = fbp;

for (i =0; i < N; i++) xb[i] = bp[i];

if ( flag > 2 ) printf("pattern mode exp failure\n");

goto L2;

L18: if ( fp <= fbp ) goto L20;

fb = fbp;

for (i=0; i < N; i++) xb[i] = bp[i];

L20:

if ( flag > 0 ) {

printf("The optimum value found\nfp = %25.6lf\n",fp);

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

printf("xb[%d] = %25.6lf\n", xb[i] );

}

fb = fp;

if ( flag > 0 ) printf("fns = %d\n",fns);

goto L23;

L21: conv = 1;

if ( flag > 0 ) {

printf("number function estimates exceeded %d\n",fns);

printf("fbp = %25.6lf\n",fbp);

for (i=0; i < N; i++) printf("bp[%d] = %25.6lf\n",i, bp[i]);

}

fb = fbp;

for ( i=0; i < N; i++) xb[i] = bp[i];

L23: return;

main() {

int ii,infs,fb,flag,conv;

printf("Enter inputs: N, ifns, flag\n");

scanf("%d %d %d", &N, &infs, &flag);

printf(" estmates of xb\n");

scanf("%lf %lf %lf", &xb[0], &xb[1], &xb[2]);

printf("Enter xhi\n");

scanf("%lf %lf %lf", &xh[0], &xh[1], &xh[2]);

printf("Enter xli\n");

scanf("%lf %lf %lf", &xl[0], &xl[1], &xl[2]);

for (ii=0; ii < N; ii++)

stp[ii] = 0.24 * ( xh[ii] - xl[ii] );

DirectSearch(N, xb, fb, xh, xl, stp, flag, infs, conv);

printf("\n\tOutputs:\n");

printf("fb = %20.6lf\n", fb);

for (ii=0; ii < N; ii++) printf("xb[%d] = %20.6lf\n", ii, xb[ii]);

}

Chương trình tính viết bằng ngôn ngữ C dựa vào các giải thuật đã nêu được giới thiệu trong

“Thư viện toán tính” (TCN).

Một phần của tài liệu Tự động hóa tính toán, thiết kế và đóng tàu (Trang 152 - 157)

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

(296 trang)