You are on page 1of 8

Toán rời rạc

Tìm hiểu phương


pháp sinh
và ứng dụng trong bài toán
liệt kê
Nhóm 2
1.Nguyễn Thị Duyên
2.Lê Huy Dưỡng
3.Nguyễn Hữu Sáng
4.Đỗ Ngọc Hậu
5.Nguyễn Duy Quân
Phương pháp sinh
• Phương pháp sinh là phương pháp mà từ một
cấu hình tổ hợp nào đó thỏa mãn yêu cầu của
bài toán liệt kê, ta có thể suy ra được cấu hình
tổ hợp tiếp theo của bài toán.
Phương pháp sinh
• Điều kiện để bài toán liệt kê có thể được giải
bằng phương pháp sinh:
1. Tập hợp các cấu hình tổ hợp thỏa mãn bài toán
phải có 1 thứ tự nào đó. Với thứ tự đó ta có thể
xác định được cấu hình tổ hợp đầu tiên và cuối
cùng trong thứ tự.
2. Ta phải xây dựng được thuật toán “sinh kế tiếp”
để suy ra cấu hình tiếp theo (trong thứ tự nêu
trên) sau 1 cấu hình tổ hợp bất kì nào (không
phải cuối cùng).
Phương pháp sinh
• Mô tả thuật toán:
1. Khởi tạo cấu hình ban đầu (trong thứ tự).
Nếu muốn liệt kê hết các cấu hình thì cấu hình khởi tạo
chính là cấu hình đầu tiên trong thứ tự ta đã xác định được.
2. Tạo 1 vòng lặp, thực hiện hàm “sinh kế
tiếp” từ cấu hình khởi tạo, điều kiện dừng là
khi cấu hình “sinh” được là cấu hình cuối cùng
mà ta đã xác định được ban đầu.
Áp dụng vào bài toán Liệt kê tất cả
những dãy nhị phân độ dài n
• Nhận xét: Bài toán này hoàn toàn thỏa mãn 2 điều kiện
để có thể áp dụng phương pháp sinh.
• Giả sử các cấu hình có dạng b1 b2 b3…bi…bn
– Với bi nhận một trong 2 giá trị 0 và 1.
• Điều kiện 1:
– Mỗi cấu hình này là biểu diễn nhị phân của 1 số nguyên
f(x). Khi đó thứ tự của các cấu hình có thể xem như thứ tự
của các số nguyên tương ứng. Ta có cấu hình a < c khi f(a)
< f(c).
– Với thứ tự trên ta hoàn toàn xác định được cấu hình đầu
tiên của dãy nhị phân độ dài n là (000…0)n phần tử
và cầu hình cuối cùng là (111…1)n phần tử
Áp dụng vào bài toán Liệt kê tất cả
những dãy nhị phân độ dài n
• Điều kiện 2:
– Ta có thể xây dựng được thuật toán suy ra cấu
hình kế tiếp 1 cấu hình đã biết trong thứ tự trên
bằng cách đơn giản là cộng 1 vào số nhị phân
tương ứng với cấu hình đã biết.
Ví dụ: (011) + 1 = (100)
– Ta có thể cụ thể hóa thuật toán này như sau:
• Cho i chạy giảm dần từ n (i = n, n-1, …). Nếu bi = 1 thì
gán bi = 0 và tiếp tục.Nếu bi = 0 thì gán bi = 1 và dừng
lại. Lúc này ta được 1 cấu hình mới kế tiếp cấu hình lúc
đầu.
Cài đặt chương trình dùng ngôn ngữ
C++
• #include<iostream.h>
• #include<conio.h>
//Hàm sinh cấu hình kế tiếp từ 1 cấu hình đã biết trong dãy thứ tự
• int NextBitString(int a[], int i)
• {
• while(a[i]==1)
• {
• if(i==0) return 1;
• a[i] = 0;
• i--;
• }
• a[i] = 1;
• return 0;
• }
//Hàm in ra 1 cấu hình
• void print(int a[], int n)
• {
• for(int i = 0; i < n; i++)
• cout<<a[i]<<" ";
• cout<<endl;
• }
Cài đặt chương trình dùng ngôn ngữ
• void main()
C++
• {
• int i, *a, c = 0;
• cout<<"Nhap vao so phan tu cua day nhi phan: ";
• cin>>i;
• //Cấp bộ nhớ cho mảng a
• a = new int[i];
• //Khởi tạo giá trị cho mảng a ( khởi tạo cấu hình tổ hợp đầu tiên (000…0) )
• for(int j = 0; j<i; j++)
• a[j] = 0;
• cout<<endl<<"Cac cau hinh to hop cua day so nhi phan do dai "<<i<<" :"<<endl<<endl;
• do
• { print(a, i); c++;}
• while(NextBitString(a, i-1)==0);
• cout<<endl<<c<<" cau hinh da duoc liet ke!!!";
• delete a;
• getch();
• }

You might also like