XỬ LÝ SONG SONG
Trang 1TRƯỜNG ĐẠI HỌC SƯ PHẠM HÀ NỘI
KHOA CÔNG NGHỆ THÔNG TIN
môi trường song song
Giáo viên hướng dẫn : Th.s Đỗ Trung Kiên Sinh viên thực hiện : Nguyền Thị Bích Nhật
Trang 22.2 Xây dựng khung nhánh cận tuần tự 15
2.3 Xây dựng khung nhánh cận song song 16
2.3.1 Lược đồ song song dữ liệu tập trung 19
2.3.2 Lược đồ song song dữ liệu phân tán 22
2.4 Công cụ phát triển hệ thống 25
2.5 Lựa chọn mô hình phát triển hệ thống 25
Chương 3 : SỬ DỤNG THUẬT TOÁN NHÁNH CẬN ĐỂ GIẢI QUYẾT BÀI TOÁN TSP 27
* Bài toán TSP (Bài toán người du lịch) 27
3.1 Giới thiệu bài toán 27
3.2 Định nghĩa bài toán 27
3.3 Sử dụng thuật toán nhánh cận để giải bài toán TSP 28
* Tính cận và phân nhánh 28
3.4 Chương trình thực thi 32
Chương 1 : TỔNG QUAN VỀ THUẬT TOÁN NHÁNH CẬN
Trang 3Thuật toán nhánh cận là phương pháp chủ yếu để giải các bài toán tối ưu tổ hợp Ta sẽ thực hiện việc đánh giá theo từng bước, nếu không có khả năng tìm thấy kết quả tốt hơn thì sẽ cắt nhánh đó, không thực hiện tìm tiếp mà chuyển ngay sang nhánh khác Khi đó, chỉ ghi nhận các kết quả tốt hơn lúc ban đầu Nghiệm của bài toán sẽ tốt dần lên do khi tìm ra kết quả tốt hơn ta sẽ cập nhật lại giá trị hiện thời của bài toán.
1.1 Thuật toán nhánh cận
Một trong những bài toán đặt ra trong thực tế là tìm một nghiệm của bài toán thỏa mãn một số điều kiện nào đó và nghiệm đó là tốt nhất theo một tiêu chí cụ thể, nghiên cứu lời giải các bài toán tối ưu thuộc về lĩnh vực quy hoạch toán học mô hình được sử dụng để tìm kiếm là mô hình cây phân cấp việc tìm nghiệm của các bài toán thường phải dựa vào việc liệt kê toàn bộ các cấu hình có thể và đánh giá tìm ra cấu hình tốt nhất.
Ví dụ: Bài toán người du lịch: không gian trạng thái là N! Bài toán K- median : không gian trạng thái là
Khi đó, không gian tìm kiếm của bài toán là rất lớn trong khi nhiều trường hợp có thể loại bỏ được ngay Điều này gây nên tình trạng lãng phí bộ nhớ và mất rất nhiều thời gian Vấn đề đặt ra là trong quá trình liệt kê lời giải cần tận dụng những thông tin đã có để loại bỏ sớm những phương án chắc chắn không tối ưu Thuật toán nhánh cận được sử dụng để khắc phục những vấn đề trên
Tư tưởng cơ bản của thuật toán là trong quá trình tìm kiếm lời giải, ta sẽ phân
hoạch tập các phương án của bài toán thành hai hay nhiều tập con biểu diễn như một
nút của cây tìm kiếm và cố gắng bằng phép đánh giá cận các nút, tìm cách loại bỏ các
nhánh cây (những tập con các phương án của bài toán) mà ta biết chắc chắn không phải
Trang 4là phương án tối ưu Mặc dù trong trường hợp tồi nhất thuật toán sẽ trở thành duyệt toàn bộ, nhưng những trường hợp cụ thể nó rút ngắn đáng kể thời gian tìm kiếm
Để áp dụng phương pháp nhánh cận đối với 1 tập các bài toán tối ưu chúng ta cần làm theo các bước sau:
đi đến Bước 3 sau khi lựa chọn Пi:= s(Ls) để kiểm tra.
T:={σ } với σ là lời giải khả thi của Пi sao cho f(x,σ )= lower_bound(П i) Đi tới bước 4.
trong tiến trình tính toán cận trên của Пi) ngược lại thì đi đến Bước 5.
upper_bound(Пi) ≤ bs Ngược lại đi tới bước 6.
đi tới bước 7.
Quay trở lại bước 2.
П0, nếu bs = - ∞ , П0 không có lời giải
1.2 Một số ví dụ cụ thể áp dụng thuật toán nhánh cận
Bài 1: Bài toán người du lịch( TSP)
Trang 5• Phát biểu bài toán : Một người du lịch muốn đi thăm quan n thành phố T1 , T2 , … , Tn Xuất phát từ một thành phố nào đó người du lịch muốn đi qua tất cả các thành phố còn lại, mối thành phố đúng một lần, rồi quay trở lại thành phố xuất phát Biết ci,j là chi phí từ thành phố Ti đến thành phố Tj Hãy tìm hành trình
• Ký hiệu : cmin = min{c[i,j]; i, j = 1,2,…,n, i≠j}
• Giả sử có phương án bộ phận (u1,u2, …, uk)
– Chi phí phải trả là : σ = c[1,u2] + c[u2,u3] + + c[uk-1, uk]
– Cận dưới là : g (u1,u2, …, uk) = σ + (n-k+1)*cmin
Trang 61 Phương pháp phân nhánh:
+ Nếu bài toán con có g() > f -(Kỉ lục tạm thời) thì cắt luôn nhánh của bài toán này
+ Nếu không thì phân nhánh tiếp bài toán con cho đến khi tính được kỉ lục của bài toán con này Nếu kỉ lục của bài toán con nhỏ hơn f() thì cập nhật lại kỉ lục tạm thời f()
2. Phương pháp tính cận:
5
9 tính cận trên của bài toán con dựa vào công thức
σ = c[1,u2] + c[u2,u3] + + c[uk-1, uk] g (u1,u2, …, uk) = σ + (n-k+1)*cmin
Bài 2: Bài toán cái túi
• Phát biểu bài toán : Một nhà thám hiểm cần đem theo một cái túi có trọng lượng không quá b Có n đồ vật có thể đem theo Đồ vật thứ j có trọng lượng a và giá trị sử dụng là c Hỏi rằng nhà thám hiểm cần đem theo các đồ vật nào để cho tổng giá trị sử dụng của các đồ vật đem theo là lớn nhất.
• Xây dựng công thức :
Phương án x = {x1,x2, …, xn} Giá trị đồ vật đem theo
Trang 7Tổng trọng lượng đồ vật
min{f(x) : g(x) ≤ b}
Chương 2 : XÂY DỰNG KHUNG THUẬT TOÁN NHÁNH CẬN
Thuật toán nhánh cận được xây dựng với mong muốn giải quyết được tập các bài toán tối ưu tổ hợp Có nghĩa là tất cả các bài toán đó sẽ được giải quyết dựa trên một khung chung của thuật toán để khi vào một bài toán cụ thể người viết chương trình chỉ cần thêm vào khung đó những dữ liệu phù hợp với bài toán của mình Nó giảm bớt thời gian xây dựng thuật toán đồng thời nó hữu ích cho những người không biết kỹ thuật nhánh cận trên môi trường song song vẫn có thể cài đặt song song Chương này sẽ trình bày việc xây dựng khung của kĩ thuật nhánh cận và kỹ thuật nhánh cận trên môi trường tuần tự hoặc song song.
Hệ thống gồm hai nhóm : một nhóm các lớp cung cấp (Provided) bao hàm các thủ
tục chung cho thuật toán nhánh cận (ví dụ như khung của thuật toán nhánh cận tuần tự,
khung của thuật toán nhánh cận song song ) và nhóm các lớp yêu cầu (Required) bao
hàm các thủ tục riêng để giải quyết một bài toán cụ thể sử dụng kỹ thuật nhánh cận (ví dụ như các thủ tục tính cận, thủ tục phân nhánh, ) Để giải quyết một bài toán bằng kỹ thuật nhánh cận, người sử dụng chỉ cần viết các khai báo và xây dựng các hàm trong nhóm yêu cầu mà không cần xây dựng lại nhóm cung cấp Hình 4.1 diễn tả mô hình
Trang 8* Nhóm các lớp yêu cầu
Mô hình chung của nhóm các lớp yêu cầu
Hình 2 diễn tả các lớp và thủ tục chính trong nhóm yêu cầu.
Hình 2 : Các lớp yêu cầu
Trang 9Các lớp yêu cầu được sử dụng để lưu trữ dữ liệu cơ bản của thuật toán : bài toán, trạng thái không gian tìm kiếm Nó bao gồm các lớp chính sau :
- Bài toán (Problem): Diễn tả các tham số của bài toán cần giải quyết.
- Bài toán con (Subproblem) : Diễn tả vùng không gian chưa được khai thác và
cung cấp các chức năng sau :
giải bộ phận sol của bài toán pbm.
sol của bài toán pbm
và lưu vào sps.
Lớp bài toán con diễn tả một bài toán bộ phận Một bài toán con được xác định bởi
các dữ liệu sau : vector sol chứa các chỉ số đỉnh làm median của bài toán con (hay là lời
giải bộ phận của bài toán cần giải quyết) và được sắp xếp theo thứ tự tăng dần, chỉ số
đỉnh cuối eV của lời giải bộ phận, và cận dưới cost ứng với lời giải bộ phận sol
Lớp bài toán con phải cung cấp các hàm chính sau :
- InitSubProblem(pbm): sinh ra bài toán con ban đầu với
- Các hàm tính cận dưới (LowerBound), tính cận trên (UpperBound), phân nhánh (Branch)
Trang 10* Nhóm các lớp cung cấp
Trước khi mô tả lớp cung cấp chúng ta cần xem xét cấu trúc dữ liệu để lưu các bài toán con chưa được giải quyết trong quá trình tính toán Vì số lượng các bài toán con là rất lớn và không biết trước nên ta sử dụng một danh sách liên kết kép để quản lý chúng.
Lớp Solver : Làm nhiệm vụ đưa ra và duy trì các thông tin có liên quan tới trạng thái
tìm kiếm trong suốt quá trình thực hiện
class Solver { protected:
const Problem& pbm;// bài toán cần giải quyết Direction dir;
SubProblem sp; // bài toán con hiện thời cần giải quyết Solution sol; // giải pháp tốt nhất hiện thời
container<SubProblem> HP;// danh sách các bài toán con cần giải quyết Bound high;// cận trên của nhánh bài toán con
Bound low;// cận dưới của nhánh bài toán con Bound bestSol;// kỉ lục hiện thời của bài toán public:
Solver(const Problem &problem);
Trang 11Có hai lớp kế thừa từ lớp Solver
- Lớp Solver_Seq : Chứa thủ tục run() để giải quyết bài toán một cách tuần tự
- Lớp Solver_Lan : Chứa thủ tục run(int argc, char** argv) để giải quyết bài
toán một cách song song trên môi trường mạng LAN Với tham số truyền vào
của hàm chính là các tên máy tham gia vào quá trình tính toán.
Người sử dụng muốn thực hiện theo phương thức nào (song song hay tuần tự) thì tạo ra
một đối tượng tương ứng sau đó gọi tới thủ tục run Ví dụ chúng ta muốn tiến hành
thuật toán nhánh cận tuần tự để giải quyết bài toán TSP có đoạn mã của thủ tục main như sau
IntMain(int argc, char** argv) {
Problem pbm;// Bài toán cần giải quyết
SolVec sol;// Lời giải tối ưu của bài toánBoundbs;// Giá trị tối ưu của bài toán
Trang 122.1 Xây dựng khung nhánh cận
2.1.1 Cấu trúc dữ liệu
Cấu trúc dữ liệu sử dụng là hàng đợi động để điều khiển bài toán con được sinh ra bằng phương thức phân nhánh Các bài toán con được thêm và0 hàng đợi phụ thuộc
vào phương thức tìm kiếm cụ thể trong lớp cài đặt: lifo(last in first out), fifo (first in
first out) hoặc prio-rity Mỗi một bài toán con được kết nối bởi 2 con trỏ tới thành phần trứơc và sau của danh sách riêng biệt.
Hình 3: Hàng đợi các bài toán con của kĩ thuật nhánh cận
2.1.2 Thuật toán
Các bài toán sử dụng nhánh cận để giải quyết đều phải sử dụng khung của thuật toán Điều này nhấn mạnh rằng người dùng nếu giải bài toán của mình trên môi trường tuần tự hoặc song song thì chỉ cần thêm một số phương thức, dữ liệu phù hợp mà không cần suy nghĩ đến việc phải thiết kế các bước như thế nào.
Dưới đây là khung chung của thuật toán:
Trang 13a. Dựa trên một phương pháp nào đó (theo chiều sâu, chiều rộng, hoặc cận tốt
nhất , ) để lựa chọn một bài toán con khả thi cùng cận của nó từ tập hoạt
b Xóa bài toán con khỏi tập hoạt động 3 Phân nhánh
a. Áp dụng luật phân nhánh để sinh ra các bài toán con mới từ bài toán đang xét Tính cận của các bài toán con mới này.
b Tiến hành kiểm tra các bài toán con vừa được sinh ra Có hai trường hợp :
(1) bài toán con đã được giải quyết – đi tới bước 5 (2) bài toán con chưa được giải quyết – đi tới bước 4.
4 Kiểm tra tính khả thi : Đưa các bài toán con có cận nhỏ hơn kỷ lục tạm thời vào tập hoạt động.
5 Dò xét kết thúc
a Bài toán con được duyệt là một lời giải khả thi khi có cận nhỏ hơn kỷ lục và khi đó nó sẽ thay thế kỷ lục Ngược lại sẽ bị xóa.
b Khi cập nhật kỷ lục mới (5a) thì tất cả các bài toán con trong tập hoạt động có cận dưới lớn hơn hoặc bằng kỷ lục sẽ bị xóa.
Trang 14a Lặp lại các bước từ 2-5 nếu tập hoạt động không rỗng Ngược lại, thì kết thúc thuật toán và lời giải tối ưu là giá trị kỷ lục.
T: lưu trữ lời giải tốt nhất
Пi: các bài toán con được sinh ra
Dưới đây là đoạn mã giả của thuật toán phân nhánh:
Trang 15Ta có thể sử dụng cấu trúc heap và queue để lưu trữ các bài toán con chưa được giải quyết Ở đây chúng tôi sử dụng queue bởi lí do khi số lượng các thành phố là lớn thì không gian bài toán con tăng lên rất nhiều mà heap không thể lưu trữ được.
Queue gồm 3 lớp sau :
• Class bbnode : Định nghĩa các nút trên cây
• Class BandbQueue : Lớp trừu tượng này miêu tả một queue
• Class BranchQueue : Lớp này sử dụng trong suốt giai đoạn phân nhánh
2.2 Xây dựng khung nhánh cận tuần tự
Ta có thể tóm lược hoạt động của thuật toán nhánh cận tuần tự như sau : Tại thời
điểm khởi tạo, tập hoạt động L chứa bài toán ban đầu, và giá trị kỷ lục tạm thời bs là ∝ Lặp đi lặp lại các bước sau cho đến khi tập hoạt động bằng ∅ : Lựa chọn một bài toán
con từ tập hoạt động, bài toán con có lời giải bộ phận là v1, v2, , vi-1 Nếu cận dưới của bài toán con nhỏ hơn kỷ lục tạm thời ta tiến hành phân nhánh thành các bài toán con
nhỏ hơn với lời giải bộ phận tương ứng là (v1, v2, , vi-1+1), , (v1, v2, , N – K + 1),
tiến hành tính cận cho các bài toán con này Nếu các bài toán con đã được giải quyết ta
tiến hành duyệt và cập nhật kỷ lục tạm thời bs, ngược lại thì đưa các bài toán con này
vào tập hoạt động L Sau đây là đoạn mã giả mô phỏng thuật toán nhánh cận tuần tự.
Trang 162.3 Xây dựng khung nhánh cận song song
Để song song hóa khung sử dụng kỹ thuật nhánh cận chúng ta sử dụng chiến
lược chủ - thợ Chiến lược này có thể được định nghĩa như sau: một bộ xử lý chủ giữ tất cả thông tin về không gian trạng thái, nơi mà chứa đựng số lượng các bài toán con chưa được phân nhánh trên cây liệt kê và nó cũng lưu giữ lời giải hiện thời Máy chủ gửi bài toán con tới máy thợ rỗi và nhận các bài toán con mới được phát sinh từ các máy thợ đó Một vài máy thợ định giá những bài toán con và phát sinh thêm những cái mới nếu cần thiết Một máy thợ rỗi nhận một bài toán con chỉ khi có những bài tóan con mà có khả năng dẫn tới một giải pháp tối ưu Chiến lược này đề xuất những sự kiện có ý nghĩa
Trang 17như là khả năng điều khiển dễ dàng và thuật toán nhánh cận song song theo phương pháp dễ hiểu và tự nhiên hơn
- Bộ xử lí chủ: chỉ có một bộ xử lí chủ trong khung Nó chứa tất cả thông tin về
không gian trạng thái và tình trạng của mỗi máy thợ ( bận hoặc rỗi.)
- Bộ xử lí thợ: Số lượng bộ xử lí thợ được xác định bởi tham số đầu vào Nó
thực hiện tất cả những thao tác tính toán để giải quyết hoặc ước lượng một bài toán con.
Sự song song hiển thị cấu trúc trong Hình 4 Máy chủ có một hàng đợi những bài toán chưa được giải quyết Nó loại bỏ mọi bài toán con từ hàng đợi của nó và giao việc của nó tới máy thợ rỗi trong giai đoạn a Trong giai đoạn b, một tập bài toán con của máy thợ đưa đến máy chủ.Trong giai đoạn c, máy chủ nhận những bài toán con và chèn chúng vào trong hàng đợi của nó Cuối cùng, máy chủ loại bỏ những bài toán con có thể thực hiện đc và gửi chúng đến máy thợ rỗi trong giai đoạn d Tiến trình kết thúc khi hàng đợi máy chủ là rỗng và lời giải tốt nhất tìm thấy đc.
Trang 18Hình 5: Các giai đoạn của mô hình Chủ - thợ
Ta nhận thấy rằng mô hình hoạt động ở trên tương đối đơn giản và dễ dàng cài đặt Tuy nhiên nó có một nhược điểm lớn là số lượng bài toán con chỉ tập trung tại máy chủ, điều đó dễ dẫn tới tràn bộ nhớ do số lượng bài toán con này là rất lớn Thêm vào nữa máy chủ luôn phải điều động từng bài toán con tới các máy thợ dẫn tới tăng số lượng công việc tại máy chủ cũng như lưu lượng truyền thông trên mạng là lớn Để giải quyết vấn đề này chúng tôi đề xuất một mô hình dữ liệu phân tán, nghĩa là trên mỗi máy thợ đều có một vùng nhớ để lưu các bài toán con Và bây giờ các bài toán con được chuyển một cách trực tiếp từ máy thợ bận (có nhiều bài toán con) tới máy thợ rỗi (
Trang 19không còn bài toán con để tìm kiếm) dưới sự điều phối của máy chủ Sau đây là thiết kế chi tiết đối với cả hai hệ thống này
2.3.1 Lược đồ song song dữ liệu tập trung
2.3.1.1 Cấu trúc dữ liệu :
Danh sách các bài toán con chưa được giải quyết lưu tại máy chủ, các bài toán con được rời và gửi tới các máy thợ Mỗi máy thợ khi nhận bài toán con tiến hành phân nhánh và lưu các bài toán con vừa mới được sinh ra cùng với cận của nó trong một danh sách cục bộ Sau đó nó gửi tới máy chủ, máy chủ lúc này tiến hành nối các bài toán con nhận được từ danh sách đó nếu cận của nó nhỏ hơn kỷ lục tạm thời Cấu trúc dữ liệu để lưu các bài toán con là một danh sách liên kết kép.
2.3.1.2 Thuật toán
a Thực hiện trên máy chủ
Hình 6 mô tả các công việc được thực hiện trên máy chủ Máy chủ thực hiện phân phối
các bài toán con giữa các máy thợ Máy chủ có một danh sách cục bộ L để lưu trữ bài toán con và cấu trúc dữ liệu I để ghi nhận trạng thái hiện thời của các máy thợ (dòng 1);
Ban đầu tất cả các máy thợ đều rỗi Khi có các máy thợ rỗi, máy chủ liên tục trích lọc từng bài toán con khả thi (có cận nhỏ hơn kỷ lục tạm thời), sau đó lựa chọn một máy thợ rỗi và gửi bài toán con tới nó để tiến hành phân nhánh và ước lượng( dòng 6-7) Nếu danh sách L rỗng hoặc không có máy thợ nào rỗi, máy chủ tiến hành kiểm tra có dữ liệu (là các bài toán con mới sinh ra) được gửi về từ máy thợ hay không Nếu có nó sẽ nhận dữ liệu từ máy thợ là một tập các bài toán con cùng cận dưới của nó Kiểm tra
lần lượt từng bài toán con Nếu bài toán được giải quyết (có số lượng median bằng k),
thì cập nhật kỷ lục và lời giải tạm thời (nếu có cận nhỏ hơn kỷ lục tạm thời) ngược lại nối các bài toán con khả thi vào danh sách L (Dòng 12-17) Quá trình tìm kiếm kết thúc