1. Trang chủ
  2. » Công Nghệ Thông Tin

Đồ án cấu trúc dữ liệu và giải thuật đề tài tìm luồng cực đại

16 245 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Tìm luồng cực đại trên mạng
Tác giả Võ Văn Hùng
Người hướng dẫn GVHD: Phan Thanh Tao
Trường học Đại học Đà Nẵng
Chuyên ngành Công nghệ thông tin
Thể loại Đồ án
Năm xuất bản 2019
Thành phố Đà Nẵng
Định dạng
Số trang 16
Dung lượng 1,16 MB

Nội dung

Đồ án giải thuật và lập trình trường đại học bách khoa đà nẵng khoa công nghệ thông tin, đề tài luồng cực đại trên mạng. Đồ án cấu trúc giải thuật và lập trình trường đại học bách khoa đà nẵng khoa công nghệ thông tin, đề tài tìm luồng cực đại trên mạng

Trang 1

ĐẠI HỌC ĐÀ NẴNG ĐẠI HỌC BÁCH KHOA KHOA CÔNG NGHỆ THÔNG TIN

ĐỒ ÁN

CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT

Đề tài 2:

Tìm luồng cực đại trên mạng

GVHD : PHAN THANH TAO SVTH : VÕ VĂN HÙNG LỚP : 17T2

NHÓM : 17.12B

Đà Nẵng 12-2019

Trang 2

LỜI MỞ ĐẦU

Luồng cực đại là một trong những bài toán tối ưu trên đồ thị tìm được những

ứng dụng rất rộng rãi trong cả thực tế cũng như trong lý thuyết tổ hợp Bài toán được đề xuất vào đầu những năm 1950 và gắn liền với tên tuổi của 2 nhà toán học Mỹ Lester Randolph FordDelbert Ray Fulkerson [1] Bài toán tìm luồng cực đại được áp

dụng nhiều trong thực tiễn cuộc sống như: tính toán lượng nước lớn nhất có thể vận chuyển giữa hai địa điểm (điểm phát và điểm thu) trong một mạng ống nước; xác định cường độ dòng vận tải lớn nhất giữa hai nút của hệ thống giao thông trong thành phố hoặc bài toán ghép cặp hay bài toán lập lịch

Trong báo cáo này, em sẽ trình bày bài toán tìm luồng cực đại trong mạng sử

dụng thuật toán Ford-Fulkerson để giải quyết bài toán đặt ra

Em xin chân thành cảm ơn thầy Phan Thanh Tao đã hướng dẫn và giúp đỡ em

trong suốt quá trình nghiên cứu và tìm hiểu để hoàn thành đề tài này Rất mong nhận được sự góp ý của thầy (cô) để đề tài của em được hoàn thiện hơn

Trang 3

MỤC LỤC

LỜI MỞ ĐẦU 2

MỤC LỤC 3

DANH MỤC HÌNH VẼ 4

1 GIỚI THIỆU ĐỀ TÀI 5

2 CƠ SỞ LÝ THUYẾT 5

2.1 Ý tưởng 5

2.2 Cơ sở lý thuyết 5

3 TỔ CHỨC CẤU TRÚC DỮ LIỆU VÀ THUẬT TOÁN 7

3.1 Phát biểu bài toán 7

3.2 Cấu trúc dữ liệu 8

3.3 Thuật toán 8

4 CHƯƠNG TRÌNH VÀ KẾT QUẢ 9

4.1 Tổ chức chương trình 9

4.2 Ngôn ngữ cài đặt 13

4.3 Kết quả 13

4.3.1 Giao diện chính của chương trình 13

4.3.2 Kết quả thực thi của chương trình 14

4.3.3 Nhận xét 15

5 KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN 15

5.1 Kết luận 15

5.2 Hướng phát triển 15

TÀI LIỆU THAM KHẢO 16

Trang 4

DANH MỤC HÌNH VẼ

Hình 1: Mạng G……….…….6

Hình 2: Mạng G và luồng trên mạng G……… ……… 6

Hình 3: File input.txt……… 8

Hình 4: File output.txt……… … 8

Hình 5: Giao diện chính của chương trình……… 14

Hình 6: Đồ thị và luồng cực đại của mạng G……… 14

Hình 7: File output.txt……… 15

Trang 5

1 GIỚI THIỆU ĐỀ TÀI

“Tìm luồng cực đại trên mạng”

Nhiều bài toán quy hoạch tuyến tính có thể quy về bài toán làm cực tiểu phí tổn vận chuyển hàng trong một mạng (gồm các nút và các cung đường) sao cho đảm bảo được các nhu cầu ở một số nút khi đã biết nguồn cung cấp tại một số nút khác Các bài

toán như vậy được gọi là các bài toán luồng trên mạng (network flow problem) hoặc bài toán chuyển vận (transshipment problem) Đây là lớp bài toán quan trọng nhất và

hay gặp nhất trong quy hoạch tuyến tính Lớp này bao gồm các bài toán quen thuộc trong thực tế như: bài toán vận tải, các bài toán mạng điện và mạng giao thông, các bài toán quản lý và phân bổ vật tư, bài toán đường ngắn nhất, bài toán luồng cực đại…

Bài toán tìm luồng cực đại là một bài toán tối ưu trên đồ thị mang tính thực tiễn,

ứng dụng cao trong cuộc sống như: tính toán lưu lượng nước (dầu) lớn nhất có thể vận chuyển giữa hai địa điểm (điểm phát và điểm thu) trong một mạng ống nước (dầu); xác định cường độ dòng vận tải lớn nhất giữa hai nút của hệ thống giao thông trong thành phố… Vì vậy, việc nghiên cứu về đề tài này góp phần đề ra những giải pháp tối ưu nhằm giải quyết những vấn đề về vận chuyển, giao thông…

2 CƠ SỞ LÝ THUYẾT

2.1 Ý tưởng

Xuất phát từ một luồng trước đó (bắt đầu từ luồng ban đầu với F = 0), ta tìm đường

đi không định hướng từ đỉnh phát đến đỉnh thu, tiến hành hiệu chỉnh giá trị luồng trên đường đi đó sao cho luồng mới có giá trị lớn hơn Lặp lại cho đến khi không còn tìm được đường tăng luồng thì thuật toán dừng và luồng ở bước lặp cuối cùng là luồng cực đại

Đường tăng luồng P có dạng:

- P: s→…→i→j→…→t thì (i,j) là cung thuận

- P: s→…→i←j→…→t thì (j,i) là cung nghịch

2.2 Cơ sở lý thuyết

2.2.1 Các khái niệm

1 Mạng[2]

- Mạng là đồ thị có hướng, có trọng số G=(V,E,C) thỏa mãn:

 G liên thông yếu (nếu bỏ hướng các cạnh thì liên thông)

 Có duy nhất một đỉnh s không có cung vào gọi là đỉnh phát

 Có duy nhất một đỉnh t không có cung ra gọi là đỉnh thu

 Mỗi cung (i,j) ∈ E được gán một số cij ≥ 0 gọi là khả năng thông qua của cung (i,j)

- Ví dụ:

Trang 6

Hình 1 Mạng G

2 Luồng[2]

Cho mạng G=(V,E,C), trong đó V là tập đỉnh, E là tập cạnh và C là tập trọng

số

Luồng F trên mạng G là tập các giá trị {fij |(i, j) ∈ E} thỏa mãn:

- ∀(i,j) ∈ E: 0 ≤ fij ≤cij

- ∀ k ∉{s,t} (s là đỉnh phát, t là đỉnh thu):

(𝑖,𝑘)∈𝐸

(𝑘,𝑗)∈𝐸

Ví dụ:

Hình 2 Mạng G và luồng trên mạng G

Với đồ thị trên thì tập {fij}(giá trị được biểu diễn trong ngoặc đơn) là luồng:

fsa=8, fab=8, fbt=5, fbc=3, fsd=6, fsc=6, fcd=9, fdt=15

t s

13

12

9 6

5

15 6

3

t s

13(8)

12(8)

9(9) 6(6)

5(5)

15(15) 6(6)

3(3)

Trang 7

3 Giá trị luồng[2]

Cho mạng G=(V,E,C)

Giá trị của luồng F là tổng giá trị trên các cung đi ra từ đỉnh phát s, hoặc tổng giá trị trên các cung đi vào đỉnh thu t Kí hiệu là Vf

(𝑠,𝑘)∈𝐸

(𝑘,𝑡)∈𝐸

Luông cực đại trên mạng G là luồng có giá trị lớn nhất trong tất cả các luồng trên G

4 Lát cắt[2]

Cho mạng G =(V,E,C)

Lát cắt S= (V1,V2) là một phân hoạch tập đỉnh V của mạng G thành hai tập V1 và V2 =V\V1, trong đó s ∈ V1, t ∈ V2

Khả năng thông qua hay giá trị của lát cắt S = (V1,V2) là số c(V1,V2) = ∑cij với vi ∈ V1 và vj ∈ V2

Lát cắt có khả năng thông qua nhỏ nhất được gọi là lát cắt cực tiểu

2.2.2 Định lý Ford-Fulkerson[2]

Luồng cực đại bằng lát cắt cực tiểu

3 TỔ CHỨC CẤU TRÚC DỮ LIỆU VÀ THUẬT TOÁN

3.1 Phát biểu bài toán

Phát biểu bài toán: Cho mạng G =(V,E,C) với đỉnh phát s, đỉnh thu t và khả năng thông qua của mỗi cung là cij(i,j ∈ V) Trong tất cả các luồng có thể có trên mạng, tìm luồng có giá trị cực đại

Input: Số lượng đỉnh (node) của mạng G, đỉnh phát s và đỉnh thu t, ma trận trọng

số chứa khả năng thông qua của các cung cij chứa trong file input.txt, với:

- Hàng thứ nhất chứa số lượng đỉnh của mạng

- Đỉnh phát s ứng với đỉnh 0, đỉnh thu t ứng với đỉnh n-1

- n hàng tiếp theo (mỗi hàng chứa n số) là ma trận trọng số chứa khả năng

thông qua của các cung

Trang 8

Hình 3 File input.txt

Output: Giá trị luồng cực đại Vmax(f), và ma trận trọng số F là các luồng cực đại trên các cung chứa trong file output.txt, với:

- Hàng thứ nhất là giá trị luồng cực đại Vmax(f)

- n hàng tiếp theo (mỗi hàng chứa n số) là ma trận trọng số chứa các luồng

cực đại trên các cung

Hình 4 File output.txt

3.2 Cấu trúc dữ liệu

- Xây dựng một lớp Node để biểu diễn các thuộc tính của đỉnh như trạng thái,

nhãn, đỉnh kề trước của nó trong luồng P

- Sử dụng hai file input.txt và output.txt để nhập dữ liệu và xuất kết quả

- Sử dụng 2 mảng hai chiều lần lượt biểu diễn khả năng thông qua của các cung

trên mạng và luồng trên cung

3.3 Thuật toán

a Thuật toán Ford-Fulkerson[2]

Trang 9

Thuật toán Ford-Fulkerson để tìm luồng cực đại F trên mạng G = (V, E, C) với đỉnh phát s và đỉnh thu t gồm các bước sau:

 Bước 1: Khởi tạo luồng F=0; ∀(i,j) ∈ E: fij=0

 Bước 2: Lặp cho đến khi hết đường tăng luồng:

- Tìm đường tăng luồng P: s→t với lượng tăng luồng δ:

+ Đặt nhãn cho s là ∞

+ Lặp cho đến khi đỉnh t có nhãn δt: khi đỉnh vi vừa có nhãn thì đánh nhãn lại mọi đỉnh vj kề vô hướng với vI nếu thỏa mãn một trong hai trường hợp sau:

 Nếu có cung (i,j) và cij – fij>0(chưa bão hòa) thì đánh nhãn của đỉnh j

là δj = min(δi,cij – fij), nạp cung thuận vào P

 Nếu có cung (j,i) và fij>0 thì nhãn của đỉnh j là δj = min(δi, fij), nạp cung nghịch vào P

- Tăng luồng dọc theo P một lượng δ:

+ Khi đỉnh t vừa có nhãn δt thì có lượng tăng luồng là δ = δt; ngược lại nếu không đánh nhãn được đỉnh t thì hết đường tăng luồng(thuật toán dừng)

+ Tăng luồng dọc theo P một lượng δ theo công thức:

 f’ij = fij + δ , nếu (i,j) là cung thuận

 f’ij = fij - δ , nếu (j,i) là cung nghịch

b Độ phức tạp của thuật toán Ford-Fulkerson

Xét mạng G = (V,E,C), khi khả năng thông qua của các cung là số tự nhiên, thì luồng thu được có giá trị cũng là số tự nhiên:

- Mỗi đường tăng luồng được tìm ra trong khoảng thời gian bị chặn bởi

O(E) vì có mạng G có E cạnh

- Mỗi lần tăng luồng chỉ tăng một lượng có giá trị nguyên dương nên lượng

nhỏ nhất có thể tăng là 1 Vậy nếu giá trị của luồng cực đại là F thì số lần tăng luồng bị chặn bởi F/1 = F

Vậy thời gian chạy của thuật toán Ford-Fulkerson bị chặn bởi O(E*F)

4 CHƯƠNG TRÌNH VÀ KẾT QUẢ

4.1 Tổ chức chương trình

File Node.h

class Node {

int status; // 0: chua gan nhan; 1: da gan nhan; -1: dua dinh vao duong tang luong

int before; // dinh ke truoc tren duong tang luong

int label; // nhan cua dinh

public :

Node();

~Node();

void resetnode( int = 0 , int l = 0, int b = -1);

void setstatus();

Trang 10

int getlabel();

};

File Node.cpp

#include "Node.h"

Node::Node() {

this ->status = 0;

this ->label = 0;

this ->before = -1;

}

Node::~Node(){

}

void Node::resetnode( int , int , int ) {

this ->status = s ;

this ->label = l ;

this ->before = b ;

}

int Node::getstatus() {

return this ->status;

}

void Node::setstatus() {

this ->status = -1;

}

int Node::getlabel() {

return this ->label;

}

int Node::getbefore() {

return this ->before;

}

File Program.cpp

#include <iostream>

#include <iomanip>

#include <fstream>

#include "Node.h"

using namespace std;

int n;

Node* node;

int s, t;

int **c;

int **f;

int F;

void Inputdata()

{

ifstream file_in;

file_in.open( "input.txt" , ios::in);

//kiem tra co mo duoc file, neu khong thi nem ngoai le

if (file_in.fail()) {

throw "Can't open the input file" ; }

Trang 11

//nhap so luong dinh va kha nang thong qua cua cac cung

file_in >> n;

c = new int * [n];

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

{

c[i] = new int [n];

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

file_in >> c[i][j];

}

file_in.close();

}

void Initialize()

{

//khoi tao luong ban dau bang 0

f = new int * [n];

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

{

f[i] = new int [n];

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

f[i][j] = 0;

}

//Khoi tao cac dinh

node = new Node[n];

s = 0;

t = n - 1;

//Khoi tao gia tri luong cuc dai

F = 0;

}

void Max_Flow()

{

// Lap cho den khi het duong tang luong

while ( true ) {

//Xoa nhan tat ca cac dinh va gan nhan cho dinh phat la vo cung

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

node[i].resetnode();

} node[s].resetnode(1, 1000, -1);

//Lap cho den khi dinh t co nhan

while (node[t].getstatus()==0) {

//Tim dinh j co nhan de dua vao duong tang luong

int j;

for (j = 0; j < n; j++) {

if (node[j].getstatus() == 1) {

break ; }

}

if (j == n) return ; //Het duong tang luong,thuat toan dung

Trang 12

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

if (node[i].getstatus() == 0) {

//Cung dang (j,i) va chua bao hoa

if (c[j][i] > 0 && (c[j][i] - f[j][i] > 0)) {

int flow;

if (node[j].getlabel()>c[j][i]-f[j][i])

flow = c[j][i] - f[j][i];

else flow = node[j].getlabel();

node[i].resetnode(1, flow, j);

}

//Cung dang (i,j)

if (c[i][j] > 0 && f[i][j] > 0) {

int flow;

if (node[j].getlabel() > f[i][j])

flow = f[i][j];

else

flow = node[j].getlabel();

node[i].resetnode(1, flow, j);

} }

} }

// Tang gia tri cua luong

int delta = node[t].getlabel();

F += delta;

// Hieu chinh luong doc theo duong tang luong

int after = t;

while (after != s) {

int before = node[after].getbefore();

if (c[before][after] > 0) f[before][after] += delta;

if (c[after][before] > 0) f[before][after] -= delta;

after = before;

} }

}

void Outputdata()

{

ofstream file_out;

file_out.open( "output.txt" , ios::out);

file_out << F << endl;

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

{

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

file_out << left << setw(3) << f[i][j];

} file_out << endl;

}

Trang 13

file_out.close();

}

void Delete()

{

//Giai phong bo nho

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

{

delete[] c[i];

delete[] f[i];

}

delete[] c;

delete[] f;

delete[] node;

}

int main()

{

try

{

Inputdata();

Initialize();

Max_Flow();

Outputdata();

Delete();

cout << "Result in ouput.txt" << endl;

}

catch ( const char * ex) {

cout << ex << endl;

}

system( "pause" );

return 0;

}

4.2 Ngôn ngữ cài đặt

Ngôn ngữ được sử dụng để cài đặt chương trình cho bài toán là C++ gồm 5 file: Node.h, Node.cpp, Program.cpp, input.txt, output.txt

4.3 Kết quả

4.3.1 Giao diện chính của chương trình

Chương trình không có giao diện tương tác người dùng, dữ liệu đầu vào được nhập

từ file input.txt và kết quả được xuất ra file output.txt

Trang 14

Hình 5 Giao diện chính của chương trình

4.3.2 Kết quả thực thi của chương trình

- Kết quả thực hiện bằng tay:

Hình 6 Đồ thi và luồng cực đại của mạng G

- Kết quả thực hiện bằng chương trình:

t s

13(8)

12(8)

9(9) 6(6)

5(5)

15(15) 6(6)

3(3)

Trang 15

Hình 7 File output.txt

4.3.3 Nhận xét

Sau khi so sánh kết quả thực hiện bằng tay và kết quả sau khi chạy chương trình thì ta thấy chương trình đã tìm được đúng luồng cực đại Tuy nhiên, ta chỉ thấy được kết quả thực thi chương trình trong file output.txt nhưng chưa quan sát được toàn bộ quá trình tìm đường tăng luồng

5 KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN

5.1 Kết luận

Thuật toán Ford-Fulkerson đã tìm được đúng luồng cực đại trên mạng Từ đây ta

có thể áp dụng thuật toán này để giải quyết nhiều vấn đề thực tiễn như cung cấp nước sinh hoạt, tìm luồng vận tải lớn nhất…

5.2 Hướng phát triển

Cần phải thiết kế thêm phần giao diện để người dùng có thể quan sát được quá trình xác định đường tăng luồng cũng như quá trình tăng luồng, khiến bài toán trở nên trực quan, hoàn thiện hơn

Trang 16

TÀI LIỆU THAM KHẢO [1] Wikipedia:

https://vi.wikipedia.org/wiki/Lu%E1%BB%93ng_c%E1%BB%B1c_%C4%91% E1%BA%A1i

[2] Bài giảng Toán rời rạc( Dành cho sinh viên ngành Công nghệ thông tin ) –

2012 – Ths Phan Thanh Tao – Khoa CNTT – Đại học Bách Khoa – Đại học Đà Nẵng

Ngày đăng: 01/09/2020, 12:50

HÌNH ẢNH LIÊN QUAN

Hình 1. Mạng G - Đồ án cấu trúc dữ liệu và giải thuật đề tài tìm luồng cực đại
Hình 1. Mạng G (Trang 6)
Hình 3. File input.txt - Đồ án cấu trúc dữ liệu và giải thuật đề tài tìm luồng cực đại
Hình 3. File input.txt (Trang 8)
Hình 6. Đồ thi và luồng cực đại của mạng G - Đồ án cấu trúc dữ liệu và giải thuật đề tài tìm luồng cực đại
Hình 6. Đồ thi và luồng cực đại của mạng G (Trang 14)
Hình 5. Giao diện chính của chương trình - Đồ án cấu trúc dữ liệu và giải thuật đề tài tìm luồng cực đại
Hình 5. Giao diện chính của chương trình (Trang 14)

TỪ KHÓA LIÊN QUAN

w