Toán học - Bài 5: Bài toán liệt kê
Giới thiệu
5.2. Phương pháp sinh
5.3. Phương pháp quay lui
Bạn đang xem trước 20 trang nội dung tài liệu Toán học - Bài 5: Bài toán liệt kê, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
BÀI 5
BÀI TOÁN LIỆT KÊ
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 1
Giáo viên: TS. Nguyễn Văn Hiệu
Email: nvhieuqt@dut.udn.vn
5.1. Giới thiệu
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 2
Nội dung
5.1. Giới thiệu
5.2. Phương pháp sinh
5.3. Phương pháp quay lui
5.1. Giới thiệu
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 3
Mục đích
Đưa ra danh sách tất cả các cấu hình có
thể có
Bản chất
Xác định một thuật toán để theo đó có
thể lần lượt xây dựng được tất cả các
cấu hình đang quan tâm.
5.1. Giới thiệu
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 4
Nguyên tắc
Không được lặp lại một cấu hình
Không được bỏ sót một cấu hình
Lưu ý
Chỉ giải với bài toán chưa có phương
pháp giải
Phương pháp Sinh
Phương pháp quay lui
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 5
Thường sử dụng
Giải bài toán liệt kê tổ hợp
Điều kiện
Xác định được một thứ tự.
Có cấu hình đầu tiên
Có cấu hình cuối cùng
Xác định được thuật toán để xây dựng
cấu hình kế tiếp
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 6
Bản chất
Generating_method() {
;
stop = islastconfigure();
while (stop==0) {
;
}
}
Chú thích
Stop = =1, là cấu hình
cuối cùng
Stop == 0, chưa phải
là cấu hình cuối cùng
là
thuật toán sinh cấu
hình tiếp theo trên thứ
tự đã xác định trước
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 7
Ví dụ
Liệt kê dãy nhị phân có độ dài n.
Liệt kê các tập con k phần tử của tập
n phần tử.
Liệt kê các hoán vị của tập n phần tử
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 8
Ví dụ 1:
Liệt kê các dãy nhị phân có độ dài n
Bước 1: Xác định thứ tự
Dãy nhị phân được biểu diễn:
b = (b1 b2 bn )
thỏa mản bi €{0,1}
Định nghĩa thứ tự từ điển:
b = (b1 b2 ... bn) và *b = (*b1 *b2 ... *bn)
thứ tự b < *b,
nếu q(b) < q(*b)
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 9
Ví dụ 1:
Liệt kê các dãy nhị phân có độ dài n
Bước 2: Cấu hình đầu
và cuối
Khi n = 4 phần tử, có 24
dãy nhị phân được liệt kê
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 10
Ví dụ 1:
Liệt kê các dãy nhị phân có độ dài n
Bước 2:
b q(b)
0000 0
0001 1
0010 2
0011 3
0100 4
0101 5
0110 6
0111 7
b q(b)
1000 8
1001 9
1010 10
1011 11
1100 12
1101 13
1110 14
1111 15
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 11
Bước 3: xác định thuật
toán
Thuật toán
0000 0001
0001 0010
0011 0100
0111 1000
i= n;
while (i>=1 && b[i]==‘1’)
b[i--] = ‘0’;
b[i] = ‘1’;
Tìm i từ bên phải:
bi = 0.
Gán lại bi = 1 và
bj = 0 với mọi j> i.
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 12
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 13
5.2. Phương pháp sinh
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 14
Kết quả
Result
Chương trình
Source Code
Ví dụ 1:
Liệt kê các dãy nhị phân có độ dài n
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 15
Ví dụ 2
Liệt kê các tập con k phần tử của tập n phần tử
Chuẩn bị
Ánh xạ tập n phần tử vào tập
X = {1,2,,n}
Mỗi tập con k phần tử của X được biểu diễn bởi
bộ có thứ tự gồm k thành phần:
a = (a1 a2 a3 ..... ak )
thỏa mản 1≤ a1< a2 < a3 <..... < ak ≤ n
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 16
Ví dụ 2
Liệt kê các tập con k phần tử của tập n phần tử
Bước 1: Xác định thứ tự
Định nghĩa thứ tự từ điển:
a = (a1 a2 a3 ...ak) và b = (b1 b2 b3 ... bk)
thứ tự a < b, nếu tồn tại j (1≤ j≤ k):
a1 = b1,...,aj-1= bj-1, aj < bj
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 17
Ví dụ 2:
Liệt kê các tập con k phần tử của tập n phần tử
Bước 2:
Các tập con 3 phần tử
của tập 5 phần tử
{1,2,3,4,5}
𝑪𝟑5 = 10
{ 1,2,3 }
{ 1,2,4 }
{ 1,2,5 }
{ 1,3,4 }
{ 1,3,5 }
{ 1,4,5 }
{ 2,3,4 }
{ 2,3,5 }
{ 2,4,5 }
{ 3,4,5 }
Cấu hình đầu
Cấu hình cuối
Cách sinh
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 18
Bước 3: xác định
thuật toán
Thuật toán
Giả sử a = (a1...ak ) không là
cuối cùng.
B1: Tìm vị trí i đầu tiên từ
bên phải của dãy:
ai ≠ n-k+i.
B2: Thay ai bởi ai + 1.
B3: Thay aj bởi ai - i +j,
với j = i+1,...,k
n=5, k=3
i = 1 2 3
a = {1, 4, 5 }
n-k+i = 3 4 5
{ 2, , }
{ 2, 3, 4}
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 19
Code
B1:
i=k;
while (a[i]==n-k+i) i-- ;
B2:
a[i]= a[i] + 1;
B3:
for (j=i+1;j<=k;j++)
a[j]= a[i]+ j –i;
Thuật toán
Giả sử a = (a1...ak ) không là
cuối cùng.
B1: Tìm vị trí i đầu tiên từ
bên phải của dãy:
ai ≠ n-k+i.
B2: Thay ai bởi ai + 1.
B3: Thay aj bởi ai - i +j,
với j = i+1,...,k
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 20
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 21
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 22
Kết quả
Result
Chương trình
Source Code
Ví dụ 2
Liệt kê các tập con k phần tử từ tập n phần tử
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 23
Ví dụ 3
Liệt kê hoán vị của tập n phần tử
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 24
Minh họa
{1,2,3,4} ?
{4,3,2,1}?
{3,4,2,1} {4,1,2,3}?
Xây dựng thuật toán
sinh
{1,2,3,4}
{1,2,4,3}
{1,3,2,4}
{1,3,4,2}
{1,4,2,3}
{1,4,3,2}
{2,1,3,4}
{2,1,4,3}
{2,3,1,4}
{2,3,4,1}
{2,4,1,3}
{2,4,3,1}
{3,1,2,4}
{3,1,4,2}
{3,2,1,4}
{3,2,4,1}
{3,4,1,2}
{3,4,2,1}
{4,1,2,3}
{4,1,3,2}
{4,2,1,3}
{4,2,3,1}
{4,3,1,2}
{4,3,2,1}
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 25
Định nghĩa Định nghĩa
Ánh xa tập n phần tử bất kỳ
vào tập
X = {1,2,,n}
Mỗi hoán vị của X được
biểu diễn bởi bộ có thứ tự
gồm n thành phần:
a = (a1 a2 ... an )
thỏa mản ai € X,
i=1,,n , ap ≠ aq , p ≠ q.
Thứ tự từ điển:
a = (a1 a2 a3 ...an)
b = (b1 b2 b3 ... bn)
thứ tự a < b,
nếu tồn tại j (1≤ j≤ n):
a1 = b1,...,aj-1= bj-1, aj < bj
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 26
Bước 3: Thuật toán
n= 4
i = 1 2 3 4
a = {1 3 4 2}
a = (a1 a2...an ) chưa phải là cuối
cùng.
B1: Tìm Right -> Left, j đầu
tiên:
aj ≤ aj+1
B2: Tìm Right -> Left, k đầu
tiên:
ak > aj.
B3: hoán vị aj và ak
B4: Lật ngược đoạn aj+1 đến an
k = 1 2 3 4
a = { 1 3 4 2}
a = { , 4 , 3, }
a = { , , 2, 3 }
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 27
Bước 3:
int j = n-1;
while(j>=1&&a[j]>a[j+1])j--;
int k = n;
while(a[j]>a[k])k--;
int temp = a[j];
a[j] = a[k]; a[k] = temp;
int l = j+1;int r = n;
while(l<r) {
int temp = a[l]; a[l]=
a[r]; [r]= temp;
l++; r--;
}
B1: Tìm Right -> Left, j
đầu tiên:
aj ≤ aj+1
B2: Tìm Right -> Left, k
đầu tiên:
ak > aj.
B3: hoán vị aj và ak
B4: Lật ngược đoạn aj+1
đến an
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 28
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 29
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 30
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 31
Kết quả
Result
Chương trình
Source Code
Ví dụ 2
Liệt kê các tập hoán vị của tập n phần tử
Bài toán liệt kê
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 32
Nội dung
5.1. Giới thiệu
5.2. Phương pháp sinh
5.3. Phương pháp quay lui
Phương pháp quay lui
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 33
Nội dung
Mục đích
Khái niệm
Phương pháp
Mã giả
Minh họa
5.3. Phương pháp quay lui
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 34
Mục đích
Để giải bài toán liệt kê
hoặc tối ưu tổ hợp
Đã giải:
Bài toán mã đi tuần
Bài toán xếp hậu
Bài toán mê cung
Bài toán người giao
hàng
Khái niệm
Backtracking
Поиск с возвратом
Quay lui
Backtracking
1950,
D.H.Lehmer
5.3. Phương pháp quay lui
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 35
Khái niệm
Backtracking– đi tìm lời
giải cho bài toán mà
nghiệm của nó là một cấu
hình hoặc một tập cấu
hình:
Tính chất P: xác định
cấu hình
Tính chất Q: xác định
tính dừng của bài toán
Khái niệm
Một cấu hình hay một nghiệp:
s 1 s 2 s n
s i ∈ D
Bài toán:
Liệt kê tất cả các cấu hình của S
S = s 1 s 2 s n
Bài toán con:
Giả sử đã tìm được s 1 s i , i < 𝑛
Hãy tìm cấu hình S
5.3. Phương pháp quay lui
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 36
Phương pháp
Giả sử có: s1s i-1
Tìm giá trị cho s i:
Duyệt ∀ j ∈ 𝐷 đề cử cho si
Mỗ𝑖 j ∈ 𝐷 kiểm tra:
Nếu j chấp nhận (∈ P ), si = j
Nếu i = n (∈ Q ) , được 1
cấu hình,
Nếu i< 𝑛, tìm s i +1.
Nếu ∀ j không được cấp nhận
(∉ P ) (ngõ cụt) thì quay lại
bước xác định si-1
Bản chất
Một quy trình tìm kiếm theo chiều
sâu
Ví dụ tìm số có 3 chữ số đầu tiên
D = {1,2, 3}
P:
(2,1,3) – chấp nhận
(2,2,3) – không chấp nhận
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
5.3. Phương pháp quay lui
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 38
Phương pháp
Giả sử có: s1s i-1
Tìm giá trị cho s i:
Duyệt ∀ j ∈ 𝐷 đề cử cho si
Mỗ𝑖 j ∈ 𝐷 kiểm tra:
Nếu j chấp nhận (∈ P ), si = j
Nếu i = n (∈ Q ) , được 1
cấu hình,
Nếu i< 𝑛, tìm s i +1.
Nếu ∀ j không được cấp nhận
(∉ P ) (ngõ cụt) thì quay lại
bước xác định si-1
Mã giả
void try (i, n){
∀j ∈ Di{
if (){
si = j;
if (i==n)
else try (i+1, n);
}
}
}
Bắt đầu
S1
s2
s3
s4
D1 ( 2pt)
D2 (2pt)
D3 (2pt)
D4 ( 3pt)
Một cấu
hình
5.3. phương pháp quay lui
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 39
5.2. Phương pháp quay lui
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 40
Ví dụ
Liệt kê dãy nhị phân có độ dài n.
Liệt kê hoán vị tập n phần tử.
Bài toán Xếp Hậu.
5.3. Phương pháp quay lui
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 41
Ví dụ 1
Liệt kê xâu nhị phân độ dài n
Biểu diễn dãy nhị phân:
b = ( b1 b2... bn ,)
bi ∈ {0,1}
Try(i,) - xác định bi
D = {0,1}
P
i = n - được 1 cấu hình ∈ 𝑄
Mã giả
void Try(int i, char b[]){
char j;
for(j='0'; j<='1';j++){
//P – bỏ qua kiêm tra
b[i]=j;
if(i==n) Out(b);
else Try(i+1,b);
}
}
5.3. Phương pháp quay lui
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 42
Mã giả
void Try(int i, char b[]){
char j;
for(j='0'; j<='1';j++){
//P – bỏ qua kiêm tra
b[i]=j;
if(i==n) Out(b);
else Try(i+1,b);
}
}
Bit 1 2 3 4
0 0 0 0 0000
1 0001
1 0 0010
1 0011
1 0 0 0100
1 0101
1 0 0110
1 0111
1 0 0 0 1000
1 1001
1 0 1010
1 1011
1 0 0 1100
1 1101
1 0 1110
1 1111
T
ry
(1
,b
)
5.3. Phương pháp quay lui
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 43
5.2. Phương pháp quay lui
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 44
Kết quả
Result
Chương trình
Source Code
Ví dụ 1
Liệt kê xâu nhị phân độ dài n
5.3. Phương pháp quay lui
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 45
Ví dụ 2
Liệt kê các hoán vị của tập
X = {1,2,,n}.
Biểu diễn hoán vị dạng
s1 s2 ... sn
si ∈ X , sp ≠ sq , p ≠ q.
Try(i,) - xác định si
D = {0,1,,n}
Chấp nhận j ∈ 𝐷 nếu j chưa
được chọn.
Ví dụ 2
Sử dụng mảng b
b = { b[1], b[2],, b[n]}
b[j] =
1 , 𝑗 𝑐ℎư𝑎 𝑐ℎọ𝑛
0 , 𝑗 đã đượ𝑐 𝑐ℎọ𝑛
Khởi tạo b[j] = 1, ∀𝑗 ∈ 𝑋
i = n - được 1 cấu hình ∈ 𝑄
5.3. Phương pháp quay lui
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 46
Ví dụ 2
Liệt kê các hoán vị của tập
X = {1,2,,n}.
Biểu diễn hoán vị dạng
s1 s2 ... sn
si ∈ X , sp ≠ sq , p ≠ q.
Try(i,) - xác định si
Mã giả
void Try(int i,int b[],int s[]){
int j;
for(j=1;j<=n;j++){
if(b[j]==1){
s[i]=j;
b[j]=0;
if(i==n) Out(s);
else Try(i+1,b,s);
b[j]=1;
} }
}
5.3. Phương pháp quay lui
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 47
5.3. Phương pháp quay lui
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 48
5.2. Phương pháp sinh
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 49
Kết quả
Result
Chương trình
Source Code
Ví dụ 2
Liệt kê hoán vị của tập n phần tử
5.3. Phương pháp quay lui
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 50
Ví dụ 3
Liệt kê tất cả các cách xếp 8
quân Hậu trên bàn cờ 8x8 sao
cho chúng không ăn được
nhau.
Ví dụ 3
Đánh số cột từ 1.. 8
Đánh số hàng từ 1.. 8
Biểu diễn cách xếp:
x1 x2 x8
xi được xếp ở hàng i
D = {1,,8}
xi= j : Hậu thứ i được
xếp vào cột j
j được chấp nhận nếu ô
(i,j) được tự do
5.3. Phương pháp quay lui
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 51
Ví dụ 3
ô (i,j) được tự do
Quản lý cột
Quản lý đường chéo thuận
Quản lý đường chéo
nghịch
Ví dụ 3
Mảng a – quản lý cột
a = { a[1], , a[8]}
a[j] =
1 , 𝑐ộ𝑡 𝑗 𝑡ự 𝑑𝑜
0 , 𝑐ộ𝑡 𝑗 đã 𝑐ℎ𝑖ế𝑢
5.3. Phương pháp quay lui
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 52
Ví dụ 3:
Quản lý đường chéo thuận
Ví dụ 3
Mảng b – quản lý đường
chéo thuận
b = { b[2], ,b[16]}
b[k]=
1 , đ𝑐 𝑐ℎ𝑢ậ𝑛 𝑘 𝑡ự 𝑑𝑜
0 , đ𝑐 𝑡ℎ𝑢ậ𝑛 𝑘 đã 𝑐ℎ𝑖ế𝑢
5.3. Phương pháp quay lui
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 53
Ví dụ 3:
Quản lý đường chéo nghịch
Ví dụ 3
Mảng c – quản lý đường
chéo nghịch
c = { c[-7], ,b[7]}
c[k]=
1 , đ𝑐 𝑛𝑔ℎị𝑐ℎ 𝑘 𝑡ự 𝑑𝑜
0 , đ𝑐 𝑛𝑔ℎị𝑐ℎ 𝑘 đã 𝑐ℎ𝑖ế𝑢
5.3. Phương pháp quay lui
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 54
Ví dụ 3:
Ví dụ 3
Khởi tạo:
∀ 𝑖, 𝑘
aj =1&& bk=1&& ck =1
j được chấp nhận khi
aj ==1&& bi+j==1
&& ci-j ==1
Try (i,.. ) – tìm cột đặt con
hậu ở hang i
X1
X2
X3
X4
X5
X6
X7
X8
1 2 3 4 5 6 7 8
5.3. Phương pháp quay lui
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 55
5.3. Phương pháp quay lui
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 56
5.3. Phương pháp quay lui
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 57
5.2. Phương pháp quay lui
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 58
Kết quả
Result
Chương trình
Source Code
x = (3 6 4 2 8 5 7 1)
Ví dụ 3
Liệt kê cách xếp hậu
Tóm lại
Kỹ thuật sinh:
(1) Xác định trạng thái đầu của bài toán.
(2) Xác định trạng thái kết thúc.
(3) Xác định một thứ tự cho các trạng thái.
(4) Tìm giải thuật đi từ trạng thái này sang trạng thái khác.
Kỹ thuật quay lui:
(1) Tại 1 thời điểm, chỉ xét thành phần thứ i của cấu hình
(2) Với mọi trị j trong miền trị của thành phần này
2.1- Nếu chọn được 1 trị hợp lệ thì
Gán xi = j
Xử lý cấu hình ở thành phần thứ i+1
Nếu i=0 thì bài toán không có lời giải.
Nguyễn Văn Hiệu, 2012, Discrete Mathematics
59
Bài Tập
1. Liệt kê nghiệm nguyên của pt x1 + x2 + x3 =
15 với x1 ≥ 0 , x2 ≥ 0 , x3 ≥ 0.
2. Liệt kê số chuổi có độ dài 3 ký tự xyz với
x ∈ { a,b,c}, y ∈ { d,e}, z ∈ { m,n,t}
3. Viết lại các bài mẫu về giải thuật quay lui
nhưng ghi kết qủa lên file.
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 60
Bài Tập
x y z
a d m
a d n
a d t
a e m
a e n
a e t
b d m
b d n
b d t
b e m
b e n
b e t
c d m
c d n
c d t
c e m
c e n
c e t
Cấu hình ban đầu: trị đầu tiên
của mỗi miền trị
Cấu hình cuối: trị cuối cùng của
mỗi miền trị
Cách sinh:Lấy trị kế tiếp của mỗi
miền trị theo cơ chế vòng tròn
Dùng thứ tự
từ điển để so
sánh:
adm < adn
Nguyễn Văn Hiệu, 2012, Discrete Mathematics 61
• WHAT NEXT?
LÝ THUYẾT ĐỒ THỊ
THAT’S ALL; THANK YOU
Các file đính kèm theo tài liệu này:
- 5_bai_toan_liet_ke_3692.pdf