III. Khung thuật toỏn SA song song giải quyết bài toỏn MAXSAT
2. Cài đặt Bài toỏn Maxsat
2.1 Sử dụng thuật toỏn SA 2.1.1 Đọc file cấu hỡnh 5 // số bước chạy độc lập 500 // số ước lượng 100 // Markov-Chain Length 0.99 // độ giảm nhiệt độ 1 // cú hiện thị trạng thỏi ? LAN-configuration
10 // trạng thỏi toàn cục được cập nhật trong n ước lượng
0 // 0: asynchronized mode // 1: synchronized mode 10 // số bước lặp để cooperate ( if 0 no
cooperation)
2.1.2 Lớp Problem đọc bài toỏn MAXSAT
Đầu vào của bài toỏn là n biến và m mệnh đề được thể hiện trong một file là Sat.dat với định dạng:
// số lượng biến, số lượng mệnh đề, chiều dài mỗi mệnh đề // mệnh đề 1 (kết thỳc là 0), nếu vị từ < 0 thỡ vị từ là phủ định. ……….
32 Vớ dụ cụ thể : Bài toỏn cú
5 7 3 //5 biến, 7 mệnh đề, độ dài mỗi mệnh đề là 3 -1 -2 3 0 ơx1 ơx2 x3 2 3 -1 0 x2 x3 ơx1 1 -2 3 0 x1 ơx2 x3 -2 -3 4 0 ơx2 ơx3 x4 3 4 5 0 x3 x4 x5 -5 1 -4 0 ơx5 x1 ơx4 2 5 3 0 x2 x5 x3
istream& operator>> (istream& is, Problem& pbm) { int l; int n; is >> pbm._numvar >> pbm._numclause >> pbm._lenclause; n = pbm._lenclause; // read clauses
pbm._clauses = new int*[pbm._numclause]; for (int i = 0; i < pbm._numclause; i++)
{
pbm._clauses[i] = new int[n]; for(int j = 0; j < n;j++) { is >> l; pbm._clauses[i][j] = l; } is >> l; }
33
return is; }
2.1.3 Hàm khởi tạo nhiệt độ
double Solver::Set_Initial_Temperature(const Problem& pbm)
{
const double beta = 1.05; const double test = 10; const double acrat = .8; const double T = 1.0; Solution current (pbm); Solution newsol (pbm); double ac; double fit; double temperature = T; do { temperature *= beta; ac = 0; current.initialize(); fit = current.fitness(); for (int i=0; i<test; i++) {
newsol = current; move->Apply(newsol);
if (AcceptQ(newsol.fitness(),fit,temperature)) ac += 1.0/test;
34
}
} while (ac < acrat);
initial_temperature_trial(temperature); return temperature;
}
Hàm cập nhật nhiệt độ
double Solver::UpdateT(double temp, int K)
{
if(K == 1) return temp / exp(2);
else return (temp * exp(K)) / exp(K+1); }
2.1.4 Hàm khởi tạo lời giải
Giả sử cú n biến: x1,, x2, x3, …, xn. Lời giải là một mảng n phần tử mà mỗi phần tử trong mảng chỉ nhận một trong hai giỏ trị là 0 hoặc 1 bằng cỏch sinh cỏc số nguyờn ngẫu nhiờn từ 0 đến 1 để gỏn cho mảng này.
Vớ dụ với 5 biến ta cú cỏc lời giải như: (có 25 lời giải tất cả) x1,, x2, x3, x4, x5 --- {0, 0, 0, 0, 0}; {1, 0, 0, 0, 0}; {1, 0, 0, 1, 0}…
Hàm khởi tạo lời giải
void Solution::initialize() {
for (int i=0;i<_pbm.numvar();i++)
_var[i]= rand_int(0,1); // Khởi tạo một mảng gồm cỏc phần tử là 0 và 1
35
Hàm nhận lời giải
istream& operator>> (istream& is, Solution& sol)
{
for (int i=0;i<sol.pbm().numvar();i++) is >> sol._var[i];
return is; }
Sử dụng NetStream tớnh toỏn song song
NetStream& operator >> (NetStream& ns, Solution& sol) {
for (int i=0;i<sol._var.size();i++) ns >> sol._var[i];
return ns; }
Hàm ỏp dụng lời giải mới, vớ dụ 0 0 0 chuyển thành 1 1 1.
void DefaultMove::Apply (Solution& sol) const {
const float probability = 0.03;
for (int i=0;i<sol.pbm().numvar();i++) { if (rand01() <= probability) { if (sol.var(i)==1) sol.var(i)=0; else sol.var(i)=1; } } } 2.1.5 Một số hàm tớnh chi phớ Hàm tớnh chi phớ tốt nhất hiện tại
36
{
double value=0.0;
unsigned long nitems,length;
_sc.get_contents_state_variable("_current_best_cost",(char *)&value, nitems, length);
return value; }
Hàm chi phớ hiện tại
double Solver::current_cost() const
{
double value=0.0;
unsigned long nitems,length;
_sc.get_contents_state_variable("_current_cost",(char *)&value, nitems, length);
return value; }
Hàm chi phớ tốt nhất toàn cục
double Solver::global_best_cost() const
{
double value=0.0;
unsigned long nitems,length;
_sc.get_contents_state_variable("_global_best_cost",(char *)&value, nitems, length);
return value; }
2.1.6 Hàm tớnh sức khoẻ
Là hàm tớnh tổng số mệnh đề đúng đối với mỗi lời giải:
37
{
double fitness = 0.0; int acum = 0;
for(int i = 0; i < _pbm.numclause(); i++) {
int *rl = _pbm.clause(i); acum = 0;
for(int j = 0; (j < _pbm.lenclause()) && (acum != 1);j++) {
if( ((rl[j] < 0) && (_var[(int)abs(rl[j])-1] == 0)) || ((rl[j] > 0) && (_var[rl[j]-1] == 1)) ) acum = 1; } fitness += acum; } return fitness; } 2.1.7 Hàm chấp nhận lời giải
bool Solver::AcceptQ (double tent, double cur, double temperature)
{
if (_direction==minimize) return (tent < cur) ||
((rand01()*(1+exp((tent- cur)/temperature)))<2.0);
else
38
((rand01()*(1+exp((cur- tent)/temperature)))<2.0);
}
2.1.8 . Hàm kết thỳc thuật toỏn
bool TerminateQ (const Problem& pbm, const Solver& solver,
const SetUpParams& setup) {
StopCondition_3 stop;
return stop.EvaluateCondition(pbm,solver,setup); }
bool StopCondition_3::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup)
{
return ((int)solver.current_best_cost() == pbm.numclause()); } 2.2Hàm void Solver_Lan::DoStep() DoStep() { //Tăng bước lặp hiện tại lờn 1; current_iteration current_iteration(current_iteration()+1); set_source(0); // Thiết đặt nguồn
_netstream._probe(packed, pending); if(pending)
{
Solution sol (problem);
39 final_phase true; } received cooperation(); if (!received) { tentative current; Apply(tentative); // Áp dụng lời giải mới }
tentfit tentative.fitness();//gỏn lại giỏ trị hàm sức khoẻ
if (AcceptQ(tentfit,curfit, currentTemperature)) { current tentative; curfit tentfit; } k k + 1; if (k >= MarkovChain_length()) { UpdateT; k = 0; }
total_time_spent start_global + time_spent_in_trial; RefreshState();
_stat.update(*this); _userstat.update(*this);
if (display_state()) show_state(); }
Nếu như pid() != 0 thỡ mỏy con thực hiện và thực hiện cõu lệnh DoStep() như trờn cũn pid() = 0 mỏy chủ thực hiện .
40
Main_Lan
{
Sử dụng khung SA
Khai bỏo: SetupParams cfg; Problem pbm;
Mở file f1 là “SA.cfg” để đọc vào cấu hỡnh
Đọc file f1>>cfg;
Mở file f2 để đọc “Problem.dat”
Đọc file f2>>pbm;
Khai bỏo: Solver_Seq solver (pbm,cfg, argc,argv); Gọi hàm solver.run();
Nếu (solver.pid()==0) thỡ hiển thị trạng thỏi. In ra lời giải tốt nhất toàn cục và giỏ trị hàm sức khỏe.
}
Kết quả thực nghiệm
(Chương trỡnh đó chạy nhưng chưa đủ máy để chạy song song nờn thứ 6 sẽ trỡnh bày sau)
1. Kết quả tuần tự 2. Kết quả song song
TÀI LIỆU THAM KHẢO
[1.] Chen Tao. Multi-FPGA Partitioning Using Simulated Annealing.
May 2003
[2.] S. Kirkpatrick, J. C. G., And Vecchi, M. Optimization by simulated annealing. Science 220(4598)(May 1983), 498-516
[3.] http://neo.lcc.uma.es/mallba/easy-mallba/html/algorithms.html. MALLBA LIBRARY v2.0
41 [4.]Teknillinen Korkeakoulu. Implementation of Simulated Annealing Optimization method for APLAC Circuit Simulator. 29-10-1996
[5.]Integrated Logic Synthesis Using Simulated Annealing. Petra Farrm.