Thuật toán xây dựng đồ thị trọng số G phục vụ kiểm chứng LDI

Một phần của tài liệu (LUẬN văn THẠC sĩ) phân tích, thiết kế và cài đặt kiểm chứng một hệ thời gian thực (Trang 30)

Chương 2 CÁC CÔNG CỤ ĐẶC TẢ

3.1. Các thuật toán

3.1.3. Thuật toán xây dựng đồ thị trọng số G phục vụ kiểm chứng LDI

Ý tưởng: Tư tưởng cơ bản trong xây dựng đồ thị trọng số G là “rời rạc hóa” đồ thị đạt được nguyên RG bằng cách xây dựng mỗi cung (vi,vj,[l,u]) sẽ được thay bằng một họ các đường đi nối vi, vj sao cho độ dài (trọng số) của các đường đi lần lượt là các số nguyên l, l+1, … , u. Tức cung (vi,vj,[l,u]) được cụ thể hóa thành u-l-1 đường đi nối vi, vj thể hiện tính rời rạc hóa được của LDI. Điều này được thực hiện trên giả thiết RG không chứa cung vô hạn.

Thuật toán xây dựng đồ thị trọng số G = (V,E,) từ RG = (V1,E1) (không chứa cung vô hạn) được thực hiện theo các bước sau:

Bước 1: V = V1, E = E1.

Bước 2: Đối với mỗi cung e = (vi,vj,[lij,uij]) tập đỉnh V, cung E và hàm trọng số

: V  E  R của G được mở rộng thành: 1. V = V  { 1, 2,..., uij1 ij ij ij v v v } và (vijk ) = cvi , với k = 0,1,2,…, uij-1 (với qui ước vij0 cho vi và uij

ij

v cho vj),

3. E = E  {(vijk,vijk1)|k=0..uij-1}, và (vijk,vijk1) = 1, k = 0..uij-1, 4. E = E  {(vijk,vj)|k = lij..uij-1}, và (vijk,vj) = 0, k = lij..uij-1. Chú ý: Trường hợp lij  uij đồ thị sẽ có 2 cung từ uij1

ij

v đến vj, một cung có trọng số 1 và cung còn lại có trọng số 0 (xem hình bên dưới). Để đảm bảo G là đồ thị đơn ta sẽ “chia đôi” cung có trọng số 0 thành 2 cung bằng cách thêm đỉnh uij

ij

v và cung này

được thay bằng 2 cung ( uij1

ij

v , uij

ij

v ) và ( uij

ij

v ,vj). Thuật toán này sẽ được cụ thể hóa trong phần cài đặt, xem cài đặt này trong phần Phụ lục A.

Hình sau đây minh họa cho việc xây dựng G từ một đồ thị RG đơn giản với 2 cung.

Hình 3.1: Xây dựng đồ thị G từ đồ thị vùng đạt được nguyên RG 3.1.4. Thuật toán kiểm chứng LDI 3.1.4. Thuật toán kiểm chứng LDI

Ý tưởng thuật toán: Thuật toán được xây dựng theo kỹ thuật vét cạn để duyệt mọi đường đi với mọi đỉnh xuất phát cố định của đồ thị trọng số đạt được G. Thuật toán

được xây dựng gồm 2 hàm, hàm thứ nhất là traverse(vstart) duyệt mọi đường đi xuất phát từ một đỉnh vstart cố định, và hàm thứ 2 là Checking-LDI sẽ gọi hàm traverse(vstart) với mọi đỉnh vstart V để quyết định tính thỏa của ôtômat A đối với LDI.

Hàm traverse(vstart) được xây dựng theo kỹ thuật quay lui như sau: đường đi p xuất phát từ đỉnh ban đầu vstart của G với l(p) = 0 và (p) = 0, đi dọc theo các cạnh tới các đỉnh mới cho đến khi l(p) ≥ A. Bắt đầu từ thời điểm l(p) ≥ A trở đi, tại mỗi đỉnh mới nếu l(p) > B thì thuật toán quay lui. Ngược lại (tức B ≥ l(p) ≥ A) nếu θ(p) > M thì thuật toán dừng và cho câu trả lời G |≠ LDI và nếu θ(p) ≤ M thì thuật toán đi tiếp đến các đỉnh khác. Thuật toán quay lui khi không còn đỉnh mới để đi tiếp thì dừng lại và cho câu trả lời G |= LDI.

Trường hợp B = ∞, để tránh vòng lặp vô hạn, thủ tục sẽ xử lý các chu trình gặp được từ lúc l(p) ≥ A trở đi như sau: Nếu chu trình dương thì thuật toán dừng và kết luận G |≠ LDI. Nếu chu trình âm hoặc bằng 0 thì việc đặt chu trình này vào đường đi là không cần thiết vì giá của đường đi vẫn không tăng, do vậy thuật toán quay lui.

Để cài đặt thuật toán sử dụng một ngăn xếp p để lưu lại đường đi. Mỗi phần tử

của p gồm 2 thành phần: tên đỉnh x và tập đỉnh Ax chưa thăm bởi x. Thủ tục succ(p) sẽ trả lại đỉnh y  Ax (với x là đỉnh cuối của p) và đồng thời loại y ra khỏi Ax. Như vậy x có thể xuất hiện nhiều lần trong p, tuy nhiên tại mỗi vị trí xuất hiện các tập đỉnh Ax là hoàn toàn độc lập với nhau và đều được tạo bởi Adj(x) là tập các đỉnh kề của x.

Các biến toàn thể được sử dụng trong thuật toán gồm: v, v’ để chỉ đỉnh cuối của p và đỉnh sẽ được bổ sung ở bước tiếp theo. Biến preach dùng để lưu lại vị trí tại đó đường đi p đạt đến độ dài A (các chu trình chỉ được xử lý nếu xuất hiện sau vị trí preach). Để điều khiển việc đánh dấu này thuật toán sử dụng biến preach như một biến lôgic nhận giá trị 1 nếu l(p) ≥ A và 0 nếu ngược lại. Hàm succ(p) tìm và trả lại đỉnh tiếp theo (đồng thời loại khỏi tập chưa thăm) hoặc trả lại giá trị NULL. Các hàm l(p), θ(p), l(C), θ(C) trả lại độ dài và giá của đường đi p và chu trình C. Thủ tục pop(p) loại phần tử cuối ra khỏi p và đồng thời tính toán lại các giá trị l(p), θ(p). Thủ tục push(x, Adj(x), p) thêm đỉnh x cùng tập Ax = Adj(x) vào cuối p và đồng thời tính toán lại các giá trị l(p), θ(p). Cuối cùng thuật toán trả lại giá trị TRUE nếu LDI được thoả bởi G và

FALSE trong trường hợp ngược lại. Sơ đồ của các thuật toán traverse(vstart) và Checking-LDI được cho trong các bảng 3.4 và 3.5.

{input : G =(V,E),D}

{output : TRUE nếu và chỉ nếu G(vstart) |= D} Function Traverse(vstart): Boolean;

Begin

p = ; push(vstart,Adj(vstart),p); while p ≠  do begin

if succ(p) == NULL then begin pop(p); loop;end; {quay lui} v’ = succ(p); push(v’, Adj(v’),p);

if l(p) < A then begin reach = 0; loop;end;

if reach == 0 then begin preach = v’; reach =1; end; if l(p) > B then begin pop(p); loop;end; {quay lui} if ((p) > M) then return FALSE; {A ≤ l(p) ≤ B }

if C (đoạn từ preach đến v’) và B =  then begin if (C) > 0 then return FALSE;

if (C) ≤ 0 then pop(p); {quay lui} end ;

end;

return TRUE; End;

Bảng 3.4: Thuật toán kiểm chứng LDI với đỉnh xuất phát cố định

{input: G =(V,E), D}

{output: G |= D hoặc G |≠ D} Function Chekcking-LDI: Boolean; Begin

for với mỗi đỉnh v V do begin

if Traverse(v) == FALSE then return G |≠ LDI; end;

return G |= LDI; End ;

Bảng 3.5: Thuật toán kiểm chứng LDI tổng quát

Nhận xét: Thuật toán kiểm chứng LDI Checking-LDI có độ phức tạp cao, độ phức tạp hàm mũ trong trường hợp xấu nhất vì phải duyệt qua tất cả các chu trình của đồ thị bằng phương pháp vét cạn quay lui.

3.2. Các chi tiết kỹ thuật

Luận văn thực hiện cài đặt công cụ phần mềm kiểm chứng trên nền web sử dụng ngôn ngữ lập trình PHP, một ngôn ngữ lập trình mã nguồn mở, rất mạnh, đặc biệt là hoàn toàn miễn phí để viết mã, với hi vọng phần mềm sẽ sử dụng được sức mạnh của các web server để giải quyết bài toán kiểm chứng công thức LDI có độ phức tạp hàm mũ hiệu quả hơn. Thông tin về môi trường cài đặt như sau:

– Ngôn ngữ lập trình: PHP-5.2.8 – Web server: Apache

– Ngoài ra còn sử dụng: Html, Javascript, Template engine smarty, v.v… Để phục vụ cho việc viết mã, luận văn cũng đã xây dựng một framework đơn giản theo mô hình MVC (Model - View - Controller), MVC là một trong những mô hình thiết kế được sử dụng rất phổ biến hiện nay trong kỹ thuật phần mềm.

Cấu trúc thư mục source code được thiết kế như hình sau:

Hình 3.2: Cấu trúc thư mục source code

3.3. Đầu vào và đầu ra của bộ kiểm thử

Đầu vào (Input) của bộ kiểm chứng là một hệ thời gian thực được đặc tả bằng một hệ các ôtômat thời gian ở dạng tổng quát A=<L, l0, , X, I, E>, tức là có tập đồng hồ X = {x1,x2,…,xn} và các ràng buộc có dạng := x  c | x  c | x  c | x  c | x – y  c | x – y  c | , ở đây x, y  X và c  N. Các thuộc tính (tính chất) mong muốn của hệ thống được đặc tả bằng công thức LDI. Các đặc tả này được lưu trong các file *.txt, các file *.txt này là đầu vào của bộ kiểm thử.

Đầu ra (Output) của bộ kiểm chứng gồm:

– Hiển thị lên màn hình các bước chính của quá trình kiểm chứng và hiển thị các đồ thị tương ứng với từng bước.

– Đưa ra câu trả lời “đúng” nếu hệ ôtômat thỏa công thức LDI hoặc “sai” nếu bộ kiểm chứng chỉ ra được 1 bộ dữ liệu hệ ôtômat không thỏa công thức LDI.

Mô tả một cách chi tiết hơn, bộ kiểm chứng sẽ hoạt động theo thứ tự các bước sau:

1) Bộ kiểm chứng sẽ đọc hệ ôtômat thời gian, các hệ số của công thức LDI từ file *.txt và chuyển đổi thành dữ liệu có cấu trúc lưu vào các biến trong chương trình.

2) Chương trình sẽ tự động nhận biết nếu hệ có nhiều hơn 1 ôtômat thì sẽ thực hiện tạo ra 1 ôtômat hợp song song của các ôtômat thành phần, còn nếu hệ chỉ có 1 ôtômat thì sẽ không làm gì mà giữ nguyên.

3) Chuyển ôtômat hoặc ôtômat hợp song song (trường hợp hệ thống có nhiều

hơn 1 ôtômat) thành đồ thị vùng đạt được nguyên dựa trên kĩ thuật ε- nguyên hóa được trình bày tại chương 4 trong Luận án Tiến sĩ Toán học của TS.

Phạm Hồng Thái.

4) Chuyển đồ thị vùng đạt được nguyên sang đồ thị trọng số phục vụ kiểm chứng LDI bằng kĩ thuật rời rạc hóa.

5) Duyệt đồ thị trọng số LDI, tính toán và đưa ra kết luận ôtômat thỏa công thức LDI hay không, tức là hệ thống được đặc tả có thỏa mãn các tính chất của hệ thống được đặc tả hay không. Trường hợp không thỏa thì phải chỉ ra được nơi xảy ra lỗi trong hệ thống.

6) Vẽ đồ họa và hiển thị lên màn hình các đồ thị ôtômat, đồ thị vùng đạt được nguyên và đồ thị trọng số LDI.

3.4. Cấu trúc dữ liệu

Sử dụng ngôn ngữ lập trình PHP để mô tả các cấu trúc dữ liệu lưu trữ các ôtômat, đồ thị vùng đạt được nguyên, đồ thị trọng số phục vụ kiểm chứng LDI và các cấu trúc dữ liệu khác để sử dụng trong chương trình.

3.4.1. File dữ liệu đầu vào

Dữ liệu đầu vào được cho dưới dạng ôtômat thời gian, các hệ số của vị trí của ôtômat và các hệ số A, B, M của công thức LDI được lưu trong 1 file *.txt. Chương trình sẽ đọc dữ liệu từ file *.txt và tính toán để được kết quả: ôtômat, ôtômat hợp song song đạt được, đồ thị vùng đạt được nguyên, đồ thị trọng số phục vụ LDI, kết quả kiểm chứng, thời gian chạy chương trình.

File dữ liệu đầu vào *.txt được thiết kế như sau:

(nếu giá trị nào đó là vô cùng thì thay bằng chữ U)

Dòng 1: {Hệ số A}_{Hệ số B}_{Hệ số M} // hệ số của công thức LDI

Dòng 2: {số đỉnh}_{tên vị trí ban đầu} // ôtômat 1

Dòng 3: {tên vị trí}#xi_low_up|xj_low_up|…#{hệ số ldi} // ôtômat 1

({tên vị trí}#{các ràng buộc}#{hệ số ldi}) //mỗi đỉnh 1 dòng

Dòng i: {số cạnh} // ôtômat 1

Dòng i+1: li#xi_xj_low_up|…#{nhãn}#xi_1|xj_1|…#lj // ôtômat 1

(phép chuyển e = < li, (low <= xi - xj <=up,…), {nhãn},{ xi, xj,…}, lj >)

….

(nếu có ôtômat 2,3,… thì lặp lại từ dòng 2 và lưu vào các dòng tiếp theo)

Ví dụ 3.1: Một hệ thống được đặc tả bằng ôtômat thời gian:

Hình 3.3: Ôtômat thời gian

Tính chất mong muốn được đặc tả bằng công thức LDI: 0  l s1 - s2  5 Khi đó file otomat1.txt có nội dung như sau:

0_U_5 2_s1 s1#x2_0_5#1 s2#x1_0_8|x2_0_10#-1 2 s1#x2_x0_3_U#a#x2_1#s2 s2#x1_x0_6_U|x2_x0_4_U#b#x1_1#s1

3.4.2. Ôtômat

Thiết kế cấu trúc dữ liệu để lưu trữ các thành phần của ôtômat thời gian A=<L, l0, , X, I, E> được lưu trong file *.txt, ta sẽ sử dụng cấu trúc mảng trong PHP để lưu các thành phần của ôtômat A như sau:

(kí hiệu xxx bên dưới thể hiện 1 giá trị nào đó của phần tử tương ứng)

$aryOtomat = array(

‘init’ => l0, //Vị trí ban đầu

‘numLocation’ => xxx, //số vị trí của ôtômat

‘numTransition’ => xxx, //số phép chuyển của ôtômat

‘clocks’ => array(x1,x2, …, xn), //là mảng chứa tập các đồng hồ X

‘aryLocation’ => array( //Mảng chứa vị trí và thông tin các vị trí của ôtômat ‘{tên vị trí}’ => array( //Mảng chứa thông tin của 1 vị trí

‘invar’ => array( //Mảng chứa các bất biến của vị trí ‘xi’ => array( // Ràng buôc đồng hồ xi: low <= xi <= up

‘low’ => xxx, //Cận dưới của đồng hồ xi

‘up’ => xxx, //Cận trên của đồng hồ xi

), … ), ‘c’ => xxx //Hệ số LDI ), … ),

‘aryTransition’ => array( //Mảng chứa các phép chuyển i => array( //Phép chuyển thứ i

‘loc_name_from’ => xxx, //Tên vị trí đầu(source) ‘loc_name_to’ => xxx, // Tên của vị trí cuối(target) ‘label’ => xxx, //Nhãn của phép chuyển

‘reset’ => array( //Tập các đồng hồ thiết lập lại bằng 0 (reset) ‘xi’ => 1, //Đồng hồ xi sẽ được gán lại giá trị 0

),

‘guard’ => array( //Mảng chưa các ràng buộc của phép chuyển ‘xi-xj’ => array( //Ràng buộc dạng: low <= xi-xj<= up

‘low’ => xxx, ‘up’ => xxx

),

‘xi’ => array( //Ràng buộc dạng: low <= xi<= up ‘low’ => xxx, ‘up’ => xxx ), … ), ), … ) ); 3.4.3. Công thức LDI

Các hệ số LDI ứng với từng vị trí của ôtômat được đưa vào cấu trúc vị trí của ôtômat (xem trong phần 3.3.2), còn các hệ số A, B, M của công thức LDI sẽ được đưa vào trong cấu trúc mảng sau:

$aryLdi = array( ‘A’ => xxx, //Hệ số A ‘B’ => xxx, //Hệ số B ‘M’ => xxx //Hệ số M ); 3.4.4. Đồ thị vùng đạt được nguyên

Đồ thị vùng được thể hiện là 1 mảng chứa các thông tin gồm: số đỉnh, số cạnh, 1 mảng chứa tập đỉnh, 1 mảng chứa tập cạnh.

$aryRegionGraph = array(

‘num_vertex’ => xxx, //số đỉnh

‘num_edge’ => xxx, //số cạnh

‘aryVertex’ => array( //Mảng chứa thông tin các đỉnh

i => array( //Đỉnh thứ i = ID đỉnh, i là số tự tăng, bắt đầu từ 1

‘vertex’ => xxx, //Tên đỉnh có dạng: {tên vị trí}_[region]

‘ldi_c’ => xxx, //Hệ số LDI

),

),

‘aryEdge’ => array( //mảng chứa thông tin các cạnh

i => array( //thông tin cạnh thứ i+1, chỉ số bắt đầu từ 0

‘id_form’ => xxx, //ID của đỉnh đầu(source)

‘id_to’ => xxx, //ID của đỉnh cuối (target)

‘duration_low’ => xxx, //Cận dưới thời gian

‘duration_up’ => xxx //Cận trên thời gian

), …

)

);

3.4.5. Đồ thị trọng số phục vụ kiểm chứng LDI

Về mặt cấu trúc thì mảng chứa đồ thị trọng số LDI và mảng chứa đồ thị vùng giống nhau, cụ thể cấu trúc mảng của đồ thị trọng số LDI như sau:

$aryWeighGraphLdi = array( ‘num_vertex’ => xxx, //số đỉnh ‘num_edge’ => xxx, //số cạnh

‘aryVertex’ => array( //Mảng chứa thông tin các đỉnh

i => array( //Đỉnh thứ i = ID đỉnh, i là số tự tăng, bắt đầu từ 1 ‘vertex’ => xxx, //Tên đỉnh

‘ldi_c’ => xxx, //Hệ số LDI ),

… ),

‘aryEdge’ => array(( //mảng chứa thông tin các cạnh i => array( //thông tin cạnh thứ i

‘id_form’ => xxx, //ID của đỉnh đầu(source) ‘id_to’ => xxx, //ID của đỉnh cuối (target) ‘w’ => xxx, //trọng số của cung (weigh)

), … )

);

3.4.6. Đường đi của đồ thị

Sử dụng ngăn xếp là 1 mảng để lưu vết đường đi phục vụ cho thuật toán (vét cạn) duyệt đồ thị trọng số LDI để kiểm chứng công thức LDI, ngăn xếp này lưu tên mỗi đỉnh và tập các đỉnh kề với nó khi thuật toán duyệt đi qua. Ngăn xếp này được thiết kế như sau:

$aryStackPath = array(

i => array( //thông tin đỉnh thứ i+1 trong đường đi

v => array(v1,v2,…,vk), //đỉnh v và các đỉnh kề với v

),

3.5. Thiết kế chương trình

Trong mục này sẽ trình bày một số biểu đồ thiết kế cơ bản chương trình của bộ kiểm thử.

3.5.1. Biểu đồ use case

Dựa trên các yêu cầu của bộ công cụ kiểm chứng được mô tả ở trên, ta xác định và đưa ra use case tổng quát của hệ thống với tác nhân (Actor) ở đây là người thiết kế hoặc người lập trình như sau:

Hình 3.4: Biểu đồ use case mức 1

Hình 3.5: Biểu đồ use case mức 2

Mô tả chi tiết use case:

chứng 1 mô hình đã chọn.

 Chọn mô hình kiểm chứng: Use case này cho phép người dùng xem và chọn 1 mô hình để thực hiện kiểm chứng trong danh sách các mô hình của bài toán đã chọn.

 Chọn bài toán kiểm chứng: Use case này cho phép người dùng chọn 1 bài toán để thực hiện kiểm chứng.

3.5.2. Biểu đồ lớp

Hình 3.6: Biểu đồ lớp

Xác định các lớp tham gia vào các use case:

STT Tên lớp Loại lớp

1. Chọn bài toán kiểm chứng

1.1 List Lớp biên

1.2 ListAction Lớp điều khiển

1.3 OtomatLogic, XmlLogic Lớp thực thể

2. Chọn mô hình kiểm chứng

2.1 searchModel Lớp biên

Một phần của tài liệu (LUẬN văn THẠC sĩ) phân tích, thiết kế và cài đặt kiểm chứng một hệ thời gian thực (Trang 30)

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

(71 trang)