You are on page 1of 37

TRƯỜNG ĐẠI HỌC MỞ TP-HCM

KHOA CÔNG NGHỆ THÔNG TIN

12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 1


 Hiểu được khái niệm “Cây bao trùm”.
 Hiểu được khái niệm “Cây bao trùm tối tiểu”.
 Hiểu và cài đặt được thuật toán Prim
 Hiểu và cài đặt được thuật toán Kruskal

12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 2


 Cây bao trùm
 Cây bao trùm tối tiểu
 Bài toán tìm cây bao trùm tối tiểu
 Thuật toán Prim
 Thuật toán Kruskal

12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 3


12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 4
A B

C
F

E D

12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 5


 Cho đồ thị liên thông G = (V, E), V là tập đỉnh, E là tập
cạnh của G
 Nếu T = (V, E’), với E’  E, và T là một cây (có nghĩa T
không có chu trình)

Thì ta nói T là cây bao trùm

12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 6


A B

C
F

D
T1 = (V, E’),
T2
E

V= {A, B, C, D, E, F};
E’ = {(A,E),
{(A,C), (B,D),
(A,E), (C,D),
(D,C), (A,F), (E,F)}  E;
(D,E), (B,D)}
12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 7
 Trên một đồ thị G (liên thông) có thể có nhiều cây bao trùm,
gọi tập các cây khung trên G là Sp(G).
 Ta có thể tìm cây bao trùm bằng các thuật giải BFS, DFS
(Duyệt hết tất cả các đỉnh, mỗi lần duyệt đỉnh u nạp đỉnh vào
trong T (với điều kiện T  {u}, T không tạo ra chu trình))
 Nếu giả sử G là đồ thi có trọng số, thì cây T cũng là cây bao
trùm có trọng số.
12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 8
12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 9
 Cho G = (V, E) là một đồ thị có trọng số,
 T là cây bao trùm tối tiểu khi:
w(T) = min{w(T) / T  Sp(G)}
w(T): tổng trọng số của các cạnh trên cây T;
Sp(G): là tập tất cả cây bao trùm trên G;

Cây bao trùm tối tiểu là 1 cây bao trùm, có tổng trọng số là tối tiểu
trên tập các cây khung Sp(G);
12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 10
1
A 8 B
3 5
C
F
1 4 3
1
6
T = (V, E’), E 2 D

V= {A, B, C, D, E, F};
E’ = {(A,E,1), (A,C,1), (C, D,1), (B,D,3), (A,F,3)}  E;
w(T) =9
12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 11
12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 12
 Đầu vào: G = (V, E) là một đồ thị liên thông vô hướng có
trọng số
 Đầu ra: T (cây bao trùm tối tiểu)

12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 13


12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 14
 Bước 0: bắt đầu từ một đỉnh u bất kì, và gọi u là đỉnh đang xét
 Bước 1: tìm tất cả các đỉnh v kề đỉnh đang xét, cho các cạnh này vào tập cạnh chuẩn
bị xét Etemp;
 Bước 2: từ Etemp lấy ra một cạnh e, sao cho:
▪  ei  Etemp/{e}, w(e)  w(ei); (w(e) là trọng số của cạnh e)
▪ Edges(T)  {e}  T không tạo ra chu trình;
 Bước 3: Nếu không lấy được e nào hoặc Vertices(T) = V thì dừng (T là cây khung tối
tiểu), ngược lại thì gọi u  e, u  Vertices(T) là đỉnh đang xét; quay lại bước 1.

12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 15


1
A 8 B
3 5
E
F
1 4 3
1
6
D
C 2

Đỉnh đang xét A C E D F


Tập E ={(A,
{}
{(A,
{(A, B,
{(A,B,
B, 8),
B,8),
8),
8), (A,
8),(A,
(A,
(A, D,
(A,D,D,
D,
D, 4),
4),
4),
4),
4), (A,
(C,
(C,
(A,
(A, F,
E,
F, F,
F, 3),
3),3),
(A,
1),
F,6),
6), (C,
E,
(A,
(C,
(C,(C,
(C, F, F,
1)D,}6),
F,
D,
F, 6),
6), 3),
2),
(C,
(C, (C,
(A,
2),D,
(E,
(E,
D, D,
C, 2),
1)}
B,(E,
B,
2),
2),
2)} E,(E,
5),
5}
(A, B, 1)}B,(D,
(D,
5), B,5)}
3)}
(E,D,B,1)}
3)}

Cây T12/09/2018
={} {(A, C,
{(A, 1),
1), (A,
C, 1)} (A, E,
E, 1),
1), (E,
1)} (E, D,
D, 1),
1)} (A,F,3),
1),KHOA CÔNG NGHỆ(D,
(A,F,3)} B,TIN3)}
THÔNG w(T) = 9 16
12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 17
// khai bao ma tran bang // khai bao TapE // khai bao TapE
mang hai chieu
int E1[MAX]; int T1[MAX];
# define MAX 20
int E2[MAX]; int T2[MAX];
int a[MAX][MAX];
int wE[MAX]; int wT[MAX];
int n; // so dinh cua do thi
int nE=0; // so phan tu tap E int nT=0; // so phan tap T

12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 18


void prim(int s) // s là đỉnh bắt đầu for(;i<nE;i++)
{ if(TonTai(E2[i], T2, nT)==0)
int u=s, min, i, d1 d2;
while(nT<n-1) if(min>wE[i])
{ { min=wE[i]; d1=E1[i];
for(int v=0;v<n;v++)
d2=E2[i];
if(a[u][v]!=0)
if (TonTai(v, T2, nT)==0) }
{ T1[nT]=d1; T2[nT]=d2;
E1[nE]=u; E2[nE]=v;
wT[nT]=a[d1][d2];
wE[nE]=a[u][v]; nE++;
} a[d1][d2]=0; a[d2][d1]=0;
for(i=0;i<nE;i++) nT++;
if (TonTai(E2[i], T2, nT)==0)
XoaCanhE(d1, d2);
{
min=wE[i]; d1=E1[i]; u=d2;
d2=E2[i]; break; }
} }
12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 19
int TonTai(int d, int D[], int nD) void XoaViTriE(int i)
{ {
for(int i=0;i<nD;i++) for(int j=i;j<nE;j++)
if(D[i]==d) {
return 1; E1[j]=E1[j+1];
return 0; E2[j]=E2[j+1];
} wE[j]=wE[j+1];
}
void output() nE--;
{ }
int tong=0;
for(int i=0;i<nT;i++) void XoaCanhE(int u, int v)
{ {
cout<<endl<<"("<<T1[i]<<","<<T2[i] for(int i=0;i<nE;i++)
<<") = "<<wT[i]; if(E1[i]==u&&E2[i]==v)
tong+=wT[i]; {
} XoaViTriE(i);
cout<<"\n Tong = "<<tong; break;
} }
}
12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 20
 Nếu G = (V, E) là đồ thị liên thông có trọng số; n là số đỉnh
của G, và m là số cạnh của G: n = |V|, m = |E|, thì ta có độ
phức tạp của thuật giải Prim là:

 O(n * max(n,m))
12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 21
12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 22
 Bước 1: từ E lấy ra một cạnh e, sao cho:
▪ ei  E, w(e)  w(ei) (w(e) là trọng số của cạnh e)
▪ Edges(T)  {e}  T không tạo ra chu trình;
 Bước 2: Nếu không lấy được e nào hoặc V = Vertices(T) thì
dừng (T là cây khung tối tiểu), ngược lại thì quay lại bước 1;

12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 23


 Bước 1: Sắp xếp E (tăng theo trọng số của cạnh)
 Bước 2: Lấy từ E ra một cạnh e, sao cho:
▪ Edges(T)  {e}  T không tạo ra chu trình;
 Bước 3: V = Vertices(T) thì dừng (T là cây khung tối
tiểu), ngược lại thì quay lại bước 2;

12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 24


1
A 8 B
3 5
E
F
1 4 3
1
6
D
C 2
{(A,B,8),
{(A,B,8), (A,D,4),
(A,D,4),
(A,C,1),
(A,D,4), (A,F,3),
(A,E,1),
(A,D,4),(A,D,4),
(B,E,5),
(A,F,3), (B,D,3),
(A,F,3),
(B,D,3), (C,D,E)
(A,E,1),
(B,D,3), (B,D,3),
(B,E,5), (C,D,2),
(A,F,3), (B,D,3),
Tập E =
(B,E,5),
(B,E,5), (C,
(C,F,6)} D, 2),(C,F,6),
(C,D,2),
(C,D,2), (C,F,6)}(D,E,1)}
(C,F,6), (D,E,1)}

Cây T12/09/2018
= { (A,C,1) ,(A,E,1) ,(E, D,1) ,(A,F,3) ,(B,D,3) }
KHOA CÔNG NGHỆ THÔNG TIN 25
12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 26
// khai bao ma tran bang // khai bao TapE // khai bao TapE
mang hai chieu
int E1[MAX]; int T1[MAX];
# define MAX 20
int E2[MAX]; int T2[MAX];
int a[MAX][MAX];
int wE[MAX]; int wT[MAX];
int n; // so dinh cua do thi
int nE=0; // so phan tu tap E int nT=0; // so phan tap T

12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 27


void kruskal()
{
for(int i=0;i<nE;i++)
{
if(TonTai(E1[i], T1, nT)==1 && TonTai(E2[i], T2, nT)==1)
continue;
if (TonTai(E1[i], T2, nT)==1 && TonTai(E2[i], T1, nT)==1)
continue;
T1[nT]=E1[i];
T2[nT]=E2[i];
wT[nT]=wE[i];
nT++;
if(nT==n-1)
break;
}
} 12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 28
void taoE()
{
void SapXepE()
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
for(int i=0;i<nE-1;i++)
if(a[i][j]!=0)
for(int j=i+1;j<nE;j++)
{
if(wE[i]>wE[j])
E1[nE]=i;
{
E2[nE]=j;
swap(wE[i],wE[j]);
wE[nE]=a[i][j];
swap(E1[i],E1[j]);
a[i][j]=0;
swap(E2[i],E2[j]);
a[j][i]=0;
}
nE++;
}
}
}

12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 29


 Nếu G = (V, E) là đồ thị liên thông có trọng số; n là số đỉnh
của G, và m là số cạnh của G: n = |V|, m = |E|, thì ta có độ
phức tạp của thuật giải Kruskal là:

 O(max(n ,
2 m ))
2

12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 30


1. Thomas H.Cormen, Charles E.Leiserson, Ronald L. Rivest, Cliffrod
Stein, (Chapter 23) Introduction to Algorithms, Third Edition, 2009.

2. Judith l. Gersting, (Chapter 6&7) mathematical structures for computer


science, 2014.

12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 31


12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 32
B 8 C 7 D

4 9
4
I E
A
11 3 4 14

8 7 4 10
F
H 1 G 2

12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 33


12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 34
12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 35
12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 36
12/09/2018 KHOA CÔNG NGHỆ THÔNG TIN 37

You might also like