61
Giải thuật xác định tính khả thi của kế hoạch
Từ nhận xét 2-1 ở trên, ta suy ra để xác định tính khả thi của một kế hoạch, chúng ta sẽ dựa vào đồ thị mà tất cả các cạnh đều là các phụ thuộc khả thi hoàn toàn (ta gọi nó là đồ thị khả thi). Còn để xác định tính không khả thi, chúng ta cần dựa vào đồ thị có tất cả các cạnh đều là các phụ thuộc không khả thi (ta gọi nó là đồ thị không khả thi). Vì cả hai loại đồ thị này đều là đồ thị VÀ/HOẶC và quá trình xác định khả thi hay không khả thi là tương tự nhau, nên ở đây chúng ta chỉ trình bầy một giải thuật để xác định tính khả thi.
Đối với giải thuật này, đầu vào của nó là một kế hoạch P, đầu ra sẽ xác định xem P là
khả thi (FEASIBLE) hoặc chưa xác định (UNKNOWN). Chú ý trạng thái chưa xác định
không có nghĩa là không khả thi. Đây là trạng thái trung gian giữa khả thi và không khả thi. Nếu kế hoạch là chưa xác định, thì cần kiểm tra tiếp tính không khả thi của nó dựa vào đồ thị không khả thi. Đối với kiểm tra tính không khả thi, thì đầu ra cũng có hai trạng thái: không khả thi (INFEASIBLE) và chưa xác định.
Ý tưởng khái quát của giải thuật này, việc kiểm tra tính khả thi sẽ xuất phát từ nút hoạt động gốc, sau đó nó sẽ đi theo các cung là các phụ thuộc khả thi để tìm đường dẫn khả thi. Nếu như tồn tại ít nhất một đường dẫn khả thi thì kế hoạch sẽ khả thi. Còn trái lại thì kết luận là kế hoạch chưa xác định. Như vậy, giải thuật này sẽ sử dụng chiến lược duyệt theo chiều sâu (Depth First Search – DFS), là chiến lược tìm được tất cả các đường dẫn xuất phát từ một nút. Tuy nhiên, ở đây xuất hiện hai vấn đề đối với cách biểu diễn đồ thị VÀ/HOẶC hiện tại cho kế hoạch. Thứ nhất, đó là tính khả thi của một nút không chỉ phụ thuộc vào một nút kế tiếp mà có thể nhiều nút, nên trong quá trình kiểm tra, từ một nút ta cũng cần truy nhập vào nhiều nút kế tiếp. Do đó, chiến lược tìm kiếm sẽ kết hợp cả chiến lược duyệt theo chiều rộng (Breadth First Search – BFS). Thứ hai, đó là trong đồ thị này, mỗi cung nối từ nút A2 đến nút A1 là một cạnh có hướng (directed arc) biểu diễn một phụ thuộc khả thi A2
→ A1. Nhưng trong phép duyệt theo chiều sâu, thì thứ tự truy nhập lại từ nút gốc đến các nút khác, tức là từ nút A1 rồi mới đến A2. Để giải quyết vấn đề này, có một giải pháp đơn giản là trước khi thực hiện giải thuật, cần tạo ra đồ thị đảo của đồ thị ban đầu (đồ thị đảo G- của một đồ thị G là đồ thị giữ nguyên các nút, nhưng có các cạnh là đảo ngược so với G).
Giải thuật kiểm tra được cài đặt dưới dạng một hàm đệ quy bằng ngôn ngữ lập trình C++, gọi là CheckFeasible(), được trình bầy trong Giải thuật 2-1. Hàm này có sử dụng một số hàm phụ và các kiểu dữ liệu đã định nghĩa trước, với ý nghĩa như được trình bầy trong Bảng 2-2.
Chú thích: để tiện theo dõi các cặp ngoặc nhọn biểu diễn khối lệnh trong hàm, các ngoặc đóng và mở tương ứng sẽ được đánh cùng một chỉ số. Ví dụ “{1” là ngoặc mở của ngoặc đóng “}1”, “{2” là ngoặc mở của ngoặc đóng “}2”, v.v. Đối với danh sách các hoạt động con L, ta dùng ký hiệu L[i-1] để lấy hoạt động thứ i. Như vậy, hoạt động nằm ở đầu danh sách là L[0].
62
Giải thuật 2-1: Giải thuật xác định tính khả thi của kế hoạch.
Đầu vào:
Kế hoạch P(LA, F), trong đó LA là danh sách các hoạt động, F là tập các phụ thuộc khả thi.
Trong đó: LA = {A1, A2, …, An} ; A1 là hoạt động gốc. Vì kế hoạch được biểu diễn bằng đồ thị VÀ/HOẶC, từ nút gốc A1 có thể truy nhập được tất cả các nút khác, với các nhánh biểu diễn các phụ thuộc khả thi, nên trong thủ tục kiểm tra chỉ cần truyền vào nút gốc A1 là nó sẽ đại diện cho toàn bộ kế hoạch P.
Đảo ngược đồ thị biểu diễn P.
Đầu ra: Kết quả kiểm tra P là khả thi (FEASIBLE) hoặc chưa xác định
(UNKNOWN).
Xử lý:
1. STATE CheckFeasible(Activity A1) {0
2. if (GetState(A1) = FEASIBLE) return FEASIBLE; 3. else {1 4. ActivityList L = GetChildren(A1); 5. int m = Size(L); 6. switch (m) {2 7. case 0: //Danh sách rỗng 8. return UNKNOWN;
9. case 1: //Danh sách chỉ có một hoạt động
10. return CheckFeasible(L[0]); 11. default: {3
12. if (GetType(A1) = AND) {4 13. int i = 0;
14. while (i < m && CheckFeasible(L[i]) = FEASIBLE) i++; 15. if (i >= m) return FEASIBLE;
16. else return UNKNOWN; 17. }4 else {5 //A1 là nút OR
18. int i = 0;
19. while (i < m && CheckFeasible(L[i]) = UNKNOWN) i++; 20. if (i >= m) return UNKNOWN;
21. else return FEASIBLE; 22. }5
23. }3
24. }2
25. }1 26.}0
63
Bảng 2-2:Một số kiểu dữ liệu và hàm phụ cho giải thuật 2-1.
Tên hàm/dữ liệu Ý nghĩa Khai báo
STATE Dữ liệu kiểu liệt kê, biểu diễn các trạng thái của hoạt động, cũng là trạng thái của kế hoạch như FEASIBLE,
INFEASIBLE, UNKNOWN.
enum STATE {FEASIBLE, INFEASIBLE, UNKNOWN};
getState(Activity A) Hàm trả về trạng thái hiện tại của một hoạt động, được biểu diễn bằng một nút trong đồ thị.
STATE getState(Activity A);
ActivityList Kiểu dữ liệu biểu diễn danh sách các hoạt động.
GetChildren(Activity A) Hàm trả về các hoạt động con của của một hoạt động A. Đó là các hoạt động mà xác định khả thi A. Tức là, nếu A1→ A2, thì A1 là nút con của A2 trong đồ thị. ActivityList GetChildren(Activity A);
Size(ActivityList L) Hàm trả về số lượng các hoạt động của danh sách L
int Size(ActivityList L); GetType(Activity A) Hàm trả về kiểu của hoạt động
A, nó có thể là một trong hai loại, nút AND hoặc nút OR.
enum NODETYPE {AND, OR};
NODETYPE
GetType(Activity A);
Định lý 2-1: Giải thuật 2-1 là dừng và xác định đúng trạng thái của một kế hoạch có nút gốc là A1.
Chứng minh: Có hai vấn đề cần chứng minh: thứ nhất là giải thuật trên là dừng và thứ hai là nó đúng.
1. Chứng minh tính dừng: giải thuật 2-1 thực ra là giải thuật duyệt đồ thị theo chiều sâu, bắt đầu từ nút gốc A1, vì mục đích của giải thuật là tìm các đường dẫn khả thi trong đồ thị. Nên số nút mà giải thuật phải thăm nhiều nhất là n (là số lượng hoạt động trong kế hoạch). Do số lượng hoạt động trong một kế hoạch là hữu hạn, nên chắc chắn giải thuật này sẽ dừng.
2. Chứng minh tính đúng đắn: Để chứng minh tính chất này, ta sẽ chỉ ra giải thuật đã dự trù tất cả các khả năng của kế hoạch để xác định đúng trạng thái của nó. Kế hoạch khả thi khi nó chứa ít nhất một đường dẫn khả thi. Ở dòng lệnh 2, giải thuật kiểm tra nếu nút gốc A1 đã khả thi thì hiển nhiên kế hoạch đã khả thi và giải thuật sẽ dừng. Còn trái lại,
64
quá trình tìm đường dẫn khả thi sẽ tiếp tục với các nút con của A1, được đặt ở danh sách L (dòng lệnh 4). Ở đây lại có ba khả năng đối với L:
a. Nếu L rỗng: tức là A1 không có phụ thuộc khả thi vào hoạt động nào nữa, mà nó cũng đang ở trạng thái UNKNOWN, nên trạng thái của kế hoạch cũng phải là UNKNOWN.
b. Nếu L có đúng một hoạt động: thì rõ ràng tính khả thi của A1 sẽ phụ thuộc vào hoạt động con này, nên có lời gọi đệ quy để kiểm tra và trả về trạng thái của hoạt động con này (dòng lệnh 10).
c. Nếu L có từ hai hoạt động trở lên: lúc này lại tùy thuộc vào A1 là loại nút nào trong đồ thị VÀ/HOẶC. Có một trong hai khả năng:
i. Nếu A1 là nút AND: khi đó cần kiểm tra tất cả các nút con của nó trong L. Nếu tất cả chúng đều khả thi thì A1 khả thi (các dòng lệnh 13-15). Còn trái lại thì A1 chưa xác định (dòng lệnh 16).
ii. Nếu A1 là nút OR: khi đó cần kiểm tra tất cả các nút con của nó trong L. Nếu tất cả chúng đều chưa xác định thì A1 cũng chưa xác định (các dòng lệnh 18-20). Còn trái lại thì A1 khả thi (dòng lệnh 21).
Như vậy, giải thuật trên là dừng và đúng đắn.
2.2 Khung cộng tác đa dụng
2.2.1 Các yêu cầu đối với khung cộng tác đa dụng
Phần này sẽ trình bày về khái niệm của một khung cộng tác đa dụng có hỗ trợ kế hoạch và các yêu cầu của khung đó.
Định nghĩa 2-12. Khung cộng tác có hỗ trợ kế hoạch: là một hệ thống phần mềm hỗ trợ việc quản lý các kế hoạch, ít nhất là các thao tác sau đây:
- Định nghĩa các hoạt động: hệ thống cần phải hỗ trợ một hoặc một số ngôn ngữ thích hợp cho phép định nghĩa các hoạt động. Các ngôn ngữ luồng công việc như BPMN và BPEL rất thích hợp cho thao tác này (Phần mô tả các hoạt động sử dụng ngôn ngữ luồng công việc sẽ được trình bầy trong phần sau 2.2.2).
- Quản lý kế hoạch: như đã trình bầy ở phần Mô hình kế hoạch, mỗi kế hoạch được biểu diễn dưới dạng một đồ thị VÀ/HOẶC. Có thể sử dụng một trong các cách cài đặt đồ thị trong Lý thuyết đồ thị để cài đặt cho cho kế hoạch. Trong cài đặt đó, cần cài đặt các thao tác cho phép cập nhật kế hoạch, như thêm/bớt hoạt động, thêm/bớt các phụ thuộc khả thi; các phép tìm kiếm hoạt động và phụ thuộc khả thi.
- Làm mịn (Refinement): Là quá trình chuyển đổi tự động hay bán tự động kế hoạch từ mức này sang mức khác (Quá trình này sẽ được trình bày chi tiết hơn ở Chương 3).
- Thực thi (Execution): Cho phép thực thi kế hoạch nhờ các engine thực thi hay hạ tầng tính toán nào đó. Việc thực thi sẽ ra kết quả nào đó, và kế hoạch là thành công nếu kết quả thực thi là khớp với kết quả mong muốn. Trái lại kế hoạch là chưa thành công và kế hoạch cần được thay đổi lại cho phù hợp.
65
Tổng quan về khung cộng tác được minh họa ở Hình 2-23. Như có thể thấy, khung cộng tác có khả năng hỗ trợ nhiều người dùng cùng tham gia vào quá trình quản lý các kế hoạch, từ việc xây dựng kế hoạch, chuyển đổi nó sang các mức chi tiết hơn mà có thể thực thi được, rồi thực thi và giám sát kế hoạch.