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

Đồ án ứng dụng của đồ thị để giải các bài toán giao thông vận tải trong tin học

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.96 MB, 64 trang )

MỤC LỤC
MỤC LỤC ................................................................................................... 1
MỞ ĐẦU ..................................................................................................... 3
CHƯƠNG 1 ................................................................................................. 4
GIỚI THIỆU TỔNG QUAN VÀ NGÔN NGỮ............................................ 4
LẬP TRÌNH DELPHI.................................................................................. 4
1.1. Giới thiệu đề tài................................................................................. 4
1.2. Ngôn ngữ lập trình Delphi ................................................................. 5
1.2.1. Giới thiệu ngôn ngữ lập trình Delphi .......................................... 5
1.2.2. DELPHI và WIN32 API ............................................................. 6
1.2.3. Các thành phần điều khiển chủa Windows.................................. 7
1.2.4. Ngôn ngữ Object Pascal............................................................ 11
CHƯƠNG 2 ............................................................................................... 17
ĐỒ THỊ VÀ ỨNG DỤNG CỦA ĐỒ THỊ .................................................. 17
2.1. Đồ thị ............................................................................................. 17
2.1.1. Định nghĩa đồ thị ...................................................................... 17
2.1.2. Các loại đồ thị.......................................................................... 18
2.1.3. Một số khái niệm và tính chất cơ bản của đồ thị ....................... 19
2.1.4. Các dạng biểu diễn của đồ thị ................................................... 24
2.2. Số ổn định và tô màu đồ thị ............................................................. 30
2.2.1. Số ổn định trong, số ổn định ngoài, nhân đồ thị ........................ 30
2.2.2. Tô màu đồ thị........................................................................... 36
2.3. Chu trình, đường đi Euler và Hamilton trong đồ thị......................... 41
2.3.1. Chu trình và đường đi Euler...................................................... 41
2.3.2. Chu trình và đường đi Hamilton ............................................... 43
2.4. Đường đi ngắn nhất trong đồ thị ...................................................... 45
2.4.1. Đường đi ngắn nhất trong đồ thị không có trọng số .................. 45

1



2.4.2. Đường đi ngắn nhất trong đồ thị có trọng số ............................. 46
2.4.3. Ví dụ ứng dụng ......................................................................... 52
CHƯƠNG 3 ............................................................................................... 57
ỨNG DỤNG VÀO BÀI TOÁN VẬN CHUYỂN CHO ............................. 57
CÔNG TY TNHH BẢO SƠN .................................................................... 57
3.1. Công ty TNHH Bảo Sơn.................................................................. 57
3.1.1. Giới thiệu Công ty TNHH Bảo Sơn .......................................... 57
3.1.2. Tầm quan trọng của bài toán tính cước phí vận chuyển cho
Công ty TNHH Bảo Sơn..................................................................... 57
3.2. Bài toán tính cước phí vận chuyển................................................... 58
3.2.1. Phát biểu bài toán ..................................................................... 58
3.2.2. Phân tích bài toán ..................................................................... 58
3.3. Kết quả ............................................................................................ 59
KẾT LUẬN................................................................................................ 63
TÀI LIỆU THAM KHẢO .......................................................................... 64

2


MỞ ĐẦU
Lý thuyết đồ thị là một lĩnh vực đã có từ lâu và có nhiều ứng dụng hiện đại,
những tư tưởng của lý thuyết đồ thị được đề xuất vào những năm đầu của thế kỷ
XVIII bởi nhà bác học lỗi lạc người Thuỵ Sỹ Lenhard Eurle. Chính ông là người
đã sử dụng đồ thị để giải bài toán nổi tiếng về các cái cầu ở thành phố
Konigsberg.
Đồ thị được sử dụng để giải các bài toán trong nhiều lĩnh vực khác nhau.
Chẳng hạn, đồ thị có thể sử dụng để xác định các mạch vòng trong vấn đề giải
tích mạch điện. Chúng ta có thể xác định hai máy tính trong mạng có thể trao đổi
thông tin được với nhau hay không nhờ mô hình đồ thị của mạng máy tính. Đồ
thị có trọng số trên các cạnh có thể sử dụng để giải các bài toán như: Tìm đường

di ngắn nhất giữa hai thành phố trong mạng giao thông, giải các bài toán về lập
lịch, thời khoá biểu và phân bố tần số cho các trạm phát thanh truyền hình …
Lý thuyết đồ thị là một nhánh quan trọng của của toán học tổ hợp đã được
nghiên cứu sâu sắc trong hàng trăm năm. Nhiều tính chất quan trọng và hữu ích
của đồ thị đã được chứng minh, nhưng vẫn còn rất nhiều vấn đề khó chưa giải
quyết xong. Ở đề tài này với mục đích tìm hiểu vấn đề cơ bản của lý thuyết đồ thị
và đi sâu tìm hiểu một số thuật toán trên đồ thị và cài đặt bằng ngôn ngữ lập trình
Delphi.
Trong thời gian làm đồ án mặc dù đã cố gắng rất nhiều nhưng do kiến thức
của bản than có hạn, ngôn ngữ lập trình phải tự tìm hiểu, nên đề tài không tránh
khỏi những thiếu sót. Em kính mong nhận được sự đánh giá và chỉ bảo của các
thầy cô giáo để đề tài của em được hoàn thiện hơn. Một lần nữa em xin chân
thành cảm ơn thầy giáo Th.S Bùi Ngọc Tuấn đã tận tình hướng dẫn giúp em hoàn
thành đồ án này.
Em xin chân thành cảm ơn !

3


CHƯƠNG 1
GIỚI THIỆU TỔNG QUAN VÀ NGÔN NGỮ
LẬP TRÌNH DELPHI

1.1. Giới thiệu đề tài
"Ứng dụng của đồ thị trong Tin học" là đề tài mang tính nghiên cứu lý
thuyết, có tầm quan trọng và có ý nghĩa thiết thực cao. Khái niệm đồ thị ở đây
khác với những đồ thị thông thường đã biết, đây là một lĩnh vực về lý thuyết đồ
thị nghiên cứu những cấu trúc mang tính rời rạc là một bộ phận quan trọng của
Toán học rời rạc.
Lý thuyết đồ thị có nhiều ứng dụng trong các ngành kỹ thuật và đã được

nghiên cứu nhiều với khối lượng kiến thức khá đồ sộ. Đề tài được thực hiện
trước tiên sẽ đề cập tới những vấn đề chủ yếu của Lý thuyết đồ thị, sau đó tuỳ
từng nội dung cũng sẽ xoay quanh tới những ứng dụng của đồ thị trong Tin học,
giải quyết các bài toán trong Tin học như xác định xem hai máy tính trong mạng
có thể truyền tin được hay không nhờ mô hình đồ thị của mạng máy tính, hay là
bài toán nối mạng máy tính sao cho tổng chi phí là nhỏ nhất hoặc việc khắc phục
những gói tin bị truyền sai nhờ các giải thuật đã nghiên cứu về đồ thị. Có những
ứng dụng của đồ thị không đi trực tiếp vào các lĩnh vực trong Tin học, ví dụ như
bài toán lập lịch trong công tác hành chính, xác định đường đi ngắn nhất giữa hai
điểm nút giao thông, ta cũng xem đó là ứng dụng một cách gián tiếp trong Tin
học vì nếu được mô hình tốt những bài toán đó bằng đồ thị thì sẽ giải quyết
chúng dễ dàng bằng máy tính, hoặc là về chơi cờ Ca rô tuy chỉ là môn chơi về trí
tuệ nhưng đồ thị cũng hỗ trợ tốt cho nhưng ai muốn lập trình chơi cờ Ca rô trên
máy tính khi đã mô hình được các thế cờ bằng đồ thị.
Trong các ứng dụng thực tế, Bài toán tìm đường đi ngắn nhất giữa hai đỉnh
của một đồ thị liên thông có một ý nghĩa to lớn. Có thể dẫn về bài toán như vậy
nhiều bài toán thực tế quan trọng. Ví dụ, Bài toán chọn một hành trình tiết kiệm
nhất (theo tiêu chuẩn khoảng cách hoặc thời gian hoặc chi phí) trên một mạng
giao thông đường bộ, đường thuỷ hoặc đường không; Bài toán chọn một phương

4


pháp tiết kiệm nhất để đưa một hệ động lực từ trạng thái xuất phát đến một trạng
thái đích, Bài toán lập lịch thi công các công đoạn trong một công trình thi công
lớn, v.v… Hiện nay có nhiều phương pháp để giải các bài toán như vậy. Thế
nhưng thông thường, các thuật toán được xây dựng dựa trên cơ sở lý thuyết đồ
thị tỏ ra là các thuật toán có hiệu quả cao nhất. Trong đề tài này em nghiên cứu
và cài đặt một bài toán như vậy - "Bài toán Vận tải ". Từ bài toán này em đi vào
ứng dụng cụ thể trong việc lập dự án đấu thầu vận chuyển cho Công ty TNHH

Bảo Sơn.

1.2. Ngôn ngữ lập trình Delphi
1.2.1. Giới thiệu ngôn ngữ lập trình Delphi
Delphi có tiền thân là ngôn ngữ lập trình Pascal (thật sự từ ngôn ngữ hướng
đối tượng Object Pascal). Pascal là một ngôn ngữ rõ ràng mạch lạc thường được
dùng trong công việc nghiên cứu giảng dạy hơn là dùng viết những ứng dụng
chuyên nghiệp như hệ điều hành hay các chương trình thương mại cao cấp.
Nhưng Delphi thì hoàn toàn mới. Delphi đã đưa ra ngôn ngữ Pascal trưởng thành
lên rất nhiều, có lẽ phải gọi là ngôn ngữ Delphi thì đúng hơn. Để làm việc bằng
Delphi phải học và nắm bắt thêm rất nhiều từ khoá và kỹ thuật mới, nhất là khái
niệm lập trình hướng đối tượng. Với môi trường phát triển Delphi, hầu như bạn
có thể kiến tạo bất kỳ chương trình ứng dụng Windows nào từ những tập tin thực
thi EXE, thư viện liên kết động DLL, ứng dụng OLE, thành phần ActiveX đến
các ứng dụng WEB trên mạng Internet, các ứng dụng giao diện đồ hoạ, các ứng
dụng về truy xuất cơ sở dữ liệu client – server, tích hợp những công nghệ hiện
đại như JAVA, CORBA, NIDAS … Nhìn chung với các ứng dụng chuyên
nghiệp đòi hỏi thời gian phát triển nhanh và có tính chuyên môn cao thì Delphi là
một lựa chọn tốt nhất. Kết hợp khả năng truy xuất cấp thấp của C cộng với tận
dụng những chức năng cao cấp của hệ điều hành, Delphi xứng đáng để các lập
trình viên đầu tư vào nó.

5


1.2.2. DELPHI và WIN32 API
Delphi đã dành cho các nhà lập trình gần như toàn bộ khả năng điều khiển
hệ điều hành Windows thông qua các thành phần đối tượng mà không cần phải
quan tâm đền các hàm Win32 API. Bạn có thể thay đổi bộ mặt cũng như cách
hàm xử của chương trình thông qua những phương thức hay thuộc tính của đối

tượng.
Để xây dựng nên hệ điều hành Windows và giúp các nhà phát triển viết ứng
dụng cho Windows, Microsoft đã cất công tạo nên thư viện API (Appication
Programming Interface) còn gọi là Giao tiếp lập trình ứng dụng. Đây là tập hợp
các lời gọi hàm cấp cao giúp các chương trình có thể tương tác với Windows
(bản thân Windows cũng được thiết kế trên những hàm API này). Bạn hãy hình
dung các lời gọi hàm cấp thấp BIOS đã được Microsoft đưa vào hệ điều hành
DOS dưới hình thức các chức năng của ngắt (Interrupt) 21h giúp lập trình viên
trên DOS đơn giản hoá các công việc thâm nhập sâu vào BIOS tận dụng được
những chức năng của hệ điều hành DOS thì với Win32 API cũng có ý nghĩa
tương tự như vậy, các hàm API giúp bạn đơn giản hoá công việc lập trình trên
Windows.
Khi lập trình trên DOS với những ngôn ngữ như Pascal, C bạn ít khi phải
vận đụng đến ngắt 21h hay các ngắt của BIOS bởi các trình biên dịch cấp cao này
đã đóng gói hầu hết những chức năng của hệ điều hành dưới dạng các thư viện
(như stdio.lib trong C hay unit crt trong Pascal chẳng hạn), lập trình viên thực sự
sử dụng ngắt 21h của DOS hay các ngắt của BIOS khi muốn thực hiện những
thao tác đặc biệt mà hệ điều hành DOS của Microsoft không cung cấp hoặc
không công bố.
Lập trình trên môi trường Windows thật sự phức tạp hơn hơn trên môi
trường DOS nhưng cũng cực kỳ đơn giản nếu bạn sử dụng các công cụ phát triển
trực quan như Visual Basic, Delphi, PowerBuilder, C++ Builder. Visual C++.
Thật sự các nhà phát triển tạo ra những công cụ này cũng đã phải làm việc rất
nhiều với các hàm API và đóng gói chúng dưới dạng các thư viện hay đối tượng
để những lập trình viên khác sử dụng. Vì một lý do nào đó thường những công cụ

6


phát triển này cũng không thể đưa ra hay đóng gói đầy đủ các chức năng của

Windows API. Nhiều và còn nhiều lý do nữa để bạn sử dụng WIN32 API như là
một công cụ tốt nhất dùng mở tung mọi cánh cửa Windows từ bất kỳ môi trường
phát triển ứng dụng Windows nào khác không riêng gì môi trường phát triển
Delphi.
1.2.3. Các thành phần điều khiển chủa Windows
a. Nút nhấn (Button)
Nút nhấn được Delphi đặt trong lớp đối tượng TButton, tình huống thường
được sử dụng nhất là là OnClick. Khi người dùng Click chuột vào nút nhấn, tình
huống này sẽ được gọi để phản ứng lại bằng một tác vụ nào đó.
b. Nhãn (Lable)
Nhãn là thành phần đơn giản nhất trong thư viện VCL. Đối tượng nhãn chỉ
dùng để trình bày một chuỗi văn bản thông thường, nhằm mục đích mô tả thêm
thông tin cho các đối tượng khác. Nhãn cũng có thể được dùng để đưa kết quả ra
màn hình dưới dạng chuỗi.
Trong Delphi, nhãn được đặt trong lớp đối tượng có tên là TLable. Thuộc tính
thường được sử dụng nhất của nhãn là:
Caption thể hiện nội dung nhãn.
Font

định font chữ, kiểu chữ cho nhãn.

Transparent cho phép màu nền của nhãn trùng với màu nền của Form.
c. Ô đánh dấu
Ô đánh dấu hay cũng gọi là CheckBox cho phép người dùng chọn hay bỏ
chọn một yêu cầu nào đó.
Checkbox được Delphi đặt trong lớp TCheckBox. Thuộc tính thường được sử
dụng nhất của CheckBox là Checked mang kiểu Boolean. Nếu Checked = True, ô
đánh dấu đang ở trạng thái chọn. Nếu Checked = False, người dùng đã bỏ chọn ô
đánh dấu. Khi ô đánh dấu được kích chuột để yêu cầu thay đổi trạng thái, tình
huống OnClick sẽ phát sinh.


7


d. Ô chọn (RadioButton)
Không như ô đánh dấu CheckBox được chọn riêng lẻ, các ô chọn (Radio)
thường đi chung với nhau và mỗi lần chỉ được thể hiện trạng thái.
Ô chọn Radio được Delphi đặt trong lớp đối tượng có tên là TRadioButton.
Thuộc tính thường được sử dụng nhất của ô chọn là Checked mang kiểu Boolean.
Nếu Checked = True, ô chọn đang ở trong trạng thái được chọn. Nếu Checked =
False, người dùng đã bỏ chọn ở ô hiện hành để chuyển sang chọn ô khác. Khi ô
chọn Radio được kích chuột để yêu cầu thay đổi trạng thái, tình huống OnClick
sẽ phát sinh.
e. Ô văn bản (EditBox)
Ô văn bản là thành phần nhập dữ liệu đơn giản nhất dùng giao diện đồ hoạ,
nó cho phép nhập vào một chuỗi văn bản, chỉnh sửa, di chuyển con nháy để soạn
thảo bằng các phím mũi tên. Ô văn bản chỉ cho phép nhập một dòng văn bản duy
nhất.
Ô văn bản được Delphi đặt trong lớp đối tượng có tên là TEdit. Thuộc tính
thường được sử dụng nhất của ô văn bản là thuộc tính text. Nó trả về một chuỗi,
cho biết nội dung dữ liệu mà người dùng nhập vào. Mỗi khi dữ liệu hay nội dung
của thuộc tính text thay đổi, tình huống OnChange sẽ được gọi .
f. Vùng văn bản (Memo)
Vùng văn bản Memo cho phép nhập vào cùng lúc nhiều dòng dữ liệu. Có thể
dùng Memo để tạo chương trình soạn thảo văn bản hay dùng để xuất ra một
chuỗi văn bản.
Vùng văn bản được Delphi đặt trong lớp đối tượng có tên là TMemo. Thuộc
tính thường được sử dụng nhất của Memo là thuộc tính Lines. Thuộc tính Lines có
kiểu String, được dùng để quản lý danh sách các dòng dữ liệu mà Memo đang có.
Để đơn giản, Memo cung cấp thuộc tính Text là một chuỗi bao gồm tất cả các

dòng trong Memo cộng lại, mỗi dòng cách nhau bởi ký tự 10 và 13. Tình huống
thường được sử dụng nhất của Memo là tình huống OnChange, tình huống này
được gọi khi người dùng thay đổi hoặc thêm dữ liệu vào Memo.

8


g. Danh sách (ListBox)
Danh sách chứa một danh sách mục chọn, mỗi mục chọn thường được thể
hiện là một chuỗi. ListBox cho phép chọn mỗi lần một hay nhiều mục cùng lúc.
Danh sách được Delphi đặt trong lớp đối tượng có tên là TlistBox. Thuộc tính
thường được sử dụng nhất của danh sách là:
Items Dùng để thêm bớt các mục chọn vào danh sách.
ItemIndex Cho biết hoặc thiết lập mục chọn hiện hành.
Selected Kiểm tra xem một mục chọn trong danh sách có được chọn hay không.
MultiSelect Cho phép danh sách được chọn đồng thời nhiều mục.
Sorted Tự động sắp xếp các mục chọn theo thứ tự ABC.
Các tình huống mà ListBox thường phát sinh là:
OnClick Khi người dùng kích chuột vào mục chọn.
OnDblClick Khi người dùng kích đôi chuột vào một mục chọn.
OnKeyPress Khi người dùng nhấn phím để chọn một mục.
OnKeyDown/ OnKeyUp Xử lý khi người dùng nhấn và nhả phím.
h. Danh sách sổ(ComboBox)
Danh sách sổ ComboBox mỗi lần chỉ thể hiện được một mục và là mục đang
ở trạng thái chọn.
Danh sách sổ được Delphi đặt trong lớp đối tượng có tên là TcomboBox.
Thuộc tính thường được sử dụng nhất ComboBox là:
Text Nội dung của mục chọn hiện hành.
Items Danh sách các mục chọn.
ItemIndex Lấy về hoặc thiết lập mục chọn hiện hành cho ComboBox.

Sorted Cho phép sắp xếp các mục chọn trong danh sách theo thứ tự ABC.
Style Chọn các kiểu ComboBox mở rộng.
Tình huống mà Litsbox thường phát sinh là tình huống OnChange, được gọi
khi nội dung của mục chọn hiện hành bị thay đổi.
i. Thanh trượt (Scrollbar)
Thanh trượt gồm mũi tên ở hai đầu và một thanh trượt đặt giữa để xác định vị
trí. Khoảng cách giữa hai thanh trượt và vị trí định vị được biểu hiện bằng các

9


thuộc tính min, max, position. Khi nhấn phím mũi tên, PageUp, PageDown hoặc
kích chuột vào hai đầu thanh trượt sẽ làm cho vị trí nút trượt di chuyển dần đến
hai bên.
Thanh trượt được Delphi đặt trong lớp đối tượng có tên là TScrollbar.
Thuộc tính thường được sử dụng nhất của thanh trượt Scrollbar là:
Min Thể hiện giới hạn dưới của thanh trượt.
Max Thể hiện giới hạn trên của thanh trượt.
Position Cho biết hoặc đặt lại vị trí hiện hành của nút trượt.
Kind Cho phép đặt thanh trượt đứng hoặc ngang.
SmallChange Bước nhảy cho thanh trượt khi phím mũi tên được nhấn.
PageSize Bước nhảy cho thanh trượt khi PageUp/PageDown được nhấn.
Tình huống mà thanh trượt Scrollbar thường phát sinh là OnChange, nó được
gọi khi vị trí của nút trượt thay đổi.
j. Nhóm các ô chọn (RadioGroup)
RadioGroup là đối tượng giúp cho việc gom các nút chọn có cùng một chức
năng lại với nhau thành một nhóm duy nhất. Thành phần này được Delphi đặt
trong lớp đối tượng có tên là TRadioGroup.
Thuộc tính thường được sử dụng nhất của thành phần này là:
Items Các ô chọn RadioButton gắn trong nhóm.

ItemIndex Nút Radio đang được chọn.
Caption Tiêu đề của nhóm ô chọn.
Column Phân cột cho các ô chọn.
Tình huống mà nhóm ô chọn thường phát sinh là OnClick, nó được gọi khi
người dùng kích chuột vào một trong các ô chọn trong nhóm.
k. Nhóm các đối tượng (GroupBox)
Có thể sử dụng nhóm chứa các đối tượng mang tên GroupBox để phân loại
đối tượng theo chủ đề. Thành phần này được Delphi đặt trong lớp đối tượng có
tên là TGroupBox.
Tương tự TRadioGroup, TGroupBox cũng dùng thuộc tính Caption để thể
hiện tiêu đề cho nhóm. TGroupBox cũng cung cấp các tình huống như OnClick,

10


OnMouseUp, OnMouseDown … nhưng hầu như rất ít khi dùng đến chúng, nó
thường chỉ được dùng với mục đích gom các đối tượng lại với nhau theo chủ đề.
Nó đóng vai trò như một vật chứa.
l. Bảng chứa (Panel)
Bảng chứa dùng để gom, nhóm các đối tượng con lại với nhau. Thành phần
bảng chứa Panel được Delphi đặt trong lớp đối tượng có tên là TPanel.
Các thuộc tính thường được sử dụng nhất của Panel là:
Align Canh lề cho bảng chứa.
BevelInner Đường viền trong.
BevelOuter Đường viền ngoài.
BevelWidth Độ dày của đường viền.
Visibled Cho phép bảng chứa hiển thị hoặc không.
m. Trình đơn chính (MainMenu)
Trình đơn chính MainMenu là một dãy các lựa chọn nằm phía trên cửa sổ.
Đối tượng này được Delphi đặt tên là TMainMenu.

n. Trình đơn tắt (PopupMenu)
Trình đơn tắt thường hiển thị khi người dùng kích phím phải chuột lên Form
hoặc lên đối tượng nào đó. Đối tượng này được Delphi đặt tên là TPopupMenu.
1.2.4. Ngôn ngữ Object Pascal
1.2.4.1. Các kiểu dữ liệu đơn giản
Delphi phát triển thêm các kiểu dữ liệu sau:
a. Kiểu nguyên
Type

Range of Values

Byte of Memory Required

Byte

0 to 255

1

Word

0 to 65535

2

ShortInt

-128 to 127

1


SmallInt

-32768 to 32767

2

Integer

-2147483648 to 2147483647

4

Cardinal

0 to 2417483647

4

LongInt

-2147483648 to 2147483647

4

11


b. Kiểu thực
Type


Range of Values

Byte of Memory Required

+2.9*10 -39 to + 1.7*1038

6

Single

+1.5*10 -45 to 3.4*10 38

4

Double

+5.0*10-324 to 1.7*10 308

8

+3.4*10-4932 to 1.1*104932

10

Real

Extended

-263 to 2 63-1


8

Type

Range of Values

Byte of Memory Required

ByteBool

Byte-size Boolean

1

Word-size Boolean

2

WordBool

Word-size Boolean

2

LongBool

Double word-size Boolean

4


Range of Values

What It Can Hold

Comp

c. Kiểu logic

Bool

d. Kiểu Ký tự
Type
ANSIChar

1

One Ansi

2

One Unicode

Character
WideChar
Character

e. Kiểu chuỗi
Type


Length

Element It Hold

Null

ShortString

255

ANSIChar

No

ANSIChar

Yes

AnsiString

up to ~3 GB

String

either 255 or up to ~3GB

ANSIChar

Yes


WideString

up to ~1.5 GB

WideChar

Yes

12


1.2.4.2. Các kiểu dữ liệu cấu trúc
a. Mảng (Array)
Mảng dựng để biểu diễn một tập hợp các phần tử có cùng kiểu dữ liệu. Mỗi
phần tử của mảng được truy xuất theo một chỉ số duy nhất.
 Cú pháp xây dựng mảng tĩnh:
Array [ indexType 1,…,indexType n ] Of baseType;
Trong đó: indexType là một tập các số có kiểu thứ tự dựng làm chỉ số mảng.
baseType là kiểu sẽ được áp dụng cho các phần tử mảng.
 Cú pháp xây dựng mảng động:
Array of array of …of baseType;
Trong khai báo mảng động, số phần tử của mảng chưa được chỉ định. Muốn
sử dụng mảng cần phải chỉ định rõ cần chính xác bao nhiêu phần tử để chương
trình cấp phát bằng lệnh sau:
Setlength(Name, Value_1, …, Value_n);
Trong đó, Name là tên mảng, Value là số lượng phần tử cần được cấp phát
theo mỗi chiều của mảng.
Để giải phóng vùng nhớ cấp phát cho mảng động ta gọi lệnh gán như sau:
Name := nil;
Chỉ số của các phần tử trong mảng được đánh số bắt đầu từ 0.

b. Kiểu Record.
Kiểu Record là một tập hợp gồm nhiều phần tử có các kiểu khác nhau hợp lại.
Mỗi phần tử trong cấu trúc bản ghi được gọi là trường.
Cú pháp khai báo bản ghi:
Type recordTypeName = Record
fieldList 1 : type 1;
fieldList 2 : type 2;

fieldList n : type n;
End;
c. Kiểu miền con (Subrange Type)

13


Kiểu miền con của một kiểu rời rạc là một miền trị của kiểu rời rạc đó.
Cú pháp khai báo kiểu miền con:
Ví dụ:
Type
Ngay=(sun,mon,tue,wed,thu,fri,sat);
Chuthuong=’a’..’z’;
Sonho=100..200;
d. Kiểu tập hợp (Set type)
Kiểu miền con là một tập các giá trị có cùng kiểu thứ tự. Mỗi biến kiểu tập
hợp có thể chứa nhiều phần tử của tập hợp. Tập hợp chỉ chứa được tối đa 256
phần tử, bao gồm cả tập hợp rỗng.
Cú pháp khai báo: Set of baseType;
Trong đó baseType là kiểu thứ tự bất kỳ có số phần tử không quá 256.
1.2.4.3. Các cấu lệnh cấu trúc
Dạng 1:

If expression then statement;
Trong đó, expression là một biểu thức logic. Nếu expression trả về giá trị
đúng thì lệnh statement được thực hiện, nếu không chương trình sẽ chuyển điều
khiển xuống dòng lệnh kế tiếp.
Dạng 2:
If expression then statement 1
Else statement 2;
Trong đó, expression là một biểu thức logic. Nếu expression trả về giá trị
đúng thì lệnh statement 1 sẽ được thực hiện, ngược lại, nếu expression trả về giá
trị sai thì lệnh statement 2 sẽ được thực hiện.
b. Câu lệnh CASE
Dạng 1:
Case selectorExpression of
caseList 1 : statement 1;


14


caseList n : statement n;
End;
Trong đó, selectorExpression là một biểu thức có kết quả mang kiểu thứ tự
integer hay char. caseList i là các điều kiện so khớp với selectorExpression.
Giá trị chứa trong các danh sách caseList i phải là duy nhất bên trong lệnh
case.
Dạng 2:
Case selectorExpression of
caseList 1 : statement 1;

.


caseList n : statement n;
else
Statement t;
End;
Với cú pháp trên, khi lệnh case thực thi, phải có ít nhất một lệnh statement được
gọi vì trong trường hợp xấu nhất là khi biểu thức selectorExpression không thoả
mãn các điều kiện của caseList thì lệnh statement t của mệnh đề else sẽ được gọi.
c. Lệnh REPEAT
Repeat
Statement 1;
.
.
statement n;
Until expression;
Trong đó, expression là một biểu thức so sánh trả về giá trị đúng hoặc sai.
Câu lệnh Repeat sẽ thực thi từng lệnh satement bên trong khối. Sau khi thực hiện
lệnh cuối cùng, biểu thức expression trong mệnh đề Until sẽ được kiểm tra. Nếu
expression trả về giá trị TRUE, lệnh Repeat sẽ ngừng thực thi, điều khiển
chương trình sẽ thoát ra khỏi vòng lặp. Nếu expression trả về giá trị FALSE ,
điều khiển chương trình sẽ nhảy về đầu vòng lặp Repeat, tiếp tục thực hiện lại
lệnh đầu tiên.

15


d. Lệnh WHILE
While expression Do statement;
Lệnh While tương tự như lệnh Repeat, ngoại trừ biểu thức giá trị điều kiện
lặp được kiểm tra đầu tiên, trước khi bước vào thực hiện các lệnh khác chứa

trong vòng lặp.
e. Lệnh FOR
Dạng 1:
For counter := initialValue to finalValue do statement;
Dạng 2:
For counter := inittialValue downto finalValue do statement;
Trong đó, counter là một biến, initialValue và finalValue là các biểu thức thể
hiện số lần lặp được gán tuần tự cho biến counter. Statement là khối lệnh lặp cần
thực hiện.
Lệnh For sẽ khởi gán giá trị đầu tiên initialValue cho biến counter, sau đó
thực thi lệnh satement. Tiếp đến, giá trị của biến counter tăng lên 1 đơn vị đối
với dạng 1 và giảm 1 đơn vị đối với dạng 2. Khi counter bằng với biểu thức
finalValue, lệnh statement sẽ được thực thi lần cuối cùng sau đó chấm dứt vòng
lặp, để điều khiển thoát khỏi vòng lặp.
f. Lệnh ngắt Break và Continue
 Lệnh Break
Lệnh Break được gọi bên trong vòng lặp sẽ làm cho vòng lặp bị ngắt. Quyền
điều khiển chương trình sẽ chuyển cho dòng lệnh nằm kế tiếp vòng lặp.
 Lệnh Continue
Lệnh Continue được gọi bên trong vòng lặp với mục đích bỏ qua các đoạn mã
lệnh còn lại bên dưới continue để quay trở về đầu vòng lặp.

16


CHƯƠNG 2
ĐỒ THỊ VÀ ỨNG DỤNG CỦA ĐỒ THỊ
2.1. Đồ thị
2.1.1. Định nghĩa đồ thị
Đồ thị là một cấu trúc rời rạc bao gồm các đỉnh và các cạnh nối các đỉnh

này, các loại đồ thị khác nhau được phân biệt bởi kiểu và số lượng cạnh nối hai
đỉnh nào đó của đồ thị.
Giả sử X là tập hữu hạn, không rỗng các phần tử nào đó và U  XX. Bộ G
= <X, U> được gọi là đồ thị hữu hạn. Mỗi phần tử xX gọi là một đỉnh và mỗi
phần tử u = (x,y)  U gọi là một cạnh của đồ thị G = <X, U>.
Xét một cạnh u  U khi đó tồn tại 2 đỉnh x, y  X sao cho u = (x, y), ta nói rằng
x nối với y hoặc x và y thuộc u.
x

u

y

- Nếu cạnh u = (x, y) mà x và y là hai đỉnh phân biệt thì ta nói x, y là hai đỉnh kề
nhau.
- Nếu u = (x, x) thì u là cạnh có hai đỉnh trùng nhau ta gọi đó là một khuyên.
- Nếu u = (x, y) mà x,y là cặp đỉnh có phân biệt thứ tự hay có hướng từ x đến y
thì u là một cung, khi đó x là gốc còn y là ngọn hoặc x là đỉnh ra, y là đỉnh vào.
- Khi giữa cặp đỉnh (x, y) có nhiều hơn một cạnh thì ta nói những cạnh cùng cặp
đỉnh là những cạnh song song hay là cạnh bội

y

x

y

a)
a. Tại đỉnh y có một khuyên


b)

x

y

c)

b. Một cung có hướng từ x sang y

c. Cặp đỉnh (x, y) có 2 cạnh song song
Hình 1.1

17


* Đồ thị đơn
Đồ thị G = <X, U> được gọi là đồ thị đơn nếu giữa hai đỉnh bất kỳ được nối
với nhau bởi không quá một cạnh (cung), tức là đồ thị không có cạnh bội, không
có khuyên.
* Đa đồ thị
Đồ thị G = <X, U> được gọi là đa đồ thị nếu nó có ít nhất một cặp đỉnh
được nối với nhau bởi hai cạnh (hai cung) trở lên.
* Giả đồ thị
Là đồ thị có ít nhất một khuyên, có thể chứa cạnh bội, cạnh đơn. Tóm lại
đây là loại đồ thị tổng quát nhất.
A

B


A

B
A

D

C

B

C

D

D

a)

b)

Hình 1.2 a.Đơn đồ thị

b. Đa đồ thị

C

c)
c. Giả đồ thị


2.1.2. Các loại đồ thị
*Đồ thị vô hướng
Đồ thị G=<X,U> được gọi là đồ thị vô hướng nếu tất cả các cạnh e  U mà
cặp đỉnh thuộc nó e = (x,y)  X không phân biệt thứ tự. Đồ thị vô hướng là đồ thị
không có bất kỳ một cung nào.
Ví dụ: như hình 1.2.b là biểu diễn của một đồ thị vô hướng.
* Đồ thị có hướng
Đồ thị G = <X, U> được gọi là đồ thị có hướng nếu tất cả các cạnh e  U
mà cặp đỉnh thuộc nó e = (x, y)  X có phân biệt thứ tự. Đồ thị có hướng là đồ
thị mà mọi e = (x, y)  X đều là cung.
Ví dụ :

18


C
A

B

Hình 2.1 Đồ thị có hướng
* Đồ thị hỗn hợp
Đồ thị G=<X,U> vừa có cạnh vô hướng, vừa có cạnh có hướng thì nó được
gọi là đồ thị hỗn hợp, loại đồ thị này rất ít khi được dùng tới.
Chú ý rằng vấn đề phân chia đồ thị và các thuật ngữ về đồ thị chỉ mang tính
tương đối, hiện nay vẫn còn chưa mang tính thống nhất chuẩn trên nhiều tài liệu.
2.1.3. Một số khái niệm và tính chất cơ bản của đồ thị
2.1.3.1. Bậc đồ thị
* Bậc đồ thị vô hướng
Cho đồ thị vô hướng G = <X,U>. Xét 1 đỉnh x  X đặt m(x) là số cạnh

thuộc đỉnh x khi đó m(x) được gọi là bậc của đỉnh x. Nếu x có một khuyên thì
m(x) được cộng thêm 2.

m(x) = 3

m(x) = 2

x

x

- Nếu m(x) = 0 thì đỉnh x được gọi là đỉnh cô lập.
- Nếu m(x) = 1 thì đỉnh x được gọi là đỉnh treo.
Ta đặt
m(G) 

 m(x)
xX

thì m(G) được gọi là bậc của đồ thị vô hướng G = <X, U>
* Bậc đồ thị có hướng
Cho đồ thị có hướng G= <X,U> xét 1 đỉnh x  X, ta ký hiệu m +(x) là số các
cung vào của đỉnh x, còn m-(x) là số các cung ra khỏi x. Khi đó ta gọi m+(x) là
bậc vào của đỉnh x còn m-(x) là bậc ra của đỉnh x.
- Nếu m+(x) + m-(x) = 0 thì đỉnh x được gọi đỉnh là cô lập.
- Nếu m+(x) + m-(x) = 1 thì đỉnh x được gọi là đỉnh treo.
Ta đặt
m(G) 

m

x X



m

(x) 

xX

19



(x)


Khi đó m(G) được gọi là bậc của đồ thị có hướng G = <X,U>.
Trong đồ thị có hướng thì m+(x) = m-(x) = U 
Ví dụ:
- Xét đồ thị vô hướng như trong hình 1.3.a ta có:
m(G) = m(A) + m(B) + m(C) + m(D) = 2 + 5 + 2 + 1 = 10
- Xét đồ thị có hướng trong hình 2.1 ta có:
m(G) = [m+(A) + m+(B) + m +(C) ] + [m-(A) + m-(B) + m-(C)]
= [1 + 2 + 1] + [2 + 1 +1] = 8
Định lý:
Cho đồ thị hữu hạn G = <X,U> khi đó bậc của đồ thị G bằng 2 lần số cạnh
của đồ thị, tức là m(G) = 2 U.
Chứng minh:
Ta thấy một cạnh thuộc 2 đỉnh, nếu xoá một cạnh thì bậc của G giảm đi 2,

nếu xoá một khuyên u = (x, x) thì bậc của G cũng giảm đi 2, còn nếu xoá hết
cạnh, hết khuyên thì bậc của đồ thị bằng 0. Từ đó suy ra định lý.
Hệ quả: Số đỉnh bậc lẻ của đồ thị G = <X,U> là một số chẵn
Chứng minh:
Gọi A và B tương ứng là tập đỉnh bậc lẻ và tập đỉnh bậc chẵn của đồ thị. Ta
2m   m(x) 
xX

 m(x)   m(x)
x A

x B

có:
Do vế trái chẵn nên tổng vế phải cũng là số chẵn. Mà tổng bậc của các đỉnh
bậc chẵn (x  A) là số chẵn nên tổng bậc của các đỉnh bậc lẻ (xB) phải là số
chẵn, do tất cả các số hạng của nó là số lẻ, nên tổng này phải gồm một số chẵn
các số hạng. Vì vậy số đỉnh bậc lẻ phải là số chẵn.
2.1.3.2. Đường đi và chu trình
* Đường đi
Xét đồ thị G = <X,U> với

20


- Tập đỉnh X = {x1,x2,...,xn}
- Tập cạnh U = {u 1,u2,...,u m}
Tập hợp các đỉnh kề nhau từ xi đến xj được gọi là 1 đường đi, kí hiệu
xixi1xi2 ... xj  xiuixi1ui1xi2ui2 ... ujxj
Trong đó các cạnh, các đỉnh trong đường đi có thể lặp lại

Độ dài của đường đi bằng số các cạnh (hoặc cung) trong đường đi đó.
-Chú ý rằng trong đồ thị có hướng, trên một cung uv chẳng hạn thì đường đi
chỉ có thể đi từ gốc (u) đến ngọn (v) không thể đi ngược lại.
* Chu trình
Xét một đường đi từ xi - xj. Nếu xi  xj thì đường đi này được gọi là một chu
trình. Như vậy chu trình là một đường đi có đỉnh xuất phát và đỉnh kết thúc trùng
nhau.
Chú ý rằng đường đi trong đồ thị có hướng không được đi ngược chiều mũi
tên
- Đường đi (chu trình) được gọi là đơn nếu nó đi qua mỗi cạnh không quá
một lần.
- Đường đi (chu trình) được gọi là sơ cấp nếu nó đi qua mỗi đỉnh đúng một
lần
A

B

E
C

D

Hình 3.1
Ví dụ như ở hình 3.1 ADBE là một đường đi sơ cấp từ A đến E độ dài 3;
ABCDBE là đường đi không sơ cấp ( qua B 2 lần) từ A đến E độ dài 5; ABDAB
là một đường đi không đơn (chứa cạnh AB 2 lần) từ A đến B độ dài 4; ABDA
Là 1 chu trình đơn và sơ cấp độ dài 3; CC là đường đi độ dài 0.
Xét đồ thị có hướng như hình 2.1 thì ABCB là một đường đi độ dài 3; CBA
không là một đường đi vì không có cung đi từ B đến A.


21


Định lý:
Nếu trong đồ thị G = <X,U> các đỉnh đều có bậc không nhỏ hơn 2 (x  X
| m(x)  2) thì trong G tồn tại ít nhất một chu trình.
Chứng minh:
Xét tất cả các đường đi đơn. Vì đồ thị là hữu hạn cho nên số các đường đi
đơn là hữu hạn. Chọn một đường đi là dài nhất nào đó ví dụ từ xi1 đến xij +1 (xem
hình vẽ dưới đây). Theo giả thiết m(x)  2 nên tồn tại ít nhất một đỉnh xi0 và một
cạnh nối đỉnh xi1 và xi0. Đỉnh xi0 thuộc một trong các đỉnh trên đường đi đã chọn
chẳng hạn xij vì đường đi là dài nhất, nên chứng tỏ tồn tại một chu trình trong
đường đi.
xi1

xi2

xi3

xij

xij+

xi0

2.1.3.3. Đồ thị liên thông
Cho đồ thị G = <X,U>. Hai đỉnh phân biệt x,y X được gọi là liên thông
nếu tồn tại một đường đi nối các đỉnh x, y với nhau. Đồ thị G được gọi là liên
thông nếu với hai đỉnh phân biệt bất kỳ trong đồ thị đều là liên thông.
Ví dụ như hình 3.1 là một đồ thị liên thông vì luôn có đường đi nối hai đỉnh

bất kỳ của đồ thị, còn đồ thị như hình 3.2 là không liên thông vì không có đường
đi từ A tới D hoặc từ D tới F v.v..
Xét 2 đồ thị liên thông
G1 = <X1, U1> và G2 = <X2, U2>
Trong đó:

X1  X2 = 
và U1  U2 = 

Khi đó:

X = X1  X2
U = U1  U2

Thì G = <X,U> là đồ thị có 2 thành phần liên thông G1, G2.

22


A

B

C

D

E

F

Hình 3.3

Ví dụ như đồ thị trong hình 3.3 có ba thành phần liên thông sau:
G1 = <X1, U1> với X1= {A,B,C} và U1 = {AB, AC, CB}
G2 = <X2, U2> với X2= {D, E} và U2 = {DE}
G3 = <X3, U3> với X3= {F} và U3 = 
Cho đồ thị có hướng G = <X, U>
- G được gọi là đồ thị liên thông yếu nếu đồ thị vô hướng tương ứng với nó là
liên thông
- G là liên thông một chiều nếu với hai đỉnh x,y khác nhau bất kỳ của G luôn có
đường đi x - y hoặc đường đi y - x.
- G là liên thông mạnh (liên thông 2 chiều) nếu hai đỉnh x,y khác nhau bất kỳ của
G đều có đường đi x - y và đường đi y - x.
A

B

A

B

A

B

D

D

D


C

C

C

H1

H2

H3

Hình 3.4
Ở hình 3.4 đồ thị H1 là liên thông mạnh, giả sử cặp đỉnh (A,C) ta có chiều
đi từ C tới A, và đồng thời cũng có chiều đi từ A tới C, và bất kỳ các cặp đỉnh
khác cũng tương tự như vậy. H2 là liên thông một chiều vì xét cặp đỉnh (A,D) có
chiều đi từ D tới A nhưng không có chiều đi từ A tới D. H3 là liên thông yếu vì
tồn tại cặp đỉnh (B,C) không có chiều đi B - C cũng không có chiều đi C - B,
nhưng đồ thị vô hướng tương ứng là liên thông.

23


2.1.4. Các dạng biểu diễn của đồ thị
2.1.4.1. Biểu diễn hình học của đồ thị
Để có cái nhìn trực quan ta thường biểu diễn đồ thị bằng hình học, một đồ
thị có thể biểu diễn trên một mặt phẳng hoặc trong không gian. Phương pháp
biểu diễn như sau: Biểu diễn các đỉnh của đồ thị bằng các điểm (hay vòng tròn
nhỏ, ô vuông nhỏ) và nối hai điểm bằng một đường (cong, thẳng, mũi tên) khi

cặp điểm đó ứng với một cạnh (cung) của đồ thị.
Ví dụ 1: Cho đồ thị G = <X,U> trong đó
X = {A, B, C, D, E} và

U = {AB, AC, AD, AE, BD, CD, CE}
D

C
B

A

E

E

a)

B

A

D

b)

C

Hình 4.1
Hình 4.1.a và hình 4.1.b đều là biểu diễn hình học của đồ thị G đã cho ở trên

2.1.4.2. Sự đẳng cấu
Với mỗi đồ thị thì có thể có nhiều dạng biểu diễn hình học, có nhiều đồ thị
tưởng chừng khác nhau nhưng đó là cách biểu diễn hình học khác nhau của cùng
một đồ thị, sự đẳng cấu cho phép chúng ta kết luận được điều đó.
Định nghĩa: Xét 2 đồ thị G1 = (X1, U1) và G2 = <X2, U2>
Hai đồ thị này được gọi là đẳng cấu với nhau nếu tồn tại 1 song ánh từ X1
vào X2 và từ U1 vào U2 sao cho nếu có cạnh e = (u, v)  U1 tương ứng với cạnh e'
= (u', v') U2 thì cặp đỉnh u, v  X1 cũng là tương ứng cặp đỉnh u', v'  X2
Ví dụ xét 2 đồ thị G1 và G2 như hình 4.2
a

b

m

n

d

c

q

p

G1

G
Hình 4.2


24


Ta có f : G1  G2
f(a) = m

f(c) = n

f(d) = q

f(b) = p

Nếu a, b  X1 kề nhau thì f(a), f(b)  X2 kề nhau.
Vậy đây là 2 đồ thị đẳng cấu với nhau, ta có thể xem G1 và G2 thực chất chỉ
là 1 chỉ có điều biểu diễn ở dạng hình học khác nhau, các tên đỉnh khác nhau. Để
xét 2 đồ thị có đẳng cấu không là việc khó, tuy nhiên để xét 2 đồ thị không đẳng
cấu với nhau thì đơn giản hơn.
Đối với 2 đồ thị đẳng cấu thì các đồ thị đó có những tính chất bất biến như sau:
- Số đỉnh bằng nhau
- Số cạnh bằng nhau
- Bậc các đỉnh tương ứng cùng như nhau
- 2 Ma trận kề cũng như nhau
- Các chu trình cũng như nhau
2.1.4.3. Một số đồ thị đặc biệt
Do tính chất, dạng biểu diễn có những nét đặc thù riêng biệt nên ta phân
loại một số đồ thị thành các dạng đặc biệt sau:
* Đồ thị đều
Là một đồ thị mà mọi đỉnh có cùng bậc, nếu bậc này bằng k thì đó là đồ thị k
- đều


a)

b)

c)

d)

Hình 4.3 a: G- 1 đều; b: G - 2 đều; c: G - 2 đều; d: G - 3 đều.
Trường hợp riêng như đồ thị hình 4.3.b và hình 4.3.c là những đồ thị vòng ký
hiệu Cn (n là số đỉnh)

25


×