Chương I: Thuật toán | Lý thuyết môn Toán rời rạc | trường Đại học Huế

Có nhiều lớp bài toán tổng quát xuất hiện trong toán học rời rạc . Chẳng hạn, cho một dãy các số nguyên, tìm số lớn nhất; cho một tập hợp, liệt kê các tập con của nó; cho tập hợp các số nguyên,xếp chúng theo thứ tự tăng dần; cho một m¿ng, tìm °ßng i ngắn nhất giữa hai ỉnh của nó. Khi được giao cho một bài toán như vậy thì việc đầu tiên phải làm là xây dựng một mô hình dịch bài toán ó thành ngữ cảnh toán học. Tài liệu giúp bạn tham khảo, ôn tập và đạt kết quả cao. Mời bạn đọc đón xem!

Môn:
Trường:

Đại học Huế 272 tài liệu

Thông tin:
19 trang 3 tháng trước

Bình luận

Vui lòng đăng nhập hoặc đăng ký để gửi bình luận.

Chương I: Thuật toán | Lý thuyết môn Toán rời rạc | trường Đại học Huế

Có nhiều lớp bài toán tổng quát xuất hiện trong toán học rời rạc . Chẳng hạn, cho một dãy các số nguyên, tìm số lớn nhất; cho một tập hợp, liệt kê các tập con của nó; cho tập hợp các số nguyên,xếp chúng theo thứ tự tăng dần; cho một m¿ng, tìm °ßng i ngắn nhất giữa hai ỉnh của nó. Khi được giao cho một bài toán như vậy thì việc đầu tiên phải làm là xây dựng một mô hình dịch bài toán ó thành ngữ cảnh toán học. Tài liệu giúp bạn tham khảo, ôn tập và đạt kết quả cao. Mời bạn đọc đón xem!

44 22 lượt tải Tải xuống
lO MoARcPSD| 45467232
lO MoARcPSD| 45467232
CHƯƠNG I:
THUT TOÁN
1.1. KHÁI NIàM THUT TN.
1.1.1. Mở đầu:
Có nhiều lớp i toán tng quát xut hiện trong toán học rßi r¿c. Chng h¿n, cho
một dãy các s nguyên, m s lớn nht; cho một tập hợp, lit kê các tập con của nó; cho
tập hợp các s nguyên, xếp chúng theo thứ tự tăng dn; cho một m¿ng, tìm °ßng i ngắn
nht giữa hai nh của nó. Khi °ợc giao cho một bài toán nh° vy thì việc u tiên pi làm
xây dựng một hình dịch bài toán ó thành ngữ cÁnh toán học. c cấu trúc i r¿c
°ợc dùng trong các mô hình này là tp hợp, dãy, hàm, hoán v, quan hệ, cùng với các cấu
trúc kc nh° thị, cây, m¿ng - những ki niệm s °ợc nghiên cứu á các ch°¡ng sau.
Lập °ợc một mô hình toán hc thích hợp chỉ là một phn ca quá trình giÁi. Để hoàn tt
quá trình gi, còn cần phÁi có một ph°¡ng pháp dùng mô hình giÁi i toán tng quát.
Nói mt cách lý t°áng, cái °ợc òi hi một th tc, ó y các b°ớc dẫn tới áp s mong
mun. Một dãy c b°ớc nh° vậy, °ợc gọi một thut toán. Khi thiết kế và cài t một
phn mềm tin học cho một vn nào ó, ta cn phÁi °a ra ph°¡ng pháp giÁi quyết thực
cht ó thut toán giÁi quyết vấn này. ràng rng, nếu không m °ợc một ph°¡ng
pháp giÁi quyết thì không thể lập trình °ợc. Chính vì thế, thut toánkhái niệm nn ng
ca hu hết các lĩnh vực của tin học.
1.1.2. Định nghĩa: Thut toán là một bÁng lit kê các chỉ dn (hay quy tc) cn thực
hiện theo từng b°ớc c ịnh nhằm giÁi một bài toán ã cho.
Thut ng <Algorithm= (thut toán) là xut phát t n nhà toán hc À Rập
AlKhowarizmi. Ban u, talgorism °ợc dùng chỉ các quy tc thc hiện các phép tính s
hc trên các s thp phân. Sau ó, algorism chuyển thành algorithm vào thế k 19. Với s
quan tâm ngày càng tăng i với các máy tính, khái niệm thuật toán ã °ợc cho mt ý nga
chung n, bao hàm cÁ các thủ tc xác nh giÁi các bài toán, ch không phÁi chỉ là th
tục thực hiện các phép nh s học.
nhiều cách trình y thuật toán: dùng ngôn ngtnhn, ngôn ng u (s¡ khi),
ngôn ng lp trình. Tuy nhn, một khi dùng ngôn ng lp trình thì chnhững lnh °ợc
phép trong ngôn ngó mới có thể dùng °ợc và iu này th°ßng làm cho smô tÁ các thut
toán trá nên rối rắm và khó hiểu. n nữa, vì nhiều ngôn ng lập trình u °ợc ng rng
rãi, nên chn một ngôn ng c biệt nào ó iều ng°ßi ta không mun. Vì vậy á ây các
thuật toán ngoài vic °ợc trình bày bằng ngôn ngtnhn cùng với nhng hiệu toán
lO MoARcPSD| 45467232
5
hc quen thuộc còn dùng một d¿ng giÁ thut toán. GiÁ t¿o ra b°ớc trung
gian giữa smô tÁ một thut toán bng ngôn ngthông th°ßng và sthực hin thut toán
ó trong ngôn ng lập trình. Các b°ớc ca thut toán °ợc chỉ rõ bng ch dùng các lnh
giống nh° trong các ngôn ng lập trình. Thí dÿ 1: thuật toán tìm phn tử lớn nhất
trong một y hữu h¿n các s nguyên. a) Dùng ngôn ngtnhn mô t các bước cần
phi thc hin:
1. Đặt g tr cực ¿i t¿m thßi bng s nguyên ầu tiên trong y. (Cực ¿i t¿m thßi s s
nguyên lớn nht ã °ợc kiểm tra á một giai o¿n nào ó của th tục.) 2. So sánh s nguyên
tiếp sau với gtrị cực ¿i t¿m thßi, nếu nó lớn n g trị cực ¿i t¿m thßi thì t cực ¿i t¿m
thßi bằng s nguyên ó. 3. Lặp l¿i b°ớc tr°ớc nếu còn các số nguyên trong dãy.
4. Dừng khi không còn s nguyên o nữa trong y. Cực ¿i t¿m thßi á im này chính
s nguyên lớn nht ca dãy. b) ng oạn giả:
procedure max (a
1
, a
2
, ..., a
n
: integers)
max:= a
1
for i:= 2 to n
if max <a
i
then max:= a
i
{max là phn tlớn nht}
Thuật toán này tr°ớc hết gán s h¿ng u tiên a
1
ca y cho biến max. Vòng lặp <for= °ợc
dùng kiểm tra lần l°ợt các s h¿ng của y. Nếu một s h¿ng lớn h¡n g tr hiện thßi
ca max thì nó °ợc gán làm g trị mới ca max.
1.1.3. c đặc trưng ca thuật toán:
-- Đu vào (Input): Một thut toán có các g tru vào tmột tp ã °ợc chỉ rõ.
-- Đu ra (Output): Tmỗi tập các g tru vào, thut toán s t¿o ra các giá trị ầu ra.
Các giá trị ầu ra chính là nghiệm của i toán.
-- Tính dừng: Sau một s hữu h¿n b°ớc thut toán phÁi dừng.
-- Tính xác định: à mỗi b°ớc, các b°ớc thao tác phÁi hết sức rõng, không gây nên s
nhp nhng. Nói rõ n, trong cùng một iu kiện hai b x cùng thực hiện một b°ớc
ca thut toán phÁi cho những kết quÁ nh° nhau.
-- Tính hiáu qu: Tr°ớc hết thut toán cn úng n, nghĩa là sau khi °a dữ liu vào thuật
toán ho¿t ng và °a ra kết quÁ nh° ý mun.
-- Tính ph dÿng: Thut toán có thgiÁi bt k một bài toán o trong lớp các bài toán.
C thể là thuật toán có thể cóc ầu vào là các bộ dliệu khác nhau trong một miền xác
ịnh.
1.2. THU¾T TOÁN TÌM KM.
1.2.1. Bài toán tìm ki¿m: i toán xác ịnh v trí của một phn tử trong một bÁng lit
kê sp tht th°ßng gp trong nhiu tr°ßng hợp khác nhau. Chẳng h¿n ch°¡ng trình kiểm
tra chính của các từ, m kiếm các tnày trong một cun từ in, tin chng qua
lO MoARcPSD| 45467232
cũng là một bÁng liệt kê sắp thtca các từ. c i toán thuộc lo¿i này °ợc gọi các
bài toán m kiếm.
i toán tìm kiếm tng quát °ợc tÁ nh° sau: xác nh v t của phần tử x trong một
bÁng liệt kê các phần tử phân bit a
1
,
a
2
, ..., a
n
hoặc xác nh rằng nó không có mặt trong
bÁng liệt kê ó. Lßi giÁi của bài toán trên là vtrí ca s h¿ng ca bÁng liệt kê có g tr
bng x (tức là i s nghiệm nếu x=a
i
và 0 nếu x không có mặt trong bÁng liệt kê).
1.2.2. Thu¿t toán m ki¿m tuy¿n tính: Tìm kiếm tuyến tính hay tìm kiếm tun tlà
bt u bng vic so sánh x với a
1
; khi x=a
1
, nghiệm là v trí a
1
, tức là 1; khi x a
1
, so sánh
x với a
2
. Nếu x=a
2
, nghiệm v t của a
2
, tức là 2. Khi x a
2
, so sánh x với a
3
. Tiếp tc
quá trình y bng ch tuần tự so sánh x với mỗi số h¿ng ca ng lit kê cho tới khi
m °ợc s h¿ng bằng x, khi ó nghim v t của s h¿ng ó. Nếu toàn ng liệt ã °ợc
kiểm tra không c nh °ợc v t của x, thì nghiệm là 0. G i với thut toán m
kiếm tuyến nh °ợc cho d°ới ây:
procedure tìm kiếm tuyến tính (x: integer, a
1
,a
2
,...,an: integers phân bit)
i := 1
while (i n and x a
i
)
i := i + 1
if i n then location := i
else location := 0
{location là chỉ s d°ới ca s h¿ng bng x hoặc là 0 nếu không tìm °ợc x}
1
.2.3. Thu¿t toán m ki¿m nh phân: Thut toán này có thể °ợc dùng khi bÁng lit
kê có các s h¿ng °ợc sắp theo thứ ttăng dần. Chng h¿n, nếu các s h¿ng là các s thì
chúng °ợc sp ts nh nht ến s lớn nht hoc nếu cng các thay xâu ký tthì
chúng °ợc sp theo thtt in. Thut toán thhai này gi là thut toán tìm kiếm nh
phân. °ợc tiến nh bng cách so sánh phn tử cn xác nh v trí với s h¿ng á giữa
bÁng lit kê. Sau ó bÁng này °ợc tách làm hai bÁng kê con nh n có kích th°ớc nh°
nhau, hoặc một trong hai bÁng con ít h¡n ng con kia một số h¿ng. Sự tìm kiếm tiếp tục
bng cách h¿n chế m kiếm á một ng kê con thích hợp dựa trên vic sonh phn t
cn xác nh v trí với s h¿ng giữa ng kê. Ta s thy rng thut toán tìm kiếm nhphân
hiệu quÁ n nhiều so với thuật toán tìm kiếm tuyến tính.
Thí dÿ 2. Để m s 19 trong ng liệt kê 1,2,3,5,6,7,8,10,12,13,15,16,18,19,20,22 ta
tách bÁng lit kê gồm 16 số h¿ng này thành hai bÁng lit kê nh h¡n, mỗi bÁng có 8 s
h¿ng, c thlà: 1,2,3,5,6,7,8,10 và 12,13,15,16,18,19,20,22. Sau ó ta so sánh 19 với s
h¿ng cui cùng ca ng con thứ nht. Vì 10<19, vic m kiếm 19 chgiới h¿n trong
bÁng liệt con th 2 từ s h¿ng thứ 9 ến 16 trong ng liệt kê ban u. Tiếp theo, ta
lO MoARcPSD| 45467232
7
l¿i tách bÁng lit kê con gm 8 số h¿ng này làm hai ng con, mỗi bÁng có 4 s h¿ng,
c th là 12,13,15,16 và 18,19,20,22. Vì 16<19, việc tìm kiếm l¿i °ợc giới h¿n chỉ trong
bÁng con th2, từ s h¿ng th13 ến 16 của ng liệt kê ban u. ng liệt kê thứ 2 này
l¿i °ợcch làm hai, c thể là: 18,19 và 20,22. Vì 19 không lớn n s h¿ng lớn nht ca
bÁng con thnht nên vic tìm kiếm giới h¿n chỉ á bÁng con thnht gồm các số 18,19,
s h¿ng th13 và 14 ca ng ban u. Tiếp theo bÁng con cha hai s h¿ng y l¿i
°ợcch làm hai, mỗi ng có một số h¿ng 18 và 19. Vì 18<19, sm kiếm giới h¿n ch
trong ng con thứ 2, bÁng liệt chchứa s h¿ng th14 ca ng liệt kê ban u, s
h¿ng ó s 19. y giß sm kiếm ã thu hp v chỉ còn một số h¿ng, sonh tiếp cho
thấy19 là s h¿ng thứ 14 của ng liệt kê ban u.
Bây g ta có th chỉ rõ các b°ớc trong thut toán tìm kiếm nhphân.
Để tìm số nguyên x trong bÁng liệt kê a
1
,a
2
,...,a
n
với a
2
< a
2
< ... < a
n
, ta bt u bằng vic
so sánh x với s h¿ng a
m
á giữa ca dãy, với m=[(n+1)/2]. Nếu x > a
m
, vic m kiếm x
giới h¿n á nửa th hai ca dãy, gồm a
m+1
,a
m+2
,...,a
n
. Nếu x không lớn n a
m
, thì sm
kiếm giới h¿n trong nửa ầu của dãy gồm a
1
,a
2
,...,a
m
.
y g stìm kiếm chgiới h¿n trong bÁng liệt kê có không h¡n [n/2] phần tử. Dùng
chính th tc này, so sánh x với số h¿ng á giữa của ng lit kê °ợc h¿n chế. Sau ó l¿i
h¿n chế vic tìm kiếm á nửa thnht hoc nửa thhai của bÁng liệt kê. Lặp l¿i quá trình
này cho tới khi nhn °ợc một ng liệt kê chcó một s h¿ng. Sau ó, ch còn xác nh s
h¿ng này có pi x hay không. GiÁ cho thut toán tìm kiếm nhphân °ợc cho d°ới
ây:
procedure tìm kiếm nhphân (x: integer, a
1
,a
2
,...,an: integersng dần)
i := 1 {i là im t trái ca khoÁng m kiếm} j := n {j iểm mút
phÁi của khoÁng m kiếm} while i < j begin
m:= [(i+j)/2]
if x>a
m
then i:=m+1
else j := m
end
if x = ai then location := i
else location := 0
{location là chỉ s d°ới ca s h¿ng bng x hoặc 0 nếu không tìm thy x}
1
.3. ĐÞ PHĂC T¾P CĀA THU¾T TN.
2
.3.1. Khái niám v ß phăc t¿p cāa mßt thu¿t toán:
Th°ớc o hiệu quÁ của một thut toán là thßi gian y nh sdụng gi bài
toán theo thuật toán ang xét, khi các giá trịu vào có mt kích th°ớc xác nh.
lO MoARcPSD| 45467232
Một th°ớc o thhai là dung l°ợng bộ nhòi hi thực hiện thut toán khi các giá trị ầu
vào có kích th°ớc xác ịnh. c vn nh° thế liên quan ến phức t¿p nh toán của một
thuật toán. Sphân ch thßi gian cn thiết ể giÁi một bài toán có kích th°ớc ặc biệt o
ó liên quan ến phức t¿p thßi gian ca thut toán. Sphân tích b nhớ cần thiết ca y
nh ln quan ến phức t¿p không gian ca thut toán. Vc xem xét phc t¿p thßi gian
và không gian ca một thut toán là một vn rất thiết yếu khi các thut toán °ợc thực
hiện. Biết một thut toán s °a ra áp s trong một micro giây, trong một phút hoc trong
một tỉ năm, hin nhiên là hết sức quan trng. T°¡ng tự nh° vy, dung l°ợng b nhòi hỏi
phÁi khÁ dng gi một i toán,vì vy phức t¿p không gian cũng cần phÁi tính
ến.Vì vic xem xét phức t¿p không gian gn liền với các cấu trúc dliệu c biệt °ợc
dùng thực hiện thut toán nên á ây ta s tập trung xem xét ộ phức t¿p thßi gian.
Độ phức t¿p thßi gian của một thut toán có thể °ợc biểu diễn qua sc phép toán °ợc
dùng bái thuật toán ó khi các giá trị ầu vào có một kích th°ớc xác nh. Sá dĩ phức t¿p
thßi gian °ợc mô thông qua s các phép toán òi hi thay vì thßi gian thực ca y tính
bái vì các y tính khác nhau thực hiện các phép tính s¡ cấp trong những khoÁng thßi
gian khác nhau. n nữa, phân tích tất cÁ các phép toán thành các phép nh bit cp
y tính sử dụng iều rất phức t¿p.
Thí dÿ 3: Xét thut toán tìm số lớn nht trong dãy n s a
1
, a
2
, ..., a
n
. Có th coi kích th°ớc
ca dữ liu nhp là sốợng phần tca dãy s, tức là n. Nếu coi mỗi ln so sánh hai s
ca thut toán òi hi một ¡n v thßi gian (giây chẳng h¿n) thì thßi gian thực hiện thut toán
trong tr°ßng hợp xấu nht là n-1 giây. Với dãy 64 số, thßi gian thực hiện thut toán nhiều
lắm là 63 gy.
Thí dÿ 4:Thut toán v trò ch¡i <Tháp Nội=
Trò ch¡i <Tháp Nội= n sau: ba cc A, B, C và 64i ĩa (có lỗ t vào cc), các
ĩa có °ßng kính ôi một kc nhau. Nguyên tắc ặt ĩa vào cc là: mỗi ĩa chỉ °ợc chng n ĩa
lớn n nó. Ban u, cÁ 64 ĩa °ợc t chng n nhau á ct A; hai ct B, C trng. Vn
phÁi chuyển cÁ 64 ĩa ó sang ct B hay C, mỗi lần chỉ °ợc di chuyn một ĩa.
Xét trò ch¡i với n ĩa ban u á cc A (cc B và C trng). Gọi S
n
là số lần chuyển ĩa ch¡i
xong trò ch¡i với n ĩa.
Nếu n=1 thì rõ ràng là S
1
=1.
Nếu n>1 thì tớc hết ta chuyển n-1 ĩa bên trên sang cc B (giữ yên ĩa thn á d°ới cùng
ca cc A). Số ln chuyển n-1 ĩa là S
n-1
. Sau ó ta chuyển ĩa thn tcc A sang cc C.
Cui cùng, ta chuyn n-1 ĩa từ cc B sang cc C (s lần chuyn là S
n-1
). Nh° vy, s ln
chuyển n ĩa từ A sang C là:
S
n
=S
n-1
+1+S
n
=2S
n-1
+1=2(2S
n-2
+1)+1=2
2
S
n-2
+2+1=.....=2
n-1
S
1
+2
n-2
+...+2+1=2
n
1.
Thut toán v t ch¡i <Tháp Nội= òi hi 2
64
1 lần chuyn ĩa (xp xỉ 18,4 tỉ tỉ
lần). Nếu mỗi lần chuyển ĩa mất 1 giây thì thßi gian thực hiện thuật toán xp x585 tỉ
năm!
lO MoARcPSD| 45467232
9
Hai thí d trên cho thy rằng: một thut toán phÁi kết thúc sau một s hữu h¿n b°ớc,
nh°ng nếu số hữu h¿n này quá lớn thì thut toán không th thực hiện °ợc trong thực tế.
Ta nói: thut toán trong Td 3 phức t¿p là n-1 và là một thut toán hữu hiệu (hay
thuật toán nhanh); thut toán trong Td 4 có phức t¿p là 2
n
1 và ó một thut toán
không hữu hiệu (hay thut toán chm).
1.3.2. So sánh ß phăc t¿p cāa các thu¿t toán:
Một bài toán th°ßng có nhiều cách giÁi, có nhiều thut toán gi, các thut toán ó có
phc t¿p khác nhau.
Xét bài toán: Tính giá trca a thc P(x)=a
n
x
n
+a
n-1
x
n-1
+ ... +a
1
x+a
0
t¿i x
0
. Thu¿t
toán 1:
Procedure nh g tr ca a thức (a
0
, a
1
, ..., a
n
, x
0
: các s thực)
sum:=a
0
for i:=1 to n
sum:=sum+a
i
x
0
i
{sum giá tr của a thức P(x) t¿i x
0
}
Chú ý rng a thức P(x) có thviết d°ới d¿ng:
P(x)=(...((a
n
x+a
n-1
)x+a
n-2
)x...)x+a
0
.
Ta có thể nh P(x) theo thut toán sau:
Thu¿t toán 2:
Procedure tính gtrị ca a thức (a
0
, a
1
, ..., a
n
, x
0
: các s thực)
P:=a
n
for i:=1 to n
P:=P.x
0
+a
n-i
{P là gtrị ca a thức P(x) t¿i x
0
}
Ta hãyt phc t¿p ca hai thut toán trên.
Đối với thut toán 1: á b°ớc 2, phÁi thực hiện 1 phép nhân và 1 phép cng với i=1; 2
phép nhân và 1 phép cng với i=2, ..., n phép nhân và 1 phép cng với i=n. Vy s phép
nh (nhân và cng) thut toán 1 òi hỏi là:
n n( 1) n n( 3)
(1+1)+(2+1)+ ... +(n+1)= +n= .
2 2
Đối với thut toán 2, b°ớc 2 phÁi thực hiện n ln, mỗi lần òi hi 2 phép nh (nhân ri
cng), do ó số phép tính (nhân và cng) thut toán 2 òi hỏi 2n.
lO MoARcPSD| 45467232
Nếu coi thßi gian thc hiện mỗi phép tính nhân và cng là nh° nhau và một ¡n v thßi
gian thì với mỗi n cho tr°ớc, thßi gian thực hin thut toán 1 n(n+3)/2, còn thßi gian
thực hiện thut toán 22n.
ràng là thßi gian thực hiện thut toán 2 ít h¡n so với thßi gian thực hiện thuật toán 1.
Hàm f
1
(n)=2n là hàm bậc nht, tăng chậm h¡n nhiu so với m bậc hai f
2
(n)=n(n+3)/2.
Ta nói rằng thut toán 2 (có phức t¿p 2n) là thut toán hu hiệu h¡n (hay nhanh h¡n)
so với thut toán 1 (có phức t¿p là n(n+3)/2).
Để so sánh phức t¿p ca các thut toán, iu tiện lợi coi phc t¿p của mỗi thut toán
nh° cp ca hàm biểu hiện thßi gian thực hiện thut toán y.
Các hàmt sau ây u là m ca biến s tự nhn n>0.
Định nghĩa 1:Ta nói hàm f(n) có cp thp h¡n hay bằng hàm g(n) nếu tồn t¿i hằng s
C>0 và một số tự nhn n
0
sao cho
|f(n)| C|g(n)| với mọi n n
0
.
Ta viết f(n)=O(g(n)) và còn nói f(n) thoÁ n quan h big-O i với g(n).
Theo nh nghĩa y, hàm g(n) là một hàm ¡n giÁn nhất có th °ợc, ¿i diện cho <sbiến
thiên= của f(n).
Khái niệm big-O ã °ợc dùng trong toán hc ã gần một thế k nay. Trong tin hc, nó °ợc
sdng rộng rãi phân ch các thut toán. Nhà toán học ng°ßi Đức Paul Bachmann
ng°ßiu tn °a ra khái niệm big-O vào năm 1892.
Thí dÿ 5: Hàm f(n)=
n n( 3)
hàm bc hai và hàm bc hai ¡n giÁn nht là n
2
. Ta
có:
2
f(n)= n n( 3) =O(n
2
) vì
n n( 3)
n
2
với mọi n 3 (C=1,
n
0
=3).
2 2
Một cách tng quát, nếu f(n)=a
k
n
k
+a
k-1
n
k-1
+ ... +a
1
n+a
0
tf(n)=O(n
k
). Tht vy, với n>1,
|f(n)|| |a
k
|n
k
+|a
k-1
|n
k-1
+ ... +|a
1
|n+|a
0
| = n
k
(|a
k
|+|a
k-1
|/n+ ...
+|a
1
|/n
k-1
+a
0
/n
k
) n
k
(|a
k
|+|a
k-1
|+ ... +|a
1
|+a
0
).
Điều y chứng t |f(n)| Cn
k
với mọi n>1.
Cho g(n)=3n+5nlog
2
n, ta có g(n)=O(nlog
2
n). Thật vy,
3n+5nlog
2
n = n(3+5log
2
n) n(log
2
n+5log
2
n) = 6nlog
2
n với mọi n 8 (C=6, n
0
=8).
nh : Cho f
1
(n)=O(g
1
(n)) và f
2
(n) là O(g
2
(n)). Khi ó
(f
1
+ f
2
)(n) = O(max(|g
1
(n)|,|g
2
(n)|), (f
1
f
2
)(n) = O(g
1
(n)g
2
(n)).
Chăng minh. Theo giÁ thiết, tồn t¿i C
1
, C
2
, n
1
, n
2
sao cho
lO MoARcPSD| 45467232
11
|f
1
(n)| C
1
|g
1
(n)| và |f
2
(n)| C
2
|g
2
(n)| với mọi n > n
1
và mọi n > n
2
.
Do ó |(f
1
+ f
2
)(n)| = |f
1
(n) + f
2
(n)| |f
1
(n)| + |f
2
(n)| C
1
|g
1
(n)| + C
2
|g
2
(n)|
(C
1
+C
2
)g(n) với mọi n > n
0
=max(n
1
,n
2
), á âyC=C
1
+C
2
và g(n)=max(|g
1
(n)| , |g
2
(n)|).
|(f
1
f
2
)(n)| = |f
1
(n)||f
2
(n)| C
1
|g
1
(n)|C
2
|g
2
(n)| C
1
C
2
|(g
1
g
2
)(n)| với mọi n >
n
0
=max(n
1
,n
2
).
Định nghĩa 2: Nếu một thut toán có phức t¿p f(n) với f(n)=O(g(n)) thì ta cũng nói
thuật toán có ộ phức t¿p O(g(n)).
Nếu có hai thut toán gi cùng một bài toán, thut toán 1 phức t¿p
O(g
1
(n)), thuật toán 2 có phức t¿p O(g
2
(n)), mà g
1
(n) có cp thp n g
2
(n), thì ta nói
rằng thut toán 1 hữu hiệu h¡n (hay nhanh n) thut toán 2.
1.3.3. Đánh g ß phăc t¿p cāa mßt thu¿t toán:
1) Thu¿t toán tìm ki¿m tuy¿n nh:
S các phép so sánh °ợc dùng trong thut toán y cũng s °ợc xem nh° th°ớc o
phc t¿p thßi gian ca nó. à mỗi một b°ớc ca vòng lặp trong thut toán, có hai phép so
sánh °ợc thực hiện: một xem ã tới cuối ng ch°a và một ể so sánh phn tx với một
s h¿ng của bÁng. Cui cùng còn mt phép so sánh nữa làm á ngoài vòng lp. Do ó, nếu
x=a
i
, thì ã có 2i+1 phép so sánh °ợc sử dng. S phép so sánh nhiều nht, 2n+2, òi hi
phÁi °ợc sử dng khi phn tx không có mặt trong bÁng. Tó, thuật toán tìm kiếm tuyến
nh có phức t¿p là O(n).
2) Thu¿t toán tìm ki¿m nhị phân:
Đ ¡n giÁn, ta g sử rng có n=2
k
phần tử trong ng lit kê a
1
,a
2
,...,a
n
, với k s
nguyên không âm (nếu n không phÁi là lũy thừa của 2, ta có th xem bÁng một phn
ca bÁng gm 2
k+1
phần tử, trong ó k là s nguyên nh nht sao cho n < 2
k+1
).
à mỗi giai o¿n ca thut toán v trí ca số h¿ng ầu tn i và s h¿ng cuối cùng j của bÁng
con h¿n chế m kiếm á giai o¿n ó °ợc so sánh xem ng con này còn nhiều h¡n một
phn thay không. Nếu i < j, mt phép so sánh s °ợc m xác nh x có lớn n s h¿ng
á giữa ca bÁng con h¿n chế hay không. Nh° vy á mỗi giai o¿n, có sdng hai phép so
sánh. Khi trong bÁng chcòn một phn tử, một phép so sánh s cho chúng ta biết rng
không còn mt phn tnào thêm na và một phép so sánh nữa cho biết s h¿ng ó có phÁi
x hay không. Tóm l¿i cn phÁi có nhiều nht 2k+2=2log
2
n+2 phép so sánh thực hiện
phép tìm kiếm nh phân (nếu n không phÁi là lũy thừa của 2, ng gc s °ợc rng
tới bÁng có 2
k+1
phần tử, với k=[log
2
n] và stìm kiếm òi hi phÁi thực hiện nhiu nhất
2[log
2
n]+2 phép sonh). Do ó thut toán m kiếm nhphân có phức t¿p là O(log
2
n).
Tsự pn ch á trên suy ra rằng thuật toán tìm kiếm nhphân, ngay cÁ trong tßng hợp
xu nht, cũng hiệu quÁ h¡n thut toán tìm kiếm tuyến tính.
3) Chú ý: Một iu quan trng cn phÁi biết là y tính phÁi cn bao lâu giÁi xong
một bài toán. T d, nếu một thuật toán òi hỏi 10 giß, thì có thể còn áng chi phí thßi
gian y tính òi hi ể gi i toán ó. Nh°ng nếu một thut toán òi hi 10 tỉ năm
lO MoARcPSD| 45467232
gi một bài toán, thì thc hiện thuật toán ó sẽ một iều phi lý. Một trong những
hiện ợng lý thú nht ca công ngh hiện ¿i sng ghê gớm ca tc và l°ợng b
nhtrong y tính. Một nhân tố quan trng khác làm gm thßi gian cần thiết ể gi
một bài toán là sxlý song song - ây là kỹ thut thc hiện ng thßi các dãy phép
nh. Do stăng tc nh toán và dung l°ợng b nhca y tính, cũng nh° nhß
vic dùng các thuật toán lợi dng °ợc °u thế của k thut xlý song song, các bài
toán vài năm tớc ây °ợc xem là không th gi °ợc, thì bây g có th giÁi bình
th°ßng.
1. Các thu¿t ngữ th°ờng dùng cho ß phăc t¿p cāa t thu¿t toán:
Độ phức t¿p
Thut ng
O(1)
Độ phức t¿p hằng s
O(logn)
Độ phức t¿p lôgarit
O(n)
Độ phức t¿p tuyến tính
O(nlogn)
Độ phức t¿p nlogn
O(n
b
)
Độ phức t¿p a thức
O(b
n
) (b>1)
Độ phức t¿p m
O(n!)
Độ phức t¿p giai thừa
2. Thi gian máy nh °ợc dùng bi mßt thu¿t toán:
Kích th°ớc
ca bài toán
c phép tính bit °ợc sử dụng
n
N
nlogn
n2
2
n
n!
10
10
-8
s
3.10
-8
s
10
-7
s
10
-6
s
3.10
-3
s
10
2
10
-7
s
7.10
-7
s
10
-5
s
4.10
13
năm
*
10
3
10
-6
s
1.10
-5
s
10
-3
s
*
*
10
4
10
-5
s
1.10
-4
s
10
-1
s
*
*
10
5
10
-4
s
2.10
-3
s
10 s
*
*
10
6
10
-3
s
2.10
-2
s
17 phút
*
*
1.4. SÞ NGUYÊN VÀ THU¾T TOÁN.
1.4.1. Thu¿t toán Euclide:
Ph°¡ng pháp tính °ớc chung lớn nht ca hai số bng cách dùng phân tích các s nguyên
ó ra thừa s nguyên t không hiệu quÁ. do là á ch thßi gian phÁi tiêu tốn cho s
phân tích ó. D°ới ây là ph°¡ng pháp hiệu quÁ h¡n m °ớc số chung lớn nhất, gọi thu¿t
toán Euclide. Thut toán này ã biết tthßi c ¿i. mang n nhà toán hc c Hy l¿p
Euclide, ng°ßi ã mô tÁ thut toán này trong cunch <Những yếu tố= nổi tiếng ca ông.
Thut toán Euclide da vào 2 mệnh sau ây.
lO MoARcPSD| 45467232
13
nh 1 (Thu¿t toán chia): Cho a và b là hai s nguyên và b 0. Khi ó tồn t¿i duy
nht hai s nguyên q và r sao cho
a = bq+r, 0 r < |b|.
Trong ng thức tn, b °ợc gọi s chia, a °ợc gi số bchia, q °ợc gọi là th°¡ng s và
r °ợc gi s d°.
Khi b là nguyên d°¡ng, ta ký hiệu s d° r trong phép chia a cho b là a mod b.
nh 2: Cho a = bq + r, trong ó a, b, q, r các số nguyên. Khi ó
UCLN(a,b) = UCLN(b,r).
ây UCLN(a,b) chỉ °ớc chung lớn nht ca a và b.)
GiÁ sa và b hai số nguyên d°¡ng với a b. Đặt r
0
= a và r
1
= b. Bằng cách áp
dng liên tiếp thut toán chia, ta tìm °ợc:
r
0
= r
1
q
1
+ r
2
0 r
2
< r
1
r
1
=
r
2
q
2
+ r
3
0 r
3
< r
2
..................
rn-2 = rn-1qn-1 + rn 0 rn < rn-1 r
n-1
= r
n
q
n
.
Cui cùng, số d° 0 s xuất hiện trong y các phép chia ln tiếp, vì dãy các s
a = r
0
> r
1
> r
2
>... 0
không th chứa quá a số h¿ng °ợc. n nữa, từ Mệnh 2 á trên ta suy ra:
UCLN(a,b) = UCLN(r
0
,r
1
) = UCLN(r
1
,r
2
) = ... = UCLN(r
n-2
, r
n-1
) = UCLN(r
n-1
,r
n
) = r
n
.
Do ó, °ớc chung lớn nhất s d° khác không cuốing trong dãy các phép chia. T dÿ
6: ng thut toán Euclide m UCLN(414, 662).
662 = 441.1 + 248
414 = 248.1 + 166
248 = 166.1+ 82
166 = 82.2 + 2
82 = 2.41.
Do ó, UCLN(414, 662) = 2.
Thut toán Euclide °ợc viết d°ới d¿ng giÁ nh° sau:
procedure ¯CLN (a,b: positive integers)
x := a y := b
while y 0 begin
r := x mod y
x := y y := r end
{UCLN (a,b) x}
lO MoARcPSD| 45467232
Trong thut toán trên, các giá trị ban u ca x và y t°¡ng ứng a và b. à mỗi giai o¿n của
thủ tc, x °ợc thay bng y và y °ợc thay bng x mod y. Qtrình này °ợc lp l¿i chừng
nào y 0. Thut toán s ngng khi y = 0 và gtr của x á im này, ó s d° khác không
cui cùng trong th tục, cũng chính là °ớc chung lớn nhất ca a và b.
1.4.2. Biu dißn các sß nguyên:
nh 3: Cho b một s nguyên d°¡ng lớn n 1. Khi ó nếu n một số nguyên d°¡ng,
nó có thể °ợc biểu diễn một cách duy nhất d°ới d¿ng:
n = a
k
b
k
+ a
k-1
b
k-
1
+ ... + a
1
b + a
0
.
à ây k là một s tự nhn, a
0
, a
1
,..., a
k
là các s tự nhn nhn b và a
k
0.
Biểu diễn ca n °ợc cho trong Mệnh 3 °ợc gi là khai triển ca n theo c¡ s b, hiệu
(a
k
a
k-1
... a
1
a
0
)
b
. y g ta sẽ mô tÁ thut toán y dựng khai trin c¡ số b của số nguyên
n bất k. Tr°ớc hết ta chia n cho b °ợc th°¡ng và s d°, tức là
n = bq
0
+ a
0
, 0 a
0
< b.
S a
0
chính chsng bên phÁi cùng trong khai trin s b của n. Tiếp theo chia
q
0
cho b, ta °ợc:
q
0
= bq
1
+ a
1
, 0 a
1
< b.
S a
1
chính chs thhai tính từ bên phÁi trong khai triển c¡ s b của n. Tiếp tc
quá trình này, bng cách ln tiếp chia các th°¡ng cho b ta s °ợc các chsố tiếp theo trong
khai trin s b ca n là các s d° t°¡ng ứng. Quá trình y s kết thúc khi ta nhn °ợc
một th°¡ng bng 0.
Thí dÿ 7: Tìm khai trin c¡ s 8 ca (12345)
10
.
12345 = 8.1543 + 1
1543 = 8.192 + 7
192 = 8.24 + 0
24 = 8.3 + 0
3 = 8.0 + 3.
Do ó, (12345)
10
= (30071)
8
.
Đo¿n g sau biểu diễn thut toán tìm khai trin c¡ số b ca số nguyên n.
procedure khai trin theo cơ s b (n: positive integer)
1
.4.3. Thu¿t toán cho các phép nh sß nguyên:
c thut toán thực hiện các phép nh với nhng s nguyên khi ng các khai trin nh
phân ca cng là cực kquan trọng trong s hc ca y tính. Ta s mô tÁ á
lO MoARcPSD| 45467232
15
q := n k :=
0 while q
0
begin
a
k
:= q mod b
q
q := [ ]
b
k := k + 1
end
ây các thuật toán cng và nhân hai s nguyên trong biểu diễn nh phân. Ta cũng s phân
ch phức t¿p tính toán của các thut toán y thông qua s các phép toán bit thực s
°ợc dùng. GiÁ skhai trin nhị phân của hai s nguyên d°¡ng a và b là:
a = (an-1an-2 ... a1 a0)2 và b = (bn-1 bn-2 ... b1 b0)2
sao cho a và b u có n bit ( ặt các bit 0 á u mỗi khai trin ó, nếu cn).
1) Phép cßng: t bài toán cng hai s nguyên viết á d¿ng nhphân. Thủ tục thực hiện
phép cng có th dựa trên ph°¡ng pháp thông th°ßng là cng cp chữ s nhphân với nhau
(có nhớ) nh tng ca hai s nguyên.
Để cng a và b, tr°ớc hết cng hai bit á phÁi cùng ca cng, tức là:
a
0
+ b
0
= c
0
.2 + s
0
.
à ây s
0
là bit phÁi cùng trong khai trin nhị phân của a+b, c
0
là s nhớ, nó có thbng
0 hoặc 1. Sau ó ta cng hai bit tiếp theo và s nh
a
1
+ b
1
+ c
0
= c
1
.2 + s
1
.
à ây s
1
là bit tiếp theo (nh tbên phÁi) trong khai trin nhphân ca a+b và c
1
là s nhớ.
Tiếp tc quá trình này bng cách cng các bit t°¡ng ứng trong hai khai triển nhphân và
số nh xác ịnh bit tiếp sau tính tbên phÁi trong khai trin nh phân ca tng a+b. à
giai o¿n cuối cùng, cng a
n-1
, b
n-1
và c
n-2
nhận °ợc c
n-1
.2+s
n-1
. Bit ứng u ca tng s
n
=c
n-
1
. Kết quÁ, th tc y t¿o ra °c khai trin nhphân ca tng, cthể a+b = (s
n
s
n-1
s
n-2
... s
1
s
0
)
2
.
Thí dÿ 8: Tìm tng ca a = (11011)
2
và b = (10110)
2
.
a
0
+ b
0
= 1 + 0 = 0.2 + 1 (c
0
= 0, s
0
= 1), a
1
+ b
1
+ c
0
= 1 + 1 + 0 = 1.2 + 0 (c
1
= 1, s
1
=
0), a
2
+ b
2
+c
1
= 0 + 1 + 1 = 1.2 + 0 (c
2
= 1, s
2
= 0), a
3
+ b
3
+ c
2
= 1 + 0 + 1 = 1.2 +
0 (c
3
= 1, s
3
= 0), a
4
+ b
4
+c
3
= 1 + 1 + 1 = 1.2 + 1 (s
5
= c
4
=1, s
4
= 1).
Do ó, a + b = (110001)
2
.
Thut toán cng có th °ợc tÁ bằng cách dùng o¿n giÁ nh° sau.
lO MoARcPSD| 45467232
procedure cộng (a,b: positive integers)
c := 0
for j := 0 to n-1
begin
ùa
j
b
j
cù
d := ú
ú û 2 û
s
j
:= a
j
+ b
j
+ c 2d
c := d
end
s
n
:= c
{khai triển nhphân ca tổng (s
n
s
n-1
...s
1
s
0
)
2
}
Tng hai s nguyên °ợc tính bng ch cng liên tiếp các cặp bit và khi cần phÁi cộng
cÁ s nhnữa. Cng một cặp bit và s nhòi ba hoặc ít h¡n phép cng các bit. Nh° vy,
tổng s các phép cng bit °ợc sử dng nh h¡n ba ln s bit trong khai triển nhphân. Do
ó, phức t¿p ca thuật toán này là O(n).
2) Phép nhân: t bài toán nhân hai s nguyên viết á d¿ng nh phân. Thut toán thông
th°ßng tiến hành nh° sau. ng luật phân phi, ta có:
n 1 n 1 ab = a b
j
2
j
= a b(
j
2 )
j
.
j 0 j 0
Ta có thể nh ab bằng cách ng ph°¡ng trình tn. Tr°ớc hết, ta thấy rng ab
j
=a nếu b
j
=1
và ab
j
=0 nếu b
j
=0. Mỗi lần ta nhân một s h¿ng với 2 ta dịch khai trin nhị phân của nó
một chv phía trái bằng cách thêm một s không vào cuối khai trin nh phân của nó.
Do ó, ta có thể nhận °ợc (ab
j
)2
j
bằng cách dịch khai trin nhị phân ca ab
j
i j ch v phía
trái, tức là thêm j số không vào cui khai trin nhị phân ca nó. Cuối cùng, ta s nhn °ợc
ch ab bng cách cng n số nguyên ab
j
.2
j
với j=0, 1, ..., n-1.
Thí dÿ 9: Tìm tích của a = (110)
2
và b = (101)
2
.
Ta ab
0
.2
0
= (110)
2
.1.2
0
= (110)
2
, ab
1
.2
1
= (110)
2
.0.2
1
= (0000)
2
, ab
2
.2
2
= (110)
2
.1.2
2
=
(11000)
2
. Đm ch, hãy cng (110)
2
, (0000)
2
và (11000)
2
. Tó ta có ab= (11110)
2
.
Th tc trên °ợctÁ bng o¿n g sau:
procedure nhân (a,b: positive
integers) for j := 0 to n-1
begin
lO MoARcPSD| 45467232
17
if b
j
= 1 then c
j
:= a °ợc dịch i j ch else c
j
:= 0
end
{c
0
, c
1
,..., c
n-1
là các tích rng phn}
p := 0
for j := 0 to n-1
p := p + c
j
{p gtrị của tích ab}
Thut toán trên nh ch của hai s nguyên a và b bằng cách cng các tích riêng phần c
0
,
c
1
, c
2
, ..., c
n-1
. Khi b
j
=1, ta nh tích riêng phn c
j
bng cách dịch khai trin nhphân ca a i
j bit. Khi b
j
=0 thì không cần có dịch chuyn nào vì c
j
=0. Do ó, tìm tất cÁ n s nguyên
ab
j
.2
j
với j=0, 1, ..., n-1, òi hi tối a là
0 + 1 + 2 + ... + n 1 =
n
n( 1)
2
phép dịch chỗ. Vì vy, sc dịch chuyển ch òi hỏi O(n
2
).
Để cng các s nguyên ab
j
tj=0 ến n 1, òi hỏi pi cộng một s nguyên n bit, một s
nguyên n+1 bit, ... và một s nguyên 2n bit. Ta ã biết rng mỗi phép cng ó òi hi O(n)
phép cng bit. Do ó, ộ phc t¿p ca thuật toán này là O(n
2
).
1.5. THU¾T TOÁN Đà QUY.
1.5.1. Khái niám á quy:
Đôi khi cng ta th quy vic gi bài toán với tập các dữ liệu u vào c ịnh v vic
gi cùng bài toán ó nh°ng với các g trịu vào nhn. Chng h¿n, bài toán tìm UCLN
ca hai s a, b với a > b có th rút gn v bài toán tìm ¯CLN ca hai s nh n, a mod b
và b. Khi việc rút gn nh° vậy thc hiện °ợc thì lßi giÁi i toán ban u có thể tìm °ợc
bng một dãy các phép rút gn cho tới nhng tr°ßng hợp ta có thể ddàng nhận °ợc
i gi ca i toán. Ta s thy rng các thuật toán rút gn ln tiếp i toán ban ầu tới
bài toán có dữ liuu vào nh h¡n, °ợc áp dụng trong một lớp rất rng các bài toán.
Định nghĩa: Một thut toán °ợc gi là quy nếu nó giÁi bài toán bng cách rút gn liên
tiếp bài toán ban ầu tới bài toán cũng nh° vậy nh°ng có d liệuu vào nhn. Thí dÿ 10:
Tìm thuật toán quy tính giá trị a
n
với a số thc khác không và n số nguyên không
âm.
Ta xây dựng thut toán quy nhß nh nghĩa quy ca a
n
, ó a
n+1
=a.a
n
với n>0 và khi n=0
thì a
0
=1. Vy nh a
n
ta quy v các tr°ßng hợp có số mũ n nh h¡n, cho tới khi n=0.
lO MoARcPSD| 45467232
procedure power (a: số thc khác không; n: s nguyên không âm)
if n = 0 then power(a,n) := 1 else power(a,n) := a *
power(a,n-1)
Thí dÿ 11: Tìm thut toán quy tính UCLN ca hai s nguyên a,b không âm và a > b.
procedure UCLN (a,b: các s nguyên không âm, a > b)
if b = 0 then UCLN (a,b) := a else UCLN (a,b) :=
UCLN (a mod b, b)
Thí dÿ 12: Hãy biểu diễn thuật toán tìm kiếm tuyến nh nh° một th tcquy. Đ tìm
x trong y tìm kiếm a
1
,a
2
,...,a
n
trong b°ớc thứ i ca thut toán ta so sánh x với a
i
. Nếu x
bng a
i
thì i v trí cần m, ng°ợc l¿i thì vic m kiếm °ợc quy v dãy có số phn tử ít
h¡n, cthể dãy a
i+1
,...,a
n
. Thuật toán tìm kiếm có d¿ng th tc quy nh° sau.
Cho search (i,j,x) thủ tục tìm số x trong dãy a
i
, a
i+1
,..., a
j
. Dliệu u vào b ba (1,n,x).
Th tc sẽ dừng khi s h¿ng u tn ca dãy còn l¿i là x hoặc khi dãy còn l¿i chỉ có mt
phn tkhác x. Nếu x không là số h¿ng u tiên và n có các số h¿ng khác thì l¿i áp dụng
thủ tc y, nh°ng y m kiếm ít h¡n một phần tnhn °ợc bằng cách xóa i phn tu
tiên của dãy tìm kiếm á b°ớc vừa qua.
procedure search (i,j,x) if a
i
= x
then loacation := i else if i = j then
loacation := 0 else search
(i+1,j,x)
Thí dÿ 13: Hãy y dựng phn bÁn quy ca thut toán tìm kiếm nhphân.
GiÁ sta mun nh v x trong y a
1
, a
2
, ..., a
n
bng m kiếm nhphân. Tớc tiên ta so
sánh x với s h¿ng giữa a
[(n+1)/2]
. Nếu cng bằng nhau thì thut toán kết thúc, nếu không
ta chuyn sang tìm kiếm trong y ngn h¡n, nửa u của dãy nếu x nh h¡n gtrị giữa
ca của y xuất phát, nửa sau nếu ng°ợc l¿i. Nh° vậy ta rút gọn vic gi bài toán m
kiếm v vic giÁi cũng i toán ó nh°ng trong y tìm kiếm có ộ dài lần l°ợt giÁm i một
nửa.
procedure binary search (x,i,j) m
:= [(i+j)/2]
if x = a
m
then loacation := m
lO MoARcPSD| 45467232
19
else if (x < a
m
and i < m) then binary search (x,i,m-1) else
if (x > a
m
and j > m) then binary search (x,m+1,j) else
loacation := 0
1.5.2. Đá quy và lặp:
Thí dÿ 14. Th tc quy sau ây cho ta g trị ca n! với n là s nguyên d°¡ng.
procedure factorial (n: positive integer)
if n = 1 then factorial(n) := 1
else factorial(n) := n * factorial(n-1)
Có cách khác tính m giai thừa của một s nguyên tnh nghĩa quy của nó. Thay cho
vic lần ợt rút gn vic nh toán choc giá tr nh h¡n, ta có thể xut phát tg trị ca
hàm t¿i 1và lần l°ợt áp dụng ịnh nghĩa quy m gtrị ca hàm t¿i các s nguyên lớn
dn. Đó là thủ tc lặp.
procedure iterative factorial (n: positive integer)
x := 1
for i := 1 to n
x := i * x
{x n!}
Thông th°ßng tính một dãy các gtr °ợc ịnh nghĩa bng quy, nếu ng ph°¡ng
pháp lặp thì s các phép tính s ít h¡n ng thut toán quy (trkhi dùng c y
quy chuyên dng). Ta s xem xét i toán nh s h¿ng th n của dãy Fibonacci.
procedure fibonacci (n: nguyên không âm)
if n = 0 the fibonacci(n) := 0
else if n = 1 then fibonacci(n) := 1
else fibonacci(n) := fibonacci(n - 1) + fibonacci(n - 2)
Theo thuật toán y, m f
n
ta biểu diễn f
n
= f
n-1
+ f
n-2
. Sau ó thay thế hai s này
bng tng của hai s Fibonacci bc thấp h¡n, ctiếp tc nh° vy cho tới khi f
0
và f
1
xuất
hiện thì °ợc thay bằng các g tr của chúng theo ịnh nghĩa. Do ótính f
n
cn f
n+1
-1 phép
cng.
y giß ta s tính các phép toán cần ng nh f
n
khi sdụng ph°¡ng pháp lp. Th tc
này khái t¿o x là f
0
= 0 và y là f
1
= 1. Khi vòng lp °ợc duyt qua tng ca x và y °ợc n
cho biến phz. Sau ó x °ợc gán giá trị ca y và y °ợc n gtrị của z. Vy sau khi i qua
lO MoARcPSD| 45467232
vòng lp lần 1, ta có x = f
1
và y = f
0
+ f
1
= f
2
. Khi qua vòng lặp ln n-1 thì x = f
n-1
. Nh° vy
chcó n 1 phép cng °ợc dùng m f
n
khi n > 1.
procedure Iterative fibonacci (n: nguyên không âm)
if n = 0 then y := 0 else begin
x := 0 ; y := 1
for i := 1 to n - 1 begin
z := x + y
x := y ; y := z
end
end
{y s Fibonacci thn}
Ta ã ch ra rng s các phép toán dùng trong thut toán quy nhiều h¡n khi dùng
ph°¡ng pháp lp. Tuy nhn ôi khi ng°ßi ta vẫn thích dùng th tục ệ quy h¡n ngay cÁ khi
nó tỏ ra kém hiệu quÁ so với thủ tục lặp. Đặc biệt, có những bài toán ch có th giÁi bng
thủ tc quy không th giÁi bng th tục lặp.
I T¾P CH¯ƠNG I:
1. Tìm một s nguyên n nhnht sao cho f(x) là O(x
n
) i với các m f(x) sau: a)
f(x) = 2x
3
+ x
2
log x.
b) f(x) = 2x
3
+ (log x)
4
.
x4 x2 1
c) f(x) =
x3 1
x
5
5logx
d) f(x) = .
x4 1
2. Chứng minh rng
a) x
2
+ 4x + 7 là O(x
3
), nh°ng x
3
không là O(x
2
+4x + 17).
b) xlog x là O(x
2
), nh°ng x
2
không là O(xlog x).
3. Cho một ánh giá big-O i với các hàm cho d°ới ây. Đối với hàm g(x) trong ánh giá
f(x) là O(g(x)), y chọn hàm ¡n giÁn có bậc thấp nht. a) nlog(n
2
+ 1) + n
2
logn.
b) (nlogn + 1)
2
+ (logn + 1)(n
2
+ 1).
lO MoARcPSD| 45467232
21
c) n
2
n
n
n
2
.
4. Cho H
n
là s iều hthn:
1 1 1
H
n
= 1 + + + ... +
2 3 n
Chứng minh rng H
n
là O(logn).
5. Lập một thuật toán tính tng tt cÁ các số nguyên trong một bÁng.
6. Lập thut toán nh x
n
với x là một s thực và n là một số nguyên.
7. thut toán chèn một số nguyên x vào v trí thích hợp trong dãy các s nguyên
a
1
, a
2
, ..., a
n
xếp theo thứ ttăng dần.
8. Tìm thut toán xác ịnh v trí gp u tiên ca phần tử lớn nht trong bÁng lit kê các
s nguyên, trong ó các s này không nhất thiết phÁi khác nhau.
9. Tìm thuật toán c nh v trí gp cuốing của phần tnh nht trong ng liệt kê
các s nguyên, trong óc số này không nht thiết phÁi khác nhau.
10. tÁ thut toán ếm số các s 1 trong một xâu bit bng cách kiểm tra mỗi bit ca
xâu xác nh nó có bit 1 hay không.
11. Thut toán tìm kiếm tam phân. c ịnh v trí của một phần tử trong một bÁng liệt
kê các s nguyên theo thttăng dn bằng cách tách liên tiếp bÁng liệt kê ó thành
ba ng lit kê con có kích th°ớc bng nhau (hoặc gn bằng nhau nht có th °ợc)
và giới h¿n vic m kiếm trong một bÁng liệt kê con thích hợp. y chỉ rõ các b°ớc
ca thut toán ó.
12. Lập thut toán tìm trong một dãy các số nguyên s h¿ng u tiên bng một số h¿ng
nào ó ứng tớc nó trong dãy.
13. Lập thut toán m trong một dãy các số nguyên tất các số h¿ng lớn n tng tt
cÁ các số h¿ng ứng tr°ớc nó trong dãy.
14. Cho ánh g big-O i với sc phép sonh °ợc dùng i thut toán trongi tp
10.
15. Đánh giá phc t¿p của thuật toán tìm kiếm tam phân °ợc cho trong i tp 11.
16. Đánh giá phc t¿p của thut toán trong i tp 12.
17. thut toán tính hiệu của hai khai trin nhị phân.
18. Lập một thuật toán xác ịnh a > b, a = b hay a < b i với hai s nguyên a và b á
d¿ng khai trin nhị phân.
lO MoARcPSD| 45467232
19. Đánh giá phc t¿p ca thut toán tìm khai trin theo s b ca s nguyên n qua
sc phép chia °ợc dùng.
20. y cho thuật toán quy tìm tổng n s nguyên d°¡ng lu tn.
21. y cho thuật toán quy tìm s cực ¿i ca tập hữu h¿n các số nguyên.
22. thut toán quy tìm x
n
mod m với n, x, m là các số nguyên d°¡ng.
23. y ngra thut toán quy tính
a
2
n
trong ó a là một số thực và n là một số ngun
d°¡ng.
24. y ngra thuật toán quy tìm số h¿ng thn của dãy °ợc xác nh nh° sau: a
0
=1,
a
1
= 2 và a
n
= a
n-1
a
n-2
với n = 2, 3, 4, ...
25. Thut toán quy hay thuật toán lp m s h¿ng thn của y trong i tập 24
có hiu quÁ h¡n?
| 1/19

Preview text:

lO M oARcPSD| 45467232 lO M oARcPSD| 45467232 CHƯƠNG I: THUẬT TOÁN
1.1. KHÁI NIàM THUẬT TOÁN. 1.1.1. Mở đầu:
Có nhiều lớp bài toán tổng quát xuất hiện trong toán học rßi r¿c. Chẳng h¿n, cho
một dãy các số nguyên, tìm số lớn nhất; cho một tập hợp, liệt kê các tập con của nó; cho
tập hợp các số nguyên, xếp chúng theo thứ tự tăng dần; cho một m¿ng, tìm °ßng i ngắn
nhất giữa hai ỉnh của nó. Khi °ợc giao cho một bài toán nh° vậy thì việc ầu tiên phÁi làm
là xây dựng một mô hình dịch bài toán ó thành ngữ cÁnh toán học. Các cấu trúc rßi r¿c
°ợc dùng trong các mô hình này là tập hợp, dãy, hàm, hoán vị, quan hệ, cùng với các cấu
trúc khác nh° ồ thị, cây, m¿ng - những khái niệm sẽ °ợc nghiên cứu á các ch°¡ng sau.
Lập °ợc một mô hình toán học thích hợp chỉ là một phần của quá trình giÁi. Để hoàn tất
quá trình giÁi, còn cần phÁi có một ph°¡ng pháp dùng mô hình ể giÁi bài toán tổng quát.
Nói một cách lý t°áng, cái °ợc òi hỏi là một thủ tục, ó là dãy các b°ớc dẫn tới áp số mong
muốn. Một dãy các b°ớc nh° vậy, °ợc gọi là một thuật toán. Khi thiết kế và cài ặt một
phần mềm tin học cho một vấn ề nào ó, ta cần phÁi °a ra ph°¡ng pháp giÁi quyết mà thực
chất ó là thuật toán giÁi quyết vấn ề này. Rõ ràng rằng, nếu không tìm °ợc một ph°¡ng
pháp giÁi quyết thì không thể lập trình °ợc. Chính vì thế, thuật toán là khái niệm nền tÁng
của hầu hết các lĩnh vực của tin học.
1.1.2. Định nghĩa: Thuật toán là một bÁng liệt kê các chỉ dẫn (hay quy tắc) cần thực
hiện theo từng b°ớc xác ịnh nhằm giÁi một bài toán ã cho.
Thuật ngữ AlKhowarizmi. Ban ầu, từ algorism °ợc dùng ể chỉ các quy tắc thực hiện các phép tính số
học trên các số thập phân. Sau ó, algorism chuyển thành algorithm vào thế kỷ 19. Với sự
quan tâm ngày càng tăng ối với các máy tính, khái niệm thuật toán ã °ợc cho một ý nghĩa
chung h¡n, bao hàm cÁ các thủ tục xác ịnh ể giÁi các bài toán, chứ không phÁi chỉ là thủ
tục ể thực hiện các phép tính số học.
Có nhiều cách trình bày thuật toán: dùng ngôn ngữ tự nhiên, ngôn ngữ l°u ồ (s¡ ồ khối),
ngôn ngữ lập trình. Tuy nhiên, một khi dùng ngôn ngữ lập trình thì chỉ những lệnh °ợc
phép trong ngôn ngữ ó mới có thể dùng °ợc và iều này th°ßng làm cho sự mô tÁ các thuật
toán trá nên rối rắm và khó hiểu. H¡n nữa, vì nhiều ngôn ngữ lập trình ều °ợc dùng rộng
rãi, nên chọn một ngôn ngữ ặc biệt nào ó là iều ng°ßi ta không muốn. Vì vậy á ây các
thuật toán ngoài việc °ợc trình bày bằng ngôn ngữ tự nhiên cùng với những ký hiệu toán lO M oARcPSD| 45467232
học quen thuộc còn dùng một d¿ng giÁ mã ể mô tÁ thuật toán. GiÁ mã t¿o ra b°ớc trung
gian giữa sự mô tÁ một thuật toán bằng ngôn ngữ thông th°ßng và sự thực hiện thuật toán
ó trong ngôn ngữ lập trình. Các b°ớc của thuật toán °ợc chỉ rõ bằng cách dùng các lệnh
giống nh° trong các ngôn ngữ lập trình. Thí dÿ 1: Mô tÁ thuật toán tìm phần tử lớn nhất
trong một dãy hữu h¿n các số nguyên. a) Dùng ngôn ngữ tự nhiên ể mô tả các bước cần phải thực hiện:
1. Đặt giá trị cực ¿i t¿m thßi bằng số nguyên ầu tiên trong dãy. (Cực ¿i t¿m thßi sẽ là số
nguyên lớn nhất ã °ợc kiểm tra á một giai o¿n nào ó của thủ tục.) 2. So sánh số nguyên
tiếp sau với giá trị cực ¿i t¿m thßi, nếu nó lớn h¡n giá trị cực ¿i t¿m thßi thì ặt cực ¿i t¿m
thßi bằng số nguyên ó. 3. Lặp l¿i b°ớc tr°ớc nếu còn các số nguyên trong dãy.
4. Dừng khi không còn số nguyên nào nữa trong dãy. Cực ¿i t¿m thßi á iểm này chính là
số nguyên lớn nhất của dãy. b) Dùng oạn giả mã:
procedure max (a1, a2, ..., an: integers)
max:= a1 for i:= 2 to n if max then max:= ai
{max là phần tử lớn nhất}
Thuật toán này tr°ớc hết gán số h¿ng ầu tiên a1 của dãy cho biến max. Vòng lặp dùng ể kiểm tra lần l°ợt các số h¿ng của dãy. Nếu một số h¿ng lớn h¡n giá trị hiện thßi
của max thì nó °ợc gán làm giá trị mới của max.
1.1.3. Các đặc trưng của thuật toán:
-- Đầu vào (Input): Một thuật toán có các giá trị ầu vào từ một tập ã °ợc chỉ rõ.
-- Đầu ra (Output): Từ mỗi tập các giá trị ầu vào, thuật toán sẽ t¿o ra các giá trị ầu ra.
Các giá trị ầu ra chính là nghiệm của bài toán.
-- Tính dừng: Sau một số hữu h¿n b°ớc thuật toán phÁi dừng.
-- Tính xác định: à mỗi b°ớc, các b°ớc thao tác phÁi hết sức rõ ràng, không gây nên sự
nhập nhằng. Nói rõ h¡n, trong cùng một iều kiện hai bộ xử lý cùng thực hiện một b°ớc
của thuật toán phÁi cho những kết quÁ nh° nhau.
-- Tính hiáu quả: Tr°ớc hết thuật toán cần úng ắn, nghĩa là sau khi °a dữ liệu vào thuật
toán ho¿t ộng và °a ra kết quÁ nh° ý muốn.
-- Tính phổ dÿng: Thuật toán có thể giÁi bất kỳ một bài toán nào trong lớp các bài toán.
Cụ thể là thuật toán có thể có các ầu vào là các bộ dữ liệu khác nhau trong một miền xác ịnh.
1.2. THU¾T TOÁN TÌM KI¾M.
1.2.1. Bài toán tìm ki¿m: Bài toán xác ịnh vị trí của một phần tử trong một bÁng liệt
kê sắp thứ tự th°ßng gặp trong nhiều tr°ßng hợp khác nhau. Chẳng h¿n ch°¡ng trình kiểm
tra chính tÁ của các từ, tìm kiếm các từ này trong một cuốn từ iển, mà từ iển chẳng qua 5 lO M oARcPSD| 45467232
cũng là một bÁng liệt kê sắp thứ tự của các từ. Các bài toán thuộc lo¿i này °ợc gọi là các bài toán tìm kiếm.
Bài toán tìm kiếm tổng quát °ợc mô tÁ nh° sau: xác ịnh vị trí của phần tử x trong một
bÁng liệt kê các phần tử phân biệt a1, a2, ..., an hoặc xác ịnh rằng nó không có mặt trong
bÁng liệt kê ó. Lßi giÁi của bài toán trên là vị trí của số h¿ng của bÁng liệt kê có giá trị
bằng x (tức là i sẽ là nghiệm nếu x=ai và là 0 nếu x không có mặt trong bÁng liệt kê).
1.2.2. Thu¿t toán tìm ki¿m tuy¿n tính: Tìm kiếm tuyến tính hay tìm kiếm tuần tự là
bắt ầu bằng việc so sánh x với a1; khi x=a1, nghiệm là vị trí a1, tức là 1; khi x a1, so sánh
x với a2. Nếu x=a2, nghiệm là vị trí của a2, tức là 2. Khi x a2, so sánh x với a3. Tiếp tục
quá trình này bằng cách tuần tự so sánh x với mỗi số h¿ng của bÁng liệt kê cho tới khi
tìm °ợc số h¿ng bằng x, khi ó nghiệm là vị trí của số h¿ng ó. Nếu toàn bÁng liệt kê ã °ợc
kiểm tra mà không xác ịnh °ợc vị trí của x, thì nghiệm là 0. GiÁ mã ối với thuật toán tìm
kiếm tuyến tính °ợc cho d°ới ây:
procedure tìm kiếm tuyến tính (x: integer, a1,a2,...,an: integers phân biệt) i := 1 while (i n and x ai) i := i + 1
if i n then location := i else location := 0
{location là chỉ số d°ới của số h¿ng bằng x hoặc là 0 nếu không tìm °ợc x}
1 .2.3. Thu¿t toán tìm ki¿m nhị phân: Thuật toán này có thể °ợc dùng khi bÁng liệt
kê có các số h¿ng °ợc sắp theo thứ tự tăng dần. Chẳng h¿n, nếu các số h¿ng là các số thì
chúng °ợc sắp từ số nhỏ nhất ến số lớn nhất hoặc nếu chúng là các từ hay xâu ký tự thì
chúng °ợc sắp theo thứ tự từ iển. Thuật toán thứ hai này gọi là thuật toán tìm kiếm nhị
phân. Nó °ợc tiến hành bằng cách so sánh phần tử cần xác ịnh vị trí với số h¿ng á giữa
bÁng liệt kê. Sau ó bÁng này °ợc tách làm hai bÁng kê con nhỏ h¡n có kích th°ớc nh°
nhau, hoặc một trong hai bÁng con ít h¡n bÁng con kia một số h¿ng. Sự tìm kiếm tiếp tục
bằng cách h¿n chế tìm kiếm á một bÁng kê con thích hợp dựa trên việc so sánh phần tử
cần xác ịnh vị trí với số h¿ng giữa bÁng kê. Ta sẽ thấy rằng thuật toán tìm kiếm nhị phân
hiệu quÁ h¡n nhiều so với thuật toán tìm kiếm tuyến tính.
Thí dÿ 2. Để tìm số 19 trong bÁng liệt kê 1,2,3,5,6,7,8,10,12,13,15,16,18,19,20,22 ta
tách bÁng liệt kê gồm 16 số h¿ng này thành hai bÁng liệt kê nhỏ h¡n, mỗi bÁng có 8 số
h¿ng, cụ thể là: 1,2,3,5,6,7,8,10 và 12,13,15,16,18,19,20,22. Sau ó ta so sánh 19 với số
h¿ng cuối cùng của bÁng con thứ nhất. Vì 10<19, việc tìm kiếm 19 chỉ giới h¿n trong
bÁng liệt kê con thứ 2 từ số h¿ng thứ 9 ến 16 trong bÁng liệt kê ban ầu. Tiếp theo, ta lO M oARcPSD| 45467232
l¿i tách bÁng liệt kê con gồm 8 số h¿ng này làm hai bÁng con, mỗi bÁng có 4 số h¿ng,
cụ thể là 12,13,15,16 và 18,19,20,22. Vì 16<19, việc tìm kiếm l¿i °ợc giới h¿n chỉ trong
bÁng con thứ 2, từ số h¿ng thứ 13 ến 16 của bÁng liệt kê ban ầu. BÁng liệt kê thứ 2 này
l¿i °ợc tách làm hai, cụ thể là: 18,19 và 20,22. Vì 19 không lớn h¡n số h¿ng lớn nhất của
bÁng con thứ nhất nên việc tìm kiếm giới h¿n chỉ á bÁng con thứ nhất gồm các số 18,19,
là số h¿ng thứ 13 và 14 của bÁng ban ầu. Tiếp theo bÁng con chứa hai số h¿ng này l¿i
°ợc tách làm hai, mỗi bÁng có một số h¿ng 18 và 19. Vì 18<19, sự tìm kiếm giới h¿n chỉ
trong bÁng con thứ 2, bÁng liệt kê chỉ chứa số h¿ng thứ 14 của bÁng liệt kê ban ầu, số
h¿ng ó là số 19. Bây giß sự tìm kiếm ã thu hẹp về chỉ còn một số h¿ng, so sánh tiếp cho
thấy19 là số h¿ng thứ 14 của bÁng liệt kê ban ầu.
Bây giß ta có thể chỉ rõ các b°ớc trong thuật toán tìm kiếm nhị phân.
Để tìm số nguyên x trong bÁng liệt kê a1,a2,...,an với a2 < a2 < ... < an, ta bắt ầu bằng việc
so sánh x với số h¿ng am á giữa của dãy, với m=[(n+1)/2]. Nếu x > am, việc tìm kiếm x
giới h¿n á nửa thứ hai của dãy, gồm am+1,am+2,...,an. Nếu x không lớn h¡n am, thì sự tìm
kiếm giới h¿n trong nửa ầu của dãy gồm a1,a2,...,am.
Bây giß sự tìm kiếm chỉ giới h¿n trong bÁng liệt kê có không h¡n [n/2] phần tử. Dùng
chính thủ tục này, so sánh x với số h¿ng á giữa của bÁng liệt kê °ợc h¿n chế. Sau ó l¿i
h¿n chế việc tìm kiếm á nửa thứ nhất hoặc nửa thứ hai của bÁng liệt kê. Lặp l¿i quá trình
này cho tới khi nhận °ợc một bÁng liệt kê chỉ có một số h¿ng. Sau ó, chỉ còn xác ịnh số
h¿ng này có phÁi là x hay không. GiÁ mã cho thuật toán tìm kiếm nhị phân °ợc cho d°ới ây:
procedure tìm kiếm nhị phân (x: integer, a1,a2,...,an: integers tăng dần)
i := 1 {i là iểm mút trái của khoÁng tìm kiếm} j := n {j là iểm mút
phÁi của khoÁng tìm kiếm}
while i < j begin m:= [(i+j)/2]
if x>am then i:=m+1 else j := m end
if x = ai then location := i else location := 0
{location là chỉ số d°ới của số h¿ng bằng x hoặc 0 nếu không tìm thấy x}
1 .3. ĐÞ PHĂC T¾P CĀA THU¾T TOÁN.
2 .3.1. Khái niám về ß phăc t¿p cāa mßt thu¿t toán:
Th°ớc o hiệu quÁ của một thuật toán là thßi gian mà máy tính sử dụng ể giÁi bài
toán theo thuật toán ang xét, khi các giá trị ầu vào có một kích th°ớc xác ịnh. 7 lO M oARcPSD| 45467232
Một th°ớc o thứ hai là dung l°ợng bộ nhớ òi hỏi ể thực hiện thuật toán khi các giá trị ầu
vào có kích th°ớc xác ịnh. Các vấn ề nh° thế liên quan ến ộ phức t¿p tính toán của một
thuật toán. Sự phân tích thßi gian cần thiết ể giÁi một bài toán có kích th°ớc ặc biệt nào
ó liên quan ến ộ phức t¿p thßi gian của thuật toán. Sự phân tích bộ nhớ cần thiết của máy
tính liên quan ến ộ phức t¿p không gian của thuật toán. Vệc xem xét ộ phức t¿p thßi gian
và không gian của một thuật toán là một vấn ề rất thiết yếu khi các thuật toán °ợc thực
hiện. Biết một thuật toán sẽ °a ra áp số trong một micro giây, trong một phút hoặc trong
một tỉ năm, hiển nhiên là hết sức quan trọng. T°¡ng tự nh° vậy, dung l°ợng bộ nhớ òi hỏi
phÁi là khÁ dụng ể giÁi một bài toán,vì vậy ộ phức t¿p không gian cũng cần phÁi tính
ến.Vì việc xem xét ộ phức t¿p không gian gắn liền với các cấu trúc dữ liệu ặc biệt °ợc
dùng ể thực hiện thuật toán nên á ây ta sẽ tập trung xem xét ộ phức t¿p thßi gian.
Độ phức t¿p thßi gian của một thuật toán có thể °ợc biểu diễn qua số các phép toán °ợc
dùng bái thuật toán ó khi các giá trị ầu vào có một kích th°ớc xác ịnh. Sá dĩ ộ phức t¿p
thßi gian °ợc mô tÁ thông qua số các phép toán òi hỏi thay vì thßi gian thực của máy tính
là bái vì các máy tính khác nhau thực hiện các phép tính s¡ cấp trong những khoÁng thßi
gian khác nhau. H¡n nữa, phân tích tất cÁ các phép toán thành các phép tính bit s¡ cấp mà
máy tính sử dụng là iều rất phức t¿p.
Thí dÿ 3: Xét thuật toán tìm số lớn nhất trong dãy n số a1, a2, ..., an. Có thể coi kích th°ớc
của dữ liệu nhập là số l°ợng phần tử của dãy số, tức là n. Nếu coi mỗi lần so sánh hai số
của thuật toán òi hỏi một ¡n vị thßi gian (giây chẳng h¿n) thì thßi gian thực hiện thuật toán
trong tr°ßng hợp xấu nhất là n-1 giây. Với dãy 64 số, thßi gian thực hiện thuật toán nhiều lắm là 63 giây.
Thí dÿ 4:Thuật toán về trò ch¡i Trò ch¡i ĩa có °ßng kính ôi một khác nhau. Nguyên tắc ặt ĩa vào cọc là: mỗi ĩa chỉ °ợc chồng lên ĩa
lớn h¡n nó. Ban ầu, cÁ 64 ĩa °ợc ặt chồng lên nhau á cột A; hai cột B, C trống. Vấn ề là
phÁi chuyển cÁ 64 ĩa ó sang cột B hay C, mỗi lần chỉ °ợc di chuyển một ĩa.
Xét trò ch¡i với n ĩa ban ầu á cọc A (cọc B và C trống). Gọi Sn là số lần chuyển ĩa ể ch¡i xong trò ch¡i với n ĩa.
Nếu n=1 thì rõ ràng là S1=1.
Nếu n>1 thì tr°ớc hết ta chuyển n-1 ĩa bên trên sang cọc B (giữ yên ĩa thứ n á d°ới cùng
của cọc A). Số lần chuyển n-1 ĩa là Sn-1. Sau ó ta chuyển ĩa thứ n từ cọc A sang cọc C.
Cuối cùng, ta chuyển n-1 ĩa từ cọc B sang cọc C (số lần chuyển là Sn-1). Nh° vậy, số lần
chuyển n ĩa từ A sang C là:
Sn=Sn-1+1+Sn=2Sn-1+1=2(2Sn-2+1)+1=22Sn-2+2+1=.....=2n-1S1+2n-2+...+2+1=2n 1.
Thuật toán về trò ch¡i lần). Nếu mỗi lần chuyển ĩa mất 1 giây thì thßi gian thực hiện thuật toán xấp xỉ 585 tỉ năm! lO M oARcPSD| 45467232
Hai thí dụ trên cho thấy rằng: một thuật toán phÁi kết thúc sau một số hữu h¿n b°ớc,
nh°ng nếu số hữu h¿n này quá lớn thì thuật toán không thể thực hiện °ợc trong thực tế.
Ta nói: thuật toán trong Thí dụ 3 có ộ phức t¿p là n-1 và là một thuật toán hữu hiệu (hay
thuật toán nhanh); thuật toán trong Thí dụ 4 có ộ phức t¿p là 2n 1 và ó là một thuật toán
không hữu hiệu (hay thuật toán chậm).
1.3.2. So sánh ß phăc t¿p cāa các thu¿t toán:
Một bài toán th°ßng có nhiều cách giÁi, có nhiều thuật toán ể giÁi, các thuật toán ó có ộ phức t¿p khác nhau.
Xét bài toán: Tính giá trị của a thức P(x)=anxn+an-1xn-1+ ... +a1x+a0 t¿i x0. Thu¿t toán 1:
Procedure tính giá trị của a thức (a0, a1, ..., an, x0: các số thực) sum:=a0 for i:=1 to n sum:=sum+a i ix0
{sum là giá trị của a thức P(x) t¿i x0}
Chú ý rằng a thức P(x) có thể viết d°ới d¿ng:
P(x)=(...((anx+an-1)x+an-2)x...)x+a0.
Ta có thể tính P(x) theo thuật toán sau: Thu¿t toán 2:
Procedure tính giá trị của a thức (a0, a1, ..., an, x0: các số thực) P:=an for i:=1 to n P:=P.x0+an-i
{P là giá trị của a thức P(x) t¿i x0}
Ta hãy xét ộ phức t¿p của hai thuật toán trên.
Đối với thuật toán 1: á b°ớc 2, phÁi thực hiện 1 phép nhân và 1 phép cộng với i=1; 2
phép nhân và 1 phép cộng với i=2, ..., n phép nhân và 1 phép cộng với i=n. Vậy số phép
tính (nhân và cộng) mà thuật toán 1 òi hỏi là: n n( 1) n n( 3) (1+1)+(2+1)+ ... +(n+1)= +n= . 2 2
Đối với thuật toán 2, b°ớc 2 phÁi thực hiện n lần, mỗi lần òi hỏi 2 phép tính (nhân rồi
cộng), do ó số phép tính (nhân và cộng) mà thuật toán 2 òi hỏi là 2n. 9 lO M oARcPSD| 45467232
Nếu coi thßi gian thực hiện mỗi phép tính nhân và cộng là nh° nhau và là một ¡n vị thßi
gian thì với mỗi n cho tr°ớc, thßi gian thực hiện thuật toán 1 là n(n+3)/2, còn thßi gian
thực hiện thuật toán 2 là 2n.
Rõ ràng là thßi gian thực hiện thuật toán 2 ít h¡n so với thßi gian thực hiện thuật toán 1.
Hàm f1(n)=2n là hàm bậc nhất, tăng chậm h¡n nhiều so với hàm bậc hai f2(n)=n(n+3)/2.
Ta nói rằng thuật toán 2 (có ộ phức t¿p là 2n) là thuật toán hữu hiệu h¡n (hay nhanh h¡n)
so với thuật toán 1 (có ộ phức t¿p là n(n+3)/2).
Để so sánh ộ phức t¿p của các thuật toán, iều tiện lợi là coi ộ phức t¿p của mỗi thuật toán
nh° là cấp của hàm biểu hiện thßi gian thực hiện thuật toán ấy.
Các hàm xét sau ây ều là hàm của biến số tự nhiên n>0.
Định nghĩa 1:Ta nói hàm f(n) có cấp thấp h¡n hay bằng hàm g(n) nếu tồn t¿i hằng số
C>0 và một số tự nhiên n0 sao cho
|f(n)| C|g(n)| với mọi n n0.
Ta viết f(n)=O(g(n)) và còn nói f(n) thoÁ mãn quan hệ big-O ối với g(n).
Theo ịnh nghĩa này, hàm g(n) là một hàm ¡n giÁn nhất có thể °ợc, ¿i diện cho thiên= của f(n).
Khái niệm big-O ã °ợc dùng trong toán học ã gần một thế kỷ nay. Trong tin học, nó °ợc
sử dụng rộng rãi ể phân tích các thuật toán. Nhà toán học ng°ßi Đức Paul Bachmann là
ng°ßi ầu tiên °a ra khái niệm big-O vào năm 1892. n n( 3) Thí dÿ 5: Hàm f(n)=
là hàm bậc hai và hàm bậc hai ¡n giÁn nhất là n2. Ta có: 2 n n( 3) f(n)= n n( 3) =O(n2) vì n2 với mọi n 3 (C=1, n0=3). 2 2
Một cách tổng quát, nếu f(n)=aknk+ak-1nk-1+ ... +a1n+a0 thì f(n)=O(nk). Thật vậy, với n>1,
|f(n)|| |ak|nk+|ak-1|nk-1+ ... +|a1|n+|a0| = nk(|ak|+|ak-1|/n+ ...
+|a1|/nk-1+a0/nk) nk(|ak|+|ak-1|+ ... +|a1|+a0).
Điều này chứng tỏ |f(n)| Cnk với mọi n>1.
Cho g(n)=3n+5nlog2n, ta có g(n)=O(nlog2n). Thật vậy,
3n+5nlog2n = n(3+5log2n) n(log2n+5log2n) = 6nlog2n với mọi n 8 (C=6, n0=8).
Mánh ề: Cho f1(n)=O(g1(n)) và f2(n) là O(g2(n)). Khi ó
(f1 + f2)(n) = O(max(|g1(n)|,|g2(n)|), (f1f2)(n) = O(g1(n)g2(n)).
Chăng minh. Theo giÁ thiết, tồn t¿i C1, C2, n1, n2 sao cho lO M oARcPSD| 45467232
|f1(n)| C1|g1(n)| và |f2(n)| C2|g2(n)| với mọi n > n1 và mọi n > n2.
Do ó |(f1 + f2)(n)| = |f1(n) + f2(n)| |f1(n)| + |f2(n)| C1|g1(n)| + C2|g2(n)|
(C1+C2)g(n) với mọi n > n0=max(n1,n2), á âyC=C1+C2 và g(n)=max(|g1(n)| , |g2(n)|).
|(f1f2)(n)| = |f1(n)||f2(n)| C1|g1(n)|C2|g2(n)| C1C2|(g1g2)(n)| với mọi n > n0=max(n1,n2).
Định nghĩa 2: Nếu một thuật toán có ộ phức t¿p là f(n) với f(n)=O(g(n)) thì ta cũng nói
thuật toán có ộ phức t¿p O(g(n)).
Nếu có hai thuật toán giÁi cùng một bài toán, thuật toán 1 có ộ phức t¿p
O(g1(n)), thuật toán 2 có ộ phức t¿p O(g2(n)), mà g1(n) có cấp thấp h¡n g2(n), thì ta nói
rằng thuật toán 1 hữu hiệu h¡n (hay nhanh h¡n) thuật toán 2.
1.3.3. Đánh giá ß phăc t¿p cāa mßt thu¿t toán:
1) Thu¿t toán tìm ki¿m tuy¿n tính:
Số các phép so sánh °ợc dùng trong thuật toán này cũng sẽ °ợc xem nh° th°ớc o ộ
phức t¿p thßi gian của nó. à mỗi một b°ớc của vòng lặp trong thuật toán, có hai phép so
sánh °ợc thực hiện: một ể xem ã tới cuối bÁng ch°a và một ể so sánh phần tử x với một
số h¿ng của bÁng. Cuối cùng còn một phép so sánh nữa làm á ngoài vòng lặp. Do ó, nếu
x=ai, thì ã có 2i+1 phép so sánh °ợc sử dụng. Số phép so sánh nhiều nhất, 2n+2, òi hỏi
phÁi °ợc sử dụng khi phần tử x không có mặt trong bÁng. Từ ó, thuật toán tìm kiếm tuyến
tính có ộ phức t¿p là O(n).
2) Thu¿t toán tìm ki¿m nhị phân:
Để ¡n giÁn, ta giÁ sử rằng có n=2k phần tử trong bÁng liệt kê a1,a2,...,an, với k là số
nguyên không âm (nếu n không phÁi là lũy thừa của 2, ta có thể xem bÁng là một phần
của bÁng gồm 2k+1 phần tử, trong ó k là số nguyên nhỏ nhất sao cho n < 2k+1).
à mỗi giai o¿n của thuật toán vị trí của số h¿ng ầu tiên i và số h¿ng cuối cùng j của bÁng
con h¿n chế tìm kiếm á giai o¿n ó °ợc so sánh ể xem bÁng con này còn nhiều h¡n một
phần tử hay không. Nếu i < j, một phép so sánh sẽ °ợc làm ể xác ịnh x có lớn h¡n số h¿ng
á giữa của bÁng con h¿n chế hay không. Nh° vậy á mỗi giai o¿n, có sử dụng hai phép so
sánh. Khi trong bÁng chỉ còn một phần tử, một phép so sánh sẽ cho chúng ta biết rằng
không còn một phần tử nào thêm nữa và một phép so sánh nữa cho biết số h¿ng ó có phÁi
là x hay không. Tóm l¿i cần phÁi có nhiều nhất 2k+2=2log2n+2 phép so sánh ể thực hiện
phép tìm kiếm nhị phân (nếu n không phÁi là lũy thừa của 2, bÁng gốc sẽ °ợc má rộng
tới bÁng có 2k+1 phần tử, với k=[log2n] và sự tìm kiếm òi hỏi phÁi thực hiện nhiều nhất
2[log2n]+2 phép so sánh). Do ó thuật toán tìm kiếm nhị phân có ộ phức t¿p là O(log2n).
Từ sự phân tích á trên suy ra rằng thuật toán tìm kiếm nhị phân, ngay cÁ trong tr°ßng hợp
xấu nhất, cũng hiệu quÁ h¡n thuật toán tìm kiếm tuyến tính.
3) Chú ý: Một iều quan trọng cần phÁi biết là máy tính phÁi cần bao lâu ể giÁi xong
một bài toán. Thí dụ, nếu một thuật toán òi hỏi 10 giß, thì có thể còn áng chi phí thßi
gian máy tính òi hỏi ể giÁi bài toán ó. Nh°ng nếu một thuật toán òi hỏi 10 tỉ năm ể 11 lO M oARcPSD| 45467232
giÁi một bài toán, thì thực hiện thuật toán ó sẽ là một iều phi lý. Một trong những
hiện t°ợng lý thú nhất của công nghệ hiện ¿i là sự tăng ghê gớm của tốc ộ và l°ợng bộ
nhớ trong máy tính. Một nhân tố quan trọng khác làm giÁm thßi gian cần thiết ể giÁi
một bài toán là sự xử lý song song - ây là kỹ thuật thực hiện ồng thßi các dãy phép
tính. Do sự tăng tốc ộ tính toán và dung l°ợng bộ nhớ của máy tính, cũng nh° nhß
việc dùng các thuật toán lợi dụng °ợc °u thế của kỹ thuật xử lý song song, các bài
toán vài năm tr°ớc ây °ợc xem là không thể giÁi °ợc, thì bây giß có thể giÁi bình th°ßng.
1. Các thu¿t ngữ th°ờng dùng cho ß phăc t¿p cāa mßt thu¿t toán: Độ phức t¿p Thuật ngữ O(1) Độ phức t¿p hằng số O(logn) Độ phức t¿p lôgarit O(n)
Độ phức t¿p tuyến tính O(nlogn)
Độ phức t¿p nlogn O(nb) Độ phức t¿p a thức O(bn) (b>1) Độ phức t¿p hàm mũ O(n!) Độ phức t¿p giai thừa
2. Thời gian máy tính °ợc dùng bởi mßt thu¿t toán: Kích th°ớc
Cá c phép tính bit °ợc sử dụng của bài toán n logn N nlogn n2 2n n! 10 3.10-9 s 10-8 s 3.10-8 s 10-7 s 10-6 s 3.10-3 s 102 7.10-9 s 10-7 s 7.10-7 s 10-5 s 4.1013năm * 103 1,0.10-8 s 10-6 s 1.10-5 s 10-3 s * * 104 1,3.10-8 s 10-5 s 1.10-4 s 10-1 s * * 105 1,7.10-8 s 10-4 s 2.10-3 s 10 s * * 106 2.10-8 s 10-3 s 2.10-2 s 17 phút * *
1.4. SÞ NGUYÊN VÀ THU¾T TOÁN.
1.4.1. Thu¿t toán Euclide:
Ph°¡ng pháp tính °ớc chung lớn nhất của hai số bằng cách dùng phân tích các số nguyên
ó ra thừa số nguyên tố là không hiệu quÁ. Lý do là á chỗ thßi gian phÁi tiêu tốn cho sự
phân tích ó. D°ới ây là ph°¡ng pháp hiệu quÁ h¡n ể tìm °ớc số chung lớn nhất, gọi là thu¿t
toán Euclide. Thuật toán này ã biết từ thßi cổ ¿i. Nó mang tên nhà toán học cổ Hy l¿p
Euclide, ng°ßi ã mô tÁ thuật toán này trong cuốn sách <Những yếu tố= nổi tiếng của ông.
Thuật toán Euclide dựa vào 2 mệnh ề sau ây. lO M oARcPSD| 45467232
Mánh ề 1 (Thu¿t toán chia): Cho a và b là hai số nguyên và b 0. Khi ó tồn t¿i duy
nhất hai số nguyên q và r sao cho a = bq+r, 0 r < |b|.
Trong ẳng thức trên, b °ợc gọi là số chia, a °ợc gọi là số bị chia, q °ợc gọi là th°¡ng số và r °ợc gọi là số d°.
Khi b là nguyên d°¡ng, ta ký hiệu số d° r trong phép chia a cho b là a mod b.
Mánh ề 2: Cho a = bq + r, trong ó a, b, q, r là các số nguyên. Khi ó UCLN(a,b) = UCLN(b,r).
(à ây UCLN(a,b) ể chỉ °ớc chung lớn nhất của a và b.)
GiÁ sử a và b là hai số nguyên d°¡ng với a b. Đặt r0 = a và r1 = b. Bằng cách áp
dụng liên tiếp thuật toán chia, ta tìm °ợc: r0 = r1q1 + r2 0 r2 < r1 r1 = r2q2 + r3 0 r3 < r2 ..................
rn-2 = rn-1qn-1 + rn 0 rn < rn-1 rn-1 = rnqn .
Cuối cùng, số d° 0 sẽ xuất hiện trong dãy các phép chia liên tiếp, vì dãy các số d°
a = r0 > r1 > r2 >... 0
không thể chứa quá a số h¿ng °ợc. H¡n nữa, từ Mệnh ề 2 á trên ta suy ra:
UCLN(a,b) = UCLN(r0,r1) = UCLN(r1,r2) = ... = UCLN(rn-2, rn-1) = UCLN(rn-1,rn) = rn.
Do ó, °ớc chung lớn nhất là số d° khác không cuối cùng trong dãy các phép chia. Thí dÿ
6: Dùng thuật toán Euclide tìm UCLN(414, 662). 662 = 441.1 + 248 414 = 248.1 + 166 248 = 166.1+ 82 166 = 82.2 + 2 82 = 2.41. Do ó, UCLN(414, 662) = 2.
Thuật toán Euclide °ợc viết d°ới d¿ng giÁ mã nh° sau:
procedure ¯CLN (a,b: positive integers) x := a y := b while y 0 begin r := x mod y x := y y := r end {UCLN (a,b) là x} 13 lO M oARcPSD| 45467232
Trong thuật toán trên, các giá trị ban ầu của x và y t°¡ng ứng là a và b. à mỗi giai o¿n của
thủ tục, x °ợc thay bằng y và y °ợc thay bằng x mod y. Quá trình này °ợc lặp l¿i chừng
nào y 0. Thuật toán sẽ ngừng khi y = 0 và giá trị của x á iểm này, ó là số d° khác không
cuối cùng trong thủ tục, cũng chính là °ớc chung lớn nhất của a và b.
1.4.2. Biểu dißn các sß nguyên:
Mánh ề 3: Cho b là một số nguyên d°¡ng lớn h¡n 1. Khi ó nếu n là một số nguyên d°¡ng,
nó có thể °ợc biểu diễn một cách duy nhất d°ới d¿ng:
n = akbk + ak-1bk-1 + ... + a1b + a0.
à ây k là một số tự nhiên, a0, a1,..., ak là các số tự nhiên nhỏ h¡n b và ak 0.
Biểu diễn của n °ợc cho trong Mệnh ề 3 °ợc gọi là khai triển của n theo c¡ số b, ký hiệu
là (akak-1... a1a0)b. Bây giß ta sẽ mô tÁ thuật toán xây dựng khai triển c¡ số b của số nguyên
n bất kỳ. Tr°ớc hết ta chia n cho b ể °ợc th°¡ng và số d°, tức là n = bq0 + a0, 0 a0 < b.
Số d° a0 chính là chữ số ứng bên phÁi cùng trong khai triển c¡ số b của n. Tiếp theo chia q0 cho b, ta °ợc: q0 = bq1 + a1, 0 a1 < b.
Số d° a1 chính là chữ số thứ hai tính từ bên phÁi trong khai triển c¡ số b của n. Tiếp tục
quá trình này, bằng cách liên tiếp chia các th°¡ng cho b ta sẽ °ợc các chữ số tiếp theo trong
khai triển c¡ số b của n là các số d° t°¡ng ứng. Quá trình này sẽ kết thúc khi ta nhận °ợc một th°¡ng bằng 0.
Thí dÿ 7: Tìm khai triển c¡ số 8 của (12345)10. 12345 = 8.1543 + 1 1543 = 8.192 + 7 192 = 8.24 + 0 24 = 8.3 + 0 3 = 8.0 + 3.
Do ó, (12345)10 = (30071)8.
Đo¿n giÁ mã sau biểu diễn thuật toán tìm khai triển c¡ số b của số nguyên n.
procedure khai triển theo cơ số b (n: positive integer)
1 .4.3. Thu¿t toán cho các phép tính sß nguyên:
Các thuật toán thực hiện các phép tính với những số nguyên khi dùng các khai triển nhị
phân của chúng là cực kỳ quan trọng trong số học của máy tính. Ta sẽ mô tÁ á lO M oARcPSD| 45467232 q := n k := 0 while q 0 begin ak := q mod b q q := [ ] b k := k + 1 end
ây các thuật toán cộng và nhân hai số nguyên trong biểu diễn nhị phân. Ta cũng sẽ phân
tích ộ phức t¿p tính toán của các thuật toán này thông qua số các phép toán bit thực sự
°ợc dùng. GiÁ sử khai triển nhị phân của hai số nguyên d°¡ng a và b là:
a = (an-1an-2 ... a1 a0)2 và b = (bn-1 bn-2 ... b1 b0)2
sao cho a và b ều có n bit ( ặt các bit 0 á ầu mỗi khai triển ó, nếu cần).
1) Phép cßng: Xét bài toán cộng hai số nguyên viết á d¿ng nhị phân. Thủ tục thực hiện
phép cộng có thể dựa trên ph°¡ng pháp thông th°ßng là cộng cặp chữ số nhị phân với nhau
(có nhớ) ể tính tổng của hai số nguyên.
Để cộng a và b, tr°ớc hết cộng hai bit á phÁi cùng của chúng, tức là: a0 + b0 = c0.2 + s0.
à ây s0 là bit phÁi cùng trong khai triển nhị phân của a+b, c0 là số nhớ, nó có thể bằng
0 hoặc 1. Sau ó ta cộng hai bit tiếp theo và số nhớ a1 + b1 + c0 = c1.2 + s1.
à ây s1 là bit tiếp theo (tính từ bên phÁi) trong khai triển nhị phân của a+b và c1 là số nhớ.
Tiếp tục quá trình này bằng cách cộng các bit t°¡ng ứng trong hai khai triển nhị phân và
số nhớ ể xác ịnh bit tiếp sau tính từ bên phÁi trong khai triển nhị phân của tổng a+b. à
giai o¿n cuối cùng, cộng an-1, bn-1 và cn-2 ể nhận °ợc cn-1.2+sn-1. Bit ứng ầu của tổng là sn=cn-
1. Kết quÁ, thủ tục này t¿o ra °ợc khai triển nhị phân của tổng, cụ thể là a+b = (sn sn-1 sn-2 ... s1 s0)2.
Thí dÿ 8: Tìm tổng của a = (11011)2 và b = (10110)2.
a0 + b0 = 1 + 0 = 0.2 + 1 (c0 = 0, s0 = 1), a1 + b1 + c0 = 1 + 1 + 0 = 1.2 + 0 (c1 = 1, s1 =
0), a2 + b2 +c1 = 0 + 1 + 1 = 1.2 + 0 (c2 = 1, s2 = 0), a3 + b3 + c2 = 1 + 0 + 1 = 1.2 +
0 (c3 = 1, s3 = 0), a4 + b4 +c3 = 1 + 1 + 1 = 1.2 + 1 (s5 = c4 =1, s4 = 1). Do ó, a + b = (110001)2.
Thuật toán cộng có thể °ợc mô tÁ bằng cách dùng o¿n giÁ mã nh° sau. 15 lO M oARcPSD| 45467232
procedure cộng (a,b: positive integers) c := 0
for j := 0 to n-1 begin ùa j bj cù d := ú ú û 2 û sj := aj + bj + c 2d c := d end sn := c
{khai triển nhị phân của tổng là (sn sn-1 ...s1 s0) 2}
Tổng hai số nguyên °ợc tính bằng cách cộng liên tiếp các cặp bit và khi cần phÁi cộng
cÁ số nhớ nữa. Cộng một cặp bit và số nhớ òi ba hoặc ít h¡n phép cộng các bit. Nh° vậy,
tổng số các phép cộng bit °ợc sử dụng nhỏ h¡n ba lần số bit trong khai triển nhị phân. Do
ó, ộ phức t¿p của thuật toán này là O(n).
2) Phép nhân: Xét bài toán nhân hai số nguyên viết á d¿ng nhị phân. Thuật toán thông
th°ßng tiến hành nh° sau. Dùng luật phân phối, ta có: n 1 n 1 ab = a bj 2 j =
a b( j 2 )j . j 0 j 0
Ta có thể tính ab bằng cách dùng ph°¡ng trình trên. Tr°ớc hết, ta thấy rằng abj=a nếu bj=1
và abj=0 nếu bj=0. Mỗi lần ta nhân một số h¿ng với 2 là ta dịch khai triển nhị phân của nó
một chỗ về phía trái bằng cách thêm một số không vào cuối khai triển nhị phân của nó.
Do ó, ta có thể nhận °ợc (abj)2j bằng cách dịch khai triển nhị phân của abj i j chỗ về phía
trái, tức là thêm j số không vào cuối khai triển nhị phân của nó. Cuối cùng, ta sẽ nhận °ợc
tích ab bằng cách cộng n số nguyên abj.2j với j=0, 1, ..., n-1.
Thí dÿ 9: Tìm tích của a = (110)2 và b = (101)2.
Ta có ab0.20 = (110)2.1.20 = (110)2, ab1.21 = (110)2.0.21 = (0000)2, ab2.22 = (110)2.1.22 =
(11000)2. Để tìm tích, hãy cộng (110)2, (0000)2 và (11000)2. Từ ó ta có ab= (11110)2.
Thủ tục trên °ợc mô tÁ bằng o¿n giÁ mã sau:
procedure nhân (a,b: positive integers)
for j := 0 to n-1 begin lO M oARcPSD| 45467232
if bj = 1 then cj := a °ợc dịch i j chỗ else cj := 0 end
{c0, c1,..., cn-1 là các tích riêng phần} p := 0
for j := 0 to n-1 p := p + cj
{p là giá trị của tích ab}
Thuật toán trên tính tích của hai số nguyên a và b bằng cách cộng các tích riêng phần c0,
c1, c2, ..., cn-1. Khi bj=1, ta tính tích riêng phần cj bằng cách dịch khai triển nhị phân của a i
j bit. Khi bj=0 thì không cần có dịch chuyển nào vì cj=0. Do ó, ể tìm tất cÁ n số nguyên
abj.2j với j=0, 1, ..., n-1, òi hỏi tối a là n 0 + 1 + 2 + ... + n 1 = n( 1) 2
phép dịch chỗ. Vì vậy, số các dịch chuyển chỗ òi hỏi là O(n2).
Để cộng các số nguyên abj từ j=0 ến n 1, òi hỏi phÁi cộng một số nguyên n bit, một số
nguyên n+1 bit, ... và một số nguyên 2n bit. Ta ã biết rằng mỗi phép cộng ó òi hỏi O(n)
phép cộng bit. Do ó, ộ phức t¿p của thuật toán này là O(n2).
1.5. THU¾T TOÁN Đà QUY.
1.5.1. Khái niám á quy:
Đôi khi chúng ta có thể quy việc giÁi bài toán với tập các dữ liệu ầu vào xác ịnh về việc
giÁi cùng bài toán ó nh°ng với các giá trị ầu vào nhỏ h¡n. Chẳng h¿n, bài toán tìm UCLN
của hai số a, b với a > b có thể rút gọn về bài toán tìm ¯CLN của hai số nhỏ h¡n, a mod b
và b. Khi việc rút gọn nh° vậy thực hiện °ợc thì lßi giÁi bài toán ban ầu có thể tìm °ợc
bằng một dãy các phép rút gọn cho tới những tr°ßng hợp mà ta có thể dễ dàng nhận °ợc
lßi giÁi của bài toán. Ta sẽ thấy rằng các thuật toán rút gọn liên tiếp bài toán ban ầu tới
bài toán có dữ liệu ầu vào nhỏ h¡n, °ợc áp dụng trong một lớp rất rộng các bài toán.
Định nghĩa: Một thuật toán °ợc gọi là ệ quy nếu nó giÁi bài toán bằng cách rút gọn liên
tiếp bài toán ban ầu tới bài toán cũng nh° vậy nh°ng có dữ liệu ầu vào nhỏ h¡n. Thí dÿ 10:
Tìm thuật toán ệ quy tính giá trị an với a là số thực khác không và n là số nguyên không âm.
Ta xây dựng thuật toán ệ quy nhß ịnh nghĩa ệ quy của an, ó là an+1=a.an với n>0 và khi n=0
thì a0=1. Vậy ể tính an ta quy về các tr°ßng hợp có số mũ n nhỏ h¡n, cho tới khi n=0. 17 lO M oARcPSD| 45467232
procedure power (a: số thực khác không; n: số nguyên không âm)
if n = 0 then power(a,n) := 1 else power(a,n) := a * power(a,n-1)
Thí dÿ 11: Tìm thuật toán ệ quy tính UCLN của hai số nguyên a,b không âm và a > b.
procedure UCLN (a,b: các số nguyên không âm, a > b)
if b = 0 then UCLN (a,b) := a else UCLN (a,b) := UCLN (a mod b, b)
Thí dÿ 12: Hãy biểu diễn thuật toán tìm kiếm tuyến tính nh° một thủ tục ệ quy. Để tìm
x trong dãy tìm kiếm a1,a2,...,an trong b°ớc thứ i của thuật toán ta so sánh x với ai. Nếu x
bằng ai thì i là vị trí cần tìm, ng°ợc l¿i thì việc tìm kiếm °ợc quy về dãy có số phần tử ít
h¡n, cụ thể là dãy ai+1,...,an. Thuật toán tìm kiếm có d¿ng thủ tục ệ quy nh° sau.
Cho search (i,j,x) là thủ tục tìm số x trong dãy ai, ai+1,..., aj. Dữ liệu ầu vào là bộ ba (1,n,x).
Thủ tục sẽ dừng khi số h¿ng ầu tiên của dãy còn l¿i là x hoặc là khi dãy còn l¿i chỉ có một
phần tử khác x. Nếu x không là số h¿ng ầu tiên và còn có các số h¿ng khác thì l¿i áp dụng
thủ tục này, nh°ng dãy tìm kiếm ít h¡n một phần tử nhận °ợc bằng cách xóa i phần tử ầu
tiên của dãy tìm kiếm á b°ớc vừa qua.
procedure search (i,j,x) if ai = x
then loacation := i else if i = j then loacation := 0 else search (i+1,j,x)
Thí dÿ 13: Hãy xây dựng phiên bÁn ệ quy của thuật toán tìm kiếm nhị phân.
GiÁ sử ta muốn ịnh vị x trong dãy a1, a2, ..., an bằng tìm kiếm nhị phân. Tr°ớc tiên ta so
sánh x với số h¿ng giữa a[(n+1)/2]. Nếu chúng bằng nhau thì thuật toán kết thúc, nếu không
ta chuyển sang tìm kiếm trong dãy ngắn h¡n, nửa ầu của dãy nếu x nhỏ h¡n giá trị giữa
của của dãy xuất phát, nửa sau nếu ng°ợc l¿i. Nh° vậy ta rút gọn việc giÁi bài toán tìm
kiếm về việc giÁi cũng bài toán ó nh°ng trong dãy tìm kiếm có ộ dài lần l°ợt giÁm i một nửa.
procedure binary search (x,i,j) m := [(i+j)/2]
if x = am then loacation := m lO M oARcPSD| 45467232
else if (x < am and i < m) then binary search (x,i,m-1) else
if (x > am and j > m) then binary search (x,m+1,j) else loacation := 0
1.5.2. Đá quy và lặp:
Thí dÿ 14. Thủ tục ệ quy sau ây cho ta giá trị của n! với n là số nguyên d°¡ng.
procedure factorial (n: positive integer)
if n = 1 then factorial(n) := 1
else factorial(n) := n * factorial(n-1)
Có cách khác tính hàm giai thừa của một số nguyên từ ịnh nghĩa ệ quy của nó. Thay cho
việc lần l°ợt rút gọn việc tính toán cho các giá trị nhỏ h¡n, ta có thể xuất phát từ giá trị của
hàm t¿i 1và lần l°ợt áp dụng ịnh nghĩa ệ quy ể tìm giá trị của hàm t¿i các số nguyên lớn
dần. Đó là thủ tục lặp.
procedure iterative factorial (n: positive integer) x := 1 for i := 1 to n x := i * x {x là n!}
Thông th°ßng ể tính một dãy các giá trị °ợc ịnh nghĩa bằng ệ quy, nếu dùng ph°¡ng
pháp lặp thì số các phép tính sẽ ít h¡n là dùng thuật toán ệ quy (trừ khi dùng các máy ệ
quy chuyên dụng). Ta sẽ xem xét bài toán tính số h¿ng thứ n của dãy Fibonacci.
procedure fibonacci (n: nguyên không âm)
if n = 0 the fibonacci(n) := 0
else if n = 1 then fibonacci(n) := 1
else fibonacci(n) := fibonacci(n - 1) + fibonacci(n - 2)
Theo thuật toán này, ể tìm fn ta biểu diễn fn = fn-1 + fn-2. Sau ó thay thế cÁ hai số này
bằng tổng của hai số Fibonacci bậc thấp h¡n, cứ tiếp tục nh° vậy cho tới khi f0 và f1 xuất
hiện thì °ợc thay bằng các giá trị của chúng theo ịnh nghĩa. Do ó ể tính fn cần fn+1-1 phép cộng.
Bây giß ta sẽ tính các phép toán cần dùng ể tính fn khi sử dụng ph°¡ng pháp lặp. Thủ tục
này khái t¿o x là f0 = 0 và y là f1 = 1. Khi vòng lặp °ợc duyệt qua tổng của x và y °ợc gán
cho biến phụ z. Sau ó x °ợc gán giá trị của y và y °ợc gán giá trị của z. Vậy sau khi i qua 19 lO M oARcPSD| 45467232
vòng lặp lần 1, ta có x = f1 và y = f0 + f1 = f2. Khi qua vòng lặp lần n-1 thì x = fn-1. Nh° vậy
chỉ có n – 1 phép cộng °ợc dùng ể tìm fn khi n > 1.
procedure Iterative fibonacci (n: nguyên không âm)
if n = 0 then y := 0 else begin x := 0 ; y := 1
for i := 1 to n - 1 begin z := x + y x := y ; y := z end end
{y là số Fibonacci thứ n}
Ta ã chỉ ra rằng số các phép toán dùng trong thuật toán ệ quy nhiều h¡n khi dùng
ph°¡ng pháp lặp. Tuy nhiên ôi khi ng°ßi ta vẫn thích dùng thủ tục ệ quy h¡n ngay cÁ khi
nó tỏ ra kém hiệu quÁ so với thủ tục lặp. Đặc biệt, có những bài toán chỉ có thể giÁi bằng
thủ tục ệ quy mà không thể giÁi bằng thủ tục lặp. BÀI T¾P CH¯ƠNG I:
1. Tìm một số nguyên n nhỏ nhất sao cho f(x) là O(xn) ối với các hàm f(x) sau: a) f(x) = 2x3 + x2log x.
b) f(x) = 2x3 + (log x)4. x4 x2 1 c) f(x) = x3 1 x5 5logx d) f(x) = . x4 1 2. Chứng minh rằng
a) x2 + 4x + 7 là O(x3), nh°ng x3 không là O(x2 +4x + 17).
b) xlog x là O(x2), nh°ng x2 không là O(xlog x).
3. Cho một ánh giá big-O ối với các hàm cho d°ới ây. Đối với hàm g(x) trong ánh giá
f(x) là O(g(x)), hãy chọn hàm ¡n giÁn có bậc thấp nhất. a) nlog(n2 + 1) + n2logn.
b) (nlogn + 1)2 + (logn + 1)(n2 + 1). lO M oARcPSD| 45467232
c) n2n nn2 .
4. Cho Hn là số iều hoà thứ n: 1 1 1 Hn = 1 + + + ... + 2 3 n
Chứng minh rằng Hn là O(logn).
5. Lập một thuật toán tính tổng tất cÁ các số nguyên trong một bÁng.
6. Lập thuật toán tính xn với x là một số thực và n là một số nguyên.
7. Mô tÁ thuật toán chèn một số nguyên x vào vị trí thích hợp trong dãy các số nguyên
a1, a2, ..., an xếp theo thứ tự tăng dần.
8. Tìm thuật toán xác ịnh vị trí gặp ầu tiên của phần tử lớn nhất trong bÁng liệt kê các
số nguyên, trong ó các số này không nhất thiết phÁi khác nhau.
9. Tìm thuật toán xác ịnh vị trí gặp cuối cùng của phần tử nhỏ nhất trong bÁng liệt kê
các số nguyên, trong ó các số này không nhất thiết phÁi khác nhau.
10. Mô tÁ thuật toán ếm số các số 1 trong một xâu bit bằng cách kiểm tra mỗi bit của
xâu ể xác ịnh nó có là bit 1 hay không.
11. Thuật toán tìm kiếm tam phân. Xác ịnh vị trí của một phần tử trong một bÁng liệt
kê các số nguyên theo thứ tự tăng dần bằng cách tách liên tiếp bÁng liệt kê ó thành
ba bÁng liệt kê con có kích th°ớc bằng nhau (hoặc gần bằng nhau nhất có thể °ợc)
và giới h¿n việc tìm kiếm trong một bÁng liệt kê con thích hợp. Hãy chỉ rõ các b°ớc của thuật toán ó.
12. Lập thuật toán tìm trong một dãy các số nguyên số h¿ng ầu tiên bằng một số h¿ng
nào ó ứng tr°ớc nó trong dãy.
13. Lập thuật toán tìm trong một dãy các số nguyên tất cÁ các số h¿ng lớn h¡n tổng tất
cÁ các số h¿ng ứng tr°ớc nó trong dãy.
14. Cho ánh giá big-O ối với số các phép so sánh °ợc dùng bái thuật toán trong Bài tập 10.
15. Đánh giá ộ phức t¿p của thuật toán tìm kiếm tam phân °ợc cho trong Bài tập 11.
16. Đánh giá ộ phức t¿p của thuật toán trong Bài tập 12.
17. Mô tÁ thuật toán tính hiệu của hai khai triển nhị phân.
18. Lập một thuật toán ể xác ịnh a > b, a = b hay a < b ối với hai số nguyên a và b á
d¿ng khai triển nhị phân. 21 lO M oARcPSD| 45467232
19. Đánh giá ộ phức t¿p của thuật toán tìm khai triển theo c¡ số b của số nguyên n qua
số các phép chia °ợc dùng.
20. Hãy cho thuật toán ệ quy tìm tổng n số nguyên d°¡ng lẻ ầu tiên.
21. Hãy cho thuật toán ệ quy tìm số cực ¿i của tập hữu h¿n các số nguyên.
22. Mô tÁ thuật toán ệ quy tìm xn mod m với n, x, m là các số nguyên d°¡ng.
23. Hãy nghĩ ra thuật toán ệ quy tính a2n trong ó a là một số thực và n là một số nguyên d°¡ng.
24. Hãy nghĩ ra thuật toán ệ quy tìm số h¿ng thứ n của dãy °ợc xác ịnh nh° sau: a0=1,
a1 = 2 và an = an-1 an-2 với n = 2, 3, 4, ...
25. Thuật toán ệ quy hay thuật toán lặp tìm số h¿ng thứ n của dãy trong Bài tập 24 là có hiệu quÁ h¡n?