Tải bản đầy đủ (.pptx) (30 trang)

ĐƯỜNG ĐI HAMILTON VÀ ỨNG DỤNG

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.04 MB, 30 trang )

Đề Tài:

ĐƯỜNG ĐI HAMILTON VÀ ỨNG DỤNG
Môn : Toán Rời Rạc
NHÓM THỰC HIỆN :
1. Nguyễn Thế Công
2. Phan Trọng Duy
3. Hà Đức Hiến
4. Phạm Trọng Hiếu


Mục Lục
I. GIỚI THIỆU VỀ ĐỒ THỊ
II. ĐỒ THỊ HAMILTON
A. THUẬT TOÁN LIỆT KÊ CÁC CHU TRÌNH VÀ
ĐƯỜNG ĐI HAMILTON
B. THUẬT TOÁN NHÁNH CẬN VÀ BÀI TOÁN TSP
III. ỨNG DỤNG


I. GIỚI THIỆU VỀ ĐỒ THỊ
1. Đồ thị - Cạnh – Đỉnh :
a) Đồ thị vô hướng : G = (V,E) gồm một tập V các đỉnh và tập E các cạnh. Mỗi cạnh
e E được liên kết với một cặp đỉnh v, w ( không kể thứ tự).
v

w

b) Đồ thị có hướng : G = (V,E) gồm một tập V các đỉnh và tập E các cạnh có hướng
gọi là cung. Mỗi cạnh e E được liên kết với một cặp đỉnh v, w có thứ tự.
v



w

c) Đồ thị lót : Cho đồ thị có hướng G = (V,E). Nếu ta thay đổi mỗi cung của G bằng
một cạnh, thì đồ thị vô hướng nhận được gọi là đồ thị lót của G.
Ghi chú : Đồ thị vô hướng có thể xem là đồ thị có hướng trong đó mỗi cạnh e =
(v,w) tương ứng với hai cung (v,w) và (w,v).


I. GIỚI THIỆU VỀ ĐỒ THỊ

2. Khái niệm Bậc :
a) Bậc :
Cho đồ thị G = (V, E)
• Bậc của đỉnh v V là tổng số cạnh liên thuộc với nó và ký
hiệu là d(v).
• Nếu đỉnh có khuyên thì mỗi khuyên được tính là 2 khi
tính bậc, như vậy:
d(v) :=Số cạnh liên thuộc + 2*Số khuyên
Từ định nghĩa suy ra , đỉnh cô lập trong đồ thị đơn là đỉnh
có bậc bằng 0.
• Số bậc lớn nhất của G ký hiệu là .
• Số bậc nhỏ nhất của G gọi là .
• Đỉnh treo là đỉnh có bậc bằng 1.


I. GIỚI THIỆU VỀ ĐỒ THỊ
3. Đường đi - chu trình :
a) Đường đi :
• Đường đi từ đỉnh v đến đỉnh w là dãy từ đỉnh v đến đỉnh w, trong đó cá cạnh không

lặp lại.
• Đường đi sơ cấp là đường đi không đi qua một đỉnh quá 1 lần.
• Đường đi có hướng trong đó đồ thị có hướng là dãy có hướng, trong đó các cung
không lặp lại.
• Đường đi có hướng sơ cấp là đường đi có hướng không đi qua một đỉnh quá 1 lần.
b) Chu trình :
• Chu trình là đường đi có đỉnh đầu và đỉnh cuối trùng nhau.
• Chu trình sơ cấp là chu trình không đi qua một đỉnh quá 1 lần.
• Chu trình có hướng là đường đi có hướng đỉnh đầu và đỉnh cuối trùng nhau.
• Chu trình có hướng sơ cấp là chu trình có hướng không đi qua một đỉnh qua 1 lần.
• Định lý 1.2 : Đồ thị G lưỡng phân khi và chỉ khi G không chứa chu trình độ dài lẻ.


I. GIỚI THIỆU VỀ ĐỒ THỊ
4. Đồ thị liên thông :
• Đồ thị vô hướng gọi là liên thông, nếu mọi cặp đỉnh của nó đều có
đường đi nối chúng với nhau.
• Đồ thị có hướng gọi là liên thông mạnh, nếu mọi cặp đỉnh của nó
đều có đường đi có hướng nối chúng với nhau.
• Đồ thị có hướng gọi là liên thông yếu, nếu đồ thị lót (vô hướng) của
nó liên thông.


II. ĐỒ THỊ HAMILTON
A. THUẬT TOÁN LIỆT KÊ CÁC CHU TRÌNH VÀ ĐƯỜNG ĐI HAMILTON
1.Định nghĩa
Đường đi qua tất cả các đỉnh của đồ thị mỗi đỉnh đúng một lần được gọi là đường đi Hamilton.
Chu trình bắt đầu từ một đỉnh v nào đó qua tất cả các đỉnh còn lại mỗi đỉnh đúng một lần rồi quay trở về v được
gọi là chu trình Hamilton.
Đồ thị G được gọi là đồ thị Hamilton nếu nó chứa chu trình Hamilton và gọi là đồ thị nữa Hamilton nếu nó có

đường đi Hamilton.
Rõ ràng đồ thị Hamilton là nửa Hamilton, nhưng điều ngược lại không còn đúng.
Ví dụ 1. Trong hình 1: G3 là Hamilton, G2 là nửa Hamilton còn G1 không là nửa Hamilton.


A. THUẬT TOÁN LIỆT KÊ CÁC CHU TRÌNH VÀ ĐƯỜNG ĐI HAMILTON
2.Định lý và thuật toán liệt kê tất cả các chu trình Hamilton.
a.Định lý 1 (Dirak 1952)
Đơn đồ thị vô hướng G với n>2 đỉnh, mỗi đỉnh có bậc không nhỏ hơn n/2 là đồ thị Hamilton.
b.Định lý 2
Giả sử G là đồ có hướng liên thông với n đỉnh.
Nếu deg+ (v) ≥ n/2, deg – (v) ≥ n/2, ∀ ∀v thì G là Hamilton.


c. Định lí 3

i) Mọi đồ thị đấu loại là nửa Hamilton.
ii) Mọi đồ thị đấu loại liên thông mạnh là Hamilton.
Ví dụ 2 Đồ thị đấu loại D5, D6 được cho trong hình 3.2

Hình 2 Đồ thị đấu loại D 5 , đấu loại liên thông mạnh D 6 .


3. Thuật toán liệt kê tất cả các chu trình Hamilton.
Thuật toán liệt kê tất cả các chu trình Hamilton của đồ thị.
Thuật toán sau đây được xây dựng dựa trên cơ sở thuật toán quay lui cho phép liệt kê
tất cả các chu trình Hamilton của đồ thị.


Ví dụ : Hình dưới đây mô tả cây tìm kiếm theo thuật toán vừa mô tả.


Hình 3: Đồ thị và cây liệt kê chu trình Hamilton của nó theo thuật toán quay lui.
Trong trường hợp đồ thị có không quá nhiều cạnh thuật toán trên có thể sử dụng để kiểm tra đồ thị
có phải là Hamilton hay không.


B. THUẬT TOÁN NHÁNH CẬN
ÁP DỤNG CHO BÀI TOÁN TSP
1.THUẬT TOÁN NHÁNH CẬN
Ta sẽ mô tả tư tưởng của thuật toán trên mô hình bài toán tối UXI tổ hợp tổng quátt sau
min { f{x) : X € D ],
trong đó D là tập hữu hạn phần tử.
Giả thiết rằng tập D được mô tả như sau
D ={ x = (x1,x2, …xn) € A1 x A2..An :x thoả mãn tính chất P],
với A1, A 2 ,..An là các tập hữu hạn, còn P là tính chất cho trên tích
Đềcac A1 x A2 x..x An
- Nhận thấy rằng, các bài toán vừa trình bày ở mục trước đều có thể mô tả dưới dạng
bài toán tr Với giả thiết về tập D nêu trên, chúng ta có thể sử dụng thuật toán quay
lui để liệt kê các phương án của bài toán. Trong quá trình liệt kê theo thuật toán
quay lui, ta sẽ xây dựng dần các thành phần của phương án. Một bộ gồm k thành
phần (a1,a2, ..an) xuất hiện trong quá trình thực hiện thuật toán sẽ gọi là phương án bộ
phận cấp k.


2. BÀI TOÁN TSP
(TRAVEL SALEMAN PROBLEM)

a.Giới thiệu bài toán
Một người du lịch muốn đi thăm quan n thành phố T1, T2, …, Tn. Xuất phát từ
một thành phố nào đó, người du lịch muốn đi qua tất cả các thành phố còn lại,

mỗi thành phố đi qua đúng một lần, rồi quay trở lại thành phố xuất phát. Biết cij
là chi phí đi từ thành phố Ti đến thành phố Tj(i = 1, 2,.., n), hãy tìm hành trình
với tổng chi phí là nhỏ nhất (một hành trình là một cách đi thoả mãn điều kiện).


b.Ý tưởng
Thuật toán nhánh cận là một trong những phương pháp giải chủ yếu của tối
ưu tổ hợp. Như trong mục trước đã thấy, tư tưởng cơ bản của nó là trong quá
trình lìm kiếm lời giải ta sẽ phân hoạch tập các phương án của bài toán ra
thành hai hay nhiều tập con được biểu diễn như là các nút của cây tìm
kiếm và cố gắng bàng phép đánh giá cận cho các nút, tìm cách loại bỏ
những nhánh của cây tìm kiếm (những tập con các phương án của bài toán)
mà ta biết chắc chấn là không chứa phương án tối ưu. M ặc dù trong tình
huống tồi nhất thuật toán sẽ trở thành duyệt toàn bộ, nhưng trong nhiều
trường họp cụ thể, kỹ thuật đó cho phép rút ngắn được một cách đáng kể
quá trình tìm kiếm. Mục này sẽ trình bày một cách thể hiện khác những tư
tưởng của thuật toán nhánh cận vào việc xây dựng thuật toán giải bài toán
người du lịch.


Có thể viết lại dưới dạng: (π(1), π(2), π(2), π(3),..., π(n-1), π(n), π(n), π(1), trong
đó mỗi thành phần: π(j-1), π(j) sẽ được gọi là một cạnh của hành trình.
Khi tiến hành tìm kiếm lời giải bài toán người du lịch chúng ta phân tập các hành
trình thành 2 tập con: Tập những hành trình chứa một cặp cạnh (i, j) nào đó còn
tập kia gồm những hành trình không chứa cạnh này. Ta gọi việc làm đó là sự
phân nhánh, mỗi tập con như vậy được gọi là một nhánh hay một node của cây
tìm kiếm. Quá trình phân nhánh được minh hoạ bởi hình sau:


Việc phân nhánh sẽ được thực hiện dựa trên một qui tắc heuristic nào đó cho

phép ta rút ngắn quá trình tìm kiếm phương án tối ưu. Sau khi phân nhánh và
tính cận dưới giá trị hàm mục tiêu trên mỗi tập con. Việc tìm kiếm sẽ tiếp tục
trên tập con có giá trị cận dưới nhỏ hơn. Thủ tục này được tiếp tục cho đến khi
ta nhận được một hành trình đầy đủ tức là một phương án cuả bài toán. Khi đó
ta chỉ cần xét những tập con các phương án nào có cận dưới nhỏ hơn giá trị của
hàm mục tiêu tại phương án đã tìm được. Quá trình phân nhánh và tính cận trên
tập các phương án của bài toán thông thường cho phép rút ngắn một cách đáng
kể quá trình tìm kiếm do ta loại được rất nhiều tập con .


1. Thủ tục rút gọn
Rõ ràng tổng chi phí của một hành trình của người du lịch sẽ chứa đúng một
phần tử của mỗi dòng và đúng một phần tử của mỗi cột trong ma trận chi phí C.
Do đó, nếu ta cộng hay trừ bớt mỗi phần tử của một dòng (hay cột) của ma trận
C đi cùng một số α thì độ dài của tất cả các hành trình đều giảm đi α vì thế hành
trình tối ưu cũng sẽ không bị thay đổi.
Vì vậy, nếu ta tiến hành bớt đi các phần tử của mỗi dòng và mỗi cột đi một
hằng số sao cho ta thu được một ma trận gồm các phần tử không âm mà trên mỗi
dòng, mỗi cột đều có ít nhất một số 0, thì tổng các số trừ đó cho ta cận dưới của
mọi hành trình.
Thủ tục bớt này được gọi là thủ tục rút gọn, các hằng số trừ ở mỗi dòng (cột)
sẽ được gọi là hằng số rút gọn theo dòng(cột), ma trận thu được được gọi là ma
trận rút gọn. thủ tục sau cho phép rút gọn ma trận một ma trận A kích thước k ×
k đồng thời .


Thủ tục rút gọn ma trận:
float Reduce(float A[][max], int k) {
sum = 0;
for (i = 1; i≤k; i++){

r[i] = < phần tử nhỏ nhất của dòng i >;
if (r[i] > 0) {
<Bớt mỗi phần tử của dòng i đi r[i] >;
sum = sum + r[i];
}
}
for (j = 1; j≤k; j++) {
s[j]: = <Phần tử nhỏ nhất của cột j>;
if (s[j] > 0)
sum = sum + S[j];
}
return(sum);
}



Tổng các hằng số rút gọn là 81, vì vậy cận dưới cho tất cả các hành trình là 81
(không thể có hành trình có chi phí nhỏ hơn 81).
Bây giờ ta xét cách phân tập các phương án ra thành hai tập. Giả sử ta chọn
cạnh (6, 3) để phân nhánh. Khi đó tập các hành trình được phân thành hai tập
con, một tập là các hành trình chứa cạnh (6,3), còn tập kia là các hành trình
không chứa cạnh (6,3). Vì biết cạnh (6, 3) không tham gia vào hành trình nên
ta cấm hành trình đi qua cạnh này bằng cách đặt C[6, 3] = ∞. Ma trận thu được
sẽ có thể rút gọn bằng cách bớt đi mỗi phần tử của cột 3 đi 48 (hàng 6 giữ
nguyên). Như vậy ta thu được cận dưới của hành trình không chứa cạnh (6,3)
là 81 + 48 = 129. Còn đối với tập chứa cạnh (6, 3) ta phải loại dòng 6, cột 3
khỏi ma trận tương ứng với nó, bởi vì đã đi theo cạnh (6, 3) thì không thể đi từ
6 sang bất sang bất cứ nơi nào khác và cũng không được phép đi bất cứ đâu từ
3.
Kết quả nhận được là ma trận với bậc giảm đi 1. Ngoài ra, do đã đi theo cạnh

(6, 3) nên không được phép đi từ 3 đến 6 nữa, vì vậy cần cấm đi theo cạnh (3,


Cây tìm kiếm lúc này có dạng như trong hình.


Lúc này cây tìm kiếm có dạng:


Cận dưới = 129

1

2

3

4

5

6

1



0

27


2

30

6

2

0



10

30

17

12

3

29

1



12


0

12

4

32

83

10



49

0

5

3

21

0

0




0

6

0

85



35

89



Cạnh (6,3) được chọn để phân nhánh vì phân nhánh theo nó ta thu được cận dưới của nhánh bên
phải là lớn nhất so với việc phân nhánh theo các cạnh khác. Qui tắc này sẽ được áp dụng ở để phân
nhánh ở mỗi đỉnh của cây tìm kiếm. Trong quá trình tìm kiếm chúng ta luôn đi theo nhánh bên trái
trước. Nhánh bên trái sẽ có ma trận rút gọn với bậc giảm đi 1. Trong ma trận của nhánh bên phải ta
thay một số bởi ∞, và có thể rút gọn thêm được ma trận này khi tính lại các hằng số rút gọn theo
dòng và cột tương ứng với cạnh phân nhánh, nhưng kích thước của ma trận vẫn giữ nguyên.
Do cạnh chọn để phân nhánh phải là cạnh làm tăng cận dưới của nhánh bên phải lên nhiều nhất,
nên để tìm nó ta sẽ chọn số không nào trong ma trận mà khi thay nó bởi ∞ sẽ cho ta tổng hằng số
rút gọn theo dòng và cột chứa nó là lớn nhất. Thủ tục đó có thể được mô tả như sau để chọn cạnh
phân nhánh (r, c).


Thủ tục chọn cạnh phân nhánh

Đầu vào: ma trận rút gọn A kích thước k x k
Đầu ra: cạnh phân nhánh (r,c) và tổng hằng số rút gọn theo dòng r cột c là beta.
void BestEdge(A, k, r, c, beta)
{
 beta = -∞;
 for (i = 1; i≤k; i++)
{
   for (j = 1; j≤k; j++)
{
    if (A[i, j] == 0)
{
     minr = < phần tửnhỏnhất trên dòng i khác với A[i, j];
     minc =  
    total = minr + minc;
 
  if (total > beta)
{
      beta = total;
      r = i; /* Chỉsốdòng tốt nhất*/
      c = j; /* Chỉsốcột tốt nhất*/
     }
    }
   }
 
}
}


Khi phân nhánh dựa vào cạnh (iu, iv) ta phải thêm cạnh này vào danh sách các cạnh của

node bên trái nhất. Nếu iu là đỉnh cuối của một đường đi (i1, i2,.., iu) và jv là đỉnh đầu của
đường đi (j1, j2,.., jk) thì để ngăn ngừa khả năng tạo thành hành trình con ta phải ngăn ngừa
khả năng tạo thành hành hành trình con ta phải cấm cạnh (jk, i1). Để tìm i1 ta đi ngược từ
iu, để tìm jk ta đi xuôi từ j1 theo danh sách các cạnh đã được kết nạp vào hành trình.


×