Thị phân bố nghiệm cho thành phố Đà Nẵng qua các thế hệ

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 51 - 68)

Ghi chú:

 Trục x là giá trị Si 1 (hàm tối ưu cho nhà quản lý bus), trục y là giá trị Si 2 (hàm tối ưu cho người dùng trong toàn mạng lưới) của mô hình bài toán.

 Màu xanh dương là nghiệm khởi tạo ngẫu nhiên ban đầu. Màu vàng là nghiệm tại thế hệ 1. Màu xanh nhạt là thế hệ 50. Màu hồng là nghiệm tại thế hệ 100.

Thời gian chạy chƣơng trình: 56 tiếng.

Cấu hình máy tính chạy chƣơng trình: Intel® Core™ i3-2530M CPU @ 2.3GHZ (4CPUs), RAM 4096MB.

Một nghiệm trong 20 nghiệm:

Sau khi cho chương trình chạy khoảng 100 thế hệ ta được một bộ gồm 20 nghiệm. Hình dưới là minh họa cho 1 nghiệm có các tuyến buýt được phân bố trên bản đồ Google Earth:

Hình 4.4: Các tuyến buýt (trong 1 nghiệm) sau khi tính toán qua 100 thế hệ

Khi đã có một bộ nghiệm, việc chọn lựa một nghiệm phù hợp để đem đi triển khai sẽ do con người thực hiện.

Nhận xét:

 Nghiệm được tối ưu dần qua các thế hệ.

 Dựa vào thông tin trong “output2.txt” ta có dãy số: 9 9 9 9 2 5 5 5 6 7 3 6 5 2 2 2 3 1 2 4 4 4 6 2 7 3 3 2 2 1 5 2 3 1 0 0 1 2 2 4 1 1 0 3 1 2 4… Nhìn vào dãy số có thể thấy 15 thế hệ đầu tiên có sự thay đổi nghiệm rất lớn. Sau 30 thế hệ, sự thay đổi nghiệm đã giảm đi rõ rệt và có xu hướng thay đổi theo chu kỳ 5-6 thế hệ một lần thay đổi nhiều.

 Với nhu cầu đi lại được xây dựng theo thuật toán đơn giản bên trên, các tuyến buýt đầu ra của chương trình chưa bám sát hoàn toàn với thực tế và cần được chỉnh sửa bằng con người. Việc xây dựng nhu cầu đi lại giữa các nút cần nhiều thời gian khảo sát thực tế, nghiên cứu kĩ càng bởi vì nhu cầu càng sát thực tế bao nhiêu thì kết quả chương trình tính toán được càng chính xác bấy nhiêu.

Kết quả này sau khi chỉnh sửa đã được báo cáo tại hai hội thảo ở Việt Nam:

 Hội thảo về giao thông thông minh của thành phố Đà Nẵng (12/2013).

 Hội thảo tối ưu và tính toán khoa học lần thứ 12 của Viện Nghiên cứu cao cấp về Toán – VIASM (23 - 25/04/2014).

4.3. Kết luận

Chương 4 giới thiệu về công cụ bản đồ Google Earth và quá trình xây dựng dữ liệu thử nghiệm cho thành phố Đà Nẵng. Sau đó, giới thiệu về kết quả chạy thử nghiệm chương trình và nhận xét nghiệm qua các thế hệ của bài toán.

KẾT LUẬN

Trong luận văn, tác giả có những đóng góp rõ ràng sau:

 Nghiên cứu một cách tổng quát và có hiểu biết về mô hình hóa mạng lưới giao thông xe buýt.

 Nghiên cứu giải thuật di truyền giải bài toán tối ưu tuyến xe buýt.

 Lập trình phần mềm.

 Thử nghiệm chương trình với thành phố Đà Nẵng.

Tuy nhiên, trong quá trình làm luận văn, tác giả cũng gặp phải một số khó khăn, tiêu biểu như việc định lượng nhu cầu đi lại bằng xe buýt giữa các điểm trong thành phố Đà Nẵng. Trong tương lai gần, tác giả và các đồng nghiệp sẽ tiếp tục hoàn thiện hơn chương trình và áp dụng được trong thực tế.

TÀI LIỆU THAM KHẢO Tiếng Anh

1. K. Deb, et al., “Fast Elitist Non-Dominated Sorting Genetic Algorithm for Multi-Objective Optimization: NSGA-II,” Parallel Problem Solving from Nature VI (PPSN-VI), 2000, pp. 849-858.

2. K. Deb, A. Pratap, S. Agarwal, T. Meyarivan, "A fast and elitist multiobjective genetic algorithm: NSGA-II," IEEE Transactions on Evolutionary Computation 6 (2002), pp. 182–197.

3. G. Gallo and S. Pallottino, “Shortest path methods: a unifying approach,”

Mathematical Programming Study 26 (1963), pp. 38-64.

4. Z. Y. Gao, et al., “A Continuous Equilibrium Network Design Model and Algorithm for Transit System,” Transpotation Research Part B, Vol. 38, No. 3, 2004, pp. 235-250.

5. J. F. Guan, et al., “Simultaneous Optimization of Transit Line Configuration and Passenger Line Assignment,” Transportation Research Part B, Vol. 40, No. 10, 2006, pp. 885-902.

6. K. Kepaptsoglou and M. Karlaftis, “Transit Route Network Design Problem: Review,” Journal of Transportation Engineering-ASCE, Vol. 135, No. 8, 2009, pp. 491-505.

7. F. Kurauchi, et al, "Capacity Constrained Transit Assignment with Common Lines," Journal of Mathematical Modelling and Algorithms, 2 (2003), pp. 309- 327.

8. K. Nachtigall and K. Jerosch, “Simultaneous Network Line Planning and Traffic Assignment,” 2008.

9. S. Nguyen and Pallotino, "Equilibrium assignment for large scale transit network," European J.Oper.Res, 37 (1988), pp. 176-186.

10. M. Petrelli, “A Transit Network Design Model for Urban Areas,” In: C. A. Brebbia and L. C. Wadhwa, Eds., Ur-ban Transport X, WIT Press, Southampton, 2004, pp.163-172.

11. H. Shimamoto, et at., “Evaluation of Public Transit Congestion Mitigation Measures Using Passenger Assignment Model,” Journal of Eastern Asia Transportation Studies, Vol. 6, 2005, pp. 2076-2091.

12. H. Shimamoto, et al., “Evaluation of an Existing Bus Network Using a Transit Network Optimisation Model: A Case Study of the Hiroshima City Bus Network,” Transportation, Vol. 37, No. 5, 2010, pp. 801-823.

13. H. Shimamoto, J-D. Schmöcker, F. Kurauchi, "Optimisation of a Bus Network Configuration and Frequency Considering the Common Lines Problem", Journal of Transportation Technologies, 2 (2012), pp. 220-229.

14. A. Zhou, B. Qu, H. Li, S. Zhao, P. N. Zhang, survey paper: "Multiobjective evolutionary algorithms: A survey of the state of the art", Swarm and Evolutionary Computation, 1 (2011), pp. 32-49.

15. J. Zhou, and W. H. K. Lam., “A Bi-Level Programming Approach – Optimal Transit Fare under Line Capacity Constraints,” Journal of Advanced Transportation, Vol. 35, No. 2, 2000, pp. 105-124.

PHỤ LỤC

Mã nguồn tập tin DSHT.cpp mô phỏng thuật toán tìm hypertree nhỏ nhất:

#include "DSHT.h" #include <iostream> #include <fstream> #include <algorithm> #include <vector> using namespace std;

const double maxC = 1000000000; // maximum value of cost // implement the n-elements binary heap tree

class HeapTree { private: int n; int *data; public: // initialisation HeapTree(int maxSizeOfHeap) { n = 0;

data = new int[maxSizeOfHeap + 2]; }

~HeapTree() {

delete []data; }

// compare two node j and jj in heap tree

bool lessCompare(int j, int jj, vector<vector<int> > bs, double **a, double **cost, int s)

{

int ii = bs[jj].back();

return (a[i][j] + cost[j][s] < a[ii][jj] + cost[jj][s]); }

// get a node from heap tree, if bs[node] equals 0 remove from tree, update value.

int popHeap(vector<vector<int> >bs, double **a, double** cost, int s) {

// get first element, remove last element. if (n == 0) return 0;

int value = data[1]; if (bs[value].size() == 1) {

data[1] = data[n]; n--;

}

// update heap tree int p = 1;

while (p * 2 <= n && lessCompare(data[p * 2], data[p], bs, a, cost, s)) {

if (p * 2 + 1 <= n && lessCompare(data[p * 2 + 1], data[p * 2], bs, a, cost, s)) { int tmp = data[p]; data[p] = data[p * 2 + 1]; data[p * 2 + 1] = tmp; p = p * 2 + 1; continue; } int tmp = data[p]; data[p] = data[p * 2]; data[p * 2] = tmp; p = p * 2; }

return value; }

// push new node into heap tree, update heap tree

void pushHeap(int value, vector<vector<int> > bs, double **a, double **cost, int s)

{

if (bs[value].empty()) return; n++;

data[n] = value; // update heap tree int p = n;

while (p/2 > 0 && lessCompare(data[p], data[p/2], bs, a, cost, s)) { int tmp = data[p]; data[p] = data[p/2]; data[p/2] = tmp; p = p/2; } } bool isEmpty() { return (n == 0); } }; struct CustomLess { private: double **a; int last; public:

CustomLess(double ** a, int last) {

this->a = a; this->last = last;

}

bool operator()(int i, int j) {

return (a[i][last] > a[j][last]); // compare to a[i][node] and a[j][node] value }

};

DSHT::DSHT(int vn, double **va, double ** vb) { //ctor n = vn; a = va; b = vb; initData(); } DSHT::~DSHT() {

for (int i = 0; i < n; i++) delete[] c[i]; delete []c; delete []br; bs.clear(); fs.clear(); r.clear(); } double** DSHT::getC() { return c; } void DSHT::initData() { c = new double* [n];

br = new double[n]; bs.resize(n);

fs.resize(n); r.resize(n);

for (int i = 0; i < n; i++) { bs[i].clear(); fs[i].clear(); r[i].clear(); br[i] = 0; }

for (int i = 0; i < n; i++) for (int j = 0; j < n; j++)

if (a[i][j] > 0 && b[i][j] > 0) {

bs[j].push_back(i); fs[i].push_back(j); }

// sort all node in bs[i] sets for (int i = 0; i < n; i++) {

CustomLess customLess(a, i);

sort(bs[i].begin(), bs[i].end(), customLess); }

for (int i = 0; i < n; i++)

for (int j = 0; j < n; j++) c[i][j] = -1; }

void DSHT::process(int s) {

vector<vector<int> > tmpBs(bs), tmpFs(fs), tmpR(r); for (int i = 0; i < n; i++) br[i] = 0;

double ** cost;

for (int i = 0; i < n; i++) {

cost[i] = new double[n]; cost[i][s] = maxC; }

//init data cost[s][s] = 0; HeapTree q(n);

// push node S into heap tree q.pushHeap(s, bs, a, cost, s);

// loop while q is not empty. start dantzig shortest hyper tree algorithm while (!q.isEmpty())

{

int j = q.popHeap(bs, a, cost, s); int i = bs[j].back();

bs[j].pop_back();

if (cost[i][s] > cost[j][s] + a[i][j]) {

if (r[i].empty()) {

r[i].push_back(j); br[i] = b[i][j];

cost[i][s] = cost[j][s] + a[i][j] + 1/b[i][j]; q.pushHeap(i, bs, a, cost, s); } else { r[i].push_back(j); br[i] += b[i][j];

cost[i][s] = cost[i][s] - (cost[i][s] - cost[j][s] - a[i][j]) * b[i][j] / br[i]; }

} }

if (cost[i][s] < maxC) c[i][s] = cost[i][s]; for (int i = 0; i < n; i++) delete[] cost[i]; delete [] cost; bs = tmpBs; fs = tmpFs; r = tmpR; tmpBs.clear(); tmpFs.clear(); tmpR.clear(); }

Mã nguồn thuật toán lai ghép và đột biến

void BusNetwork::randomLines() {

cout << "Begin to randomize line" << endl; bool mark[n];

for (int i = 0; i < L; i++) {

while (true) {

for (int j = 0; j < n; j++) mark[j] = true; int index = 0; int counter = 0; int start = n-1; while (true) { counter++; mark[index] = false; if (index == n-1) break;

if (isDesNode[index] && counter >= maxNumNode) { lines[i][index] = n-1; index = n-1; continue; } int node = 0;

int whileCount = 0;

while ((mark[node] == false) || ((node == n-1) && (counter <= minNumNode)))

{

whileCount++;

if (whileCount > n) break;

int pos = rand() % next[index].size(); node = next[index][pos]; if (C[start][node] > -1) node = 0; } if (whileCount > n) break; lines[i][index] = node; start = index; index = node; } if (mark[n-1]) continue; for (int j = 0; j < n; j++) if (mark[j]) {

int pos = rand() % next[j].size(); int node = next[j][pos];

lines[i][j] = node; } break; } } int total = NV;

for (int i = 0; i < L; i++) {

int maxBus = maxNumBus;

if (total < maxNumBus) maxBus = total; int num = rand() % (maxBus + 1);

busNum[i] = num; total = total - num; }

}

bool BusNetwork::doMutation() {

cout << "Begin to do mutation" << endl; int tmpLine[n];

int random; bool mark[n];

for (int i = 0; i < L; i++) { int loop = 0; while (true) { ++loop; if (loop > loopLim) { return false; } for (int j = 0; j < n; j++) { mark[j] = true; tmpLine[j] = lines[i][j]; } int index = 0; int counter = 0; int start = n-1; while (true) { counter++; mark[index] = false; if (index == n-1) break;

if (isDesNode[index] && (counter >= maxNumNode)) {

tmpLine[index] = n-1; index = n-1;

continue; }

int node = tmpLine[index]; int whileCount = 0;

random = rand() % 100;

if (random < rate || mark[node] == false || (node == n-1) && (counter < minNumNode))

{

node = 0;

while (((node == n-1) && (counter < minNumNode)) || (mark[node] == false))

{

whileCount++;

if (whileCount > n) break;

int pos = rand() % next[index].size(); node = next[index][pos]; if (C[start][node] > -1) node = 0; } } if (whileCount > n) break; tmpLine[index] = node; start = index; index = node; } if (mark[n-1]) continue; for (int j = 0; j < n; j++) if (mark[j]) {

int pos = rand() % next[j].size(); int node = next[j][pos];

lines[i][j] = node; }

else lines[i][j] = tmpLine[j]; break;

} }

int total = NV;

{

int num = busNum[i]; int random = rand() % 100; if (random < rate || total < num) {

int maxBus = maxNumBus;

if (total < maxNumBus) maxBus = total; num = rand() % (maxBus + 1);

}

busNum[i] = num; total = total - num; }

return true; }

bool BusNetwork::doCrossover(BusNetwork bus, BusNetwork &tmp) {

cout << "Begin to do crossover" << endl; int** tmpLines;

int* tmpBusNum;

tmpBusNum = new int[L]; tmpLines = new int*[L];

for (int i = 0; i < L; i++) tmpLines[i] = new int[n]; int** secondLines = bus.getLines();

int* secondBusNum = bus.getBusNum(); bool mark[n];

for (int i = 0; i < L; i++) { int loop = 0; while (true) { loop++; if (loop > loopLim) { return false; }

for (int j = 0; j < n; j++) mark[j] = true; int index = 0; int counter = 0; int start = n-1; while (true) { counter++; mark[index] = false; if (index == n-1) break;

if (start == 0 && index != 0) start = index;

if (isDesNode[index] && counter >= maxNumNode) { tmpLines[i][index] = n-1; index = n-1; continue; } int node = 0; int whileCount = 0;

while ((mark[node] == false) || ((node == n-1) && (counter <= minNumNode)))

{

whileCount++;

if (whileCount > n) break; int pos = rand() % 2;

if (pos == 0) node = lines[i][index]; else node = secondLines[i][index]; } if (whileCount > n) break; tmpLines[i][index] = node; start = index; index = node; } if (mark[n-1]) continue; for (int j = 0; j < n; j++) if (mark[j]) { int node;

int pos = rand() % 2;

if (pos == 0) node = lines[i][j]; else node = secondLines[i][j]; tmpLines[i][j] = node; } break; } } int total = NV;

for (int i = 0; i < L; i++) {

int num;

int random = rand() % 2;

if (random == 0) num = busNum[i]; else num = secondBusNum[i]; if (num > total)

{

int maxBus = maxNumBus;

if (total < maxNumBus) maxBus = total; num = rand() % (maxBus + 1);

}

tmpBusNum[i] = num; total = total - num; }

tmp.setBusNum(tmpBusNum); tmp.setLines(tmpLines);

return true; }

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 51 - 68)

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

(68 trang)