Tải bản đầy đủ (.pdf) (16 trang)

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

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.16 MB, 16 trang )

ĐẠ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


Đồ án Cấu trúc dữ liệu và Giải thuật

GVHD: Phan Thanh Tao

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 Ford và Delbert 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 2


Đồ án Cấu trúc dữ liệu và Giải thuật

GVHD: Phan Thanh Tao

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

3.

4.

2.1.

Ý tưởng ................................................................................................ 5

2.2.

Cơ sở lý thuyết...................................................................................... 5

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

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 3



Đồ án Cấu trúc dữ liệu và Giải thuật

GVHD: Phan Thanh Tao

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 4


Đồ án Cấu trúc dữ liệu và Giải thuật

GVHD: Phan Thanh Tao

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 5


Đồ án Cấu trúc dữ liệu và Giải thuật

GVHD: Phan Thanh Tao
12

a

b
5

13
3

t

s
6

15

6
c

d
9
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ụ:
12(8)
a

b
5(5)

13(8)

3(3)
t

s
6(6)

15(15)

6(6)

c

d
9(9)

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

Trang 6


Đồ án Cấu trúc dữ liệu và Giải thuật

GVHD: Phan Thanh Tao

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 7


Đồ án Cấu trúc dữ liệu và Giải thuật

GVHD: Phan Thanh Tao

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 8



Đồ án Cấu trúc dữ liệu và Giải thuật

GVHD: Phan Thanh Tao

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
duong tang luong
int before; // dinh ke
int label; // nhan cua
public:
Node();
~Node();
void resetnode(int s =
void setstatus();
int getstatus();
int getbefore();

gan nhan;

1: da gan nhan; -1: dua dinh vao

truoc tren duong tang luong
dinh

0 , int l = 0, int b = -1);

Trang 9



Đồ án Cấu trúc dữ liệu và Giải thuật

GVHD: Phan Thanh Tao

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 s,int l,int b) {
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
#include
#include
#include

<iostream>
<iomanip>
<fstream>
"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 10


Đồ án Cấu trúc dữ liệu và Giải thuật

GVHD: Phan Thanh Tao

//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
node[j].setstatus(); // Dua j vao duong tang luong
//Danh nhan lai moi dinh ke vo huong voi dinh j


Trang 11


Đồ án Cấu trúc dữ liệu và Giải thuật

GVHD: Phan Thanh Tao

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 12


Đồ án Cấu trúc dữ liệu và Giải thuật

GVHD: Phan Thanh Tao

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 13


Đồ án Cấu trúc dữ liệu và Giải thuật

GVHD: Phan Thanh Tao

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:
12(8)
a

b

5(5)

13(8)
3(3)

t

s

6(6)
15(15)

6(6)
c

d
9(9)

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:


Trang 14


Đồ án Cấu trúc dữ liệu và Giải thuật

GVHD: Phan Thanh Tao

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 15


Đồ án Cấu trúc dữ liệu và Giải thuật


GVHD: Phan Thanh Tao

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

/>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.

Trang 16



×