Sử dụng ghép nối với các modul khác

Một phần của tài liệu tối ưu hoá hàm nhiều biến không có ràng buộc (Trang 55 - 58)

Dựa vào các thuật toán tối ưu đã trình bày ở các chương trước ta xây dựng được các modul tương ứng, các modul này chính là các thư viện có thể ghép nối với các modul khác để giải trọn vẹn một bài toán, mục III sau đây sẽ minh hoạ cụ thể cho điều này bằng hai ví dụ.

ở chương trước có 4 thuật toán tối ưu: Hook Jeeves, Powell, Rosenbrock, Nelder Mead. Từ đó xây dựng được 4 thư viện bằng C++ trong 4 tệp tin gốc (cho chi tiết trong Phụ lục): “HookJeeves.cpp”, “Powell.cpp”, “Rosenbrock.cpp”, “NelderMead.cpp” cùng 4 tệp tin đầu tương ứng “HookJeeves.h”, “Powell.h”, “Rosenbrock.h” và “NelderMead.h”. Các thủ tục tối ưu trong mỗi tệp tin đều trùng với tên của tệp tin đó, các tham số phải được khai báo rõ ràng. Tất cả các thủ tục đó đều được khai báo như sau:

void <Tên_phương_pháp>(double *&x, int n, double *h, int m, double *g, int p);

Trong đó:

n là số biến trạng thái (độ dài mảng x).

Mảng x có dùng tham chiếu là biến trạng thái của hàm mục tiêu. Trước khi có lời gọi thủ tục tối ưu thì mảng x phải được gán cho các giá trị khởi tạo ban đầu. Sau đó thì kết quả tối ưu sẽ được gán vào trong mảng x.

m là số các ràng buộc đẳng thức. p là số các ràng buộc bất đẳng thức.

h là mảng chứa các ràng buộc đẳng thức, g là mảng chứa các ràng buộc bất đẳng thức mà trong thủ tục tối ưu dùng đến, cả hai mảng này không cần gán giá trị khởi tạo.

Ví dụ trước khi gọi thủ tục Powell thì phải cho trước n, m, p, khai báo và cấp phát các mảng x, h, g và gán các giá trị đầu vào mảng x, sau đó gọi:

Powell(x, n, h, m, g, p);

Một yêu cầu nữa đối với người sử dụng các thư viện trên là cung cấp hàm mục tiêu do trong các thủ tục tối ưu đều gọi đến hàm này. Hàm tính hàm mục tiêu nằm trong tập tin gốc “objective_function.cpp” và được khai báo trong tập tin đầu “objective_function.h” được khai báo như sau:

double f(double *x, int n);

Trong đó x và n là hai biến được cho trong thủ tục tối ưu ở trên. Các tập tin khai báo hàm mục tiêu luôn đi kèm với các tập tin chứa các thủ tục tối ưu tương ứng, do đó người sử dụng chỉ việc mở tập tin gốc “objective_function.cpp” rồi sửa đổi hàm f(x,n) ở trên như mong muốn.

Sau khi thay đổi xong hàm mục tiêu thì nhập các ràng buộc vào thủ tục:

void constrains(double *x,int n,double *&h,int m,double *&g,int p) cũng được khai báo trong cùng tệp với hàm mục tiêu f(x,n).

Tên các tham số trong thủ tục trên trùng với các tham số trong lời gọi thủ tục tối ưu đã nói ở trên.

Ngoài ra cần đặc biệt chú ý là tên hàm mục tiêu (f(x,n)) và tên thủ rục các ràng buộc (constrains(…)) không được thay đổi vì trong các thủ tục tối ưu đều gọi tới chúng với tên cố định như trên.

Việc kết nối với các thư viện tính toán khác luôn được gọi đến trong hàm mục tiêu. Do đó trong phần đầu tập tin gốc “objective_function.cpp” người sử dụng phải thêm vào dòng lệnh:

#include “tên_tệp_tin_đầu”

trong đó tên_tệp_tin_đầu là tên của thư viện chứa các hàm tính toán được gọi trong hàm mục tiêu. Các hàm này phải được gọi sao cho phù hợp với các tham số của hàm mục tiêu mà các modul tối ưu sẽ gọi đến.

Trong mỗi tệp tin mà có gọi đến các thủ tục tối ưu thì đầu tệp phải có lời gọi:

#include “tên_tệp_tin_đầu”

Trong đó tên tệp tin đầu là tập tin chứa thủ tục tối ưu mà người sử dụng sẽ gọi.

Chú ý ở đây có thể sử dụng bất kì ngôn ngữ nào để xây dựng các thư viện và việc sử dụng các thư viện đó tuân theo quy tắc của ngôn ngữ lập trình tương ứng.

Như vậy với một chương trình tính toán hoàn chỉnh có sử dụng các modul tối ưu thì người dùng phải thực hiện các công việc sau:

- Xây dựng chương trình chính bao gồm khai báo các thư viện tối ưu sẽ gọi tới và khai báo đầy đủ các tham số đã nói tới ở trên. - Ghép nối các thư viện tính toán khác với thư viện các modul tối

ưu. Cách ghép nối tuỳ theo quy tắc của từng ngôn ngữ mà mình dùng.

- Thay đổi hàm mục tiêu f(x,n) và các ràng buộc như đã nói ở trên tuỳ theo yêu cầu của từng bài toán cụ thể.

Một phần của tài liệu tối ưu hoá hàm nhiều biến không có ràng buộc (Trang 55 - 58)