Chiến lược tìm kiếm

Một phần của tài liệu Giải bài toán xếp lịch bảo vệ thạc sỹ bằng các kỹ thuật tối ưu dựa trên ràng buộc (Trang 29)

a. Chọn biến: Nguyên tắc first-fail là nguyên tắc thử những biến có khả năng sai nhiều nhất tức là biến đó không thỏa mãn các ràng buộc.

o Dom heuristic: chọn biến có miền giá trị nhỏ nhất

o Deg heuristic: chọn biến tham gia nhiều ràng buộc nhất

o Dom + Deg heuristic: kết hợp cả 2 phương án trên

Chương 3: Quy hoạch ràng buộc

b. Chọn giá trị

o Best first prociple: chọn những giá trị có khả năng đúng nhiều nhất tức là giá trị đó thỏa mãn mọi ràng buộc bài toán

o Possibilities:

 Thử những giá trị theo thứ tự tang dần  Thử những giá trị theo thứ tự giảm dần  Thử những giá trị nằm ở miền giá trị

c. Ví dụ: nguyên tắc first fail trong comet, tìm giá trị đầu tiên gần điểm giữa của miền giá trị.

function void searchFirstFail(Var<CP>{int}[] x) { Solver<CP> cp = x[x.getLow()].getSolver(); forall(i in x.getRange()) by (x[i].getSize()) {

int mid = (x[i].getMax() + x[i].getMin())/2;

tryall<cp> (v int x[i].getMin()..x[i].getMax(): x[i].memberOf(v)) by (abs(v - mid))

cp.post(x[i] == v); }

}

3.2 Thƣ viện Choco

Hiện nay có rất nhiều thư viện hỗ trợ giải bài toán quy hoạch ràng buộc như ], Choco [15], Gecode [16], MiniZinc [17],vv. Trong luận văn này, chúng tôi tập trung vào tìm hiểu một trong những thư viện này đó là Choco vì nó được phát triển bằng ngôn ngữ Java một ngôn ngữ lập trình rất phổ biến để phát triển các ứng dụng công nghiệp.

3.2.1 Giới thiệu về Choco

Choco là một thư viện viết bằng ngôn ngữ Java dung để giải quyết các bài toán thỏa mãn ràng buộc (CSP). Choco xây dựng các ràng buộc cho các biến trong bài toán thông quá các thuật toán được cài đặt và đưa ra các giá trị thỏa mãn yêu cầu hoặc không đưa ra lời giải nếu không có nghiệm thỏa mãn.

Trong thư viện Choco có các thành phần chính sau:

 Mô hình (model) là đối tượng trung tâm trong chương trình Choco, nó bao gồm các biến, các ràng buộc

 Biến (Variables): là cái chưa biết của bài toán cần giải quyết. Thư viện Choco hỗ trợ các biến kiểu: IntegerVariable, SetVariable, RealVariable. Các biến có thể giới hạn trong miền giá trị của biến đó

Chương 3: Quy hoạch ràng buộc

 Ràng buộc (Constrain): xác định mối quan hệ thỏa mãn giữa các biến và các hằng số

 Lời giải (Solver) dùng để thực hiện mô hình bài toán và đưa ra một hoặc tất cả các lời giải thỏa mãn.

3.2.2 Hoạt động của Choco

Model và Solver là một trong 2 thành phần chính của chương trình Choco.

 Model được khai báo như một đối tượng : Model m = new CPModel();

 Model = Variables + Expressions + Constraints

3.2.2.1 Variable

Choco hỗ trợ khai báo các loại biến: Biến nguyên (Integer Variable), biến số thực (Real Variable), biến tập hợp (Set Variable). Các biến được add vào trong mô hình thông qua phương thức addVariable của model:

Model.addVariable(var1) hoặc Model.addVariables(var2, var3);

a. Các biến đơn giản:

Choco đã xây dựng sẵn các kiểu biến đơn giản như biến số nguyên, biến số thực và biến tập hợp.

 Biến số nguyên: IntegerVariable n;

 Biến số thực: RealVariable r;

 Biến tập hợp: SetVariable s; b. Biến hằng số:

Biến hằng số là một biến có giá trị không đổi trong suốt bài toán. Mộtbiến được khai báo với một giá trị duy nhất cũng có thể coi là biến hằng số.

Ví dụ:

IntegerConstantVariable intConst = Choco.constant(10); RealConstantVariable realConst = Choco.constant(10.0);

SetConstantVariable setConst = Choco.constant(new int[]{1,2}); SetConstantVariable emptySetConst = Choco.emptySet();

c. Biến biểu thức:

Biến biểu thức là biến xác định các phép toán giữa 2 biến. Biến biểu thức bao gồm biến biểu thức nguyên (IntegerExpressVariable) và biến biểu thức số thực (RealExpressVariable).

Chương 3: Quy hoạch ràng buộc

Ví dụ:

IntegerVariable v1 = Choco.makeIntVar("v1", 1,3); IntegerVariable v2 = Choco.makeIntVar("v2", 1,3);

IntegerExpressionVariable v1PlusV2 = Choco.plus(v1, v2);

Để xây dựng biểu thức giữa các biến, Choco hỗ trợ các toán tử đơn giản như abs, div, ifThenElse, max, min, minus, etc.

d. Biến mục tiêu :

Biến mục tiêu là các biến xác định mục tiêu của nó trong ràng buộc bài toán. Trong Choco có thể xác định một biến là biến mục tiêu thông qua option V_OBJECTIVE của biến đó trong hàm khởi tạo

Vi dụ: Đoạn chương trình sau tìm giá trị nhỏ nhất của hàm x = y * 20 với 20 ≤ y ≤ 50

IntegerVariable x = Choco.makeIntVar("x", 1, 1000, Options.V_OBJECTIVE);

IntegerVariable y = Choco.makeIntVar("y", 20, 50); CPModel m = new CPModel();

m.addConstraint(Choco.eq(x, Choco.mult(y, 20))); CPSolver s = new CPSolver();

s.read(m);

s.minimize(true);

3.2.2.2 Ràng buộc

Choco cung cấp một lượng lớn các ràng buộc đơn giản và các ràng buộc chung giúp cho người dung có thể định nghĩa các ràng buộc riêng cho từng bài toán. Ràng buộc có thể có một hay nhiều biến của bài toán và quy định điều kiện chứa biến đó. Ví dụ:

Constraint c = Choco.neq(intVar1, intVar2); m.addConstraint(c);

m.addConstraint(Choco.neq(intVar1, intVar2));

a. Ràng buộc nhị phân:

Các loại ràng buộc giữa 2 biến. ví dụ như eq, neq, gt, leq, vv. b. Ràng buộc cho 3 biến (Ternary constraint):

Choco cung cấp một số ràng buộc bao gồm 3 biến nguyên như: distanceEQ, distanceNEQ, .vv.

c. Ràng buộc kênh (Channeling Contraints): ràng buộc lien kết giữa các mô hình với nhau.

Chương 3: Quy hoạch ràng buộc

d. Ràng buộc cụ thể hóa (Reified Contraints):

Giá trị thực của 1 ràng buộc là một Boolean, nó chỉ đúng nếu ràng buộc đó không đổi. việc cụ thể hóa một ràng buộc nghĩa là đi tìm giá trị thực của ràng buộc đó.

Choco cung cấp một ràng buộc chung loại Reified Contraint để cụ thể hóa mọi ràng buộc trong biến Boolean để thể hiện giá trị của ràng buộc đó.

e. Ràng buộc chung (Global constraints): Ràng buộc chung cho nhiều biến trong một ràng buộc:

Để xây dựng cấu trúc phức tạp của ràng buộc, Choco cung cấp các ràng buộc chung như: and, or, implies, ifOnlyIf, IfThenElse, not, nand, nor.

Ví dụ: biểu thức sau: ((x =10 *|y| v (z≤9))  alldifferent(a,b,c) Có thể được biểu diễn như sau:

Constraint exp = ifOnlyIf(or(eq(x, mult(10, abs(y))), leq(z,9)), alldifferent(new IntegerVariable[]{a, b,c}));

Một số loại ràng buộc chung:

 Ràng buộc nối: domainChanneling, max, min, inverseChanneling,..vv.

 Ràng buộc tối ưu: among, occurrence ..

 Ràng buộc đóng gói: các ràng buộc bao gồm các hạng mục cần đóng gói mà không gây chồng chéo.

3.2.2.3 Lời giải (Solver)

Solver đọc model, dùng các thuật toán được cài đặt sẵn trong thư viện hoặc kết hợp thêm để giải yêu cầu của bài toán.

Ví dụ

IntegerVariable x = Choco.makeIntVar("x", 1, 1000, Options.V_OBJECTIVE); IntegerVariable y = Choco.makeIntVar("y", 20, 50);

CPModel m = new CPModel();

m.addConstraint(Choco.eq(x, Choco.mult(y, 20))); CPSolver s = new CPSolver();

s.read(m); s.solve();

Quá trình đọc model được chia thành 2 phần: đọc các biến và đọc các ràng buộc.

a. Biến trong solver

Các biến được khai báo trong Model dưới dạng như IntegerVariable, SetVaribale, RealVariable. Khi đọc Model, Solver lặp lại trên các biến của Model sau

Chương 3: Quy hoạch ràng buộc

đó tạo ra các biến trên Solver tương ứng và các cấu trúc dữ liệu tên miền theo các loại biến trên.

Biến trên Model và biến trên Solver là các đối tượng riêng biệt. Các biến trên Model dùng kiểu _Variable còn trên Solver dùng kiểu _Var. Một biến trong Model được xác định là một đại diện trừu tượng của miền ban đầu trông khi một biến trong Solver được tóm gọn là một đại diện rời rạc của tên miền và duy trị trạng thái hiện tại của nó trong quá trình tìm kiếm. Do đó chúng ta không thể trực tiếp đọc giá trị từ một biến trong Model nhưng lại có thể truy cập vào giá trị biến trong Solver tương ứng. Các biến trong Solver là ẩn danh nhưng lại có thể tiếp cận trực tiếp bằng cách sử dụng các phương thức getVar.

 IntDomainVar: Đối với các số nguyên IntDomainVar là đối ứng của IntegerVariable trong Solver.

IntegerVariable x = Choco.makeEnumIntVar(“x”, 1, 100); // do something here

// read variable on Solver

IntDomainVar xOnSolver = solver.getVar(x);

 SetVar: Đối với các biến tập hợp, SetVar là đối tượng đối ứng với SetVariable trong Solver.

SetVariable x = Choco.makeBoundSetVar(“x”, 1, 100); // do something here

// read variable on Solver

SetVar xOnSolver = solver.getVar(x);

 RealVar: RealVar là đối ứng của RealVariable trong Solver

IntegerVariable x = Choco.makeRealVar(“x”, 1.0, 100.0); // do something here

// read variable on Solver

RealVar xOnSolver = solver.getVar(x);

b. Ràng buộc trong solver

Sau khi đọc và tạo ra các biến trong Solver, quá trình đọc sẽ tiếp tục đọc và tạo ra các ràng buộc trong Solver bằng cách dùng phương pháp gọi makeConstraint của đối tượng ConstraintManager kết hợp với các loại ràng buộc trong Model. Ở bước này có thể tạo ra các biến trong Solver phụ thuộc và các ràng buộc. Sau đó các ràng buộc mới được tạo được được thêm vào mạng ràng buộc bên trong.

Mỗi ràng buộc trong Solver tóm lược một thuật toán lọc mà quá trình tìm kiếm khi một bước lan truyền ngược hoặc khi có một sự kiện bên ngoài tác động (như xóa giá trị hay thay đổi ràng buộc) xảy ra ở một biến trong ràng buộc.

Chương 3: Quy hoạch ràng buộc

c. Chiến lƣợc tìm kiếm

Một phần quan trọng của bất kỳ phương pháp giải quyết bài toán ràng buộc là một chiến lược tìm kiếm thông minh. Trong cách tiếp cận nhánh, ràng buộc hay quay lui, tìm kiếm được tổ chức như một cây trong đó mỗi nút như một không gian con của tìm kiếm và mỗi nút con là một nhánh của không gian tìm kiếm trong nút lớn. Cây được tạo ra trong quá trình phân chia không gian tìm kiếm thông qua các chiến lược phân nhánh.

Các phương pháp tiếp cận ràng buộc, nhánh hay quay lui trong lập trình ràng buộc phát triển theo dạng cây liệt kê ở một thể thức DFS (tìm kiếm ưu tiên chiều sâu).

 Đánh giá một nút

 Nếu thất bại hoặc nếu không gian tìm kiếm không thể phân tách. Backtrack, đánh giá các nút tiếp theo

 Nếu có thể tách rời thì phân chia không gian tìm kiếm, tiếp tục đánh giá các nút con.

Với Choco, quá trình tìm kiếm của CPSolver hiện tại cho phép tìm kiếm trên cây với tất các các cách thức khác nhau, chẳng hạn chiến lược tìm kiếm ưu tiên tốt nhất.

Ngoài ra, cách phổ biến để phân chia không gian tìm kiếm là giới hạn miền giá trị của biến và gán giá trị cho biến. Choco cung cấp một chiến lược phân nhánh và các tùy chỉnh để người dùng có thể thay đổi, tùy chỉnh biến và giá trị chọn lựa trong chiến lược, Tuy nhiên Choco có thể thực hiện nhiều chiến lược phân nhánh phức tạp như phân nhánh ràng buộc, phân nhánh lưỡng phân.

3.2.3 Các yếu tố trong Choco

3.2.3.1 Variables

a. IntegerVariable:

IntegerVariable là kiểu biến dạng số nguyên, Choco có những method để khai báo các biến dạng số nguyên như sau:

Phƣơng thức Giá trị trả về

makeIntVar(String name, int lowB, int uppB, String... options)

IntegerVariable makeIntVar(String name, List<Integer> values, String...

options)

IntegerVariable makeIntVar(String name, int[] values, String... options) IntegerVariable makeBooleanVar(String name, String... options) IntegerVariable makeIntVarArray(String name, int dim, int lowB, int

uppB, String... options)

IntegerVariable[] makeIntVarArray(String name, int dim, int[] values, IntegerVariable[]

Chương 3: Quy hoạch ràng buộc

String... options)

makeBooleanVarArray(String name, int dim, String... options)

IntegerVariable[] makeIntVarArray(String name, int dim1, int dim2, int

lowB, int uppB, String... options)

IntegerVariable[] makeIntVarArray(String name, int dim1, int dim2, int[]

values, String... options)

IntegerVariable[]

Table 1: Các phương thức khai báo biến IntegerVariable trong Choco

Trong đó các options

 Options.V_ENUM: Solver sẽ tạo ra một miền liệt kê cho biến

 Options.V_BOUND: Solver tạo ra một miền bị chặn cho biến

 Options.V_LINK: Solver tạo ra một miền danh sách liên kết (Linked List) cho biến

 Options.V_OBJECTIVE: xác định các biến để tối ưu hóa Ví dụ

IntegerVariable ivar1 = makeIntVar(“ivar1”, -10, 10);

IntegerVariable ivar2 = makeIntVar(“ivar2”, -10, 10000, Options.V_BOUND, Options.V_NO_DECITION);

IntegerVariable bool = makeBooleanVar(“bool”);

b. RealVariable

RealVariable là kiểu biến số thực. Choco hỗ trợ khai báo kiểu biến số thực như sau :

makeRealVar(String name, double lowB, double uppB, String... options)

Ví dụ:

RealVariable rval = makeRealVar(“rvar1”, -10.0, 10.0)

c. SetVariable

SetVariable là kiểu biến tập hợp. Các phương thức khai báo biến tập hợp trong Choco như sau:

Phƣơng thức Giá trị trả về

makeSetVar(String name, int lowB, int uppB, String... options)

SetVariable makeSetVarArray(String name, int dim, int lowB, int uppB,

String... options)

SetVariable[]

Table 2: Phương thức khai báo biến tập hợp trong Choco

Ví dụ :

SetVariable svar1 = makeSetVar(“svar1”, -10, 10 );

Chương 3: Quy hoạch ràng buộc

TaskVariable là một kiểu biến đại diện cho các tác vụ. TaskVariable là tổng hợp gồm có các thông tin:

 Thông tin về thời gian bắt đầu: IntegerVariable start

 Thông tin về thời gian kết thúc: IntegerVariable end

 Thông tin về quá trình thực hiện tác vụ: integerVarible duration. Ví dụ:

TaskVariable tvar1 = makeTaskVar("tvar1", 0, 123, 18, Options.V_ENUM);

3.2.3.2 Operators

a. abs

Hàm abs trả về một IntegerExpressionVariable biểu diễn giá trị tuyệt đối của một biến. Hàm abs có dạng như sau:

IntegerExpressionVariable abs = abs(IntegerExpressionVariable n)

Ví dụ: ràng buộc y =|x| có thể mô tả trong thư viện Choco như sau

Model m = new CPModel();

IntegerVariable x = makeIntVar("x",1,5, Options.V_ENUM); IntegerVariable y = makeIntVar("y",-5,5, Options.V_ENUM); m.addConstraint(eq(abs(x), y));

Solver s = new CPSolver(); s.read(m);

s.solve();

b. div

Hàm div trả về một IntegerExpressionVariable biểu diễn phần nguyên của phép chia 2 biến trong biểu thức ⌊ ⌋. Prototype:

Hàm div có cấu trúc như sau:

- div(IntegerExpressionVariable n1, IntegerExpressionVariable n2); - div(IntegerExpressionVariable n1, int n2);

- div(int n1, IntegerExpressionVariable n2);

Ví dụ: mô hình ràng buộc z = w/x dựa trên thư viện Choco.

Model m = new CPModel(); Solver s = new CPSolver();

IntegerVariable x = makeIntVar(“x”, 1, 10); IntegerVariable w = makeIntVar(“w”, 22, 44);

Chương 3: Quy hoạch ràng buộc

m.addConstraint(eq(z, div(w,x))); s.read();

s.solve();

c. IfThenElse:

Hàm IfThenElse nếu thỏa mãn ràng buộc c thì trả về biểu thức v1, ngược lại trả về biểu thức v2. Cấu trúc hàm ifThenElse như sau:

ifThenElse(Constraint c,IntegerExpressionVariable v1, IntegerExpressionVariable v2)

Ví dụ:

Đoạn chương trình sau giải bài toán tìm (x,y) thỏa mãn: 0 ≤ x ≤ 5; 0 ≤ y ≤ 10; và

{

Model m = new CPModel();

IntegerVariable x = makeIntVar("x",1,5); IntegerVariable y = makeIntVar("y",0,10);

m.addConstraint(eq(y, ifThenElse(gt(x,2), mult(x,x), x))); Solver s = new CPSolver();

s.read(m); s.solveAll();

d. Max

Hàm max trả về giá trị lớn nhất của các biến truyền vào. Hàm max có dạng như sau:

- max(IntegerExpressionVariable x1, IntegerExpressionVariable x2) - max(int x1, IntegerExpressionVariable x2)

- max(IntegerExpressionVariable x1, int x2) - max(IntegerExpressionVariable[] x)

Ví dụ:

Model m = new CPModel();

m.setDefaultExpressionDecomposition(true);

IntegerVariable[] v = makeIntVarArray("v",3,-3,3); IntegerVariable maxv = makeIntVar("max",-3,3); Constraint c = eq(maxv, max(v));

m.addConstraint(c);

Solver s = new CPSolver(); s.read(m);

s.solveAll();

e. Các operator khác

Chương 3: Quy hoạch ràng buộc

 Với IntegerExpressionVariable: các hàm: max, min, minus, mod, mult, neg, plus, power, scalar, sum, etc.

 Với RealExpressionVariable: cos, minus, mult, plus, power, sin, etc.

3.2.3.3 Constraint

Trong phần này sẽ trình bày chi tiết một số constraint trong choco.

a. Abs

Ràng buộc abs(IntegerVariable x, IntegerVariable y) thể hiện ràng buộc y =|x|.

Ví dụ:

Model m = new CPModel();

IntegerVariable x = makeIntVar("x",1,5, Options.V_ENUM); IntegerVariable y = makeIntVar("y",-5,5, Options.V_ENUM); m.addConstraint(abs(x, y));

Solver s = new CPSolver(); s.read(m);

s.solve();

b. allDifferent

Ràng buộc alldifferent(x1, x2, .. xn) thể hiện xi # xj với mọi i # j. Ràng buộc allDifferent được khai báo thông qua API như sau:

- allDifferent(IntegerVariable... x)

- allDifferent(String options, IntegerVariable... x)

Trong đó các options cho người dùng chọn thuật toán được cài đặt sẵn trong choco để thực hiện ràng buộc.

Ví dụ: bài toán con hậu nQueens:

int n =8;

CPModel m = new CPModel();

IntegerVariable[] queens = new IntegerVariable[n]; IntegerVariable[] diag1 = new IntegerVariable[n]; IntegerVariable[] diag2 = new IntegerVariable[n]; for (int i =0; i < n; i++){

queens[i]= makeIntVar("Q"+ i,1, n); diag1[i]= makeIntVar("D1"+ i,1,2* n); diag2[i]= makeIntVar("D2"+ i,-n +1, n); }

Chương 3: Quy hoạch ràng buộc

m.addConstraint(eq(diag1[i], plus(queens[i], i))); m.addConstraint(eq(diag2[i], minus(queens[i], i))); }

m.addConstraint(Options.C_ALLDIFFERENT_CLIQUE, allDifferent(diag1)); m.addConstraint(Options.C_ALLDIFFERENT_CLIQUE, allDifferent(diag2)); // diagonal constraints

CPSolver s = new CPSolver(); s.read(m);

long tps = System.currentTimeMillis(); s.solveAll();

c. among

Ràng buộc among(z, (x1, x2..xn), S) thể hiện z là số lượng các xi nằm trong tập S.

among(IntegerVariable z, IntegerVariable [] x, Int[] v); among(IntegerVariable z, IntegerVariable [] x, SetVariable v)

Ví dụ:

Model m = new CPModel(); Solver s = new CPSolver();

IntegerVariable var = makeIntVar("v1",0,100, Options.V_BOUND); int[] values = new int[]{0,25,50,75,100};

m.addConstraint(among(var, values)); s.read(m);

s.solve();

d. and

Ràng buộc and(c1, c2, .. cn) trong đó ci là các ràng buộc thể hiện sự thỏa mãn đồng thời tất cả các ràng buộc c1, c2, .. cn. Ràng buộc and(b1, b2...bn) trong đó bi là các biến Boolean thể hiển tất cả các biến b1, b2,.. bn đều đồng thời bằng true.

- and(Constraint... c) - and(IntegerVariable... b)

Ví dụ:

Model m = new CPModel(); Solver s = new CPSolver();

IntegerVariable v1 = makeIntVar("v1",0,1); IntegerVariable v2 = makeIntVar("v2",0,1); m.addConstraint(and(eq(v1,1), eq(v2,1)));

Chương 3: Quy hoạch ràng buộc

s.read(m); s.solve();

e. nth

nth là một ràng buộc khá quen thuộc để truy cập giá trị các biến trong quá trình tìm kiếm lời giải bài toán.

- nth(i, x[], y): thể hiện x[i]= y

- nth(I, x[], y, o) thể hiện x[i + o]= y (trong đó o được gọi là offset.

- nth(i; j; x[][]; y) thể hiện ràng buộc x[i][j]= y Người dùng có thể sử dụng ràng buộc nth thông qua các API:

- nth(IntegerVariable i, int[] x, IntegerVariable y)

- nth(String option, IntegerVariable i, int[] x,

IntegerVariable y)

- nth(IntegerVariable i, IntegerVariable[] x,

IntegerVariable y)

- nth(IntegerVariable i, int[] x, IntegerVariable y, int

offset)

- nth(String option, IntegerVariable i, int[] x,

IntegerVariable y, int offset)

- nth(IntegerVariable i, IntegerVariable[] x,

IntegerVariable y, int offset)

- nth(String option, IntegerVariable i, IntegerVariable[]

x, IntegerVariable y, int offset)

- nth(IntegerVariable i, IntegerVariable j, int[][] x,

IntegerVariable y)

Trong bài toán sắp xếp thời khóa biểu cũng sử dụng ràng buộc nth để xây dựng hàm

Một phần của tài liệu Giải bài toán xếp lịch bảo vệ thạc sỹ bằng các kỹ thuật tối ưu dựa trên ràng buộc (Trang 29)

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

(66 trang)