Professional Documents
Culture Documents
Phan 2 - Chia de Tri
Phan 2 - Chia de Tri
Phan 2 - Chia de Tri
2
1. Chiến lược chia để trị (Divide and Conquer)
• Là một trong những chiến lược nổi tiếng trong lập trình.
Khoa Công Nghệ Thông Tin
• Gộp lời giải của các bài toán con để xây dựng lời giải bài
toán lớn ban đầu.
3
1. Chiến lược chia để trị
• Ý tưởng: chiến lược chia để trị gồm 3 bước cơ bản
– Chia: chia nhỏ vấn đề thành nhiều phần
Khoa Công Nghệ Thông Tin
4
1.Chiến lược chia để trị
• Sơ đồ kỹ thuật chia
để trị trong trường
Khoa Công Nghệ Thông Tin
5
2. Các bài toán thông dụng
Tìm nhị phân
Tính tổng của các phần tử trong mảng a có n số nguyên
Khoa Công Nghệ Thông Tin
7
2.4. Tìm kiếm nhị phân
Cho M có n = 7 phần tử, left = 0 và right = 6 = n - 1 = l + r = 0 + 6
Ví dụ:
2 5 7 10 11 16 18
Minh họa thuật toán: tìm số 11
Khoa Công Nghệ Thông Tin
2 5 7 10 11 16 18 Mmid = 11 = 11
right = mid - 1
Mid-i = (4+4)/2 = left mid right
4
8
2.4. Tìm kiếm nhị phân
Giải thuật
B0: First 1 ; Last n // xét toàn đoạn M
Khoa Công Nghệ Thông Tin
9
2.4. Tìm kiếm nhị phân
Giải thuật không đệ qui
B0: First 1 ; Last n-1 // xét toàn đoạn M
Khoa Công Nghệ Thông Tin
l = 0; r = n − 1;
while (l ≤ r){
m = (l + r)/2;
if (K = A[m]) return m;
else if (K < A[m])
r = m − 1;
else
l = m + 1;
}
return −1;
11
Tìm kiếm nhị phân: cài đặt với đệ qui
int RecBinarySearch (T M[], int First, int Last, T x){ //(T cho trước)
1. if (First > Last) return (-1); // phần neo
Khoa Công Nghệ Thông Tin
12
2.4. Tìm kiếm nhị phân
Thuật toán BinarySearch(A, n, x)
//Input: Mảng A[n] tăng dần, x
Khoa Công Nghệ Thông Tin
14
Tìm kiếm nhị phân: phân tích với đệ qui
• Trường hợp tốt nhất, phần tử ở giữa có giá trị x:
– Số phép gán: Gmin = 1
Khoa Công Nghệ Thông Tin
17
2.1. Tính tổng của các phần tử trong mảng a có n số
Cho M có n = 7 phần tử, left = 0 và right = 6 = n - 1 = l + r = 0 + 6
• Ví dụ:
Mid = (l + r)/2 = 3
1 4 7 3 5 2 6
Mảng–trái (l, Mid-1) = M(0, 2)
Khoa Công Nghệ Thông Tin
Mid = (l + r)/2 = 1
1 4 7 3 5 2 6
Mảng–trái (l, Mid-1) = M(0, 0)
Sao chép Mảng–trái 4 7 3 5 2 6
Mảng–phải (Mid, r) = M(1, 2)
Sao chép Mảng–phải
Mid = (l + r)/2 = 1
11 8 8
Mảng–trái (l, Mid-1) = M(0, 0)
Sao chép Mảng–trái 12 16
Mảng–phải (Mid, r) = M(1, 2)
Sao chép Mảng–phải
28
{
if (n == 1)
return a[0];
saoChep a[0 .. n/2 - 1] vào b[0.. n/2 - 1];
saoChep a[n/2 .. n - 1] vào c[0.. n/2 - 1];
return tinhTong (b, n/2) + tinhTong(c, n - n/2);
}
19
2.1. Tính tổng của các phần tử trong mảng a có n số
• Thuật toán:
tinhTong(a, l, r)
Khoa Công Nghệ Thông Tin
{
if (l == r)// kiểm tra phép so sánh làm điểm neo
return a[0];
//tính lại l1 và r1
//tính lại l2 và r2
return tinhTong(a, l1, r1) + tinhTong(a, l2, r2);
}
20
2.3. Sắp xếp QuickSort
• Mục tiêu: Phân chia các phần tử của cấu trúc dãy dựa theo giá trị của
chúng và sắp xếp 1 4 7 3 5 2 6
• Phương pháp:
Khoa Công Nghệ Thông Tin
• Dãy 1: M[0].. M[j] có các phần tử mà giá trị không lớn hơn x
• Dãy 2: M[j]..M[n-1] có các phần tử mà giá trị không nhỏ hơn x
Kết quả M được phân thành 3 phần:
• M[k] < x , với k = 0..j
• dãy 2 đã có thứ tự,
• M[k] = x , với k = j+1...i-1 • dãy 1 và 3 chỉ có 1 phần tử
• M[k] > x , với k = i...n-1 thì chúng cũng đã có thứ tự,
• M đã được sắp xếp
22
2.3. Sắp xếp QuickSort
• Trình bày ví dụ minh họa, mảng M có 10 phần tử
Khoa Công Nghệ Thông Tin
1
0
24
2.3. Sắp xếp QuickSort
• Thuật toán Quicksort(A, l, r)
//Input: Mảng con của A[n] được xác định bởi l và r
//Output: Mảng con A[l, r] đã sắp xếp theo thứ tự tăng dần
Khoa Công Nghệ Thông Tin
if (l < r)
s = Partition(A, l, r); //s vị trí phân hoạch
Quicksort(A, l, s − 1);
Quicksort(A, s + 1, r); Partition(A, l, r){
x = A[r], i = l - l;
for (j = l; j <= r; j++)
A[l..r] if (A[j] x)
i = i + 1;
8 swap(A[i], A[j]);
A[l..s - 1] A[s + 1..r] swap(A[i + 1], A[r]);
return i + 1;
Partition 8
}
<8 >8
25
2.3. Sắp xếp QuickSort
• Thuật toán Quicksort(A, l, r)
//Input: Mảng con của A[n] được xác định bởi l và r
//Output: Mảng con A[l, r] đã sắp xếp theo thứ tự tăng dần
Khoa Công Nghệ Thông Tin
if (l < r)
s = Partition(A, l, r); //s vị trí phân hoạch
Quicksort(A, l, s − 1);
Quicksort(A, s + 1, r); Partition(A, l, r){
k = (l + r)/2, x = A[k];
do{
while (a[l] < x) l++;
A[l..r] while (a[r] > x) r--;
if (l < r)
8 swap(A[l], A[r]);
A[l..s - 1] A[s + 1..r]
l++; r--;
}while (l <= r);
Partition 8
return r;
<8 >8 }
26
2.3. Sắp xếp QuickSort
• Ví dụ:
7 18 11 10 2 5 16
Khoa Công Nghệ Thông Tin
i=0 x j=6
7 18 11 10 2 5 16
i=1 x j=5
7 5 11 10 2 18 16
i=2 x j=4
7 5 2 10 11 18 16
j=3
i=3 x
7 5 2 10 11 18 16
27
2.3. Sắp xếp QuickSort
• Ví dụ:
7 5 2 10 11 18 16
Khoa Công Nghệ Thông Tin
i x j
2 5 7 10 11 18 16
= =
02 i 5x j 27 10 11 18 16
= =
1 5 17 i i x j
2 10 11 16 18
== =
2 5 7 10
j
411 5 16 i618
= = 28
2.3. Sắp xếp QuickSort
• Cài đặt thuật toán Quicksort(A, l, r)
Khoa Công Nghệ Thông Tin
29
2.3. Sắp xếp QuickSort
• Cài đặt thuật toán Quicksort(A, l, r)
Partition(int a[], int left, int right) {
Khoa Công Nghệ Thông Tin
32
2.2. Thuật toán MergeSort
• Ý tưởng:
Khoa Công Nghệ Thông Tin
33
2.2. Thuật toán MergeSort
• Ví dụ:
Khoa Công Nghệ Thông Tin
34
2.2. Thuật toán MergeSort
min min
A G L O R H I M S T
35
2.2. Thuật toán MergeSort
min
min
A G L O R H I M S T
A G
36
2.2. Thuật toán MergeSort
min
min
A G L O R H I M S T
A G H
37
2.2. Thuật toán MergeSort
min
min
A G L O R H I M S T
A G H I
38
2.2. Thuật toán MergeSort
min
min
A G L O R H I M S T
A G H I L
39
2.2. Thuật toán MergeSort
min
min
A G L O R H I M S T
A G H I L M
40
2.2. Thuật toán MergeSort
min
min
A G L O R H I M S T
A G H I L M O
41
2.2. Thuật toán MergeSort
min
min
A G L O R H I M S T
A G H I L M O R
42
2.2. Thuật toán MergeSort
min
A G L O R H I M S T
A G H I L M O R S
43
2.2. Thuật toán MergeSort
min
A G L O R H I M S T
A G H I L M O R S T
44
2.2. Thuật toán MergeSort
A G L O R H I M S T
A G H I L M O R S T
45
2.2. Thuật toán MergeSort
46
2.2. Thuật toán MergeSort
1 1 0 1 0 1 0 1
+ 0 1 1 1 1 1 0 1 1 1 0 1 0 1 0 1
1 0 1 0 1 0 0 1 0 * 0 1 1 1 1 1 0 1
1 1 0 1 0 1 0 1 0
0 0 0 0 0 0 0 0 0
• Nhân 2 số nguyên có n chữ số 1 1 0 1 0 1 0 1 0
1 1 0 1 0 1 0 1 0
1 1 0 1 0 1 0 1 0
1 1 0 1 0 1 0 1 0
1 1 0 1 0 1 0 1 0
0 0 0 0 0 0 0 0 0
0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0
48
2.5. Thuật toán nhân 2 số nguyên lớn
• Mục tiêu: Thực hiện phép nhân 2 số nguyên có n chữ số.
• Phương pháp:
Khoa Công Nghệ Thông Tin
49
2.5. Thuật toán nhân 2 số nguyên lớn - Karatsuba
• Mục tiêu: Thực hiện phép nhân 2 số nguyên có n chữ số.
• Phương pháp:
Khoa Công Nghệ Thông Tin
log 2 3
T(n) O(n ) O(n1.585 )
50
Bài toán nhân ma trận
52
2.6. Thuật toán nhân ma trận Strassen
• Mục tiêu: Nhân hai ma trận có kích thước N x N + giảm thời gian thực
hiện.
Khoa Công Nghệ Thông Tin
• Phương pháp:
– Chia: Chia A và B thành (n/2) x (n/2) ma trận con
– Trị: Thực hiên đệ quy 7 phép nhân (n/2) x (n/2) ma trận
– Gộp: Tạo ma trận C sử dụng + và – trên (n/2) x (n/2) ma trận con
53
2.6. Thuật toán nhân ma trận Strassen
• Ví dụ:
A B = C
Khoa Công Nghệ Thông Tin
A0 A1 B0 B1 A0 B0 + A1 B2 A0 B1 + A1 B3
=
A2 A3 B2 B3 A2 B0 + A3 B2 A2 B1 + A3 B3
54
2.6. Thuật toán nhân ma trận Strassen
• Ví dụ:
𝐶11 𝐶12 𝐴11 𝐴12 𝐵11 𝐵12
=
Khoa Công Nghệ Thông Tin
55
2.6. Thuật toán nhân ma trận Strassen
• Thuật toán Strassen
if (n == 1) {
(*R) += (*A) * (*B);
}
else {
MatMul(A, B, R, n/4);
MatMul(A, B + (n/4), R + (n/4), n/4);
MatMul(A + 2 * (n/4), B, R + 2 * (n/4), n/4);
MatMul(A + 2 * (n/4), B + (n/4), R + 3 * (n/4), n/4);
MatMul(A + (n/4), B + 2 * (n/4), R, n/4);
MatMul(A + (n/4), B + 3 * (n/4), R + (n/4), n/4);
MatMul(A + 3 * (n/4), B + 2 * (n/4), R + 2 * (n/4), n/4);
MatMul(A + 3 * (n/4), B + 3 * (n/4), R + 3 * (n/4), n/4);
}
}
56
2.6. Thuật toán nhân ma trận Strassen
• Thời gian thực hiện
Khoa Công Nghệ Thông Tin
57
Bài tập
58
Bài tập
Sử dụng kỹ thuật chia để trị thực hiện:
1. Tìm vị trí của phần tử lớn nhất trong mảng n số nguyên. Trong
Khoa Công Nghệ Thông Tin
trường hợp mảng có nhiều phần tử có giá trị lớn nhất thì đầu
ra của thuật toán là gì?
2. Tính an.
3. Tìm phần tử trung bình của mảng
4. Tìm dãy con có tổng lớn nhất
5. Thiết kế một thuật toán để sắp xếp các phần tử của một dãy n
số thực cho trước sao cho tất cả các phần tử âm của mảng
đứng trước tất cả các phần tử dương trong mảng.
59