CATEGORII DOCUMENTE |
Bulgara | Ceha slovaca | Croata | Engleza | Estona | Finlandeza | Franceza |
Germana | Italiana | Letona | Lituaniana | Maghiara | Olandeza | Poloneza |
Sarba | Slovena | Spaniola | Suedeza | Turca | Ucraineana |
DOCUMENTE SIMILARE |
|
iame paragrafe aptarsime pagrindinius kombinatorinių objektų (derinių, kėlinių, aibės iskaidymo ir kt.) generavimo algoritmus.
Optimali tokių objektų generavimo algoritmo struktūra yra:
begin
generuoti pradinį junginį (kombinatorinį objekt¹);
while generavimo s¹lyga do
begin
nagrinėti (spausdinti) junginį (kombinatorinį objekt¹);
generuoti junginį (kombinatorinį objekt¹), gretim¹ inagrinėtam (atspausdintam).
end
end
Priklausomai nuo pasirinktų objektų bei jų generavimo tvarkos, iame algoritme turi būti konkretizuoti sakiniai generuoti pradinį junginį, generavimo s¹lyga, generuoti gretim¹ junginį.
Pirmiausia aptersime derinių generavimo leksikografine didėjimo tvarka algoritm¹. Apie leksikografinź vektorių tvark¹ kalbėjome 1.3 paragrafe. Čia priminsime, kad jei į derinį iūrėsime kaip į skaičių, tai deriniams atitinkantys skaičiai bus idėstyti didėjimo tvarka.
Pavyzdys. Panagrinėkime . Deriniai, surayti leksikografine tvarka, bus:
Derinius nuosekliai talpinsime masyve ir io masyvo elementai apibrė derinį.
Pradinio derinio generavimas. Aiku, kad pradinis derinys generuojamas taip:
for l 0 to k do c [l] := l;
Kaip generuoti patį maiausi¹ leksikografikai didesnį derinį nei turimas?
Tarkime, turimas derinys. Leksikografine tvarka pats didiausias derinys yra: . Vadinasi, , . todėl, norint apskaičiuoti patį maiausi¹ leksikografikai didesnį derinį nei nagrinėjamas derinys, elgsimės taip:
masyve rasime pirm¹ i deinės element¹ cl, , tenkinantį s¹lyg¹ ;
į element¹ padidinsime vienetu, t.y. ;
likusius elementus upildysime i eilės einančiais natūraliaisiais skaičiais, t.y.
for i l + 1 to k do ci: = ci-1 + 1;
Generavimo pabaigos s¹lyga. Jei pirmasis i deinės elementas, tenkinantis s¹lyg¹ , yra , tai reikia, kad nagrinėjame derinį: . Vadinasi, jau visi deriniai sugeneruoti.
Tuo būdu, derinių generavimo leksikografine tvarka algoritmas yra.
Duota: n objektų skaičius,
k objektų skaičius derinyje.
Rasti: generuoti derinius leksikografine tvarka.
begin
for l := 0 to k do c [l] := l;
p := true;
while p do
begin
spausdinti derinį
l := k;
while (l >= 1) and c [l] >= n k + l do l := l 1;
if l = 0 then p := false
else begin
c [l] := c [l] + 1;
for i := l + 1 to k do c [i] := c [i 1] + 1;
end
end
end
Kaip matyti i antrojo Grėjaus kodo generavimo algoritmo (r. 1.3 paragraf¹), Grėjaus kodus galima generuoti i pradinio kodo, inant sek¹ . ios sekos elementas ymi skiltį, kuri¹ reikia invertuoti, kad i -ojo kodo gautume i-¹jį kod¹.
Pavyzdiui, kai , seka T3 yra tokia: .
Vadinasi, pakanka mokėti efektyviai generuoti sek¹ Tn, kad galėtume generuoti Grėjaus kodus.
Sek¹ Tn galima efektyviai generuoti naudojant stek¹.
Pradioje stekas upildomas elementais: (viruje yra elementas 1). Algoritmas ima virutinį steko element¹ i ir patalpina jį į sek¹ Tn; po to į stek¹ įraomi elementai . Būtent tokiu būdu emiau pateiktas algoritmas generuoja Grėjaus kodus.
begin
s
for j := n downto 1 do begin
g [j] := 0;
s j
end
while s ¹ Æ do
begin
spausdinti
i s
g [i] := 1 g [i];
for j := i 1 downto 1 do s j
end
end
end
Skaičiuojant pagal į algoritm¹, steko turinys (virutinis elementas yra steko virūnėje) kis taip: , o i reikmės sudarys T3 sek¹ .
Pateikt¹ algoritm¹ galima patobulinti. Kiekvien¹ kart¹, kai į stek¹ patalpinamas elementas , mes apriori inome, kad vir jo bus patalpinti elementai . Protingas ios informacijos panaudojimas įgalina vietoj steko naudoti masyv¹ tokiu būdu. Elementas yra virutinis steko elementas ir kiekvienam yra elementas, steke esantis tuoj po elemento j (emiau elemento j), jei j yra steke. Jei elemento j steke nėra, tai elemento reikmė negali turėti jokios įtakos skaičiavimams ir todėl priskiriame reikmź , kadangi mes inome, kad kai kit¹ kart¹ elementas bus patalpintas į stek¹, elementu, esančiu vir jo, bus elementas j. Dar daugiau, kadangi elementai bus talpinami į stek¹ paalinus element¹ i, mums reikia tiktai priskirti , laikant, kad visiems j, , reikmė buvo priskirta, kai j buvo paalintas i steko (primename, tada ). Pagaliau, kai , elementai į stek¹ patalpinami operacijos dėka.
Dabar gausime tokį algoritm¹.
begin
for j := 0 to n + 1 do begin
g [j] := 0;
t [j] := j + 1;
end
i
while i < n + 1 do
begin
spausdinti
i t
g [i] := 1 g [i];
t [i 1] := t [i];
t [i] := i + 1;
if i ¹ 1 then t
end
end
Kai , masyvo t turinys skaičiavimo eigoje kis taip:
Pateikt¹jį
algoritm¹ galima truputį patobulinti. Pastebėsim, jei operatorių
patalpintume po operatoriaus g [i] :=
1 g [i], tai
operatorių if i ¹ 1 then t[0]:=1 galima imesti. I tikro, jei , tai
operatorius
t [i
1] := t [i] tuoj pat itaisys neteising¹ t [0]
reikmź. Tuo būdu galutinis Grėjaus kodų generavimo algoritmas
bus toks.
begin
for j := 0 to n + 1 do begin
g [j] := 0;
t [j] := j + 1;
end
i
while i < n + 1 do
begin
spausdinti
i t
g [i] := 1 g [i];
t t [i 1] := t [i]; t [i] := i + 1;
end
end
Aptarkome derinių generavimo minimlaus pokyčio tvarka algoritm¹. Minimlaus pokyčio tvarka tai tokia derinių seka, kai bet koks ios sekos derinys yra gaunamas i prie jį stovinčio derinio, pakeitus jame vien¹ element¹ kitu.
Pavyzdys. Panagrinėkime . Deriniai, surayti minimalaus pokyčio tvarka, bus tokie:
Nesunku pastebėti, kad bet koks ios sekos derinys, iskyrus pirm¹jį, yra gaunamas i prie jį stovinčio derinio, pakeitus vien¹ element¹ kitu.
Jei pirmajame derinyje element¹ 2 pakeisime elementu 4, tai gausime antr¹jį derinį. Jei jame element¹ 1 pakeisime elementu 2, tai gausime treči¹jį derinį ir t.t.
Reikia pastebėti, kad i derinių seka yra uciklinta, t.y. jei paskutiniame derinyje element¹ 5 pakeisime elementu 3, tai gausime pirm¹jį ios sekos derinį.
Kiekvien¹ derinį galima ukoduoti n-skilčiu dvejetainiu skaičiumi : jei , tai elementas i priklauso deriniui; jei , tai elementas i nepriklauso deriniui. Tuo būdu deriniai bus ukoduoti n-skilčiais dvejetainiais skaičiais, kiekvienas i kurių turi k vienetukų ir nulių.
Aiku, kad minimalaus pokyčio derinių sekos kodai bus dvejetainiai skaičiai, turintys k vienetukų, ir bet kokie du gretimi skaičiai skirsis dviem skiltimis: vienoje nulis keičiamas vienetu, o kitoje vienetas keičiamas nuliu.
Pavyzdys. Aukčiau pateikto minimalaus pokyčio derinių sekos kodai bus:
Tokių kodų generavimas yra glaudiai susijźs su 1.3 paragrafe inagrinėtu Grėjaus kodų generavimu.
Tarkime, Grėjaus kodai, o , seka Grėjaus kodų, turinčių lygiai k vienetukų. Tada, kaip parodyta literatūroje [RND80], seka sutampa su minimalaus pokyčio derinių seka.
Pavyzdys. Panagrinėkime Grėjaus kodus, kai . Remiantis 1.3 paragrafe inagrinėtu algoritmu, gausime toki¹ sek¹:
Kodai, turintys 3 vienetukus, pabraukti. Iraź iuos kodus, gausime minimalaus pokyčio derinio sekos kodus.
Norėdami efektyviai generuoti , , kodus, pasinaudokime rekursyviniu apibrėimu:
(3.4.1)
ir
čia ymi kodus, suraytus atvirkčia tvarka, o reikia, kad n skilčių upildome nuliais, o kad n skilčių upildome vienetais.
Pastaroji rekurentinė formulė generuoja pradedant ir baigiant.
Pavyzdys. Remdamiesi (3.4.1) formule, pavaizduokime generavimo medį (r. 3.4.1 pav.).
1 pav. G(5, 3) generavimas, remiantis (3.4.1) rekurentine formule
Remdamiesi iuo mediu, gausime sek¹:
Eilės nr. |
Kodas |
Eilės nr. |
Kodas |
Nesunku parodyti (r. [RND80]), kad 3.4.1 pav. pavaizduoto binarinio medio kabančios virūnės yra arba arba .
Kodų generavimo udavinys transformuojasi į binarinio medio kabančių virūnių periūr¹: pradedant virutine ir baigiant apatine.
Norint pereiti nuo vienos kabančios virūnės į gretim¹ kabanči¹ virūnź, nagrinėjame keli¹ i pirmos kabančios virūnės medio aknies link. Tuo keliu link aknies keliaujame virūnėmis, kurios yra apatiniai sūnūs (r. 3.4.1 pav.). Pasiekź pirm¹j¹ virūnź, kuri yra virutinis sūnus, pereiname pas jo brolį (apatinį sūnų) ir i jo, eidami virutiniais sūnumis, einame į kabanči¹ virūnź.
Pavyzdiui (r. 3.4.1 pav.), inagrinėjź kabanči¹ virūnź , pirmiausia pasieksime virutinį sūnų ir pereisime pas jo brolį (apatinį sūnų) . Ir i jo virutiniais sūnumis , pasieksime virūnei gretim¹ kabanči¹ virūnź . (3.4.1 pav. is kelias parykintas).
Nagrinėdami kabanči¹ binarinio medio virūnź , mes tuo pačiu inome keli¹ i aknies į kabanči¹ virūnź. Norėdami pereiti prie gretimos kabančios virūnės, turime saugoti informacij¹ apie virūnź , į kuri¹ turime sugrįti (virūnės visada yra apatiniai sūnūs). ios virūnės bus saugomos steke. Toliau pateiktame generavimo algoritme stekas bus organizuojamas taip pat, kaip jis buvo organizuotas generuojant Grėjaus kodus (r. treči¹jį Grėjaus kodų generavimo algoritm¹). Parametras t rodo skaičių vienetukų tarp skilčių ir gali būti nesunkiai apskaičiuojamas. Todėl steke saugoma tik i reikmė.
Atidiai ityrinėjus binarinį medį, galima pastebėti, kad nagrinėjamo kodo, kai i jo grįtama į virūnź , perskaičiavimas į gretim¹ kod¹ reiklauja nagrinėti emiau pateiktus keturis atvejus, priklausomai nuo gi ir t reikmės:
gi , t > 1
|
gi , t > 0
|
gi , t
|
gi , t
|
ie pertvarkymai turi įtakos vienetukų skaičiui tarp skilčių : t reikmź turime sumainti 1, jei , ir padidinti 1, jei .
Pereinant prie gretimo kodo yra invertuojamos dvi skiltys:
skiltis ,
ir
Atlikus iuos veiksmus, į stek¹ reikia įrayti papildom¹ informacij¹: tarpines virūnes, esančias tarp nagrinėjamos virūnės ir nagrinėjamos kabančios virūnės. Kadangi tas priklauso nuo virūnės steko viruje, tai t reikmė gali vėl pasikeisti.
Jei arba , tai reikia, kad virūnė, kurioje mes esame, yra kabanti virūnė: arba ir jokių tarpinių virūnių saugoti nereikia. iuo atveju t visada lygus .
Kita vertus, jei ir , tai į stek¹ turime įtraukti virūnes , iskyrus t¹ atvejį, kai . iuo atveju į stek¹ įtraukiame tik .
Parametro t reikmė turi būti perskaičiuojama. Kadangi tarp vienetukų gali būti tik , tai . Be to, jei iuo atveju t tampa lygus 0, tai .
emiau pateiktas derinių generavimo minimalaus pokyčio tvarka algoritmas. iame algoritme stekas organizuojamas masyvu , o jo virutinis elementas yra (r. treči¹jį Grėjaus kodų generavimo algoritm¹). Kadangi , tai ekvivalentu, kad į stek¹ įtraukiame .
const nn =
type mas = array [0..nn] of integer;
var n, i, k : integer;
g, tau : mas;
procedure der (n, k : integer);
var i, j, t : integer;
g, tau : mas;
begin
for j := 1 to k do
begin
g [j] := 1;
tau [j] := j + 1;
end
for j := k + 1 to n + 1 do
begin
g [j] := 0;
tau [j] := j + 1;
end
t := k;
tau [1] := k + 1;
i
while i <> n + 1 do
begin
writeln
for j := n downto 1 do write (g [j] : 3);
writeln
i := tau [1];
tau [1] := tau [i];
tau [i] := i + 1;
if g [i] = 1 then
begin
if t <> 0 then g[t]:=1-g[t]
else g[i-1]:=1-g[i-1];
t:=t+1;
end
else
begin
if t <> 1 then g [t 1] := 1 g [t 1]
else g [i 1] := 1 g [i 1];
t := t 1;
end
g [i] :=1 g [i];
if (t = i 1) or (t = 0) then t := t + 1
else
begin
t := t g [i 1];
tau [i 1] := tau [1];
if t = 0 then tau [1] := i 1
else tau [1]:=t+1;
end
end
end
begin
writeln ('įveskite n');
readln (n);
writeln ('įveskite k');
readln (k);
der (n, k);
end
Aptarsime atsitiktinio poaibio, turinčio k elementų, i aibės, turinčios n elementų , generavim¹. Aiku, kad tokio poaibio generavimo tikimybė yra .
Tam tikslui atsitiktinai parenkame vien¹ i n elementų (pasirinkimo tikimybė ) ir po to atsitiktinai generuojame -elementį poaibį i likusių elementų.
Tada ios procedūros eigoje k-elemenčio poaibio isirinkimo tikimybė yra tokių tikimybių sandauga:
P (pirmasis isirinktas elementas vienas i k elementų
P (antrasis isirinktas elementas vienas i k 1 likusių elementų)
_ _ __ _ _ __ _ _ __ _ _ __ _ _ __ _ _ _
P (k-asis isirinktas elementas paskutinysis i likusių elementų) .
i sandauga bus lygi:
Aptarsime atsitiktinio derinio generavimo algoritm¹.
Algoritmo
realizavimui panaudosime papildom¹ masyv¹ p,
kuriame saugosime dar neirinktų elementų numerius.
emiau pateikiamas atsitiktinio derinio generavimo algoritmas.
begin
for j := 1 to n do p [j] := j;
R Æ
for j := 1 to k do
begin
r := rand (j, n);
R := R È
p [r] := p [j];
end
end
Aptarsime kėlinių i n elementų generavimo leksikografine tvarka udavinį. Sprźsdami į udavinį, laikysime aukčiau pateiktos (r. 3.4 paragrafo pradi¹) kombinatorinų objektų generavimo algoritmo struktūros. Norėdami isiaikinti io algoritmo pagrindinius momentus, panagrinėkime pavyzdį, kai .
Pradinio kodo generavimas. Kėlinį talpinsime masyve , kurio elementai ir nusako kėlinį. Aiku, kad pradinis kėlinys yra . Pavyzdiu, jei , tai .
Paties maiausio, leksikografikai didesnio kėlinio nei nagrinėjamas, apskaičiavimas. Tarkime, nagrinėjamas kėlinys. Pavyzdiui, . Jei į kėlinį iūrėsime kaip į skaičių, tai reikia rasti patį maiausi¹ skaičių, didesnį nei nagrinėjamas. Tam tikslui reikia:
rasti pirm¹ i deinės por¹ toki¹, kad ,
rasti , t.y tarp elementų rasti patį maiausi¹ element¹, didesnį u ,
elementus ir sukeisti vietomis,
elementus (uodeg¹) surayti atvirkčia tvarka (apversti).
Pavyzdiui, pirmoji i deinės pora, tenkinanti 1) punkto reikalavim¹, yra , o elementas . Tada, sukeitź 4 su 5, gausime . Apvertź uodeg¹, gausime patį maiausi¹ leksikografikai didesnį kėlinį nei duotas: .
Generavimo pabaigos s¹lyga. Aiku, kad pats didiausias kėlinys yra (masyvo elementas yra pagalbinis, ir jo reikmė lygi nuliui). Tada pirma i deinės pora , tenkinanti s¹lyg¹ yra . Kitaip tariant, jei , tai generavimo pabaiga.
Vadinasi, kėlinių generavimo leksikografine tvarka algoritmas gali būti uraytas taip.
begin
fo i:= 0 to n do p [i] :=i;
t := true;
while t do
begin
spausdinti
i := n 1;
while p [i] > p [i+ 1] do i := i 1;
if i = 0 then t := false
else
begin
j := n;
while p [j] < p [i] do j := j 1;
pp := p [i]; p [i] := p [j]; p [j] := pp;
k := i + 1; l := n;
while k < l do
begin
pp := p [k]; p [k] := p [l]; p [l] := pp;
k := k + 1; l := l 1;
end
end
end
end
Be kėlinių generavimo leksikografine tvarka naudojamas ir kėlinių generavimo antileksikografine tvarka metodas.
Apibrėimas. Vektorius yra antileksikografikai maesnis u vektorių (ymime ), jei egzistuoja toks , kad , o , . Pastebėsime, jei vietoje skaičių paimtume raides , idėstytas natūralia, pavyzdiui, abėcėlės tvarka: , tai leksikografinė tvarka apibrė n ilgio odių isidėstym¹ odyne įprasta tvarka. Tuo tarpu antileksikografinė tvarka apibrėia odių tvark¹, kai tiek pozicijų eilikumas sekoje, tie ir aibės elementų isidėstymas odyje yra atvirkčias.
Pavyzdiui, uraykime aibės kėlinius leksikografine ir antileksikografine tvarka.
Leksikografine tvarka:
1, 3, 2; 2, 1, 3; 2, 3, 1; 3, 1, 2; 3, 2, 1.
Antileksikografine tvarka:
2, 1, 3; 1, 3, 2; 3, 1, 2; 2, 3, 1; 3, 2, 1.
I leksikografinės tvarkos kėlinio 1, 3, 2 gausime antileksikografinės tvarkos kėlinį, jei 1-t¹ keisime 3-tu, 3-t¹ keisime 1-tu (imame aibės X elementus atvirkčia tvarka) ir kėlinio pozicijas suraome atvirkčia tvarka. Gausime 3, 1, 2, o po to 2, 1, 3.
Kėlinių generavimas antileksikografine didėjimo tvarka yra labai panaus į kėlinių generavimo leksikografine didėjimo tvarka algoritm¹. Kėlinių generavimui įveskime masyv¹ , kurio elementai apibrėia nagrinėjam¹jį kėlinį.
Pradinio kėlinio generavimas. for i := 1 to n + 1 do p [i] := i;
Paties maiausio antileksikografikai didesnio kėlinio apskaičiavimas. Tam tikslui reikia:
rasti pirm¹ i kairės por¹ , toki¹, kad
rasti , t.y tarp elementų rasti patį didiausi¹ element¹, maesnį nei ,
elementus ir sukeisti vietomis,
elementus surayti atvirkčia tvarka.
Generavimo pabaigos s¹lyga. Paskutinysis antileksikografinės tvarkos kėlinys yra , o , t.y. masyvo elementai yra . Aiku, kad iuo atveju pirmoji i deinės pora , tenkinanti 1)-ojo punkto reikalavim¹: , yra . Vadinasi, jei , tai generavimo pabaigos s¹lyga.
Pateiksime kėlinių generavimo antileksikografine tvarka algoritm¹.
begin
fo i:= 0 to n + 1 do p [i] :=i;
t := true;
while t do
begin
spausdinti
i
while p [i-1] > p [i] do i := i + 1;
if i = n + 1 then t := false
else
begin
j
while p [j] > p [i] do j := j + 1;
pp := p [i]; p [i] := p [j]; p [j] := pp;
k := 1; l := i - 1;
while k < l do
begin
pp := p [k]; p [k] := p [l]; p [l] := pp;
k := k + 1; l := l 1;
end
end
end
end
Kai , tai pateiktas algoritmas apskaičiuos kėlinius:
Panagrinėkime kėlinių generavimo minimalaus pokyčio tvarka metod¹ ir algoritm¹. Kėlinių minimalaus pokyčio tvarka tai tokia kėlinių generavimo seka, kai bet kokie du gretimi kėliniai skiriasi tik dviejų elementų padėtimi. Pavyzdiui, kai , gautume sek¹: 1, 2, 3; 1, 3, 2; 3, 1, 2; 3, 2, 1; 2, 3, 1; 2, 1, 3.
Aptarsime kėlinių generavimo tokia tvarka metod¹.
Kai , tai egzistuoja vienintelis kėlinys: 1. Tarkime, kad turime kėlinius, tenkinančius minimalaus pokyčio tvark¹. Tada kėlinį generuosime taip.
Sunumeruokime visus kėlinius numeriais nuo 1 iki . Tada, jei kėlinio i elemento numeris yra nelyginis skaičius, tai prie io kėlinio priraykime element¹ n i deinės ir nuosekliai atlikime visus galimus to elemento postūmius į kairź. Jei kėlinio i elemento numeris yra lyginis, tai prie jo priraykime element¹ n i kairės ir nuosekliai atlikime visus galimus to elemento postūmius į deinź.
Atlikź iuos veiksmus, gausime kėlinių minimalaus pokyčio sek¹ (r. 3.4.2 pav.).
3.4.2 pav. Kėlinų generavimas minimalaus pokyčio tvarka
Aptartas kėlinių minimalaus pokyčio sekos generavimo metodas neatitinka aukčiau pateiktos kombinatorinių objektų generavimo algoritmo schemos: skaičiavimo eigoje reikia saugoti visus kėlinius. Literatūroje [RND80] pateikta io metodo realizacija, atitinkanti kombinatorinių objektų generavimo algoritmo scem¹.
Aptarkime i¹ realizacij¹.
Įveskime tris masyvus: , ir .
Masyvo p elementai apibrė nagrinėjam¹ kėlinį. Elementai p0 ir pn+1 yra pagalbiniai elementai.
Masyvo a elementai nusako atvirktinį kėlinį: ak nurodo viet¹ (adres¹), kurioje masyve p yra elementas k. Kitaip tariant, . Masyvo d elementai apibrėiami taip:
Kėlinyje elementas i stumiamas iki jis pasiekia element¹, didesnį u jį patį. Tada yra keičiama io elemento judėjimo kryptis ir bandoma stumti (jei galima) element¹ i 1. Kadangi turime masyv¹ a, tai is elementas lengvai randamas masyve p.
Tam, kad nutrauktume elemento n judėjim¹, į masyv¹ p įvesti du papildomi elementai ir , kurių reikmės yra lygios .
Elemento reikmė yra lygi 0, nes p elemento, lygaus vienetui, judinti nereikia. Tai sekos generavimo pabaigos s¹lyga.
begin
for i := 1 to n do begin
p [i] := i;
a [i] := i;
d [i] := 1;
end
d [1] := 0; p [0] := n + 1; p [n + 1] := n + 1; t := true;
while t do
begin
Spausdinti ();
m := n;
while p [a [m] + d [m]] > m do begin
d [m] := d [m];
m := m 1;
end
if m = 1 then t := false
else
begin
pp := p [a [m]];
p [a [m]] := p [a [m] + d [m]];
p [a [m] + d [m]] : =pp;
pp := a [m]; k := p [a [m]];
a [m] := a [k];
a [k] : =pp;
end
end
end
Kai , pateiktas algoritmas apskaičiuoja:
Tarkime, kad bet koks kėlinys. Perskaičiuokime į kėlinį pagal algoritm¹:
begin
for i := n downto 2 do
sukeisti p [i] su p [rand (1, i)],
čia rand k, l tolygiai pasiskirsčiusių atsitiktinių skaičių i atkarpos k, l generavimo procedūra
end
Taip gautas kėlinys p su tikimybe gali sutapti su bet kuriuo kėliniu i visų kėlinių aibės.
Tam, kad įrodytume, jog visi kėliniai vienodai galimi, pasinaudokime matematinės indukcijos metodu.
Kai akivaizdu.
Tarkime, kad algoritmas generuoja atsitiktinį kėlinį, kai elementų skaičius yra . Tegu yra bet kuris aibės kėlinys. Tada tikimybė, kad yra:
n-elementės aibės X iskaidymas į k poaibių (blokų) tai aibės X poaibių eima , kurios elementai tenkina reikalavimus:
Poaibius vadinsime blokais.
Aibės X visų galimų iskaidymų į k blokus aibź ymėsime , o aibės X visų galimų iskaidymų aibź ymėsime . Aiku, kad
Su aibės X iskaidymu į blokus yra susijź Stirlingo ir Belo skaičiai.
Antrosios rūies Stirlingo skaičius tai skirtingų n-elementės aibės iskaidymo į k blokus skaičius, t.y.
čia .
Pavyzdiui, , kadangi yra 7 skirtingi 4-ių elementų aibės iskaidymo į du blokus būdai:
Akivaizdu, kad , kai . Be to, , kadangi tučia blokų aibė sutinkamai su apibrėimu yra tučiosios aibės iskaidymas.
Su antrosios rūies Stirlingo skaičiais, kaip ir su binominiais koeficientais, yra susijź daug tapatybių.
Pirmiausia įrodysime tapatybź, primenanči¹ derinių sudėties savybź, kuri yra susijusi su Paskalio trikampiu:
a) , ,
b) , , (3.4.2)
c) , .
Formulių ir teisingumas akivaizdus. 3.4.1 a) formulės teisingum¹ įrodysime taip. Visus n-elementės aibės iskaidymus į k blokų suskirstykime į dvi klases. Pirmajai klasei priskirkime visus iskaidymus, kuriuse yra vienelementinis blokas , o antrajai klasei priskirkime visus iskaidymus, kai elementas n yra didesnio bloko (maiausiai dviejų elementų aibės) elementas.
Aiku, kad pirmosios klasės galia yra , t.y. tokia, kokia yra aibės iskaidymo į blokus galia.
Antrosios klasės galia yra , kadangi prie kiekvieno iskaidymo į k blokus k skirtingais būdais galima prijungti element¹ n: elementas n paeiliui jungiamas prie kiekvieno bloko.
(1.3.4) formulė įgalina lengvai apskaičiuoti . emiau pateikta reikmių lentelė, primenanti Paskalio trikampį.
i¹ lentelź galima traktuoti kaip Stirlingo trikampį. i-osios eilutės elementas yra lygus -osios eilutės elemento i kairės ir -osios eilutės elemento i viraus, padauginto i k, sumai.
6 lentelė. Antrosios rūies Stirlingo skaičiai
n k | |||||||||||
Antrosios rūies Stirlingo skaičiai yra susijź su n- osios eilės polinomo , urayto bazėje , uraymu bazėje , čia
Teorema [Lip88]. Kiekvienam
Pavyzdiui, .
I tikro,
Pirmosios rūies Stirlingo skaičiai. ie skaičiai ymimi ir jie yra koeficientai prie x laipsnių daugianaryje , t.y.
Kitaip tariant, skaičiai vaidina atvirkči¹ vaidmenį atvilgiu , t.y. leidia polinom¹, urayt¹ bazėje pervesti į polinomo ura¹ bazėje .
Nesunku parodyti (palyginant koeficientus prie laipsnių lygybėje ), kad tenkina s¹ryius:
, ,
, , (3.4.3)
, .
emiau pateikta pirmosios rūies Stirlingo skaičių lentelė.
7 lentelė. Pirmosios rūies Stirlingo skaičiai
n k | |||||||||||
|
Belo skaičius Bn. Belo skaičius tai visų galimų n-elementės aibės X iskaidymo į blokus skaičius:
, čia .
Kitaip tariant,
Įrodysime Belo skaičius siejantį rekurentinį s¹ryį:
, . (3.4.4)
Aibės visų galimų iskaidymų aibź galima iskaidyti į klases, priklausomai nuo bloko B, turinčio savyje element¹ , arba, kas ekvivalentu, priklausomai nuo aibės . Kiekvienai aibei egzistuoja tiksliai aibės X iskaidymų, turinčių savyje blok¹ B. Grupuodami klases priklausomai nuo aibės galios, gauname (3.4.3) formulź.
emiau pateikta Belo skaičių lentelė.
8 lentelė. Belo skaičiai
n |
Bn |
Aptarsime n-elementės aibės visų galimų iskaidymų generavimo algoritm¹. io algoritmo idėj¹ lengviausia paaikinti suformulavus j¹ rekurentinėje formoje.
Aiku, kad kiekvienas aibės iskaidymas p vienareikmikai nusako aibės iskaidym¹ pn , gaut¹ i iskaidymo p, kai i jo atitinkamo bloko paalinamas elementas n (ir paalinamas tučiasis blokas, jei elementas n sudarė vienelementį blok¹).
Ir atvirkčiai, jei turime aibės iskaidym¹ , tai lengva rasti visus aibės iskaidymus p, kad , t.y.
(3.4.5)
i savybė įgalina sudaryti paprast¹ rekurentinį metod¹, generuojantį visus galimus aibės iskaidymus: jei mes inome aibės visų galimų iskaidymų s¹ra¹ Ln-1, tai visų galimų aibės iskaidymų s¹raas Ln gaunamas pakeičiant kiekvien¹ s¹rao Ln-1 iskaidym¹ s (3.4.5) seka. Be to, nesunku pastebėti, jei kas antram s¹rao s¹rao Ln-1 iskaidymui s invertuosime (raysime atvirkčia tvarka) (3.4.5) sek¹, tai s¹rao Ln gretimi iskaidymai maai skirsis vienas nuo kito. Tiksliau kalbant, kiekvienas gretimas s¹rao Ln iskaidymas bus gautas i prie jį esančio iskaidymo paalinant kakokį element¹ i kakurio bloko ir patalpinant į element¹ į kit¹ blok¹, arba sukuriant i jo vienelementinį blok¹. Pavyzdiui, jei , tai gausime tokius s¹raus:
Toliau aptarsime nerekurentinź io metodo realizacij¹.
Aibės iskaidymo blokus suraysime jų maiausio elemento didėjimo tvarka. Bloko maiausi¹ element¹ mes vadinsime bloko numeriu. Reikia paymėti, kad gretimų blokų numeriai bendru atveju nėra i eilės ein¹ natūralieji skaičiai.
iame algoritme naudosime kintamuosius ir , , atitinkamai reikiančius prie ir po bloko, kurio numeris i, stovinčių blokų numerius. Jei blokas, kurio numeris i, yra paskutinysis iskaidymo blokas, tai .
Naudosime kintam¹jį , . Jei , tai reikia, kad i-tasis aibės elementas priklauso blokui, kurio numeris k.
Elemento judėjimo kryptį nusakys kintamasis , . Jei , tai elementas i juda pirmyn.
emiau pateiktas algoritmas generuoja visus galimus aibės iskaidymo būdus, kai duotas aibės elementų skaičius n. Algoritmo rezultatas: visų galimų aibės iskaidymų seka, kurioje kiekvienas iskaidymas gaunamas i prie tai buvusio, perkeliant vienintelį element¹ į kit¹ blok¹.
begin
for i := 1 to n do
begin
blok [i] := 1; pirmyn [i] := true;
end
sek
Atspausdinti iskaidym¹
elementai, masyve blok paymėti tuo pačiu numeriu k,
priklauso k-ajam blokui.
j := n;
while j > 1 do
begin
k := blok [j];
if pirmyn [j] then
begin
if sek [k] := 0 then
begin
sek [k] := j; prec [j] := k; sek [j] := 0;
end
if sek [k] > j
begin
prec [j] := k;
sek [j] := sek [k];
prec [sek [j]] := j; sek [k] := j;
end
blok [j] := sek [k]
end
else
begin
blok [j] := prec [k];
if k = j then
if sek [k] = 0 then sek [prec [k]] := 0;
else
begin
sek [prec [k]] := sek [k];
prec [sek [k]] := prec [k];
end
end
Atspausdinti iskaidym¹.
j := n;
while ((j > 1) and ((pirmyn [j]) and (blok [j] = j))
or ((not pirmyn [j]) and (blok [j] := 1))) do
begin
pirmyn [j] := not pirmyn [j];
j := j 1;
end
end
end
Pateiktas algoritmas pradioje generuoja iskaidym¹ , t.y. pirm¹jį aibės iskaidym¹ s¹rae Ln, kuris gaunamas aukčiau apraytu rekurentiniu metodu.
Pagrindinio ciklo while j > 1 do paskirtis yra aktyvaus elemento j radimas ir jo perkėlimas į kaimyninį blok¹, t.y. į blok¹ i deinės, jei pirmyn [j] turi reikmź true (iuo atveju gali būti sukuriamas blokas ), ir į blok¹ i kairės, jei pirmyn [j] = false.
I aukčiau pateikto rekurentinio metodo iplaukia, kad elementas j gali būti judinamas, kai visi didesni u jį elementai pasiekia savo ribinź kairi¹j¹ arba deini¹j¹ padėtį. Kitaip tariant, aktyvusis elementas j* yra toks elementas, kai visi didesni u jį elementai j (j > j*) tenkina vien¹ i dviejų s¹lygų:
a) pirmyn [j] and (blok [j] = j), t.y. elementas juda pirmyn (į deinź) ir pasiekia savo deini¹j¹ ribinź padėtį (aiku, kad j negali būti elementu bloko, kurio maiausias elementas yra didesnis u j);
b) not pirmyn [j] and (blok [j] = 1), t.y. elementas juda atgal (į kairź) ir pasiekia savo kairi¹j¹ ribinź padėtį.
Aiku, kad, jei elementas j tenkina vien¹ i minėtų s¹lygų, tai keičiama jo judėjimo kryptis.
Paanalizuokime aktyvaus elemento perkėlimo į kit¹ blok¹ proces¹.
Pirmiausia randamas numeris bloko, kuriame yra aktyvusis elementas. Tarkime, kad tokio bloko numeris yra k.
Jei aktyvusis elementas juda į deinź, tai pakanka perkelti jį į blok¹, kurio numeris yra , jei ir .
Jei arba , tai pirmiausia reikia modifikuoti reikmź.
Tarkime, sek [k] . Vadinasi, aktyviojo elemento blokas yra paskutinysis iskaidymo blokas. iuo atveju bus sudaromas naujas blokas . Tam tikslui pakanka priimti: ir atitinkamai pakeisti ir reikmes (r. algoritmo tekst¹).
Tarkime, sek [k] > j. Tai reikia, kad visi blokai, esantys deiniau bloko k, sudaryti i elementų, didesnių nei j (visi tie elementai uima ribinź deinź padėtį). Vadinasi, (r. rekurentinį metod¹), iuo atveju reikia sukurti vienelementį blok¹ . Tai ir įvykdoma (r. algoritmo tekst¹).
Situacijoje, kai aktyvusis elementas juda atgal (į kairź), pakanka patalpinti į element¹ į prie blok¹ k stovintį blok¹ ir atlikti atitinkamus masyvų sek ir prec elementų pakeitimus.
emiau surayti visi galimi aibės iskaidymo būdai, apskaičiuoti pagal aukčiau pateikt¹ algoritm¹.
Aiku, kad iskaidymų skaičius yra
Nagrinėsime natūraliojo skaičiaus n iskaidym¹ į neneigiamų sveikųjų skaičių sek¹, kad .
Jei skaičių tvarka sekoje yra svarbi, tai toks skaičiaus n iskaidymas vadinamas kompozicija. iuo atveju paprastai įvedamas apribojimas: , .
Jei skaičių tvarka nesvarbi ir , tai yra multiaibė (aibė su pasikartojančiais elementais) ir vadinama skaičiaus n iskaidymu.
Pavyzdiui, jei , tai (3), (1, 2), (2, 1), (1, 1, 1) yra skaičiaus 3 kompozicija, o (3), (1, 2), (1, 1, 1) iskaidymas.
Nagrinėjant kompozicij¹, į skaičių n patogu iūrėti kaip į atkarp¹, sudaryt¹ i vienetinio ilgio atkarpėlių, ir atkarpėlių susijungimo vietos paymėtos takais.
Pavyzdiui, kai , turėsime (r. 3.4.2 pav.).
3.4.2 pav. Grafinis kompozicijos (2, 1, 2, 2, 1) vaizdavimas
Tada kompozicijos elementai yra atstumas tarp gretimų paymėtų takų. 3.4.2 pav. pavaizduota skaičiaus kompozicija (2, 1, 2, 2, 1). Aiku, kad kiekvien¹ kompozicij¹ galima vaizduoti dvejetainiu skaičiumi, turinčiu skiltį: vienetinė skiltis rodo paymėt¹ tak¹. Pavyzdiui, kompozicijos (2, 1, 2, 2, 1) kodas yra .
n skaičiaus kompozicija, susidedanti i k dalių, atitinka -skiltį dvejetainį skaičių, turintį vienetuk¹, ir todėl egzistuoja tokių kompozicijų.
Iskaidymas skiriasi nuo kompozicijos tuo, kad komponentų tvarka nesvarbi. Pavyzdiui, iskaidymo atveju nedarome skirtumo tarp tokių skaičiaus 4 iskaidymų: , , . Nagrinėjant skaičiaus n iskaidym¹, patogu komponentes idėstyti didėjimo tvarka, t.y. .
Skaičiaus n iskaidym¹ į l komponentes patogu generuoti leksikografine tvarka, pradedant iskaidymu , , ir tźsiant proces¹ tokiu būdu: norėdami gauti leksikografikai didesnį iskaidym¹ nei nagrinėjamas, nagrinėjame elementus i deinės į kairź iki rasime pirm¹jį element¹ , tenkinantį s¹lyg¹ ; po to keičiame visiems , ir elementui pl suteikiame reikmź .
Pavyzdiui, jei , ir nagrinėjame iskaidym¹ , tai gausime, kad pirmasis i deinės vienetukas tenkina s¹lyg¹ . Todėl kitas iskaidymas bus .
Jei nei vienas iskaidymo elementas netenkina s¹lygos , tai generavimo procedūra baigiama.
emiau pateikiamas aptarto metodo algoritmas.
begin
l
p [1] := n;
p
while l £ n do
begin
spausdinti
i := l 1;
while p [l] p [i] < 2 do i := i 1;
if i ¹ 0 then for j := i to l 1 do p [j] := p [i] + 1
else
begin
for j := 1 to l do p [j] := 1;
l := l + 1:
end
end
end
Skaičiaus n iskaidymo algoritm¹ galima i esmės pagerinti. Skaičiaus n iskaidym¹ galima urayti taip:
čia rodo, kad komponentė į iskaidym¹ įeina kartų, t.y.
Pasinaudojant tokiu iskaidymo uraymu ir generuojant iskaidymus taip, kad , galima gauti efektyvesnį iskaidymų generavimo algoritm¹ nei aukčiau pateiktas.
Pavyzdiui, kai , generuodami iskaidymus nurodyta tvarka, gausime toki¹ iskaidymų sek¹:
emiau pateiktame algoritme skaičiaus n iskaidym¹ pradėsime nuo iskaidymo . Norėdami gauti nagrinėjamam iskaidymui gretim¹ iskaidym¹, nagrinėsime patį deinįjį iskaidymo element¹ .
Jei , tai galime paalinti du elementus ir įvesti dar vien¹ element¹ (arba įvesti vien¹ element¹ , jei tokio elemento nagrinėjamu momentu nebuvo).
Jei , tai suma pakankamai didelė, kad galėtume įvesti dar vien¹ . Bet kuriuo atveju tas, kas lieka, paverčiama į atitinkam¹ vienetukų skaičių.
begin
l
p [1] := 0; m [1] := 0;
p [0] := n + 1;
m
p
m [1] := n;
while l ¹ 0 do
begin
spausdinti
sum := m [l] * p [l];
if m [l] = 1 then
begin
l := l 1
sum := sum + m [l] * p [l];
end
if p [l 1] = p [l] + 1 then
begin
l := l 1;
m [l] := m [l] + 1
end
else
begin
p [l] := p [l] + 1;
m [l] := 1;
end
if sum > p [l] then
begin
p [l + 1] := 1;
m [l + 1] := sum p [l];
l := l + 1
end
end
end
Aiku, kad pateiktas algoritmas yra tiesinis, kadangi skaičius operacijų, reikalingų pereinant nuo vieno iskaidymo prie kito, yra apribotas konstanta, nepriklausančia nei nuo n, nei nuo l.
Politica de confidentialitate | Termeni si conditii de utilizare |
Vizualizari: 2792
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved