Tải bản đầy đủ - 0 (trang)
§7. CHU TRÌNH HAMILTON, ĐƯỜNG ĐI HAMILTON, ĐỒ THỊ HAMILTON

§7. CHU TRÌNH HAMILTON, ĐƯỜNG ĐI HAMILTON, ĐỒ THỊ HAMILTON

Tải bản đầy đủ - 0trang

Lý thuyết đồ thị



227



Đồ thị có hướng G liên thơng mạnh và có n đỉnh. Nếu deg+(v) ≥ n / 2 và deg-(v) ≥ n / 2 với

mọi đỉnh v thì G có chu trình Hamilton



7.3. CÀI ĐẶT

Dưới đây ta sẽ cài đặt một chương trình liệt kê tất cả các chu trình Hamilton xuất phát từ đỉnh

1, các chu trình Hamilton khác có thể có được bằng cách hốn vị vòng quanh. Lưu ý rằng cho

tới nay, người ta vẫn chưa tìm ra một phương pháp nào thực sự hiệu quả hơn phương pháp

quay lui để tìm dù chỉ một chu trình Hamilton cũng như đường đi Hamilton trong trường hợp

đồ thị tổng quát.

Input: file văn bản HAMILTON.INP

Dòng 1 ghi số đỉnh n (2 ≤ n ≤ 100) và số cạnh m của đồ thị cách nhau 1 dấu cách

m dòng tiếp theo, mỗi dòng có dạng hai số nguyên dương u, v cách nhau 1 dấu cách, thể

hiện u, v là hai đỉnh kề nhau trong đồ thị

Output: file văn bản HAMILTON.OUT liệt kê các chu trình Hamilton

1

5



2



4



3



HAMILTON.INP

56

12

13

24

35

41

52



HAMILTON.OUT

135241

142531



P_4_07_1.PAS * Thuật tốn quay lui liệt kê chu trình Hamilton

{$MODE DELPHI} (*This program uses 32-bit Integer [-231..231 - 1]*)

program All_of_Hamilton_Circuits;

const

InputFile = 'HAMILTON.INP';

OutputFile = 'HAMILTON.OUT';

max = 100;

var

fo: Text;

a: array[1..max, 1..max] of Boolean; {Ma trận kề của đồ thị: a[u, v] = True ⇔ (u, v) là cạnh}

Free: array[1..max] of Boolean; {Mảng đánh dấu Free[v] = True nếu chưa đi qua đỉnh v}

x: array[1..max] of Integer; {Chu trình Hamilton sẽ tìm là; 1=x[1]→x[2] → … →x[n] →x[1]=1}

n: Integer;

procedure Enter;

var

i, u, v, m: Integer;

f: Text;

begin

Assign(f, InputFile); Reset(f);

FillChar(a, SizeOf(a), False);

ReadLn(f, n, m);

for i := 1 to m do

begin

ReadLn(f, u, v);

a[u, v] := True;

a[v, u] := True;

end;

Close(f);

end;

Lê Minh Hoàng



228



Chuyên đề



procedure PrintResult; {In kết quả nếu tìm thấy chu trình Hamilton}

var

i: Integer;

begin

for i := 1 to n do Write(fo, x[i], ' ');

WriteLn(fo, x[1]);

end;

procedure Attempt(i: Integer); {Thử các cách chọn đỉnh thứ i trong hành trình}

var

j: Integer;

begin

for j := 1 to n do {Đỉnh thứ i (x[i]) có thể chọn trong những đỉnh}

if Free[j] and a[x[i - 1], j] then {kề với x[i - 1] và chưa bị đi qua}

begin

x[i] := j; {Thử một cách chọn x[i]}

if i < n then {Nếu chưa thử chọn đến x[n]}

begin

Free[j] := False; {Đánh dấu đỉnh j là đã đi qua}

Attempt(i + 1); {Để các bước thử kế tiếp không chọn phải đỉnh j nữa}

Free[j] := True; {Sẽ thử phương án khác cho x[i] nên sẽ bỏ đánh dấu đỉnh vừa thử}

end

else {Nếu đã thử chọn đến x[n]}

if a[j, x[1]] then PrintResult; {và nếu x[n] lại kề với x[1] thì ta có chu trình Hamilton}

end;

end;

begin

Enter;

FillChar(Free, SizeOf(Free), True); {Khởi tạo: Các đỉnh đều chưa đi qua}

x[1] := 1; Free[1] := False; {Bắt đầu từ đỉnh 1}

Assign(fo, OutputFile); Rewrite(fo);

Attempt(2); {Thử các cách chọn đỉnh kế tiếp}

Close(fo);

end.



Bài tập

Bài 1

a) Lập chương trình nhập vào một đồ thị và chỉ ra đúng một chu trình Hamilton nếu có.

b) Lập chương trình nhập vào một đồ thị và chỉ ra đúng một đường đi Hamilton nếu có.

Bài 2

Trong đám cưới của Persée và Andromède có 2n hiệp sỹ. Mỗi hiệp sỹ có khơng q n - 1 kẻ

thù. Hãy giúp Cassiopé, mẹ của Andromède xếp 2n hiệp sỹ ngồi quanh một bàn tròn sao cho

khơng có hiệp sỹ nào phải ngồi cạnh kẻ thù của mình. Mỗi hiệp sỹ sẽ cho biết những kẻ thù

của mình khi họ đến sân rồng.

Bài 3

Gray code: Một hình tròn được chia thành 2n hình quạt đồng tâm. Hãy xếp tất cả các xâu nhị

phân độ dài n vào các hình quạt, mỗi xâu vào một hình quạt sao cho bất cứ hai xâu nào ở hai

hình quạt cạnh nhau đều chỉ khác nhau đúng 1 bit. Ví dụ với n = 3:



ĐHSPHN 1999-2004



Lý thuyết đồ thị



229



100



000



101



001



111



011

110



010



Bài 4

Thách đố: Bài tốn mã đi tuần: Trên bàn cờ tổng qt kích thước n x n ô vuông (n chẵn và 6

≤ n ≤ 20). Trên một ơ nào đó có đặt một quân mã. Quân mã đang ở ô (x[1], y[1]) có thể di

chuyển sang ơ (x[2], y[2]) nếu ⏐x[1]-x[2]⏐.⏐y[1]-y[2]⏐ = 2 (Xem hình vẽ).



Hãy tìm một hành trình của quân mã từ ô xuất phát, đi qua tất cả các ô của bàn cờ, mỗi ô

đúng 1 lần.

Ví dụ:

Với n = 8, ô xuất phát (3, 3)



45

2

43

16

47

30



42

17

46

31

60

15



3

44

1

48

37

64



18

41

36

59

32

57



35

4

19

40

49

38



20

7

50

33

58

25



5

34

9

22

39

52



8

21

6

51

10

23



61 56 13 28 63 54 11 26

14 29 62 55 12 27 24 53

Với n = 10, ô xuất phát (6, 5)



Lê Minh Hồng



230



Chun đề



18



71 100



43



20



69



86



45



22



55



97



42



19



70



99



44



21



24



87



46



72



17



98



95



68



85



88



63



26



23



41

16



96

83



73

80



84

93



81

74



94

89



67

64



90

49



47

62



50

27



79



40



35



82



1



76



91



66



51



48



36

39



15

12



78

37



75

34



92

77



65

60



2

57



61

52



28

3



53

6



14



33



10



59



56



31



8



5



54



29



11



38



13



32



9



58



55



30



7



4



Hướng dẫn: Nếu coi các ơ của bàn cờ là các đỉnh của đồ thị và các cạnh là nối giữa hai đỉnh

tương ứng với hai ô mã giao chân thì dễ thấy rằng hành trình của quân mã cần tìm sẽ là một

đường đi Hamilton. Ta có thể xây dựng hành trình bằng thuật tốn quay lui kết hợp với

phương pháp duyệt ưu tiên Warnsdorff: Nếu gọi deg(x, y) là số ô kề với ô (x, y) và chưa đi

qua (kề ở đây theo nghĩa đỉnh kề chứ khơng phải là ơ kề cạnh) thì từ một ô ta sẽ không thử xét

lần lượt các hướng đi có thể, mà ta sẽ ưu tiên thử hướng đi tới ơ có deg nhỏ nhất trước. Trong

trường hợp có tồn tại đường đi, phương pháp này hoạt động với tốc độ tuyệt vời: Với mọi n

chẵn trong khoảng từ 6 tới 18, với mọi vị trí ơ xuất phát, trung bình thời gian tính từ lúc bắt

đầu tới lúc tìm ra một nghiệm < 1 giây. Tuy nhiên trong trường hợp n lẻ, có lúc khơng tồn tại

đường đi, do phải duyệt hết mọi khả năng nên thời gian thực thi lại hết sức tồi tệ. (Có xét ưu

tiên như trên hay xét thứ tự như trước kia thì cũng vậy thơi. Ta có thể thử với n lẻ: 5, 7, 9 …

và ô xuất phát (1, 2), sau đó ngồi xem máy tính tốt mồ hơi).



ĐHSPHN 1999-2004



Lý thuyết đồ thị



231



§8. BÀI TỐN ĐƯỜNG ĐI NGẮN NHẤT

8.1. ĐỒ THỊ CĨ TRỌNG SỐ

Đồ thị mà mỗi cạnh của nó được gán cho tương ứng với một số (nguyên hoặc thực) được gọi

là đồ thị có trọng số. Số gán cho mỗi cạnh của đồ thị được gọi là trọng số của cạnh. Tương tự

như đồ thị khơng trọng số, có nhiều cách biểu diễn đồ thị có trọng số trong máy tính. Đối với

đơn đồ thị thì cách dễ dùng nhất là sử dụng ma trận trọng số:

Giả sử đồ thị G = (V, E) có n đỉnh. Ta sẽ dựng ma trận vng C kích thước n x n. Ở đây:

Nếu (u, v) ∈ E thì C[u, v] = trọng số của cạnh (u, v)

Nếu (u, v) ∉ E thì tuỳ theo trường hợp cụ thể, C[u, v] được gán một giá trị nào đó để có thể

nhận biết được (u, v) khơng phải là cạnh (Chẳng hạn có thể gán bằng +∞, hay bằng 0, bằng

-∞, v.v…)

Quy ước c[v, v] = 0 với mọi đỉnh v.

Đường đi, chu trình trong đồ thị có trọng số cũng được định nghĩa giống như trong trường

hợp khơng trọng số, chỉ có khác là độ dài đường đi khơng phải tính bằng số cạnh đi qua, mà

được tính bằng tổng trọng số của các cạnh đi qua.



8.2. BÀI TOÁN ĐƯỜNG ĐI NGẮN NHẤT

Trong các ứng dụng thực tế, chẳng hạn trong mạng lưới giao thông đường bộ, đường thuỷ

hoặc đường không. Người ta khơng chỉ quan tâm đến việc tìm đường đi giữa hai địa điểm mà

còn phải lựa chọn một hành trình tiết kiệm nhất (theo tiêu chuẩn khơng gian, thời gian hay chi

phí). Khi đó phát sinh u cầu tìm đường đi ngắn nhất giữa hai đỉnh của đồ thị. Bài tốn đó

phát biểu dưới dạng tổng qt như sau: Cho đồ thị có trọng số G = (V, E), hãy tìm một đường

đi ngắn nhất từ đỉnh xuất phát s ∈ V đến đỉnh đích f ∈ V. Độ dài của đường đi này ta sẽ ký

hiệu là d[s, f] và gọi là khoảng cách (distance) từ s đến f. Nếu như không tồn tại đường đi từ

s tới f thì ta sẽ đặt khoảng cách đó = +∞.

Nếu như đồ thị có chu trình âm (chu trình với độ dài âm) thì khoảng cách giữa một số cặp

đỉnh nào đó có thể khơng xác định, bởi vì bằng cách đi vòng theo chu trình này một số lần đủ

lớn, ta có thể chỉ ra đường đi giữa hai đỉnh nào đó trong chu trình này nhỏ hơn bất kỳ một số

cho trước nào. Trong trường hợp như vậy, có thể đặt vấn đề tìm đường đi cơ bản (đường đi

khơng có đỉnh lặp lại) ngắn nhất. Vấn đề đó là một vấn đề hết sức phức tạp mà ta sẽ không

bàn tới ở đây.

Nếu như đồ thị không có chu trình âm thì ta có thể chứng minh được rằng một trong những

đường đi ngắn nhất là đường đi cơ bản. Và nếu như biết được khoảng cách từ s tới tất cả

những đỉnh khác thì đường đi ngắn nhất từ s tới f có thể tìm được một cách dễ dàng qua thuật

tốn sau:



Lê Minh Hồng



232



Chun đề



Gọi c[u, v] là trọng số của cạnh [u, v]. Qui ước c[v, v] = 0 với mọi v ∈ V và c[u, v] = +∞ nếu

như (u, v) ∉ E. Đặt d[s, v] là khoảng cách từ s tới v. Để tìm đường đi từ s tới f, ta có thể nhận

thấy rằng luôn tồn tại đỉnh f1 ≠ f sao cho:

d[s, f] = d[s, f1] + c[f1, f]

(Độ dài đường đi ngắn nhất s→f = Độ dài đường đi ngắn nhất s→f1 + Chi phí đi từ f1→ f)

Đỉnh f1 đó là đỉnh liền trước f trong đường đi ngắn nhất từ s tới f. Nếu f1≡s thì đường đi ngắn

nhất là đường đi trực tiếp theo cung (s, f). Nếu khơng thì vấn đề trở thành tìm đường đi ngắn

nhất từ s tới f1. Và ta lại tìm được một đỉnh f2 khác f và f1 để:

d[s, f1] = d[s, f2] + c[f2, f1]

Cứ tiếp tục như vậy, sau một số hữu hạn bước, ta suy ra rằng dãy f, f1, f2, … không chứa đỉnh

lặp lại và kết thúc ở s. Lật ngược thứ tự dãy cho ta đường đi ngắn nhất từ s tới f.



s



f1

f2



f



Tuy nhiên, người ta thường không sử dụng phương pháp này mà sẽ kết hợp lưu vết đường đi

ngay trong quá trình tìm kiếm.

Dưới đây ta sẽ xét một số thuật tốn tìm đường đi ngắn nhất từ đỉnh s tới đỉnh f trên đơn đồ

thị có hướng G = (V, E) có n đỉnh và m cung. Trong trường hợp đơn đồ thị vơ hướng với

trọng số khơng âm, bài tốn tìm đường đi ngắn nhất có thể dẫn về bài tốn trên đồ thị có

hướng bằng cách thay mỗi cạnh của nó bằng hai cung có hướng ngược chiều nhau. Bạn có thể

đưa vào một số sửa đổi nhỏ trong thủ tục nhập liệu để giải quyết bài toán trong trường hợp đa

đồ thị

Input: file văn bản MINPATH.INP

Dòng 1: Chứa số đỉnh n ( ≤ 1000), số cung m của đồ thị, đỉnh xuất phát s, đỉnh đích f cách

nhau ít nhất 1 dấu cách

m dòng tiếp theo, mỗi dòng có dạng ba số u, v, c[u, v] cách nhau ít nhất 1 dấu cách, thể

hiện (u, v) là một cung ∈ E và trọng số của cung đó là c[u, v] (c[u, v] là số nguyên có giá

trị tuyệt đối ≤ 1000)

Output: file văn bản MINPATH.OUT ghi đường đi ngắn nhất từ s tới f và độ dài đường đi đó



ĐHSPHN 1999-2004



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

§7. CHU TRÌNH HAMILTON, ĐƯỜNG ĐI HAMILTON, ĐỒ THỊ HAMILTON

Tải bản đầy đủ ngay(0 tr)

×