Giải bài toán TRDNP

Một phần của tài liệu (LUẬN văn THẠC sĩ) áp dụng thuật toán di truyền giải bài toán tối ưu tuyến xe buýt (Trang 28)

Như trình bày ở Chương 1, bài toán TRNDP là bài toán tối ưu hai mức với mức trên là bài toán tối ưu đa mục tiêu. Để giải bài toán ở mức trên, ta sử

dụng thuật toán non-dominated sorting genetic algorithm (NSGA-II) [1, 2] được đề xuất trong tài liệu tham khảo.

Trong phần này, ta sẽ mô tả thuật toán bao gồm 6 thủ tục: phân công xe, thiết kế tuyến, thiết lập tần suất, thủ tục chính, lai ghép và đột biến, và phân lớp. [13]

2.3.1. Phân công xe

Hình 2.3: Nhiễm sắc thể mô tả thủ tục phân công xe. [13]

Hình 2.3 mô tả nhiễm sắc thể ứng với việc phân xe buýt vào các tuyến. Có hai kiểu gien trong nhiễm sắc thể: gien A biểu diễn 1 xe buýt và gien B là biên, chỉ rõ mỗi tuyến xe có bao nhiêu xe. Số lượng gien A bằng với số lượng xe hiện có và số lượng gien B ít hơn số lượng tuyến xe buýt một đơn vị. Sử dụng kiểu nhiễm sắc thể này, số xe được phân cho một tuyến sẽ bằng số gien A nằm giữa hai gien B.

Ví dụ 2.4. Hình trên cho thấy: có 2 xe được phân vào tuyến 1, có 3 xe được phân vào tuyến 2 và tuyến 3 không được phân xe.

2.3.2. Thiết kế tuyến

Trong mục này, ta mô tả việc việc xây dựng tuyến xe buýt xuất phát và kết thúc tại 2 địa điểm định trước.

Nhiễm sắc thể mô tả việc thiết kế tuyến có độ dài bằng số đỉnh N của đồ thị biểu diễn mạng xe buýt. Mỗi gien nhận một giá trị tương ứng với một đỉnh nào đó. Nếu tuyến xe nối m với nút n, thì gien thứ m sẽ nhận giá trị là n. Do đó, việc sắp xếp các gien trong nhiễm sắc thể sẽ cung cấp cho ta một dãy các đỉnh

tạo nên một tuyến xe. Cũng vì vậy, có hai kiểu gien: kiểu gien biểu diễn nút trong tuyến xe và kiểu còn lại thì không.

Hình 2.4: (a) Đồ thị ví dụ. (b) Nhiễm sắc thể mô tả công việc thiết kế tuyến.

Ví dụ 2.5. Hình 2.4a mô tả đồ thị với 8 đỉnh và Hình 2.4b mô tả một nhiễm sắc thể biểu diễn tuyến xe xuất phát tại nút 0 và kết thúc tại nút 7: 0 - 1 - 4 - 6 - 7. Các gien hình vuông biểu diễn một nút trong tuyến xe, các gien hình tròn không biểu diễn nút nào trong tuyến xe và được gán ngẫu nhiên một đỉnh chưa được đưa vào tuyến xe.

2.3.3. Thiết lập tần suất

Việc thiết lập tần suất tuyến xe là kết quả của thủ tục phân công xe và thiết kế tuyến. Tần suất của mỗi tuyến xe được xác định theo công thức: [13]

, 2 l l l V f l L T    trong đó:

Tl là tổng thời gian đi trên tuyến xe l,

2.3.4. Các bước chính trong xử lý bài toán TRNDP

Hình 2.5: Mô hình chọn lọc cá thể qua các thế hệ [2]

Giải thuật di truyền áp dụng trong bài toán thiết kế tuyến buýt được thực hiện qua các bước sau: [2]

 B1: Sinh ngẫu nhiên N bộ nghiệm: L tuyến xe và phân bố số lượng xe trên mỗi tuyến.

 B2: Dựa vào 2 phép là lai ghép và đột biến sinh ra N bộ nghiệm khác từ N bộ nghiệm ban đầu.

 B3: Từ 2N bộ nghiệm chuyển thành 2N đồ thị với chi phí cụ thể để tính hai hàm mục tiêu 𝜓1, 𝜓2 dựa vào bài toán mức dưới shortest hyper path đã được lập trình trước đó.

 B4: Thực hiện thuật toán phân lớp các nghiệm để chọn ra N nghiệm tốt nhất (Tại bước này có 2 thuật toán con là phân lớp các nghiệm và chọn các nghiệm giãn cách nhau trên cùng 1 đường cong pareto).

 B5: Lặp từ B2 đến B4 M lần.

2.3.5. Thuật toán lai ghép và đột biến

Hình 2.6: (a) Thuật toán lai ghép. (b) Thuật toán đột biến [13]

Các kí hiệu dùng trong thuật toán:

 r: nút nguồn

 s: nút đích

 N: tập các nút trong mạng lưới

 g[*]: gien của cá thể cha

 h[*]: gien của cá thể con

 𝑀𝑟𝑎𝑡𝑒: tỉ lệ xảy ra đột biến Thuật toán lai ghép: [13]

 B1: Khởi tạo

Gán 𝑚 ← 𝑟 và 𝑕[𝑛] ← ∅ với 𝑛 ∈ 𝑁;

 B2: Chọn ngẫu nhiên hai cá thể cha 𝑔1 và 𝑔2;

 B3: Thực hiện lai ghép

Chọn ngẫu nhiên một cá thể cha 𝑖 (𝑖 = 1,2) và 𝑕 𝑚 ← 𝑔𝑖 𝑚 , 𝑚 ←

 B4: Lặp B3 đến khi 𝑚 = 𝑠;

 B5: Nếu 𝑔 𝑚 = ∅ (𝑚 ∈ 𝑁) thì chọn một nút 𝑛 đi ra từ nút 𝑚 và

𝑔[𝑚] ← 𝑛.

Hình 2.6(a) ở trên là ví dụ minh họa cho thuật toán lai ghép. Sau khi lai ghép hai tuyến cha 0-1-4-6-7 và 0-2-1-3-7 ta có tuyến con là 0-1-4-5-6-7.

Thuật toán đột biến: [13]

 B1: Khởi tạo

Gán 𝑚 ← 𝑟 và 𝑕[𝑛] ← ∅ với 𝑛 ∈ 𝑁;

 B2: Đột biến

Sinh một số ngẫu nhiên rnd;

Nếu 𝑟𝑛𝑑 < 𝑀𝑟𝑎𝑡𝑒 thì chọn một nút 𝑛 đi ra từ nút 𝑚 và 𝑕 𝑚 ← 𝑛, 𝑚 ← 𝑛;

Nếu không thì 𝑕 𝑚 ← 𝑔 𝑚 , 𝑚 ← 𝑔 𝑚 ;

 B3: Lặp B2 cho đến khi 𝑚 = 𝑠;

 B4: Nếu 𝑔 𝑚 = ∅, 𝑚 ∈ 𝑁 thì chọn một nút 𝑛 đi ra từ nút 𝑚 và 𝑔[𝑚] ←

𝑛.

Hình 2.6(b) ở trên là ví dụ minh họa cho thuật toán đột biến. Sau khi đột biến tuyến xe 0-1-4-6-7 trở thành tuyến 0-2-4-6-7.

2.3.6. Thuật toán phân lớp các nghiệm

Thuật toán fast-non-dominated-sort(P) phân lớp các nghiệm pareto: [2]

 Với mỗi 𝑝 ∈ 𝑃 o 𝑆𝑝 = ∅ o 𝑛𝑝 = 0 o Với mỗi 𝑞 ∈ 𝑃  Nếu 𝑝 < 𝑞 thì 𝑆𝑝 = 𝑆𝑝 ∪ {𝑞}  Nếu 𝑞 < 𝑝 thì 𝑛𝑝 = 𝑛𝑝 + 1 o Nếu 𝑛𝑝 = 0 thì  𝑝𝑟𝑎𝑛𝑘 = 1  𝐹1 = 𝐹1 ∪ {𝑝}  𝑖 = 1  While 𝐹i ≠ ∅ o 𝑄 = ∅ o Với mỗi 𝑝 ∈ 𝐹𝑖 o Với mỗi 𝑞 ∈ 𝑆𝑝  𝑛𝑞 = 𝑛𝑞 − 1  Nếu 𝑛𝑞 = 0 thì

 𝑞𝑟𝑎𝑛𝑘 = 𝑖 + 1

 𝑄 = 𝑄 ∪ {𝑞}

o 𝑖 = 𝑖 + 1

o 𝐹𝑖 = 𝑄

Trong hình 2.5 ở trên, các cá thể được phân lớp theo thuật toán fast-non- dominated-sort và chọn ưu tiên bắt đầu từ lớp 1. Khi các cá thể được chọn trong lớp 3 nhiều hơn N cá thể thì phải phân loại các cá thể sao cho khoảng cách giữa các nghiệm trải đều trên đường cong pareto của lớp 3. Thuật toán tính khoảng cách được trình bày bên dưới:

Hình 2.7: Khoảng cách giữa các cá thể trên đường cong pareto [2]

Thuật toán crowding-distance-assignment(I): [1,2]

 𝑙 = 𝐼

 Với mỗi 𝑖, gán 𝐼[𝑖]𝑑𝑖𝑠𝑡𝑎𝑛𝑐𝑒 = 0

 Với mỗi mục tiêu tối ưu 𝑚

o 𝐼 = 𝑠𝑜𝑟𝑡(𝐼, 𝑚)

o 𝐼[1]𝑑𝑖𝑠𝑡𝑎𝑛𝑐𝑒 = 𝐼[𝑙]𝑑𝑖𝑠𝑡𝑎𝑛𝑐𝑒 = ∞

o For 𝑖 = 2 𝑡𝑜 (𝑙 − 1)

o 𝐼[𝑖]𝑑𝑖𝑠𝑡𝑎𝑛𝑐𝑒 = 𝐼[𝑖]𝑑𝑖𝑠𝑡𝑎𝑛𝑐𝑒 + (𝐼 𝑖 + 1 . 𝑚 − 𝐼 𝑖 − 1 . 𝑚)/(𝑓𝑚𝑚𝑎𝑥 −

𝑓𝑚𝑚𝑖𝑛)

Ý tưởng cơ bản đằng sau thuật toán này là tìm khoảng cách Euclid giữa các cá thể với nhau dựa số lượng mục tiêu cần tối ưu 𝑚. Các giá trị ở biên bao giờ cũng được chọn vì chúng được gán khoảng cách xa nhất.

Sau khi tính xong các giá trị khoảng cách, ta chọn các cá thể có giá trị khoảng cách tính được lớn nhất trong dãy.

Như vậy, các cá thể con trong quần thể được sinh ra từ N cá thể cha ban đầu bằng các phép lai ghép và đột biến được mô phỏng giống như trong tự nhiên. Sau đó, tất cả 2 * N cá thể được đánh giá mức độ tốt-xấu dựa vào 𝑚 hàm mục tiêu tương ứng với 𝑚 mục tiêu tối ưu theo yêu cầu đặt ra của bài toán. Sau

khi đã có sự đánh giá, các cá thể được lựa chọn tồn tại trong thế hệ tiếp theo có giá trị tốt hơn so với các cá thể khác. Thuật toán phân lớp và tính khoảng cách sẽ giúp lựa chọn ra N cá thể tốt nhất cho thế hệ tiếp theo. N cá thể này được phân bố đều trên bề mặt đường cong pareto. Quá trình trên sẽ tiếp diễn đến khi kết quả sinh ra được chấp nhận. Thuật toán di truyền tìm nghiệm tối ưu cho thiết kế tuyến và tần suất xe buýt đã được viết thành chương trình và sẽ trình bày cụ thể hơn trong chương sau.

2.4. Kết luận

Chương 2 trình bày một số kiến thức tổng quan về tối ưu đa mục tiêu và thuật toán di truyền. Sau đó, đưa ra lời giải áp dụng thuật toán di truyền cho bài toán thiết kế tuyến và tần suất xe buýt tối ưu hai mục tiêu.

CHƢƠNG 3 – CHƢƠNG TRÌNH MÔ PHỎNG THUẬT TOÁN DI TRUYỀN GIẢI BÀI TOÁN THIẾT KẾ TUYẾN VÀ TẦN SUẤT XE

BUÝT 3.1. Công cụ phát triển chƣơng trình

Thuật toán di truyền trong đề tài được lập trình bằng ngôn ngữ C++, và được quản lý mã nguồn bằng môi trường phát triển tích hợp (IDE - Integrated Development Environment) Code::Blocks.

3.1.1. Giới thiệu tổng quan về C++

C++ là một dạng ngôn ngữ đa mẫu hình tự do có kiểu tĩnh và hỗ trợ lập trình thủ tục, dữ liệu trừu trượng, lập trình hướng đối tượng, và lập trình đa hình. Từ thập niên 1990, C++ đã trở thành một trong những ngôn ngữ thương mại phổ biến nhất trong khi đó. C++ có hai phần chính: phần ngôn ngữ cốt lõi và phần Thư viện chuẩn C++(STL - Standard Template Library). Chương trình có sử dụng một số cấu trúc dữ liệu và hàm trong thư viện STL của C++.

Thư viện chuẩn C++ dùng lại thư viện chuẩn C với một số điều chỉnh nhỏ để giúp nó hoạt động tốt hơn với ngôn ngữ C++. Một bộ phận lớn khác của thư viện C++ dựa trên Thư viện chuẩn (STL). Thư viện này có nhiều công cụ hữu dụng như: vectors, lists, maps, algorithms, sets, queues, stacks, arrays, etc. Ngoài ra, thư viện có hỗ trợ dùng template để viết các thuật toán tổng quát mà chúng làm việc được với bất kì cấu trúc dữ liệu nào.

Một chức năng quan trọng của C++ được áp dụng trong chương trình là hướng đối tượng. C++ hỗ trợ hướng đối tượng với 4 tính năng chính: tính trừu tượng, tính bao đóng, tính đa hình, và tính kế thừa. Bên cạnh đó, các đặc điểm sau về thiết kế cũng giúp cho C++ trở thành một ngôn ngữ phổ biến thông dụng hiện nay. Đó là:

 C++ được thiết kế để là một ngôn ngữ tổng quát có kiểu tĩnh mà lại hữu hiệu và năng động như C.

 C++ được thiết kế nhằm hỗ trợ trực tiếp và đầy đủ nhiều kiểu lập trình như là lập trình cấu trúc, sự trừu tượng của dữ liệu, lập trình hướng đối tượng, và lập trình tổng quát.

 C++ được thiết kế để người lập trình có cơ hội lựa chọn ngay cả khi điều này có thể dẫn tới sự chọn lựa sai lầm của người lập trình.

 C++ được thiết kế để tương thích với C càng nhiều càng tốt, do đó, có cung ứng một sự chuyển đổi (ngôn ngữ) rất thuận tiện từ C.

 C++ tránh các chức năng mà chúng thuộc về dặc điểm riêng của nền tảng hay của mục đích chung chung.

 C++ không lệ thuộc vào các phần bổ sung cho các tính năng thừa

 C++ được thiết kế để hoạt động mà không cần phải có môi trường lập trình hoàn thiện.

3.1.2. Giới thiệu tổng quan về Code::Blocks

Code::Blocks là IDE mã nguồn mở miễn phí chạy trên nhiều platform có hỗ trợ nhiều trình biên dịch GCC, Clang,… IDE này được phát triển bằng C++ sử dụng framework wxWidget làm bộ công cụ giao diện người dùng (GUI – graphic user interface). Sử dụng một kiến trúc kiểu plugin, các tính năng của Code::Blocks được mở rộng bằng cách plugins tương ứng.

Hình 3.1: Giao diện đồ họa của Code::Blocks

Một số các đặc điểm chính của Code::Blocks:

 Trình biên dịch: Code::Blocks hỗ trợ nhiều trình biên dịch bao gồm: GCC, MinGW, Digital Mars, Microsoft Visual C++, Borland C++, LLVM Clang, Watcom, LCC and the Intel C++ compiler. Mặc dù IDE này được thiết kế cho ngôn ngữ C++ những cũng nó hỗ trợ cho các ngôn ngữ khác như Fortran và D thông qua plugin của hệ thống.

 Trình soạn thảo mã nguồn: IDE có chức năng tô sáng lỗi cú pháp, cuộn các khối mã nguồn, tự điền đầy đủ các từ khóa C++, các lớp. Ngoài ra nó

có trình soạn thảo hex và nhiều tiện ích khác. Các tập tin được quản lý theo các tab. Người dùng cũng có thể chỉnh cỡ chữ, và các tùy chỉnh màu sắc khác.

 Trình sửa lỗi: Code::Blocks hỗ trợ đầy đủ tính năng breakpoint. Nó cũng cho phép người dùng sửa lỗi chương trình bằng cách truy cập đến các hàm địa phương, hiển thị các tham số, truy vết gọi hàm, kết xuất bộ nhớ, chuyển thread, đăng ký CPU và giao diện sửa lỗi GNU.

 Giao diện: Như hình minh họa 3.1 bên trên.

 Tiếp nhận mã nguồn từ IDE khác: Một số tính năng của Code::Blocks cho phép người dùng chuyển mã nguồn từ các IDE khác sang như: Dev-C++, Microsoft Visual C++,…

 Tập tin project và hệ thống build chương trình: Code::Blocks lưu các thông tin của project trong các file XML. Nó cũng có thể sử đụng các makefiles bên ngoài, tương tác với project thông qua hệ thống build của GNU hoặc qmake.

3.2. Giới thiệu về chƣơng trình

Chƣơng trình bao gồm hai thành phần chính:

 Thành phần thứ nhất là module chức năng mô phỏng thuật toán DSHT đã trình bày bên trên. Module này viết dưới dạng thư viện, và được include vào trong project.

 Thành phần thứ hai của chương trình là module mô phỏng thuật toán di truyền bao gồm các thuật toán con bên trong: lai ghép, đột biến, phân lớp nghiệm, tính khoảng cách nghiệm, tiền xử lý dữ liệu,…

Đầu vào chƣơng trình bao gồm:

 n: số lượng các nút trên đồ thị.

 numDes: số lượng các nút trên đồ thị là điểm đầu cuối của tuyến xe.

 N: số lượng các nghiệm của mô hình.

 M: số bước lặp quá trình sinh nghiệm.

 L: số lượng các tuyến xe bus.

 NV: tổng số xe phân cho L tuyến. Có thể có tuyến không đươc phân xe.

 Ma trận kích thước n x n C: chi phí tính theo thời gian (đơn vị phút) cho hai đỉnh i,j có đường đi từ i đến j. Nếu từ i đến j có đường đi thì C[i][j] >=0, ngược lại C[i][j] = -1.

 Ma trận kích thước n x n D: nhu cầu lưu lượng người đi giữa hai đỉnh i,j trên đồ thị. Nếu có lưu lượng người đi giữa 2 đỉnh i và j thì D[i][j] > 0, ngược lại bằng 0.

 Alpha: Hệ số tính cho chi phí đi bus (trong mô hình khi tính chi phí trên cung i,j sẽ lấy alpha x C[i][j]).

 Beta: Hệ số tính cho chi phí đi bộ (tương tự lấy như trên khi tính chi phí đi bộ từ i đến j sẽ lấy beta x C[i][j]).

Ghi chú:

 Ma trận nhập vào được đánh số hàng và cột từ 1, thứ tự các đỉnh bắt đầu từ 1.

 Trong mô hình bài báo có thêm tham số Cmax là thời gian đối đa cho 1 tuyến xe bus nhưng sẽ lược bỏ trong lập trình vì trong quá trình tối ưu những tuyến xe có thời gian dài sẽ tự nhiên bị loại bỏ do là nghiệm không tốt.

Đầu ra của chƣơng trình:

Kết quả của chương trình là một tập hợp gồm N nghiệm trên đường cong pareto tối ưu, mỗi nghiệm là L tuyến xe cùng với phân bố số lượng xe bus trên từng tuyến đó. Lúc này có thể chọn một nghiệm sao cho có được thứ tự ưu tiên hợp lý của hai hàm mục tiêu.

Biểu diễn nghiệm của chƣơng trình:

Ngoài các biến tham số là đầu vào của mô hình kể trên, thành phần trọng tâm của chương trình là biểu diễn cấu hình của một mạng lưới tuyến và tần suất xe buýt. Một nghiệm hợp lệ có thiết kế tuyến buýt sao cho bắt đầu và kết thúc một tuyến thuộc các đỉnh đầu và cuối tuyến, đồng thời không có chu trình đơn trong tuyến xe đó. Một nghiệm của chương trình được biểu diễn dưới dạng lớp như sau:

class BusNetwork {

protected: int id;

double si1, si2, distance; int classNum; int *busNum; int **lines; public: BusNetwork(); void randomLines(); bool doMutation();

bool doCrossover(BusNetwork bus, BusNetwork &tmp); void computeCost();

… };

Trong đó ý nghĩa của các thuộc tính là:

 Id: số thứ tự của nghiệm (cá thể).

 Si2: chi phí đi lại của người dân trên toàn bộ mạng lưới.

Một phần của tài liệu (LUẬN văn THẠC sĩ) áp dụng thuật toán di truyền giải bài toán tối ưu tuyến xe buýt (Trang 28)

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

(68 trang)