1. Trang chủ
  2. » Công Nghệ Thông Tin

Chapter 1 algorithm and algorithm complexity

117 1 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Algorithm and Algorithm Complexity
Chuyên ngành Computer Science
Thể loại Lecture Notes
Định dạng
Số trang 117
Dung lượng 1,26 MB
File đính kèm ch2_test.rar (33 KB)

Nội dung

Giải thuật nâng cao tài liệu đào tạo chuyên ngành công nghệ thông tin bao gồm kiến thức về đồ thị. Tự động hóa quá trình thu thập dữ liệu từ nhiều nguồn khác nhau như cơ sở dữ liệu khách hàng, trang web, mạng xã hội, email marketing, và các nguồn khác. Điều này giúp đảm bảo rằng dữ liệu được cập nhật và đầy đủ.

Trang 1

Advanced algorithms

Trang 2

Chapter 1.

Algorithm and algorithm

complexity

Trang 3

Algorithm and algorithm complexity

Problem (in informatics)

Trang 4

BÀI

TOÁN

• Trong phạm vi tin học, ta xem bài toán

là một công việc nào đó mà ta muốn máy tính thực hiện.

• Khi dùng máy tính giải bài toán, ta cần quan tâm trước hết đến hai yếu tố: đưa vào máy tính thông tin gì ( Input ) và cần lấy ra thông tin gì ( Output ) ?

• Do đó, để phát biểu một bài toán ta cần phải trình bày rõ Input và Output của bài toán đó và mối quan hệ giữa Input và Output.

Trang 5

Ví dụ

• Giải phương trình dạng ax2 + bx + c = 0

• Tìm tất cả phương án để đặt n quân hậu trên bàn cờ n  n

• Cho dãy n số, tìm dãy con tăng dài nhất (dãy con này không

nhất thiết chứa các phần tử liên tiếp nhau)

• Tìm một số nguyên tố lớn (từ hàng nghìn đến hàng triệu chữ số)

• Tính 21000

Trang 6

THUẬT TOÁN

Thuật toán để giải một bài toán là một dãy hữu hạn các thao tác được sắp xếp theo một trình tự xác định sao cho sau khi thực hiện dãy thao tác ấy, từ Input của bài toán, ta nhận được Output của bài toán.

Although there is no universally agreed-on wording to describe this notion, there is general agreement about what the concept

Trang 7

• Đầu ra (Output): Với mỗi tập các dữ liệu đầu vào, thuật

toán đưa ra các dữ liệu tương ứng với lời giải của bài toán

• Chính xác (Precision): Các bước của thuật toán được mô

tả chính xác

• Hữu hạn (Finiteness): Thuật toán cần phải đưa được đầu

ra sau một số hữu hạn (có thể rất lớn) bước với mọi đầu vào

• Đơn trị (Uniqueness): Các kết quả trung gian của từng

bước thực hiện thuật toán được xác định một cách đơn trị và chỉ phụ thuộc vào đầu vào và các kết quả của các bước trước

• Tổng quát (Generality): Thuật toán có thể áp dụng để giải

Trang 8

Ngôn ngữ biểu

diễn thuật toán

• Ngôn ngữ sơ đồ khối

• Ngôn ngữ mã giả

• Ngôn ngữ lập trình

• Ngôn ngữ tự nhiên

Trang 9

(thời gian tính ) và bộ nhớ.

• Khi nói đến độ phức tạp là ý nói đến độ phức tạp thời gian tính.

Trang 10

Kích thước dữ

liệu đầu vào

của bài toán

Ta gọi kích thước dữ liệu đầu vào (hay

độ dài dữ liệu vào) của bài toán là số bít cần thiết để biểu diễn nó.

Ta sẽ tìm cách đánh giá thời gian tính của thuật toán bởi một hàm của độ dài

dữ liệu vào.

Thời gian tính của thuật toán phụ thuộc vào dữ liệu vào.

Trang 11

Phép toán cơ

bản

Ta gọi phép toán cơ bản là phép toán có thể thực hiện với thời gian bị chặn bởi một hằng số không phụ thuộc vào kích thước dữ liệu.

Trang 12

Các loại thời

gian tính

Để tính toán thời gian tính của thuật toán ta

sẽ đếm số phép toán cơ bản mà nó phải

thực hiện

• Thời gian tối thiểu cần thiết để thực hiện thuật toán với mọi bộ dữ liệu đầu vào kích

thước n Thời gian như vậy sẽ được gọi là thời

gian tính tốt nhất của thuật toán với đầu vào

kích thước n.

• Thời gian nhiều nhất cần thiết để thực hiện thuật toán với mọi bộ dữ liệu đầu vào kích

thước n Thời gian như vậy sẽ được gọi là thời

gian tính kém nhất của thuật toán với đầu vào

Trang 13

ta cũng rất hay viết f(n) =(g(n)).

Trang 14

• Ta nói g(n) là cận trên tiệm cận của

f(n) và viết f(n)  O(g(n)) hoặc f(n)

=O(g(n)).

Trang 17

Cách nói về

thời gian tính

• Câu nói “thời gian tính là O(f(n))” hiểu là:

đánh giá trong tình huống kém nhất là

O(f(n)) Thường nói: “Đánh giá thời gian

tính trong tình huống kém nhất là

O(f(n))”; nghĩa là thời gian tính trong tình

huống tồi nhất được xác định bởi một

hàm nào đó g(n)  O(f(n)).

• Câu nói “thời gian tính là  (f(n))” hiểu là:

đánh giá trong tình huống tốt nhất là

(f(n)) Thường nói: “Đánh giá thời gian

tính trong tình huống tốt nhất là 

(f(n))”; nghĩa là thời gian tính trong tình

huống tốt nhất được xác định bởi một

hàm nào đó g(n) (f(n)).

Trang 19

Cận trên và cận

dưới

• Cận trên (Upper bound): Cho bài toán P,

ta nói cận trên cho thời gian tính của P là O(g(n)) nếu để giải P tồn tại thuật toán giải với thời gian tính là O(g(n)).

• Cận dưới (Lower bound): Cho bài toán P,

ta nói cận dưới cho thời gian tính của P

là  (g(n)) nếu mọi thuật toán giải P đều

có thời gian tính là  (g(n)).

• Ta nói thời gian tính của P là (g(n)) nếu

P có cận trên là O(g(n)) và cận dưới là

(g(n)).

Trang 20

Bài toán dễ

giải – khó

giải-không giải

được

• Bài toán dễ giải

• Bài toán khó giải

• Bài toán không giải được

Trang 21

Bài toán dễ giải

• Một bài toán được gọi là dễ giải nếu như

nó có thể giải được bởi thuật toán đa thức

Ví dụ:

✓ bài toán tìm dãy con liên tiếp có tổng lớn nhất,

✓ sắp xếp dãy n số,…

Trang 22

Bài toán khó giải

• Một bài toán được gọi là khó giải nếu như nó không thể giải được bởi thuật toán đa thức

Ví dụ:

✓ bài toán liệt kê các hoán vị của n số,

✓ bài toán liệt kê các dãy nhị phân chiều dài n

• Một dạng bài toán nữa cũng được xem là khó giải: Đó

là những bài toán cho đến hiện tại vẫn chưa tìm được thuật toán đa thức để giải.

Ví dụ:

✓ bài toán cái túi,

✓ bài toán người đi du lịch,…

❖ Tham khảo “Bài toán tổ hợp” ở các trang tiếp theo.

Trang 23

Bài toán không giải

Trang 24

Đánh giá độ phức tạp của thuật toán bằng một

Trang 26

for (i=1;i<=n;i++)

<công việc>

Ví dụ: Hãy đánh giá độ phức tạp của đoạn lệnh sau

Trang 29

• Việc phát triển thuật toán đệ quy là thuận tiện khi cần xử lý với các đối tượng được định nghĩa đệ quy (biểu thức quy nạp, cây có gốc,…).

Trang 30

Sơ đồ thuật

toán đệ qui

void Reccursive(Input) {

if (kích thước của Input là nhỏ nhất)

Thực hiện Bước cơ sở;

else {

RecAlg (Input với kích thước nhỏ hơn); /* Bước đệ quy

*/

/*Có thể có thêm những lệnh gọi đệ quy */

Tổ hợp lời giải của các bài toán con để thu được Lờigiải;

return Lờigiải;

}

Trang 31

Ví dụ

Tìm số hạng thứ n của dãy Fibonacci

Trang 32

Đệ quy có nhớ

• Ta sẽ dùng biến ghi nhớ lại thông tin về lời giải của các bài toán con ngay sau lần đầu tiên nó được giải

• Điều đó cho phép rút ngắn thời gian tính của thuật toán, bởi vì, mỗi khi cần đến có thể tra cứu mà không phải giải lại những bài toán con đã được giải trước đó.

Trang 34

Ví dụ 1

liên tiếp là dãy mà thành phần của nó là các

thành phần liên tiếp nhau trong {a}, ta gọi

tổng của dãy con là tổng tất cả các thànhphần của nó Tìm tổng lớn nhất trong tất cả

các tổng của các dãy con của {a}

Ví dụ:

n=7

4 -5 6 -4 2 3 -7

Kết quả:

Trang 35

Thuật toán 1

• Xét tất cả các cặp số

nguyên L và U thỏa mãn

1  L  U  n;

• Đối với mỗi cặp như vậy

ta tính tổng của dãy con

int sum=0;

for (int I=L;I<=U;I++) sum=sum+a[I];

maxsofar=max(maxsofar,sum);//hàm max trả về số lớn nhất trong 2 số

} cout<<maxsofar;

Trang 36

} cout<<maxsofar;

}

Trang 37

Thuật toán 3

• Tổng lớn nhất trong dãy con

a[1 i] là tổng lớn nhất trong dãy

con a[1 i-1] (gọi là maxsofar)

hoặc tổng lớn nhất trong tất cả

các tổng của các dãy con kết

thúc tại i (gọi là maxendinghere).

• Chúng ta có nhận xét rằng: Dãy

con lớn nhất kết thúc tại i là dãy

con lớn nhất kết thúc tại vị trí i-1

được bổ sung thêm phần tử a[i]

ở cuối hoặc là dãy con rỗng

trong trường hợp tổng của dãy

con nhận được là số âm Ta có

thuật toán như sau:

void algorithm3(int a[], int n) {

cout<<maxsofar;

}

Trang 38

Ví dụ 2

chuyển k phần tử đầu dãy về cuối dãy

Yêu cầu không dùng mảng trung gian

Trang 39

Thuật toán 1

Để dịch chuyển một phần tử đầu dãy

về cuối dãy, ta thực hiện 3 bước sau:

Chuyển một phần tử đầu dãy vào biến

tạm; dịch chuyển tất cả các phần tử

của dãy về bên trái một vị trí; gán phần

tử cuối dãy bằng giá trị của biến tạm

Dễ thấy độ phức tạp của công đoạn

gồm 3 bước trên là O(n); do vậy để

dịch chuyển k phần tử đầu dãy về cuối

} }

Trang 40

Thuật toán 2

Sử dụng thuật toán chia để trị

để giải bài toán trên với độ phức

}

Thuật toán giải bài toán này có độ phức tạp O(n).

void solve(int a[], int n, int k) {

sequence_reverse(a,1,k);

sequence_reverse(a,k+1,n);

sequence_reverse(a,1,n);

Trang 41

Ví dụ 3

Cho dãy n số nguyên a1,a2,….an (n ≤ 106)

Hãy tìm 3 số sao cho tích của chúng là lớn nhất (xuất tích lớn nhất tìmđược)

Trang 42

if (a[i]*a[j]*a[k]>max)

max=a[i]*a[j]*a[k];

return max;

}

Trang 44

Thuật toán 3

• Tìm 3 số lớn nhất max1, max2, max3

• Tìm 2 số nhỏ nhất min1,min2

• Đặt p= max1 * max2 * max3;

q= max1 * min1 * min2

• So sánh p,q để tìm ra kết quả

Trang 45

BÀI TẬP

Trang 46

Trình bày thuật toán và đánh giá độ phức tạp của các thuật toán giải các bài toán sau

Bài tập 1.

Cho dãy gồm n số nguyên a1,a2,…,a n (n  106)

Tìm một dãy con liên tiếp tăng dài nhất Xuất chiều dài của dãy tìm được

Trang 47

Bài tập 2.

trên có bao nhiêu số có giá trị đôi một khác nhau ?

Trang 48

Bài tập 3.

Cho số nguyên dương p, ước số nguyên dương không kể chính nó gọi là ước

số thực sự của p Ví dụ 10 có 3 ước số thực sự là 1,2 và 5.

Hãy đếm xem có bao nhiêu cặp số nguyên dương p,q với 1<p,q < M (với

M<=106) sao cho tổng các ước số thực sự của p bằng q và tổng các ước số thực sự của q bằng p.

Trang 49

Bài tập 4

Trang 50

Special sorting algorithms

Trang 52

GIỚI THIỆU BÀI TOÁN SẮP XẾP

Trang 53

• Khóa sắp xếp là bộ phận của bản ghi; khóa xác định thứ tự sắp xếp của bản ghi trong họ các bản ghi;

Trang 55

Ứng dụng của

bài toán sắp

xếp

• Quản trị cơ sở dữ liệu,

• Trong các máy tìm kiếm,

• Sắp xếp là một công đoạn quan trọng hỗ trợgiải quyết một vấn đề tin học hiệu quả,…

Trang 56

Sắp xếp nội

(internal sort)

• Các thuật toán sắp xếp đòi hỏi toàn

bộ dữ liệu cần sắp xếp được đưa vào

bộ nhớ trong của máy tính.

Trang 57

Thuật toán

sắp xếp dựa

vào phép so

sánh

Các thuật toán sắp xếp mà việc xác định thứ

tự của các phần tử dựa vào phép so sánhđược gọi là các thuật toán sắp xếp dựa vàophép so sánh:

Trang 58

nhất tìm được là O(n log n);

• Đây là thời gian tính tốt nhất của dạng thuật toán này và về mặt lý thuyết là không thể cải thiện hơn được nữa.

Trang 61

• Tính ổn định (stability): Nếu các phần tử

có cùng giá trị vẫn giữ nguyên thứ tự tương đối của chúng như trước khi sắp xếp.

• Tính tại chỗ (in place): Nếu không gian bộ nhớ phụ mà thuật toán đòi hỏi là O(1), nghĩa là bị chặn bởi hằng số không phụ thuộc vào độ dài của dãy cần sắp xếp.

Trang 63

PHÂN TÍCH THỜI GIAN TÍNH

MỘT SỐ THUẬT TOÁN SẮP XẾP

CÓ DỰA VÀO PHÉP SO SÁNH

Trang 64

• Trình bày ý tưởng/minh họa bằng ví dụ ?

• Trong trường hợp trung bình, thuật toán

Trang 65

void Interchangesort(int a[], int n)

{

for (int i=0; i<n-1;i++)

for (int j=i+1;j<n ;j++)

if (a[i]>a[j])

exch(a[i],a[j]);

}

Ý tưởng chính của thuật toán:

Xuất phát từ đầu dãy, tìm tất cả nghịch thế chứa phần tử này, triệt tiêu chúng bằng cách đổi chỗ phần

tử này với phần tử tương ứng trong cặp nghịch thế Lặp lại quá trình trên với các phần tử tiếp theo trong dãy

Trang 66

void exch(int &x, int &y)

Trang 67

Thuật toán

sắp xếp nổi

bọt (bubble

sort)

• Trình bày ý tưởng/minh họa bằng ví dụ ?

• Trong trường hợp trung bình, thuật toán

Trang 68

void Bubblesort(int a[],int n)

{

for (int i=1;i<n;i++) for (int j=n-1;j>=i;j )

if (a[j]<a[j-1]) exch(a[j],a[j-1]);

Ý tưởng chính của thuật toán:

Xuất phát từ cuối dãy (hoặc đầu dãy), đổi chỗ bất kỳ hai phần tử kế cận nào ngược thứ tự để đưa phần tử nhỏ nhất (hoặc lớn nhất) trong các cặp phần tử đó về vị trí đúng là đầu (cuối) dãy hiện hành,

kế tiếp không xét đến nó nữa ở bước tiếp theo, do vậy ở lần xử lý thứ i sẽ có vị trí đầu dãy là i Lặp lại quá trình trên cho đến khi không còn cặp phần tử nào để xét

Trang 69

Thuật toán

sắp xếp chọn

(selection

sort)

• Trình bày ý tưởng/minh họa bằng ví dụ ?

• Trong trường hợp trung bình, thuật toán

Trang 70

void Selectionsort(int a[],int n)

exch(a[min], a[i]);// nghia la ai

la phan tu nho nhat o buoc chon thu i

}

}

Ý tưởng chính của thuật toán:

Chọn phần tử nhỏ nhất trong n phần tử

khởi tạo, đưa phần tử này về vị trí đúng

là đầu dãy hiện hành; sau đó không quan tâm đến nó nữa, xem dãy hiện hành mới chỉ còn n-1 phần tử của dãy ban đầu, bắt đầu từ vị trí thứ hai; lặp lại quá trình trên cho dãy hiện hành cho đến khi dãy hiện hành chỉ còn một phần tử

Trang 71

Thuật toán

sắp xếp chèn

(insertion

sort)

• Trình bày ý tưởng/minh họa bằng ví dụ ?

• Trong trường hợp trung bình, thuật toán

Trang 72

void Insertionsort(int a[], int n)

Ý tưởng chính của thuật toán:

Dãy đầu tiên chỉ có một thứ tự a0 là dãy

đã được sắp Ta từng bước mở rộng dãy được sắp bằng cách lần lượt thêm phần tử

ai (i=1 n-1) vào Khi chèn ai vào dãy đã được sắp thì ta tiến hành các công đoạn

chèn Thứ hai tìm vị trí pos thích hợp

trong đoạn a 0 đến a i-1 để chèn ai vào Thứ

ba là chèn x vào vị trí pos.

Trang 74

có kích thước vừa phải (chẳng hạn

Trang 75

void Shellsort (int a[], int n)

{

int h = 1;

while (h < n/3) h = 3*h + 1; // 1, 4, 13, 40, 121, 364, 1093, while (h >= 1)

{ // h-sort the array

for (int i = h; i < n; i++){ // Insert a[i] among a[i-h], a[i-2*h], a[i-3*h]

for (int j = i; j >= h && a[j]<a[j-h]; j -= h)

exch(a[j], a[j-h]);

}

h = h/3;

}}

Trang 76

số thuật toán sắp xếp tốt dựa vào ý tưởng cơ bản từ các thuật toán này.

• Thuật toán Bubble sort và thuật toán Interchange sort hoạt động kém hiệu quả hơn so với các thuật toán Selection sort và Insertion sort

• Thuật toán Selection sort và thuật toán Insertion sort có thời gian tính tốt hơn so với các thuật toán Bubble sort và

Trang 77

Thuật toán

sắp xếp

nhanh (quick

sort)

• Trình bày ý tưởng/minh họa bằng ví dụ ?

• Thuật toán Quick sort do C.A.R Hoare đềxuất vào năm 1960;

• Đây là thuật toán sắp xếp trên thực tếchạy nhanh nhất hiện nay trong số các

thuật toán cỡ O(n log n);

• Là thuật toán được ứng dụng nhiều trongkhoa học và kỹ thuật;

• Thời gian tính trung bình của thuật toán

Quick sort cỡ O(n log n) và trong trường

Trang 78

• Chọn phần tử làm mốc phân hoạch tốt hơn (->rút ngắn được thời gian tính khoảng 5%)

Trang 79

phần sau đó sắp các phần này riêng biệt nhau như sau:

• Đầu tiên chọn phần tử tùy ý; thường được chọn là x=a[(l+r)/2] làm mốc,

kế tiếp quét từ đầu trái của mảng cho đến khi gặp một phần tử lớn hơn x

phần tử dừng việc quét dĩ nhiên là không đúng chỗ trong mảng kết quả

cuối cùng nên phải hoán vị chúng

• Sau khi thực hiện bước này thì bảo đảm rằng tất cả các phần tử ở bên

• Sau bước này ta đã chia dãy thành hai dãy con; ta lại tiếp tục phân hoạch theo kiểu đệ qui cho mỗi dãy con này

Trang 80

void quicksort(int a[],int l,int r)

Trang 81

Thuật toán

sắp xếp trộn

(merge sort)

• Trình bày ý tưởng/minh họa bằng ví dụ ?

• Thời gian tính của thuật toán Merge sort không bị ảnh hưởng bởi thứ tự của dữ liệu đầu vào;

• Trong cả ba trường hợp tốt nhất, trung bình và xấu

nhất, thuật toán Merge sort cần không quá n log n lần so sánh và không quá n log n lần đổi chỗ;

• Trong khi thời gian tính trong trường hợp xấu nhất

của thuật toán Quick sort là O(n2 ); đây là một trong những tiêu chí cần được xem xét khi lựa chọn thuật

toán sắp xếp dạng O(n log n) cho một bài toán sắp

xếp cụ thể.

• Minh họa: Dãy số: n=10;

8 5 1 3 6 9 12 4 7 10

Trang 83

void merge(int a[], int n, int l, int m, int r)

a[k] = L[i++];

else

a[k] = R[j++];

}

Trang 84

void mergesort(int a[], int n, int l, int r)

{

if(l < r){

Trang 85

• Trong các trường hợp xấu nhất và

trường hợp trung bình, thuật toán

Heap sort cần không quá O(n log n) lần so sánh và cần không quá O(n log n) lần đổi chỗ.

Trang 86

Thuật toán heap sort gồm hai giai đoạn sau:

Giai đoạn 1: Hiệu chỉnh dãy số ban đầu thành Heap Giai đoạn 2: Sắp xếp dãy số dựa trên Heap

Bước 1:

Đưa phần tử lớn nhất về vị trí đứng ở cuối dãy

r = n;

Hoán vị (a1,ar) Bước 2:

Loại bỏ phần tử lớn nhất ra khỏi Heap r=r-1;

Hiệu chỉnh phần còn lại của dãy từ a l đến a r thành một Heap.

Bước 3:

Nếu r >1 ( heap còn phần tử) : lặp lại bước 2

Ngược lại: dừng

Trang 88

r ;

insertheap(a,0,r);

} }

Trang 89

• Với các file dữ liệu kích thước nhỏ thì Quick sort không hiệu quả bằng Heap sort và merge sort;

• Thuật toán Shell sort có thời gian tính nhanh hơn nhiều so với thuật toán Insertion sort;

Ngày đăng: 30/03/2024, 12:41

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN