Bài toán lit kê
Lê Minh Hoàng
{ 1z
MC LC
§
0. GI
I THIU
...................................................................................................................................... 2
§
1. NH
C LI MT S KIN THC I S T HP
....................................................................... 3
I. CH
NH HP LP
...........................................................................................................................................3
II. CH
NH HP KHÔNG LP
...........................................................................................................................3
III. HOÁN V
......................................................................................................................................................3
IV. T
HP
.........................................................................................................................................................3
§
2. PH
NG PHÁP SINH (GENERATE)
............................................................................................ 5
I. SINH CÁC DÃY NH
PHÂN DÀI N
.......................................................................................................6
II. LI
T KÊ CÁC TP CON K PHN T
........................................................................................................7
III. LI
T KÊ CÁC HOÁN V
.............................................................................................................................9
§
3. THU
T TOÁN QUAY LUI
............................................................................................................. 12
I. LI
T KÊ CÁC DÃY NH PHÂN DÀI N
...............................................................................................13
II. LI
T KÊ CÁC TP CON K PHN T
......................................................................................................14
III. LI
T KÊ CÁC CHNH HP KHÔNG LP CHP K
..............................................................................15
IV. BÀI TOÁN PHÂN TÍCH S
.....................................................................................................................16
V. BÀI TOÁN X
P HU
.................................................................................................................................18
§
4. K
THUT NHÁNH CN
.............................................................................................................. 22
I. BÀI TOÁN T
I U
......................................................................................................................................22
II. S
BÙNG N T HP
...............................................................................................................................22
III. MÔ HÌNH K
THUT NHÁNH CN
.....................................................................................................22
IV. BÀI TOÁN NG
I DU LCH
...................................................................................................................23
V. DÃY ABC ....................................................................................................................................................25
Bài toán lit kê
Lê Minh Hoàng
{ 2z
§
0. GII THIU
Trong thc t, có mt s bài toán yêu cu ch rõ: trong mt tp các đi tng cho trc có bao
nhiêu đi tng tho mãn nhng điu kin nht đnh. Bài toán đó gi là bài toán đm cu hình t
hp.
Trong lp các bài toán đm, có nhng bài toán còn yêu cu ch rõ nhng cu hình tìm đc tho
mãn điu kin đã cho là nhng cu hình nào. Bài toán yêu cu đa ra danh sách các cu hình có th
có gi là bài toán lit kê t hp.
gii bài toán lit kê, cn phi xác đnh đc mt thut toán đ có th theo đó ln lt xây dng
đc tt c các cu hình đang quan tâm. Có nhiu phng pháp lit kê, nhng chúng cn phi đáp
ng đc hai yêu cu di đây:
• Không đc lp li mt cu hình
• Không đc b sót mt cu hình
Có th nói rng, phng pháp lit kê là phng k cui cùng đ gii đc mt s bài toán t hp
hin nay. Khó khn chính ca phng pháp này chính là s bùng n t hp. xây dng 1 t cu
hình (con s này không phi là ln đi vi các bài toán t hp - Ví d lit kê các cách xp n≥13
ngi quanh mt bàn tròn) và gi thit rng mi thao tác xây dng mt khong 1 giây, ta phi mt
quãng 31 nm mi gii xong. Tuy nhiên cùng vi s phát trin ca máy tính đin t, bng phng
pháp lit kê, nhiu bài toán t hp đã tìm thy li gii. Qua đó, ta cng nên bit rng ch nên dùng
phng pháp lit kê khi không còn mt phng pháp nào khác tìm ra li gii. Chính nhng n
lc gii quyt các bài toán thc t không dùng phng pháp lit kê đã thúc đy s phát trin ca
nhiu ngành toán hc.
Cui cùng, nhng tên gi sau đây, tuy v ngha không phi đng nht, nhng trong mt s trng
hp ngi ta có th dùng ln ngha ca nhau đc. ó là:
• Phng pháp lit kê
• Phng pháp vét cn trên tp phng án
• Phng pháp duyt toàn b
Bài toán lit kê
Lê Minh Hoàng
{ 3z
§
1. NHC LI MT S KIN THC I S T HP
Cho S là mt tp hu hn gm n phn t và k là mt s t nhiên.
Gi X là tp các s nguyên dng t 1 đn k: X = {1, 2, ..., k}
I. CHNH HP LP
Mi ánh x f: X → S. Cho tng ng vi mi i ∈ X, mt và ch mt phn t f(i) ∈ S.
c gi là mt chnh hp lp chp k ca S.
Nhng do X là tp hu hn (k phn t) nên ánh x f có th xác đnh qua bng các giá tr f(1), f(2),
..., f(k).
Ví d: S = {A, B, C, D, E, F}; k = 3. Mt ánh x f có th cho nh sau:
i 123
f(i) E C E
Nên ngi ta đng nht f vi dãy giá tr (f(1), f(2), ..., f(k)) và coi dãy giá tr này cng là mt
chnh hp lp chp k ca S. Nh ví d trên (E, C, E) là mt chnh hp lp chp 3 ca S. D dàng
chng minh đc kt qu sau bng quy np hoc bng phng pháp đánh giá kh nng la chn:
S chnh hp lp chp k ca tp gm n phn t:
k
k
n
nA =
II. CHNH HP KHÔNG LP
Khi f là đn ánh có ngha là vi ∀i, j ∈ X ta có f(i) = f(j) ⇔ i = j. Nói mt cách d hiu, khi dãy giá
tr f(1), f(2), ..., f(k) gm các phn t thuc S khác nhau đôi mt thì f đc gi là mt chnh hp
không lp chp k ca S. Ví d mt chnh hp không lp (C, A, E):
i 123
f(i) C A E
S chnh hp không lp chp k ca tp gm n phn t:
)!kn(
!n
)1kn)...(2n)(1n(nA
k
n
−
=+−−−=
III. HOÁN V
Khi k = n. Mt chnh hp không lp chp n ca S đc gi là mt hoán v các phn t ca S.
Ví d: mt hoán v: (A, D, C, E, B, F) ca S = {A, B, C, D, E, F}
i123456
f(i) A D C E B F
ý rng khi k = n thì s phn t ca tp X = {1, 2, .., n} đúng bng s phn t ca S. Do tính cht
đôi mt khác nhau nên dãy f(1), f(2), ..., f(n) s lit kê đc ht các phn t trong S. Nh vy f là
toàn ánh. Mt khác do gi thit f là chnh hp không lp nên f là đn ánh. Ta có tng ng 1-1 gia
các phn t ca X và S, do đó f là song ánh. Vy nên ta có th đnh ngha mt hoán v ca S là mt
song ánh gia {1, 2, ..., n} và S.
S hoán v ca tp gm n phn t = s chnh hp không lp chp n:
!nP
n
=
IV. T HP
Mt tp con gm k phn t ca S đc gi là mt t hp chp k ca S.
Bài toán lit kê
Lê Minh Hoàng
{ 4z
Ly mt tp con k phn t ca S, xét tt c k! hoán v ca tp con này. D thy rng các hoán v đó
là các chnh hp không lp chp k ca S. Ví d ly tp {A, B, C} là tp con ca tp S trong ví d
trên thì: (A, B, C), (C, A, B), (B, C, A), ... là các chnh hp không lp chp 3 ca S. iu đó tc là
khi lit kê tt c các chnh hp không lp chp k thì mi t hp chp k s đc tính k! ln. Vy:
S t hp chp k ca tp gm n phn t:
)!kn(!k
!n
!k
A
C
k
n
k
n
−
==
S tp con ca tp n phn t:
nnn
n
1
n
0
n
2)11(C...CC
=+=+++
Bài toán lit kê
Lê Minh Hoàng
{ 5z
§
2. PHNG PHÁP SINH (GENERATE)
Phng pháp sinh có th áp dng đ gii bài toán lit kê t hp đt ra nu nh hai điu kin sau
tho mãn:
1. Có th xác đnh đc mt th t trên tp các cu hình t hp cn lit kê. T đó có th xác
đnh đc cu hình đu tiên và cu hình cui cùng trong th t đã xác đnh
2. Xây dng đc thut toán t cu hình cha phi cu hình cui, sinh ra đc cu hình k
tip nó.
Phng pháp sinh có th mô t nh sau:
<Xây dng cu hình đu tiên>;
repeat
<a ra cu hình đang có>;
<T cu hình đang có sinh ra cu hình k tip nu còn>;
until <ht cu hình>;
Th t t đin
Trên các kiu d liu đn gin chun, ngi ta thng nói ti khái nim th t. Ví d trên kiu s
thì có quan h: 1 < 2; 2 < 3; 3 < 10; ..., trên kiu ký t Char thì cng có quan h 'A' < 'B'; 'C' < 'c'...
Xét quan h th t toàn phn "nh hn hoc bng" ký hiu "≤" trên mt tp hp S, là quan h hai
ngôi tho mãn bn tính cht:
Vi ∀a, b, c ∈ S
• Tính ph bin: Hoc là a ≤ b, hoc b ≤ a;
• Tính phn x: a ≤ a
• Tính phn đi xng: Nu a ≤ b và b ≤ a thì bt buc a = b.
• Tính bc cu: Nu có a ≤ b và b ≤ c thì a ≤ c.
Trong trng hp a ≤ b và a ≠ b, ta dùng ký hiu "<" cho gn, (ta ngm hiu các ký hiu nh ≥, >,
khi phi đnh ngha)
Ví d nh quan h "≤" trên các s nguyên cng nh trên các kiu vô hng, lit kê là quan h th t
toàn phn.
Trên các dãy hu hn, ngi ta cng xác đnh mt quan h th t:
Xét a = (a
1
, a
2
, ..., a
n
) và b = (b
1
, b
2
, ..., b
n
); trên các phn t ca a
1
, ..., a
n
, b
1
, ..., b
n
đã có quan h
th t "≤". Khi đó a ≤ b nu nh
• Hoc a
i
= b
i
vi ∀i: 1 ≤ i ≤ n.
• Hoc tn ti mt s nguyên dng k: 1 ≤ k < n đ:
a
1
= b
1
a
2
= b
2
...
a
k-1
= b
k-1
a
k
= b
k
a
k+1
< b
k+1
Trong trng hp này, ta có th vit a < b.
Th t đó gi là th t t đin trên các dãy đ dài n.
Khi đ dài hai dãy a và b không bng nhau, ngi ta cng xác đnh đc th t t đin. Bng cách
thêm vào cui dãy a hoc dãy b nhng phn t đc bit gi là phn t ∅ đ đ dài ca a và b bng
Bài toán lit kê
Lê Minh Hoàng
{ 6z
nhau, và coi nhng phn t ∅ này nh hn tt c các phn t khác, ta li đa v xác đnh th t t
đin ca hai dãy cùng đ dài. Ví d:
• (1, 2, 3, 4) < (5, 6)
• (a, b, c) < (a, b, c, d)
• 'calculator' < 'computer'
I. SINH CÁC DÃY NH PHÂN Đ DÀI N
Mt dãy nh phân đ dài n là mt dãy x = x
1
x
2
...x
n
trong đó x
i
∈ {0, 1} (∀i : 1 ≤ i ≤ n).
D thy: mt dãy nh phân x đ dài n là biu din nh phân ca mt giá tr nguyên p(x) nào đó nm
trong đon [0, 2
n
- 1]. S các dãy nh phân đ dài n = s các s nguyên ∈ [0, 2
n
- 1] = 2
n
. Ta s lp
chng trình lit kê các dãy nh phân theo th t t đin có ngha là s lit kê ln lt các dãy nh
phân biu din các s nguyên theo th t 0, 1,..., 2
n
-1.
Ví d: Khi n = 3, các dãy nh phân đ dài 3 đc lit kê nh sau:
p(x)01234567
x 000 001 010 011 100 101 110 111
Nh vy dãy đu tiên s là 00...0 và dãy cui cùng s là 11...1. Nhn xét rng nu dãy x = (x
1
, x
2
, ...,
x
n
) là dãy đang có và không phi dãy cui cùng thì dãy k tip s nhn đc bng cách cng thêm 1
( theo c s 2 có nh) vào dãy hin ti.
Ví d khi n = 8:
Dãy đang có:
10010000 Dãy đang có: 10010111
cng thêm 1: + 1 cng thêm 1: + 1
Dãy mi: 10010001 Dãy mi: 10011000
Nh vy k thut sinh cu hình k tip t cu hình hin ti có th mô t nh sau: Xét t cui
dãy v đu (xét t hàng đn v lên), gp s 0 đu tiên thì thay nó bng s 1 và đt tt c các phn
t phía sau v trí đó bng 0.
i := n;
while (i > 0) and (x
i
= 1) do i := i - 1;
if i > 0 then
begin
x
i
:= 1;
for j := i + 1 to n do x
j
:= 0;
end;
D liu vào (Input): nhp t file vn bn BSTR.INP cha s nguyên dng n ≤ 30
Kt qu ra(Output): ghi ra file vn bn BSTR.OUT các dãy nh phân đ dài n.
BSTR.INP BSTR.OUT
3 000
001
010
011
100
101
110
111
PROG02_1.PAS * Thut toán sinh lit kê các dãy nh phân đ dài n
program Binary_Strings;
const
max = 30;
Bài toán lit kê
Lê Minh Hoàng
{ 7z
var
x: array[1..max] of Integer;
n, i: Integer;
begin
{nh ngha li thit b nhp/xut chun}
Assign(Input, 'BSTR.INP'); Reset(Input);
Assign(Output, 'BSTR.OUT'); Rewrite(Output);
ReadLn(n);
FillChar(x, SizeOf(x), 0);
{C
u hình ban đu x
1
= x
2
= ... = x
n
:= 0}
repeat
{Thu
t toán sinh}
for i := 1 to n do Write(x[i]);
{In ra c
u hình hin ti}
WriteLn;
i := n;
{x
i
là ph
n t cui dãy, lùi dn i cho ti khi gp s 0 hoc khi i = 0 thì dng}
while (i > 0) and (x[i] = 1) do Dec(i);
if i > 0 then
{Ch
a gp phi cu hình 11...1}
begin
x[i] := 1;
{Thay x
i
b
ng s 1}
FillChar(x[i + 1], (n - i) * SizeOf(x[1]), 0); {t x
i + 1
= x
i + 2
= ... = x
n
:= 0}
end;
until i = 0; {ã ht cu hình}
{óng thit b nhp xut chun, thc ra không cn vì BP s t đng đóng Input và Output trc khi thoát chng trình}
Close(Input); Close(Output);
end.
II. LIT KÊ CÁC TP CON K PHN T
Ta s lp chng trình lit kê các tp con k phn t ca tp {1, 2, ..., n} theo th t t đin
Ví d: vi n = 5, k = 3, ta phi lit kê đ 10 tp con:
1.{1, 2, 3} 2.{1, 2, 4} 3.{1, 2, 5} 4.{1, 3, 4} 5.{1, 3, 5}
6.{1, 4, 5} 7.{2, 3, 4} 8.{2, 3, 5} 9.{2, 4, 5} 10.{3, 4, 5}
Nh vy tp con đu tiên (cu hình khi to) là {1, 2, ..., k}.
Cu hình kt thúc là {n - k + 1, n - k + 2, ..., n}.
Nhn xét: Ta s in ra tp con bng cách in ra ln lt các phn t ca nó theo th t tng dn. T
đó, ta có nhn xét nu x = {x
1
, x
2
, ..., x
k
} và x
1
< x
2
< ... < x
k
thì gii hn trên (giá tr ln nht có
th nhn) ca x
k
là n, ca x
k-1
là n - 1, ca x
k-2
là n - 2...
C th: gii hn trên ca x
i
= n - k + i;
Còn tt nhiên, gii hn di ca x
i
(giá tr nh nht x
i
có th nhn) là x
i-1
+ 1.
Nh vy nu ta đang có mt dãy x đi din cho mt tp con, nu x là cu hình kt thúc có ngha là
tt c các phn t trong x đu đã đt ti gii hn trên thì quá trình sinh kt thúc, nu không thì ta
phi sinh ra mt dãy x mi tng dn tho mãn va đ ln hn dãy c theo ngha không có mt tp
con k phn t nào chen gia chúng khi sp th t t đin.
Ví d: n = 9, k = 6. Cu hình đang có x = {1, 2, 6, 7, 8, 9}. Các phn t x
3
đn x
6
đã đt ti gii
hn trên nên đ sinh cu hình mi ta không th sinh bng cách tng mt phn t trong s các x
6
, x
5
,
x
4
, x
3
lên đc, ta phi tng x
2
= 2 lên thành x
2
= 3. c cu hình mi là x = {1, 3, 6, 7, 8, 9}. Cu
hình này đã tho mãn ln hn cu hình trc nhng cha tho mãn tính cht va đ ln mun vy
ta li thay x
3
, x
4
, x
5
, x
6
bng các gii hn di ca nó. Tc là:
• x
3
:= x
2
+ 1 = 4
• x
4
:= x
3
+ 1 = 5
• x
5
:= x
4
+ 1 = 6
• x
6
:= x
5
+ 1 = 7
Ta đc cu hình mi x = {1, 3, 4, 5, 6, 7} là cu hình k tip. Nu mun tìm tip, ta li nhn thy
rng x
6
= 7 cha đt gii hn trên, nh vy ch cn tng x
6
lên 1 là đc x = {1, 3, 4, 5, 6, 8}.
Vy k thut sinh tp con k tip t tp đã có x có th xây dng nh sau:
Bài toán lit kê
Lê Minh Hoàng
{ 8z
• Tìm t cui dãy lên đu cho ti khi gp mt phn t x
i
cha đt gii hn trên n - k + i.
i := n;
while (i > 0) and (x
i
= n - k + i) do i := i - 1;
(1, 2, 6, 7, 8, 9);
• Nu tìm thy:
if i > 0 then
♦ Tng x
i
đó lên 1.
x
i
:= x
i
+ 1;
(1, 3, 6, 7, 8, 9)
♦ t tt c các phn t phía sau x
i
bng gii hn di:
for j := i + 1 to k do x
j
:= x
j-1
+ 1;
(1, 3, 4, 5, 6, 7)
Input: file vn bn SUBSET.INP cha hai s nguyên dng n, k (1 ≤ k ≤ n ≤ 30) cách nhau ít nht
mt du cách
Output: file vn bn SUBSET.OUT các tp con k phn t ca tp {1, 2, ..., n}
SUBSET.INP SUBSET.OUT
5 3 {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}
PROG02_2.PAS * Thut toán sinh lit kê các tp con k phn t
program Combinations;
const
max = 30;
var
x: array[1..max] of Integer;
n, k, i, j: Integer;
begin
{nh ngha li thit b nhp/xut chun}
Assign(Input, 'SUBSET.INP'); Reset(Input);
Assign(Output, 'SUBSET.OUT'); Rewrite(Output);
ReadLn(n, k);
for i := 1 to k do x[i] := i;
{x
1
:= 1; x
2
:= 2; ... ; x
3
:= k (C
u hình khi to)}
Count := 0;
{Bi
n đm}
――repeat
{In ra c
u hình hin ti}
Write('{');
for i := 1 to k - 1 do Write(x[i], ', ');
WriteLn(x[k], '}');
{Sinh ti
p}
i := k;
{x
i
là ph
n t cui dãy, lùi dn i cho ti khi gp mt x
i
ch
a đt gii hn trên n - k + i}
while (i > 0) and (x[i] = n - k + i) do Dec(i);
if i > 0 then―
{N
u cha lùi đn 0 có ngha là cha phi cu hình kt thúc}
―― begin
Inc(x[i]); {Tng x
i
lên 1,
t các phn t đng sau x
i
b
ng gii hn di ca nó}
for j := i + 1 to k do x[j] := x[j - 1] + 1;
end;
until i = 0;
{Lùi
đn tn 0 có ngha là tt c các phn t đã đt gii hn trên - ht cu hình}
Close(Input); Close(Output);
end.
Bài toán lit kê
Lê Minh Hoàng
{ 9z
III. LIT KÊ CÁC HOÁN V
Ta s lp chng trình lit kê các hoán v ca {1, 2, ..., n} theo th t t đin.
Ví d vi n = 4, ta phi lit kê đ 24 hoán v:
1.1234 2.1243 3.1324 4.1342 5.1423 6.1432
7.2134 8.2143 9.2314 10.2341 11.2413 12.2431
13.3124 14.3142 15.3214 16.3241 17.3412 18.3421
19.4123 20.4132 21.4213 22.4231 23.4312 24.4321
Nh vy hoán v đu tiên s là (1, 2, ..., n). Hoán v cui cùng là (n, n-1, ... , 1).
Hoán v s sinh ra phi ln hn hoán v hin ti, hn th na phi là hoán v va đ ln hn hoán v
hin ti theo ngha không th có mt hoán v nào khác chen gia chúng khi sp th t.
Gi s hoán v hin ti là x = (3, 2, 6, 5, 4, 1), xét 4 phn t cui cùng, ta thy chúng đc xp gim
dn, điu đó có ngha là cho dù ta có hoán v 4 phn t này th nào, ta cng đc mt hoán v bé
hn hoán v hin ti!. Nh vy ta phi xét đn x
2
= 2, thay nó bng mt giá tr khác. Ta s thay bng
giá tr nào?, không th là 1 bi nu vy s đc hoán v nh hn, không th là 3 vì đã có x
1
= 3 ri
(phn t sau không đc chn vào nhng giá tr mà phn t trc đã chn). Còn li các giá tr 4, 5,
6. Vì cn mt hoán v va đ ln hn hin ti nên ta chn x
2
= 4. Còn các giá tr (x
3
, x
4
, x
5
, x
6
) s
ly trong tp {2, 6, 5, 1}. Cng vì tính va đ ln nên ta s tìm biu din nh nht ca 4 s này gán
cho x
3
, x
4
, x
5
, x
6
tc là (1, 2, 5, 6). Vy hoán v mi s là (3, 4, 1, 2, 5, 6).
(3, 2, 6, 5, 4, 1) → (3, 4, 1, 2, 5, 6).
Ta có nhn xét gì qua ví d này: on cui ca hoán v đc xp gim dn, s x
5
= 4 là s nh nht
trong đon cui gim dn tho mãn điu kin ln hn x
2
= 2. Nu đi ch x
5
cho x
2
thì ta s đc x
2
= 4 và đon cui vn đc sp xp gim dn. Khi đó mun biu din nh nht cho các giá tr
trong đon cui thì ta ch cn đo ngc đon cui.
Trong trng hp hoán v hin ti là (2, 1, 3, 4) thì hoán v k tip s là (2, 1, 4, 3). Ta cng có th
coi hoán v (2, 1, 3, 4) có đon cui gim dn, đon cui này ch gm 1 phn t (4)
Vy k thut sinh hoán v k tip t hoán v hin ti có th xây dng nh sau:
• Xác đnh đon cui gim dn dài nht, tìm ch s i ca phn t x
i
đng lin trc đon cui đó.
iu này đng ngha vi vic tìm t v trí sát cui dãy lên đu, gp ch s i đu tiên tha mãn x
i
< x
i+1
. Nu toàn dãy đã là gim dn, thì đó là cu hình cui.
i := n - 1;
while (i > 0) and (x
i
> x
i+1
) do i := i - 1;
• Trong đon cui gim dn, tìm phn t x
k
nh nht tho mãn điu kin x
k
> x
i
. Do đon cui
gim dn, điu này thc hin bng cách tìm t cui dãy lên đu gp ch s k đu tiên tho mãn
x
k
> x
i
(có th dùng tìm kim nh phân).
k := n;
while x
k
< x
i
do k := k - 1;
• i ch x
k
và x
i
, lt ngc th t đon cui gim dn (t x
i+1
đn x
k
) tr thành tng dn.
Input: file vn bn PERMUTE.INP cha s nguyên dng n ≤ 12
Output: file vn bn PERMUTE.OUT các hoán v ca dãy (1, 2, ..., n)
PERMUTE.INP PERMUTE.OUT
3 1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
Bài toán lit kê
Lê Minh Hoàng
{ 10z
PROG02_3.PAS * Thut toán sinh lit kê hoán v
program Permute;
const
max = 12;
var
n, i, k, a, b: Integer;
x: array[1..max] of Integer;
procedure Swap(var X, Y: Integer);
{Th
tc đo giá tr hai tham bin X, Y}
var
Temp: Integer;
begin
Temp := X; X := Y; Y := Temp;
end;
begin
Assign(Input, 'PERMUTE.INP'); Reset(Input);
Assign(Output, 'PERMUTE.OUT'); Rewrite(Output);
ReadLn(n);
for i := 1 to n do x[i] := i;―
{Kh
i to cu hình đu: x
1
:= 1; x
2
:= 2; ..., x
n
:= n}
――repeat
――――for i := 1 to n do Write(x[i], ' ');
{In ra c
u hình hoán v hin ti}
WriteLn;
i := n - 1;
while (i > 0) and (x[i] > x[i + 1]) do Dec(i);
if i > 0 then
{Ch
a gp phi hoán v cui (n, n-1, ... ,1)}
――――――begin
k := n;
{x
k
là ph
n t cui dãy}
―――― while x[k] < x[i] do Dec(k);―
{Lùi d
n k đ tìm gp x
k
đu tiên ln hn x
i
}
Swap(x[k], x[i]); {i ch x
k
và x
i
}
―――――― a := i + 1; b := n;
{L
t ngc đon cui gim dn, a: đu đon, b: cui đon}
―― while a < b do
begin
Swap(x[a], x[b]); {i ch x
a
và x
b
}
Inc(a);
{Ti
n a và lùi b, đi ch tip cho ti khi a, b chm nhau}
Dec(b);
end;
end;
until i = 0;―
{Toàn dãy là dãy gi
m dn - không sinh tip đc - ht cu hình}
Close(Input); Close(Output);
end.
Bài tp:
1. Các chng trình trên x lý không tt trong trng hp tm thng, đó là trng hp n = 0 đi
vi chng trình lit kê dãy nh phân cng nh trong chng trình lit kê hoán v, trng hp k = 0
đi vi chng trình lit kê t hp, hãy khc phc điu đó.
2. Lit kê các dãy nh phân đ dài n có th coi là lit kê các chnh hp lp chp n ca tp 2 phn t
{0, 1}. Hãy lp chng trình:
Nhp vào hai s n và k, lit kê các chnh hp lp chp k ca {0, 1, ..., n -1}.
Gi ý: thay h c s 2 bng h c s n.
3. Hãy lit kê các dãy nh phân đ dài n mà trong đó cm ch s "01" xut hin đúng 2 ln.
Bài tp:
4. Nhp vào mt danh sách n tên ngi. Lit kê tt c các cách chn ra đúng k ngi trong s n
ngi đó.
Gi ý: xây dng mt ánh x t tp {1, 2, ..., n} đn tp các tên ngi. Ví d xây dng mt mng
Tên: Tên[1] := 'Nguyn vn A'; Tên[2] := 'Trn th B';.... sau đó lit kê tt c các tp con k phn t
Bài toán lit kê
Lê Minh Hoàng
{ 11z
ca tp {1, 2, ..., n}. Ch có điu khi in tp con, ta không in giá tr s {1, 3, 5} mà thay vào đó s in
ra {Tên[1], Tên [3], Tên[5]}. Tc là in ra nh ca các giá tr tìm đc qua ánh x
5. Lit kê tt c các tp con ca tp {1, 2, ..., n}. Có th dùng phng pháp lit kê tp con nh trên
hoc dùng phng pháp lit kê tt c các dãy nh phân. Mi s 1 trong dãy nh phân tng ng vi
mt phn t đc chn trong tp. Ví d vi tp {1, 2, 3, 4} thì dãy nh phân 1010 s tng ng vi
tp con {1, 3}. Hãy lp chng trình in ra tt c các tp con ca {1, 2, ..., n} theo hai phng pháp.
5. Nhp vào danh sách tên n ngi, in ra tt c các cách xp n ngi đó vào mt bàn
6. Nhp vào danh sách n ngi nam và n ngi n, in ra tt c các cách xp 2n ngi đó vào mt
bàn tròn, mi ngi nam tip đn mt ngi n.
7. Ngi ta có th dùng phng pháp sinh đ lit kê các chnh hp không lp chp k. Tuy nhiên có
mt cách là lit kê tt c các tp con k phn t ca tp hp, sau đó in ra đ k! hoán v ca nó. Hãy
vit chng trình lit kê các chnh hp không lp chp k ca {1, 2, ..., n}.
8. Lit kê tt c các hoán v ch cái trong t MISSISSIPPI theo th t t đin.
9. Lit kê tt c các cách phân tích s nguyên dng n thành tng các s nguyên dng, hai cách
phân tích là hoán v ca nhau ch tính là mt cách.
Cui cùng, ta có nhn xét, mi phng pháp lit kê đu có u, nhc đim riêng và phng pháp
sinh cng không nm ngoài nhn xét đó. Phng pháp sinh không th sinh ra đc cu hình th
p nu nh cha có cu hình th p - 1, chng t rng phng pháp sinh t ra u đim trong trng
hp lit kê toàn b mt s lng nh cu hình trong mt b d liu ln thì li có nhc đim và
ít tính ph dng trong nhng thut toán duyt hn ch. Hn th na, không phi cu hình ban đu
lúc nào cng d tìm đc, không phi k thut sinh cu hình k tip cho mi bài toán đu đn gin
nh trên (Sinh các chnh hp không lp chp k theo th t t đin chng hn). Ta sang mt chuyên
mc sau nói đn mt phng pháp lit kê có tính ph dng cao hn, đ gii các bài toán lit kê
phc tp hn đó là: Thut toán quay lui (Back tracking).
Bài toán lit kê
Lê Minh Hoàng
{ 12z
§
3. THUT TOÁN QUAY LUI
Thut toán quay lui dùng đ gii bài toán lit kê các cu hình. Mi cu hình đc xây dng
bng cách xây dng tng phn t, mi phn t đc chn bng cách th tt c các kh nng.
Gi thit cu hình cn lit kê có dng (x
1
, x
2
,..., x
n
). Khi đó thut toán quay lui thc hin qua các
bc sau:
1) Xét tt c các giá tr x
1
có th nhn, th cho x
1
nhn ln lt các giá tr đó. Vi mi giá tr th
gán cho x
1
ta s:
2) Xét tt c các giá tr x
2
có th nhn, li th cho x
2
nhn ln lt các giá tr đó. Vi mi giá tr
th gán cho x
2
li xét tip các kh nng chn x
3
... c tip tc nh vy đn bc:
n) Xét tt c các giá tr x
n
có th nhn, th cho x
n
nhn ln lt các giá tr đó, thông báo cu hình
tìm đc (x
1
, x
2
, ..., x
n
).
Trên phng din quy np, có th nói rng thut toán quay lui lit kê các cu hình n phn t dng
(x
1
, x
2
, .., x
n
) bng cách th cho x
1
nhn ln lt các giá tr có th. Vi mi giá tr th gán cho x
1
li
lit kê tip cu hình n - 1 phn t (x
2
, x
3
, ..., x
n
).
Mô hình ca thut toán quay lui có th mô t nh sau:
{Th
tc này th cho x
i
nh
n ln lt các giá tr mà nó có th nhn}
procedure Try(i: Integer);
begin
for (mi giá tr V có th gán cho x
i
) do
begin
<Th cho x
i
:= V>;
if (x
i
là phn t cui cùng trong cu hình) then
<Thông báo cu hình tìm đc>
else
begin
<Ghi nhn vic cho x
i
nhn giá tr V (Nu cn)>;
Try(i + 1);
{G
i đ quy đ chn tip x
i+1
}
―― <Nu cn, b ghi nhn vic th x
i
:= V, đ th giá tr khác>;
end;
end;
end;
Thut toán quay lui s bt đu bng li gi Try(1)
Ta có th trình bày quá trình tìm kim li gii ca thut toán quay lui bng cây sau:
Try(2)
Try(3) Try(3) Try(3) Try(3)
Try(2)
Try(1)
Hình 1: Cây tìm kim quay lui
Bài toán lit kê
Lê Minh Hoàng
{ 13z
I. LIT KÊ CÁC DÃY NH PHÂN Đ DÀI N
Input/Output vi khuôn dng nh trong PROG2_1.PAS
Biu din dãy nh phân đ dài N di dng (x
1
, x
2
, ..., x
n
). Ta s lit kê các dãy này bng cách th
dùng các giá tr {0, 1} gán cho x
i
. Vi mi giá tr th gán cho x
i
li th các giá tr có th gán cho
x
i+1
.Chng trình lit kê bng thut toán quay lui có th vit:
PROG03_1.PAS * Thut toán quay lui lit kê các dãy nh phân đ dài n
program BinaryStrings;
const
max = 30;
var
x: array[1..max] of Integer;
n: Integer;
procedure PrintResult;
{In c
u hình tìm đc, do th tc tìm đ quy
Try g
i khi tìm ra mt cu hì nh}
var
i: Integer;
begin
for i := 1 to n do Write(x[i]);
WriteLn;
end;
procedure Try(i: Integer);
{Th
các cách chn x
i
}
var
j: Integer;
begin
for j := 0 to 1 do
{Xét các giá tr
có th gán cho x
i
, v
i mi giá tr đó}
――――begin
x[i] := j;
{Th
đt x
i
}
if i = n then PrintResult
{N
u i = n thì in kt qu}
―――― else Try(i + 1);
{N
u i cha phi là phn t cui thì tìm tip x
i+1
}
end;
end;
begin
Assign(Input, 'BSTR.INP'); Reset(Input);
Assign(Output, 'BSTR.OUT'); Rewrite(Output);
ReadLn(n);
{Nh
p d liu}
Try(1);
{Th
các cách chn giá tr x
1
}
Close(Input);
Close(Output);
end.
Ví d: Khi n = 3, cây tìm kim quay lui nh sau:
Try(3)
Try(2)
Try(3) Try(3) Try(3)
Try(2)
Try(1)
x
1
:= 0
x
1
:= 1
x
2
:= 0
x
2
:= 1
x
2
:= 0
x
2
:= 1
x
3
:= 0
x
3
:= 1
x
3
:= 0
x
3
:= 1
x
3
:= 0
x
3
:= 1
x
3
:= 0
x
3
:= 1
000
001
010
011
100
101
110
111
result
Hình 2: Cây tìm kim quay lui trong bài toán lit kê dãy nh phân
Bài toán lit kê
Lê Minh Hoàng
{ 14z
II. LIT KÊ CÁC TP CON K PHN T
Input/Output có khuôn dng nh trong PROG02_2.PAS
lit kê các tp con k phn t ca tp S = {1, 2, ..., n} ta có th đa v lit kê các cu hình (x
1
, x
2
,
..., x
k
) đây các x
i
∈ S và x
1
< x
2
< ... < x
k
. Ta có nhn xét:
• x
k
≤ n
• x
k-1
≤ x
k
- 1 ≤ n - 1
• ...
• x
i
≤ n - k + i
• ...
• x
1
≤ n - k + 1.
T đó suy ra x
i-1
+ 1 ≤ x
i
≤ n - k + i (1 ≤ i ≤ k) đây ta gi thit có thêm mt s x
0
= 0 khi xét i = 1.
Nh vy ta s xét tt c các cách chn x
1
t 1 (=x
0
+ 1) đn n - k + 1, vi mi giá tr đó, xét tip tt
c các cách chn x
2
t x
1
+ 1 đn n - k + 2,... c nh vy khi chn đc đn x
k
thì ta có mt cu
hình cn lit kê. Chng trình lit kê bng thut toán quay lui nh sau:
PROG03_2.PAS * Thut toán quay lui lit kê các tp con k phn t
program Combinations;
const
max = 30;
var
x: array[0..max] of Integer;
n, k: Integer;
procedure PrintResult;
(*In ra t
p con {x
1
, x
2
, ..., x
k
}*)
var
i: Integer;
begin
Write('{');
for i := 1 to k - 1 do Write(x[i], ', ');
WriteLn(x[k], '}');
end;
procedure Try(i: Integer);
{Th
các cách chn giá tr cho x[i]}
var
j: Integer;
begin
for j := x[i - 1] + 1 to n - k + i do
begin
x[i] := j;
if i = k then PrintResult
else Try(i + 1);
end;
end;
begin
Assign(Input, 'SUBSET.INP'); Reset(Input);
Assign(Output, 'SUBSET.OUT'); Rewrite(Output);
ReadLn(n, k);
x[0] := 0;
Try(1);
Close(Input); Close(Output);
end.
Bài toán lit kê
Lê Minh Hoàng
{ 15z
Nu đ ý chng trình trên và chng trình lit kê dãy nh phân đ dài n, ta thy v c bn chúng
ch khác nhau th tc Try(i) - chn th các giá tr cho x
i
, chng trình lit kê dãy nh phân ta
th chn các giá tr 0 hoc 1 còn chng trình lit kê các tp con k phn t ta th chn x
i
là mt
trong các giá tr nguyên t x
i-1
+ 1 đn n - k + i. Qua đó ta có th thy tính ph dng ca thut toán
quay lui: mô hình cài đt có th thích hp cho nhiu bài toán, khác vi phng pháp sinh tun t,
vi mi bài toán li phi có mt thut toán sinh k tip riêng làm cho vic cài đt mi bài mt khác,
bên cnh đó, không phi thut toán sinh k tip nào cng d cài đt.
III. LIT KÊ CÁC CHNH HP KHÔNG LP CHP K
lit kê các chnh hp không lp chp k ca tp S = {1, 2, ..., n} ta có th đa v lit kê các cu
hình (x
1
, x
2
, ..., x
k
) đây các x
i
∈ S và khác nhau đôi mt.
Nh vy th tc Try(i) - xét tt c các kh nng chn x
i
- s th ht các giá tr t 1 đn n, mà các giá
tr này cha b các phn t đng trc chn. Mun xem các giá tr nào cha đc chn ta s dng
k thut dùng mng đánh du:
• Khi to mt mng c
1
, c
2
, ..., c
n
mang kiu logic. đây c
i
cho bit giá tr i có còn t do hay đã
b chn ri. Ban đu khi to tt c các phn t mng c là TRUE có ngha là các phn t t 1
đn n đu t do.
• Ti bc chn các giá tr có th ca x
i
ta ch xét nhng giá tr j có c
j
= TRUE có ngha là ch
chn nhng giá tr t do.
• Trc khi gi đ quy tìm x
i+1
: ta đt giá tr j va gán cho x
i
là đã b chn có ngha là đt c
j
:=
FALSE đ các th tc Try(i + 1), Try(i + 2)... gi sau này không chn phi giá tr j đó na
• Sau khi gi đ quy tìm x
i+1
: có ngha là sp ti ta s th gán mt giá tr khác cho x
i
thì ta s đt
giá tr j va th đó thành t do (c
j
:= TRUE), bi khi x
i
đã nhn mt giá tr khác ri thì các phn
t đng sau: x
i+1
, x
i+2
... hoàn toàn có th nhn li giá tr j đó. iu này hoàn toàn hp lý trong
phép xây dng chnh hp không lp: x
1
có n cách chn, x
2
có n - 1 cách chn, ...Lu ý rng khi
th tc Try(i) có i = k thì ta không cn phi đánh du gì c vì tip theo ch có in kt qu ch
không cn phi chn thêm phn t nào na.
Input: file vn bn ARRANGES.INP cha hai s nguyên dng n, k (1 ≤ k ≤ n ≤ 20) cách nhau ít
nht mt du cách
Output: file vn bn ARRANGES.OUT ghi các chnh hp không lp chp k ca tp {1, 2, ..., n}
ARRANGES.INP ARRANGES.OUT
3 2 1 2
1 3
2 1
2 3
3 1
3 2
PROG03_3.PAS * Thut toán quay lui lit kê các chnh hp không lp chp k
program Arranges;
const
max = 20;
var
x: array[1..max] of Integer;
c: array[1..max] of Boolean;
n, k: Integer;
procedure PrintResult;
{Th
tc in cu hình tìm đc}
Bài toán lit kê
Lê Minh Hoàng
{ 16z
var
i: Integer;
begin
for i := 1 to k do Write(x[i],' ');
WriteLn;
end;
procedure Try(i: Integer);
{Th
các cách chn x
i
}
var
j: Integer;
begin
for j := 1 to n do
if c[j] then
{Ch
xét nhng giá tr j còn t do}
begin
x[i] := j;
if i = k then PrintResult
{N
u đã chn đc đn xk thì ch vic in kt qu}
―― else
begin
c[j] := False; {ánh du: j đã b chn}
―――――――― Try(i + 1);
{Th
tc này ch xét nhng giá tr còn t do gán cho x
i+1
, t
c là s không chn phi j}
―― c[j] := True;
{B
đánh du: j li là t do, bi sp ti s th mt cách chn khác ca x
i
}
―――――――― end;
end;
end;
begin
Assign(Input, 'ARRANGES.INP'); Reset(Input);
Assign(Output, 'ARRANGES.OUT'); Rewrite(Output);
ReadLn(n, k);
FillChar(c, SizeOf(c), True);
{T
t c các s đu cha b chn}
Try(1);
{Th
các cách chn giá tr ca x
1
}
Close(Input); Close(Output);
end.
Nhn xét: khi k = n thì đây là chng trình lit kê hoán v
IV. BÀI TOÁN PHÂN TÍCH S
Bài toán
Cho mt s nguyên dng n ≤ 30, hãy tìm tt c các cách phân tích s n thành tng ca các s
nguyên dng, các cách phân tích là hoán v ca nhau ch tính là 1 cách.
Cách làm:
1. Ta s lu nghim trong mng x, ngoài ra có mt mng t. Mng t xây dng nh sau: t
i
s là tng
các phn t trong mng x t x
1
đn x
i
: t
i
:= x
1
+ x
2
+ ... + x
i
.
2. Khi lit kê các dãy x có tng các phn t đúng bng n, đ tránh s trùng lp ta đa thêm ràng
buc x
i-1
≤ x
i
.
3. Vì s phn t thc s ca mng x là không c đnh nên th tc PrintResult dùng đ in ra 1 cách
phân tích phi có thêm tham s cho bit s in ra bao nhiêu phn t.
4. Th tc đ quy Try(i) s th các giá tr có th nhn ca x
i
(x
i
≥ x
i - 1
)
5. Khi nào thì in kt qu và khi nào thì gi đ quy tìm tip ?
Lu ý rng t
i - 1
là tng ca tt c các phn t t x
1
đn x
i-1
do đó
• Khi t
i
= n tc là (x
i
= n - t
i - 1
) thì in kt qu
• Khi tìm tip, x
i+1
s phi ln hn hoc bng x
i
. Mt khác t
i+1
là tng ca các s t x
1
ti x
i+1
không đc vt quá n. Vy ta có t
i+1
≤ n ⇔ t
i-1
+ x
i
+ x
i+1
≤ n ⇔ x
i
+ x
i + 1
≤ n - t
i - 1
tc là x
i
Bài toán lit kê
Lê Minh Hoàng
{ 17z
≤ (n - t
i - 1
)/2. Ví d đn gin khi n = 10 thì chn x
1
= 6, 7, 8, 9 là vic làm vô ngha vì nh
vy cng không ra nghim mà cng không chn tip x
2
đc na.
Mt cách d hiu ta gi đ quy tìm tip khi giá tr x
i
đc chn còn cho phép chn thêm mt
phn t khác ln hn hoc bng nó mà không làm tng vt quá n. Còn ta in kt qu ch khi
x
i
mang giá tr đúng bng s thiu ht ca tng i-1 phn t đu so vi n.
6. Vy th tc Try(i) th các giá tr cho x
i
có th mô t nh sau: (đ tng quát cho i = 1, ta đt x
0
=
1 và t
0
= 0).
• Xét các giá tr ca x
i
t x
i - 1
đn (n - t
i-1
) div 2, cp nht t
i
:= t
i - 1
+ x
i
và gi đ quy tìm tip.
• Cui cùng xét giá tr x
i
= n - t
i-1
và in kt qu t x
1
đn x
i
.
Input: file vn bn ANALYSE.INP cha s nguyên dng n ≤ 30
Output: file vn bn ANALYSE.OUT ghi các cách phân tích s n.
ANALYSE.INP ANALYSE.OUT
6 6 = 1+1+1+1+1+1
6 = 1+1+1+1+2
6 = 1+1+1+3
6 = 1+1+2+2
6 = 1+1+4
6 = 1+2+3
6 = 1+5
6 = 2+2+2
6 = 2+4
6 = 3+3
6 = 6
PROG03_4.PAS * Thut toán quay lui lit kê các cách phân tích s
program Analyses;
const
max = 30;
var
n: Integer;
x: array[0..max] of Integer;
t: array[0..max] of Integer;
procedure Init;
{Kh
i to}
begin
ReadLn(n);
x[0] := 1;
t[0] := 0;
end;
procedure PrintResult(k: Integer);
var
i: Integer;
begin
Write(n,' = ');
for i := 1 to k - 1 do Write(x[i], '+');
WriteLn(x[k]);
end;
procedure Try(i: Integer);
var
j: Integer;
begin
for j := x[i - 1] to (n - T[i - 1]) div 2 do
{Tr
ng hp còn chn tip x
i+1
}
begin
x[i] := j;
Bài toán lit kê
Lê Minh Hoàng
{ 18z
t[i] := t[i - 1] + j;
Try(i + 1);
end;
x[i] := n - T[i - 1];
{N
u x
i
là ph
n t cui thì nó bt buc phi là ... và in kt qu}
PrintResult(i);
end;
begin
Assign(Input, 'ANALYSE.INP'); Reset(Input);
Assign(Output, 'ANALYSE.OUT'); Rewrite(Output);
Init;
Try(1);
Close(Input);
Close(Output);
end.
Bây gi ta xét tip mt ví d kinh đin ca thut toán quay lui:
V. BÀI TOÁN XP HU
Bài toán
Xét bàn c tng quát kích thc nxn. Mt quân hu trên bàn c có th n đc các quân khác nm
ti các ô cùng hàng, cùng ct hoc cùng đng chéo. Hãy tìm các xp n quân hu trên bàn c sao
cho không quân nào n quân nào.
Ví d mt cách xp vi n = 8:
Hình 3: Xp 8 quân hu trên bàn c 8x8
Phân tích
• Rõ ràng n quân hu s đc đt mi con mt hàng vì hu n đc ngang, ta gi quân hu s đt
hàng 1 là quân hu 1, quân hu hàng 2 là quân hu 2... quân hu hàng n là quân hu n.
Vy mt nghim ca bài toán s đc bit khi ta tìm ra đc v trí ct ca nhng quân hu.
• Nu ta đnh hng ông (Phi), Tây (Trái), Nam (Di), Bc (Trên) thì ta nhn thy rng:
♦ Mt đng chéo theo hng ông Bc - Tây Nam (B-TN) bt k s đi qua mt s ô, các ô
đó có tính cht: Hàng + Ct = C (Const). Vi mi đng chéo B-TN ta có 1 hng s C và
vi mt hng s C: 2 ≤ C ≤ 2n xác đnh duy nht 1 đng chéo B-TN vì vy ta có th đánh
ch s cho các đng chéo B- TN t 2 đn 2n
♦ Mt đng chéo theo hng ông Nam - Tây Bc (N-TB) bt k s đi qua mt s ô, các ô
đó có tính cht: Hàng - Ct = C (Const). Vi mi đng chéo N-TB ta có 1 hng s C và
vi mt hng s C: 1 - n ≤ C ≤ n - 1 xác đnh duy nht 1 đng chéo N-TB vì vy ta có th
đánh ch s cho các đng chéo N- TB t 1 - n đn n - 1.
Bài toán lit kê
Lê Minh Hoàng
{ 19z
12345678
1
2
3
4
5
6
7
N
S
EW
8
Hình 4: ng chéo B-TN mang ch s 10 và đng chéo N-TB mang ch s 0, ô chung (5, 5)
Cài đt:
1. Ta có 3 mng logic đ đánh du:
•
Mng a[1..n]. a
i
= TRUE nu nh ct i còn t do, a
i
= FALSE nu nh ct i đã b mt quân hu
khng ch
• Mng b[2..2n]. b
i
= TRUE nu nh đng chéo B-TN th i còn t do, b
i
= FALSE nu nh
đng chéo đó đã b mt quân hu khng ch.
• Mng c[1 - n..n - 1]. c
i
= TRUE nu nh đng chéo N-TB th i còn t do, c
i
= FALSE nu
nh đng chéo đó đã b mt quân hu khng ch.
• Ban đu c 3 mng đánh du đu mang giá tr TRUE. (Các ct và đng chéo đu t do)
2. Thut toán quay lui: Xét tt c các ct, th đt quân hu 1 vào mt ct, vi mi cách đt nh vy,
xét tt c các cách đt quân hu 2 không b quân hu 1 n, li th 1 cách đt và xét tip các cách đt
quân hu 3...Mi cách đt đc đn quân hu n cho ta 1 nghim
3. Khi chn v trí ct j cho quân hu th i, thì ta phi chn ô(i, j) không b các quân hu đt trc đó
n, tc là phi chn ct j còn t do, đng chéo B-TN (i+j) còn t do, đng chéo N-TB(i-j)
còn t do. iu này có th kim tra (a
j
= b
i+j
= c
i-j
= TRUE)
4. Khi th đt đc quân hu th i vào ct j, nu đó là quân hu cui cùng (i = n) thì ta có mt
nghim. Nu không:
• Trc khi gi đ quy tìm cách đt quân hu th i + 1, ta đánh du ct và 2 đng chéo b quân
hu va đt khng ch (a
j
= b
i+j
= c
i-j
:= FALSE) đ các ln gi đ quy tip sau chn cách đt
các quân hu k tip s không chn vào nhng ô nm trên ct j và nhng đng chéo này na.
•
Sau khi gi đ quy tìm cách đt quân hu th i + 1, có ngha là sp ti ta li th mt cách đt
khác cho quân hu th i, ta b đánh du ct và 2 đng chéo b quân hu va th đt khng ch
(a
j
= b
i+j
= c
i-j
:= TRUE) tc là ct và 2 đng chéo đó li thành t do, bi khi đã đt quân hu i
sang v trí khác ri thì ct và 2 đng chéo đó hoàn toàn có th gán cho mt quân hu khác
Hãy xem li trong các chng trình lit kê chnh hp không lp và hoán v v k thut đánh du.
đây ch khác vi lit kê hoán v là: lit kê hoán v ch cn mt mng đánh du xem giá tr có t do
không, còn bài toán xp hu thì cn phi đánh du c 3 thành phn: Ct, đng chéo B-TN,
đng chéo N- TB. Trng hp đn gin hn: Yêu cu lit kê các cách đt n quân xe lên bàn c
nxn sao cho không quân nào n quân nào chính là bài toán lit kê hoán v
Input: file vn bn QUEENS.INP cha s nguyên dng n ≤ 12
Output: file vn bn QUEENS.OUT, mi dòng ghi mt cách đt n quân hu
Bài toán lit kê
Lê Minh Hoàng
{ 20z
QUEENS.INP QUEENS.OUT
5 (1, 1); (2, 3); (3, 5); (4, 2); (5, 4);
(1, 1); (2, 4); (3, 2); (4, 5); (5, 3);
(1, 2); (2, 4); (3, 1); (4, 3); (5, 5);
(1, 2); (2, 5); (3, 3); (4, 1); (5, 4);
(1, 3); (2, 1); (3, 4); (4, 2); (5, 5);
(1, 3); (2, 5); (3, 2); (4, 4); (5, 1);
(1, 4); (2, 1); (3, 3); (4, 5); (5, 2);
(1, 4); (2, 2); (3, 5); (4, 3); (5, 1);
(1, 5); (2, 2); (3, 4); (4, 1); (5, 3);
(1, 5); (2, 3); (3, 1); (4, 4); (5, 2);
PROG03_5.PAS * Thut toán quay lui gii bài toán xp hu
program n_Queens;
const
max = 12;
var
n: Integer;
x: array[1..max] of Integer;
a: array[1..max] of Boolean;
b: array[2..2 * max] of Boolean;
c: array[1 - max..max - 1] of Boolean;
procedure Init;
begin
ReadLn(n);
FillChar(a, SizeOf(a), True);
{M
i ct đu t do}
FillChar(b, SizeOf(b), True);
{M
i đng chéo ông Bc - Tây Nam đu t do}
――FillChar(c, SizeOf(c), True);
{M
i đng chéo ông Nam - Tây Bc đu t do}
end;
procedure PrintResult;
var
i: Integer;
begin
for i := 1 to n do Write('(', i, ', ', x[i], '); ');
WriteLn;
end;
procedure Try(i: Integer);
{Th
các cách đt quân hu th i vào hàng i}
var
j: Integer;
begin
for j := 1 to n do
if a[j] and b[i + j] and c[i - j] then
{Ch
xét nhng ct j mà ô (i, j)
ch
a
b
khng ch}
――――――begin
x[i] := j;
{Th
đt quân hu i vào ct j}
――――――――if i = n then PrintResult
else
begin
a[j] := False; b[i + j] := False; c[i - j] := False; {ánh du}
―― Try(i + 1);
{Tìm các cách
đt quân hu th i + 1}
―――――― a[j] := True; b[i + j] := True; c[i - j] := True;
{B
đánh du}
―――― end;
end;
end;
begin
Assign(Input, 'QUEENS.INP'); Reset(Input);
Assign(Output, 'QUEENS.OUT'); Rewrite(Output);
Init;
Bài toán lit kê
Lê Minh Hoàng
{ 21z
Try(1);
Close(Input); Close(Output);
end.
Tên gi thut toán quay lui, đng trên phng din cài đt có th nên gi là k thut vét cn bng
quay lui thì chính xác hn, tuy nhiên đng trên phng din bài toán, nu nh ta coi công vic gii
bài toán bng cách xét tt c các kh nng cng là 1 cách gii thì tên gi Thut toán quay lui cng
không có gì trái logic. Xét hot đng ca chng trình trên cây tìm kim quay lui ta thy ti bc
th chn x
i
nó s gi đ quy đ tìm tip x
i+1
có ngha là quá trình s duyt tin sâu xung phía di
đn tn nút lá, sau khi đã duyt ht các nhánh, tin trình lùi li th áp đt mt giá tr khác cho x
i
, đó
chính là ngun gc ca tên gi "thut toán quay lui"
Bài tp:
1. Mt s chng trình trên x lý không tt trong trng hp tm thng (n = 0 hoc k = 0), hãy
khc phc các li đó
2. Vit chng trình lit kê các chnh hp lp chp k ca n phn t
3. Cho hai s nguyên dng l, n. Hãy lit kê các xâu nh phân đ dài n có tính cht, bt k hai xâu
con nào đ dài l lin nhau đu khác nhau.
4. Vi n = 5, k = 3, v cây tìm kim quay lui ca chng trình lit kê t hp chp k ca tp {1, 2, ...,
n}
5. Lit kê tt c các tp con ca tp S gm n s nguyên {S
1
, S
2
, ..., S
n
} nhp vào t bàn phím
6. Tng t nh bài 5 nhng ch lit kê các tp con có max - min ≤ T (T cho trc).
7. Mt dãy (x
1
, x
2
, ..., x
n
) gi là mt hoán v hoàn toàn ca tp {1, 2,..., n} nu nó là mt hoán v và
tho mãn x
i
≠ i vi ∀i: 1 ≤ i ≤ n. Hãy vit chng trình lit kê tt c các hoán v hoàn toàn ca tp
trên (n vào t bàn phím).
8. Sa li th tc in kt qu (PrintResult) trong bài xp hu đ có th v hình bàn c và các cách đt
hu ra màn hình.
9. Bài toán mã đi tun: Cho bàn c tng quát kích thc nxn và mt quân Mã, hãy ch ra mt hành
trình ca quân Mã xut phát t ô đang đng đi qua tt c các ô còn li ca bàn c, mi ô đúng 1 ln.
10. Chuyn tt c các bài tp trong bài trc đang vit bng sinh tun t sang quay lui.
11. Xét s đ giao thông gm n nút giao thông đánh s t 1 ti n và m đon đng ni chúng, mi
đon đng ni 2 nút giao thông. Hãy nhp d liu v mng li giao thông đó, nhp s hiu hai
nút giao thông s và d. Hãy in ra tt c các cách đi t s ti d mà mi cách đi không đc qua nút giao
thông nào quá mt ln.
Bài toán lit kê
Lê Minh Hoàng
{ 22z
§
4. K THUT NHÁNH CN
I. BÀI TOÁN TI U
Mt trong nhng bài toán đt ra trong thc t là vic tìm ra mt nghim tho mãn mt s điu kin
nào đó, và nghim đó là tt nht theo mt ch tiêu c th, nghiên cu li gii các lp bài toán ti u
thuc v lnh vc quy hoch toán hc. Tuy nhiên cng cn phi nói rng trong nhiu trng hp
chúng ta cha th xây dng mt thut toán nào thc s hu hiu đ gii bài toán, mà cho ti nay
vic tìm nghim ca chúng vn phi da trên mô hình lit kê toàn b các cu hình có th và đánh
giá, tìm ra cu hình tt nht. Vic lit kê cu hình có th cài đt bng các phng pháp lit kê: Sinh
tun t và tìm kim quay lui. Di đây ta s tìm hiu phng pháp lit kê bng thut toán quay lui
đ tìm nghim ca bài toán ti u.
II. S BÙNG N T HP
Mô hình thut toán quay lui là tìm kim trên 1 cây phân cp. Nu gi thit rng ng vi mi nút
tng ng vi mt giá tr đc chn cho x
i
s ng vi ch 2 nút tng ng vi 2 giá tr mà x
i+1
có
th nhn thì cây n cp s có ti 2
n
nút lá, con s này ln hn rt nhiu ln so vi d liu đu vào n.
Chính vì vy mà nu nh ta có thao tác tha trong vic chn x
i
thì s phi tr giá rt ln v chi phí
thc thi thut toán bi quá trình tìm kim lòng vòng vô ngha trong các bc chn k tip x
i+1
, x
i+2
,
... Khi đó, mt vn đ đt ra là trong quá trình lit kê li gii ta cn tn dng nhng thông tin đã tìm
đc đ loi b sm nhng phng án chc chn không phi ti u. K thut đó gi là k thut
đánh giá nhánh cn trong tin trình quay lui.
III. MÔ HÌNH K THUT NHÁNH CN
Da trên mô hình thut toán quay lui, ta xây dng mô hình sau:
procedure Init;
begin
<Khi to mt cu hình bt k BESTCONFIG>;
end;
{Th tc này th chn cho x
i
tt c các giá tr nó có th nhn}
procedure Try(i: Integer);
begin
for (Mi giá tr V có th gán cho x
i
) do
begin
<Th cho x
i
:= V>;
if (Vic th trên vn còn hi vng tìm ra cu hình tt hn BESTCONFIG) then
if (x
i
là phn t cui cùng trong cu hình) then
<Cp nht BESTCONFIG>
else
begin
<Ghi nhn vic th x
i
= V nu cn>;
Try(i + 1);
{G
i đ quy, chn tip x
i+1
}
<B ghi nhn vic th cho x
i
= V (nu cn)>;
end;
end;
end;
begin
Init;
Try(1);
<Thông báo cu hình ti u BESTCONFIG>
end.
Bài toán lit kê
Lê Minh Hoàng
{ 23z
K thut nhánh cn thêm vào cho thut toán quay lui kh nng đánh giá theo tng bc, nu ti
bc th i, giá tr th gán cho x
i
không có hi vng tìm thy cu hình tt hn cu hình
BESTCONFIG thì th giá tr khác ngay mà không cn phi gi đ quy tìm tip hay ghi nhn kt
qu làm gì. Nghim ca bài toán s đc làm tt dn, bi khi tìm ra mt cu hình mi (tt hn
BESTCONFIG - tt nhiên), ta không in kt qu ngay mà s cp nht BESTCONFIG bng cu hình
mi va tìm đc
IV. BÀI TOÁN NGI DU LCH
Bài toán
Cho n thành ph đánh s t 1 đn n và m tuyn đng giao thông hai chiu gia chúng, mng li
giao thông này đc cho bi bng C cp nxn, đây C
ij
= C
ji
= Chi phí đi đon đng trc tip t
thành ph i đn thành ph j. Gi thit rng C
ii
= 0 vi ∀i, C
ij
= +∞ nu không có đng trc tip t
thành ph i đn thành ph j.
Mt ngi du lch xut phát t thành ph 1, mun đi thm tt c các thành ph còn li mi thành
ph đúng 1 ln và cui cùng quay li thành ph 1. Hãy ch ra cho ngi đó hành trình vi chi phí ít
nht. Bài toán đó gi là bài toán ngi du lch hay bài toán hành trình ca mt thng gia
(Traveling Salesman)
Cách gii
1) Hành trình cn tìm có dng (x
1
= 1, x
2
, ..., x
n
, x
n+1
= 1) đây gia x
i
và x
i+1
: hai thành ph liên
tip trong hành trình phi có đng đi trc tip (C
ij
≠ +∞) và ngoi tr thành ph 1, không thành
ph nào đc lp li hai ln. Có ngha là dãy (x
1
, x
2
, ..., x
n
) lp thành 1 hoán v ca (1, 2, ..., n).
2) Duyt quay lui: x
2
có th chn mt trong các thành ph mà x
1
có đng đi ti (trc tip), vi
mi cách th chn x
2
nh vy thì x
3
có th chn mt trong các thành ph mà x
2
có đng đi ti
(ngoài x
1
). Tng quát: x
i
có th chn 1 trong các thành ph cha đi qua mà t x
i-1
có đng đi
trc tip ti.(1 ≤
i ≤ n)
3) Nhánh cn: Khi to cu hình BestConfig có chi phí = +∞. Vi mi bc th chn x
i
xem chi
phí đng đi cho ti lúc đó có < Chi phí ca cu hình BestConfig?, nu không nh hn thì th
giá tr khác ngay bi có đi tip cng ch tn thêm. Khi th đc mt giá tr x
n
ta kim tra xem x
n
có đng đi trc tip v 1 không ? Nu có đánh giá chi phí đi t thành ph 1 đn thành ph x
n
cng vi chi phí t x
n
đi trc tip v 1, nu nh hn chi phí ca đng đi BestConfig thì cp
nht li BestConfig bng cách đi mi.
4) Sau th tc tìm kim quay lui mà chi phí ca BestConfig vn bng +∞ thì có ngha là nó không
tìm thy mt hành trình nào tho mãn điu kin đ bài đ cp nht BestConfig, bài toán không
có li gii, còn nu chi phí ca BestConfig < +∞ thì in ra cu hình BestConfig - đó là hành trình
ít tn kém nht tìm đc
Input: file vn bn TOURISM.INP
• Dòng 1: Cha s thành ph n (1 ≤ n ≤ 20) và s tuyn đng m trong mng li giao thông
• m dòng tip theo, mi dòng ghi s hiu hai thành ph có đng đi trc tip và chi phí đi trên
quãng đng đó (chi phí này là s nguyên dng ≤ 100)
Output: file vn bn TOURISM.OUT
Ghi hành trình tìm đc.