Szakdolgozat
Miskolci Egyetem
A polihipergeometrikus eloszlás értékeinek
algoritmikus számítása
Készítette:
Sülyi Ákos
programtervező informatikus szak
Témavezetők:
Dr. Fegyverneki Sándor
Dr. Karácsony Zsolt
Miskolc, 2015
Miskolci Egyetem
Gépészmérnöki és Informatikai Kar
Alkalmazott Matematikai Tanszék Szám:
Szakdolgozat Feladat
Sülyi Ákos (QPATL4) programtervező informatikus jelölt részére.
A szakdolgozat tárgyköre: Kombinatorikus leszámlálás
A szakdolgozat címe: A polihipergeometrikus eloszlás értékeinek algoritmikus
számítása
A feladat részletezése:
Egy sorrend megadása, mely az eloszlás összes esetét tartalmazza.
A probléma hálóelméleti megfogalmazása és egy részben rendezés megadása.
Megfelelő esetek a sorrendben felvett indexeinek számítása.
Valószínűség értékek számítása a teljes valószínűség tételének segítségével.
Algoritmus megadása.
Az algoritmus implementációja python nyelven.
Az algoritmus összeghasonlítása a kombinatorikus képlettel valószámítással.
Témavezetők:
Dr. Fegyverneki Sándor egyetemi docens,
Dr. Karácsony Zsolt egyetemi docens
A feladat kiadásának ideje:
2013. szeptember 10.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
szakfelelős
2
Eredetiségi Nyilatkozat
Alulírott . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; Neptun-kód: . . . . . . . . . . . . . . . . . . .
a Miskolci Egyetem Gépészmérnöki és Informatikai Karának végzős . . . . . . . . . . . . . . . . . . .
szakos hallgatója ezennel büntetőjogi és fegyelmi felelősségem tudatában nyilatkozom
és aláírásommal igazolom, hogy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
című szakdolgozatom/diplomatervem saját, önálló munkám; az abban hivatkozott szak-
irodalom felhasználása a forráskezelés szabályai szerint történt.
Tudomásul veszem, hogy szakdolgozat esetén plágiumnak számít:
• szószerinti idézet közlése idézőjel és hivatkozás megjelölése nélkül;
• tartalmi idézet hivatkozás megjelölése nélkül;
• más publikált gondolatainak saját gondolatként való feltüntetése.
Alulírott kijelentem, hogy a plágium fogalmát megismertem, és tudomásul veszem,
hogy plágium esetén szakdolgozatom visszautasításra kerül.
Miskolc, . . . . . . . . . . . .év . . . . . . . . . . . .hó . . . . . . . . . . . .nap
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Hallgató
3
1.
szükséges (módosítás külön lapon)
A szakdolgozat feladat módosítása
nem szükséges
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
dátum témavezető(k)
2. A feladat kidolgozását ellenőriztem:
témavezető (dátum, aláírás): konzulens (dátum, aláírás):
. . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . .
3. A szakdolgozat beadható:
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
dátum témavezető(k)
4. A szakdolgozat . . . . . . . . . . . . . . . . . . . szövegoldalt
. . . . . . . . . . . . . . . . . . . program protokollt (listát, felhasználói leírást)
. . . . . . . . . . . . . . . . . . . elektronikus adathordozót (részletezve)
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . egyéb mellékletet (részletezve)
. . . . . . . . . . . . . . . . . . .
tartalmaz.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
dátum témavezető(k)
5.
bocsátható
A szakdolgozat bírálatra
nem bocsátható
A bíráló neve: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
dátum szakfelelős
6. A szakdolgozat osztályzata
a témavezető javaslata: . . . . . . . . . . . . . . . .
a bíráló javaslata: . . . . . . . . . . . . . . . .
a szakdolgozat végleges eredménye: . . . . . . . . . . . . . . . .
Miskolc, . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
a Záróvizsga Bizottság Elnöke
4
Tartalomjegyzék
Jelölések 6
1. Bevezetés 7
2. A probléma megfogalmazása 8
3. A probléma algoritmikus megoldása 17
3.1. Az esetek felsorolása . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.2. Leszálló bejárás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.3. Cikk-cakk bejárás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4. Az alkalmazás korlátai 30
5. Fejlesztői dokumentáció 33
6. Az algoritmus tesztelése 38
7. Összefoglalás 45
Irodalomjegyzék 46
Adathordozó használati útmutató 47
5
Jelölések
∀ bármely (összes)
∃, ∃! létezik, létezik pontosan egy
N természetes számok (nemnegatív egészek)
Z+
pozitív egész számok
P prím számok
∅ üres halmaz
× Decartes-féle szorzat
∪, ∩ halmazműveletek: unió, metszet
∈ halmazelméleti reláció: tartalmazza (eleme)
∨, ∧ hálóműveletek: egyesítés, metszet
MIN, MAX indexenkénti minumum, maximum
κ (közvetlen) követési reláció
a1, . . . , an sorozat
üres sorozat
⊕ hozzáfűzés
, rendezési relációk: megelőző, követő
<L
, >L
lexikografikus relációk: megelőző, követő
, lényegesen (nagyságrenddel) kisebb, nagyobb
.
= definíció szerint egyenlő
, összegzés, produktum
n
k
binomiális együttható
a! faktoriális
quod erat demonstrandum
6
1. fejezet
Bevezetés
A polihipergeometrikus eloszlás számos probléma megoldására használható. Könnyen
találhatunk szerencsejátékok közt is olyat, ahol a lehetőségek valószínűségét ennek se-
gítségével számolhatjuk. A történet írás szerint a probléma első megfogalmazása[1] is
szerencsejátékhoz kötődik. A Huygens által felvetett problémát számos más egyén mel-
lett James Bernoulli is megoldotta, ő azonban ezt a ma is használt általános alakban
adta meg[2]. Magát a nevet azonban jóval később kapta Karl Pearson javasoltára[7].
A szerencsejátékon kívül azonban fontosak azok a statisztikai becslések is, melyeket
ennek az eloszlás segítségével végezhetünk el. Például egy választáson induló pártok
támogatottságára vagy egy élőlény populáció genetikai összetételére vonatkozó becslés.
Ezen kívül homogenitási hipotézis eldöntésére is használhatjuk. Az eloszlás számítá-
sát azonban több tényező is nehezíti. A legnyilvánvalóbb nehézség, hogy az általános
problémában a változók száma kötetlen.
Ebben a munkában rámutatok további nehézségekre is, melyek az esetek felsorolása
kapcsán felmerülnek. Ugyanakkor ismertetem a probléma általam kidolgozott megfo-
galmazását, aminek segítségével ezek a nehézségek kezelhetővé vállnak. Az új megköze-
lítés egyben lehetővé teszi, hogy az eloszlás értékeit a klasszikus kombinatórikus képlet
helyett, a teljes valószínűség tételének segítségével számoljuk ki. A számítás ilyen for-
mában történő elvégzéséhez fontos a felsorolás sorendjének megfelelő megválasztása
is.
A számítási módszert algoritmikus formában is megadom. A dolgozat végén pe-
dig ismertetem az általam python nyelven elkészített implementációt és az elvégzett
futtatási tesztek eredményeit.
Szeretnék személyes köszönetet mondani témavezető tanáraimnak, Dr. Fegyverneki
Sándornak és Dr. Karácsony Zsoltnak nagy türelmükért, akiknek jó tanácsai és út-
mutató kérdései nélkül ez a dolgozat nem készülhetett volna el. Továbbá középiskolai
tanáromnak Dezsőfi Györgynek, hogy megmutatta számomra a matematika iránti ra-
jongás és közös művelésének élvezetét. Valamint nem utolsó sorban szüleimnek töretlen
bizalmukért.
Ez a kutató munka a Miskolci Egyetem stratégiai kutatási területén működő Mechatronikai és
Logisztikai Kiválósági Központ keretében valósult meg.
7
2. fejezet
A probléma megfogalmazása
Tekintsük azt a helyzetet, melyben a következő feltételek teljesülnek:
a) Adott egy N elemű halmaz.
b) A halmaz elemei valamilyen tulajdonságuk alapján m ∈ Z+
számú kategóriába
különíthetőek. Az egyes kategóriába tartozó elemek száma rendre n1, . . . , nm, azaz
m
i=1 ni = N.
c) A halmazból egyszeri véletlenszerű húzással (visszatevés nélküli mintavétellel) K
darab elemet emelünk ki.
Legyen ξ1 . . . , ξm valószínűségi változók értéke a megfelelő kategóriába tartozó elemek
száma a kihúzott elemek között. Ekkor a klasszikus valószínűségi modell szerint an-
nak a valószínűsége, hogy ξ1 . . . , ξm valószínűségi változó rendre felveszi a k1, . . . , km,
0 ki ni, i = 1, . . . , m értéket:
P(ξ1 =k1, . . . , ξm =km) =
n1
k1
. . .
nm
km
N
K
, (2.1)
ahol m
i=1 ki = K, m
i=1 ni = N. A ξ1 . . . , ξm valószínűségi változók polihipergeomet-
rikus eloszlásúak, illetve a változók eloszlását (2.1) szerint számolhatjuk [3].
Az alkalmazás szempontjából fontosabb eloszlásfüggvényt az eloszlás egyes változók
szerinti összegzéseként kaphatjuk:
P(ξ1 k1, . . . , ξm−1 km−1, K) =
=
k1
x1=0
· · ·
km−1
xm−1=0
n1
x1
. . .
nm−1
xm−1
nm
K − x1 − . . . − xm−1
N
K
=
= 1 −
K
x1=k1+1
· · ·
K
xm−1=km−1+1
n1
x1
. . .
nm−1
xm−1
nm
K − x1 − . . . − xm−1
N
K
,
(2.2)
ahol K m−1
i=1 ki.
8
Fontos megjegyeznünk, hogy az m = 2 speciális esetben egyszerűen hipergeomet-
rikus eloszlásról beszélünk. Továbbá említésre méltó, hogy általában a tankönyvek di-
daktikai szempontokból az említett két eloszlást fordított sorrendben tárgyalják, tehát
a polihipergeometrikus eloszlást a hipergeometrikus általánosításaként.
Az eloszlás, illetve az eloszlásfüggvény értékeinek megállapítása a binomiális együtt-
hatók miatt nagy n1, . . . , nm esetén számítás technikailag több nehézséget is felvet. A
binomiális együttható számlálója és nevezője a faktoriálisok miatt nagyságrendekkel
nagyobb az együttható értékénél. Ez kiküszöbölhető, ha a számítás úgy szervezzük,
hogy felváltva végzünk osztást és szorzást. Azonban az egyes együtthatók értékei még
így is kívül eshetnek a rendelkezésre álló ábrázolási tartományból, ezért szükség lehet
ennek a módszernek a kiterjesztésére a függvény által kijelölt osztás műveletekre is. Ez
a módszer célra vezető lehet hiszen a függvény értéke 0 és 1 közé esik, ugyanakkor a tört
számok ábrázolásából fakadó numerikus instabilitás valamint a nagy mennyiségű mű-
velet igény továbbra is korlátozó tényező lehet. Az említett nehézségek áthidalhatóak,
ha a (2.1) valamint a (2.2) pontos értéke helyett alkalmas közelítést használunk.
Legkézenfekvőbb, ha a közelítés úgy tesszük, hogy eltekintünk a c) feltétel azon
kikötésétől, hogy a K elemet egyszerre (visszatevés nélkül) húzzuk ki, helyette úgy
tekintjük mintha az elemek kihúzása nem változtatná meg az egyes kategóriák arányát
a teljes halmazhoz képest (visszatevéses mintavétel). Az így módosított feltételi körül-
mények, pedig pontosan a polinomiális eloszlást eredményezik. Tehát a polinomiális
eloszlás, ami
P(ξ1 =k1, . . . , ξm =km) =
K!
k1! . . . km!
n1
N
k1
. . .
nm
N
km
,
ahol K = m
i=1 ki, valamint ennek eloszlásfüggvénye, ami
P(ξ1 k1, . . . , ξm km−1, K) =
= 1 −
K
x1=k1+1
· · ·
K
xm−1=km−1+1
K!
x1! . . . xm−1!(K − x1 − . . . − xm−1)!
n1
N
x1
. . .
. . .
nm−1
N
xm−1 nm
N
K−x1−...−xm−1
,
ahol K m−1
i=1 ki, használhatóak a polihipergeometrikus eloszlás közelítésére. A le-
vezetésből az is kitűnik, hogy a közelítés akkor tekinthető jónak, ha N K vagy
alkalmazás során ezt a feltételt K/N < 0.1 esetén tekintjük teljesítettnek.
A polihipergeometrikus eloszlás m ∈ Z+
darab ξ1, . . . , ξm valószínűségi változó által
felvett értékek valószínűségeit írja le. Ezen valószínűségi változók előállnak egy kezdeti
urnából történő húzás során, mely urnában m kategóriába sorolható elemek vannak.
Ekkor a valószínűségi változók jelölik, hogy a kihúzott elemek között, hány darab van az
egyes kategóriából. Ezt úgy is megadhatjuk, hogy azt mondjuk meg, hogy hány darab
maradt az egyes kategóriából a húzás után az urnában. Ez a megközelítés, olyan szem-
pontból előnyösebb, hogy a kiindulási halmaz kategóriánkénti elemek számára minden-
képpen szükség van. Célunk egy algoritmus megadása, mely a kezdeti elemszámokat
csökkentve felsorolja az összes esetet, valamint az ezekhez tartozó valószínűségeket ki-
számítja.
A probléma jobban kezelhető hálóelmélet segítségével történő megfogalmazásban,
mert a következőkben bevezetett algebrai struktúra megkönnyíti az algoritmikus felso-
rolást.
9
2.1. definíció. Azonosítsuk az X = { xi | xi ∈ N, i ∈ I } indexelt halmazokkal a po-
lihipergeometrikus eloszlás eseteit, ahol ξi = xi a valószínűségi változók által felvett
értékek, vagyis az egyes kategóriákba tartozó elemek darabszámai. Jelöljünk továbbá
ezen X halmazok összességét
D = X X ∈ ×
i∈I
N ,
vagy egyszerűbben
D = ×
i∈I
N.
Ez a megfogalmazás azért igen kellemes mivel jól leírja azt az előfeltételt, hogy a
ξi, ξj illetve xi, xj változók felcserélését nem tekintjük külön esetnek. Ugyanakkor lehe-
tővé teszi, hogy rögzítsük i1, . . . , im ∈ I indexek egy tetszőleges i1, . . . , im , sorozatát,
ezzel megtartsuk sorrendjüket.
Ezután D elemein adjunk meg egy részben rendezést. Ezt tegyük meg a következő
D felett értelmezett két binér művelet bevezetésével.
2.2. definíció. Az X, Y ∈ D elemenként vett minimuma és maximuma
X ∨ Y = MAX(X, Y ) = { max{xi, yi} | xi ∈ X, yi ∈ Y, i ∈ I },
X ∧ Y = MIN(X, Y ) = { min{xi, yi} | xi ∈ X, yi ∈ Y, i ∈ I }.
2.3. tétel. A (D, MIN, MAX) algebrai struktúra háló.
Bizonyítás. A tétel állítás belátható, ha belátjuk a két műveletre a következő hat
állítást[6]:
∀ A = {ai}, B = {bi}, C = {ci} ∈ D esetén, ahol i ∈ I,
asszociatívak:
MIN(A, MIN(B, C)) = MIN(MIN(A, B), C), (H1)
MAX(A, MAX(B, C)) = MAX(MAX(A, B), C), (H2)
kommutatívak:
MIN(A, B) = MIN(B, A), (H3)
MAX(A, B) = MAX(B, A), (H4)
és abszorptívak:
MIN(A, MAX(A, B)) = A, (H5)
MAX(A, MIN(A, B)) = A. (H6)
A (H1) eset bizonyítása: Legyen
MIN(A, MIN(B, C)) = X = {xi},
MIN(B, C) = U = {ui}.
10
A MIN definíciója szerint ∀ i ∈ I,
xi ai, (I)
xi ui, (II)
ui bi, (III)
ui ci. (IV)
A (II) és a (III) tulajdonságból valamint a (II) és a (IV) tulajdonságból
xi bi , (V)
xi ci , (VI)
ugyanakkor az (I), az (V) és a (VI) alapján
xi min{ai, bi, ci}, (VII)
ebből azonban
min{ai, bi, ci} ai (VIII)
min{ai, bi, ci} bi,
min{ai, bi, ci} ci
vagyis
min{ai, bi, ci} min{bi, ci}. (IX)
Ezenkívül a (VIII) és a (IX) tulajdonságból
min{ai, bi, ci} min{ai, min{bi, ci}} = xi, (X)
végül a (VII) és a (X) tulajdonságból
xi = min{ai, bi, ci}
következik.
Ezután (H1) igazolása érdekében belátjuk, hogy
MIN(MIN(A, B), C) = Y = {yi} valamint
MIN(A, B) = V = {vi} esetén
yi = min{ai, bi, ci},
a következők szerint:
yi ci,
yi vi,
vi ai,
vi bi,
tehát
yi min{ai, bi, ci},
11
ugyanakkor
min{ai, bi, ci} ai,
min{ai, bi, ci} bi,
min{ai, bi, ci} min{ai, bi},
min{ai, bi, ci} ci,
vagyis
min{ai, bi, ci} min{min{ai, bi}, ci} = yi,
ezért
yi = min{ai, bi, ci},
min{ai, min{bi, ci}} = xi = min{ai, bi, ci} = yi = min{min{ai, bi}, ci},
MIN(A, MIN(B, C)) = X = Y = MIN(MIN(A, B), C).
A (H2) hasonlóan látható be mint a (H1) állítás, mindössze minimum helyett ma-
ximumot valamint kisebb-egyenlő helyett nagyobb-egyenlőt kell írnunk.
A (H3) és a (H4) állítás jól látszik, hiszen
min{ai, bi} = min{bi, ai}
illetve
max{ai, bi} = max{bi, ai}.
A (H5) állítást következők szerint kaphatjuk meg:
MIN(A, MAX(A, B)) = Z = {zi},
ui ai, ui bi,
zi ai, zi ui,
zi = ai.
A (H6) belátható, ha a (H5) állításon végrehajtjuk a (H2) állításnál említett átala-
kításokat.
Könnyen belátható, hogy a bevezetett részben rendezés valódi részhalmaza a lexi-
kografikus rendezésnek, hiszen
∀X, Y ∈ D : ha MIN(X, Y ) = X =⇒ X ≤L
Y,
itt X ≤L
Y reláció jelentése, hogy X a lexikografikus sorrendben megelőzi az Y hal-
mazt. Az állítás megfordítva azonban nem igaz. Ezt is egyszerűen látható, hiszen a
lexikografikus reláció teljes, azaz
∀X, Y ∈ D : X ≤L
Y és Y ≥L
X ⇐⇒ X = Y,
ellenben a { (X, Y ) ∈ D × D | MIN(X, Y ) = X } relációra ez a kritérium nem teljesül.
Mielőtt meg tudnánk mutatni, hogy a fenti struktúra, hogyan segít az eloszlás
értékeinek számításában, szükséges lesz további jelölések bevezetése.
12
2.4. definíció. Az X, Y ∈ D elemekről mondjuk azt, hogy Y követi X-et, illetve
követési relációban van X-el, ha
MIN(X, Y ) = Y és Z ∈ D, hogy MIN(X, Z) = Z és MAX(Y, Z) = Z.
Jelöljük ezt a (X, Y ) ⊂ D × D relációt κ-val.
Könnyen belátható, hogy
Y κX =⇒ ∃! i : yi = xi − 1, és ∀ j = i : yj = xj,
ahol xi, xj ∈ X, yi, yj ∈ Y, i, j ∈ I, azaz X pontosan egy eleme kisebb Y azonos indexű
eleménél pontosan eggyel, a többi indexhez tartozóak pedig egyenlőek.
2.5. definíció. Jelöljük (D, MIN, MAX) háló atomjait A ⊂ D módon, melyekre
A = { E ∈ D | Eκ{0}m
}.
Az atomokra teljesül, hogy ∀E ∈ A : ∃ ! i ∈ I, index, amelyre
ej =
1, ha j = i,
0, egyébként,
ahol ej ∈ E, j ∈ I.
Az atomok segítségével fel tudunk írni egy függvényt, ami a nullától különböző elem
indexét adja vissza:
ε: A → I, ε (E) = i,
ha ei = 1, ei ∈ E, ahol E ∈ A.
(2.3)
Ez a függvény, akkor lesz igazán hasznos, ha két indexelt halmaz különbségét is meg
tudjuk adni. Ennek érdekében értelmezzük D felett a hozzárendelést a kivonás mű-
veletének olyan módon történő a megkötésével, hogy az ne vezessen ki D halmazból.
Hogy ezt elkerüljük rendeljük az ∅, üres halmazt az operandusokhoz, azaz:
: D × D → D ∪ {∅},
(X, Y ) →
{xi − yi | xi ∈ X, yi ∈ Y }, ha xi yi, ∀ i ∈ I
∅, különben.
Tehát,
∀ Y κX =⇒ X Y ∈ A,
ezért
ε(X Y ) = i, esetén yi = xi − 1 és yj = xj,
ahol X, Y ∈ D, xi, xj ∈ X, yi, yj ∈ Y i, j ∈ I, és i = j. Tehát ∀ X, Y ∈ D, Y κX hal-
mazokról megtudjuk mondani azt az i ∈ I indexet, amelyhez tartozó elemeik eltérnek
egymástól.
Tekintsük (D, MAX, MIN) háló egy részhálóját, aminek legyen R = {ri | i ∈ I} ∈ D
a szuprémuma. Ez a részháló tartalmazza az összes olyan X ∈ D esetet, melyek úgy
állnak elő, hogy a kezdeti halmaz, amiből húzunk, az egyes kategóriában rendre ri darab
elemet tartalmaz. Az általunk keresett algoritmus, ennek a részhálónak a szintenként
történő bejárását hajtja végre. Tehát R halmazból kiindulva megadja azon sorozatokat,
melyek az összes olyan halmazt tartalmazzák, amelyet úgy kaphatunk meg, hogy R
halmazból n i∈I ri számú elemet húzunk ki.
13
2.6. definíció. A D elemeiből képzett véges sorozatok halmaza D∗
, azaz
D∗
=
∞
m=0
Dm
,
ahol
D0
= , az üres sorozat.
Továbbá az általunk bejárt részháló egy szintje:
L(n)
∈ D∗
,
L(n)
= X ∈ D
x∈X
x = N − n ,
ahol N = i∈I ri az elemek száma a kezdeti halmazban.
A 3. fejezetben a felsorolás megadásához fogjuk felhasználni a 2.4. definícióban
megadott relációt illetve a (2.3) függvényt. Egyenlőre tegyük fel, hogy ismerjük az
L(n)
, n = 0, . . . , N szintek egy felsorolását. Ezt a sorrendet felhasználva P(Y |X) fel-
tételes valószínűségeket, ahol X ∈ L(n−1)
, Y ∈ L(n)
, egy mátrixba tudjuk foglalni.
2.7. definíció. Nevezzük a W(n)
mátrixot az L(n)
szint átviteli súlymátrixának, ahol
L(n)
a (D, MAX, MIN) háló valamely részhálójának n. szintje. Az átvitelisúlyok legye-
nek a következők:
W(n)
= [1], ha n = 0,
W(n)
= [P(Y |X) ]Y ∈L(n),
X∈L(n−1)
, egyébként.
Ha a részháló szuprémuma R ∈ D, akkor n = 0, . . . N, ahol N =
r∈R
r.
A W(n)
oszlopai tehát az L(n−1)
szinten található halmazokhoz rendelhetőek, míg sorai
az L(n)
szinten lévőkhöz. Az oszlopok és sorok sorrendje a megfelelő szintek felsorolá-
sának sorrendjét követik.
A feltételes valószínűségek értékei egyszerűen számíthatóak a következő képlet sze-
rint:
P(Y |X) =



xi
x∈X
x
, ha Y κX, és i = ε(X Y ),
0, egyébként,
ahol X ∈ L(n−1)
, Y ∈ L(n)
, illetve
x∈X
x = N − (n − 1).
Egyben ez a képlet jól mutatja a κ reláció, és a feltételes valószínűségek közötti kap-
csolatot.
A feltételes valószínűségek ismeretében kiszámíthatjuk az egyes esetek valószínűsé-
gét. Ennek érdekében az L(n)
szint eseteinek valószínűségeit a sorrend megtartásával
p(n)
egy vektorba foglaljuk.
14
2.8. tétel. A p(n)
= [P(Y )]Y ∈L(n) valószínűség értékekből képzett vektor előállítható
p(n)
= W(n)
p(n−1)
szorzat alakjában, ahol n = 1, . . . N
p(0) .
= [1] = W(0)
p(n−1)
= [P(X)]X∈L(n−1) ,
p(n)
= [P(Y )]Y ∈L(n) .
Bizonyítás. Bontsuk a W(n)
= [wY ]Y ∈L(n) átviteli súlymátrixot sorvektoraira, ahol
wY = [P(Y |X)]X∈L(n−1) , ekkor a tétel állítása szerint
[P(Y )]Y ∈L(n) = [wY ]Y ∈L(n) p(n−1)
,
tehát ∀ Y ∈ L(n)
P(Y ) = wY p(n−1)
,
P(Y ) =
X∈L(n−1)
P(Y |X)P(X).
Tehát a tétel állítását visszavezettük a teljes valószínűség tételére.
Annak érdekében, hogy a valószínűség értékeket a 2.8. tétel szerint tudjuk előállí-
tani a felsorolás sorrendjét olyannak kell választanunk, hogy Y ∈ L(n)
esetén elő tudjuk
állítani ∀ X ∈ L(n−1)
: Y κX eset az L(n−1)
sorozatban felvett indexét, hiszen ez egyben
W(n)
oszlop indexe is.
A (D, MIN, MAX) hálóról érdemesnek tartjuk megjegyezni, hogy m dimenziós rács.
Ez az állítás könnyen látható, hiszen ∀ X ∈ D, X ∈ E, X = {0}m
halmaz esetén
∀Yi, Yj ∈ D, Yi = Yj : YiκX, YjκX halmazokhoz, ∃ Z ∈ D, hogy ZκYi és ZκYj. Más-
képpen fogalmazva, nem teszünk különbséget, hogy előbb az egyik majd a másik ka-
tegóriából húzunk vagy fordítva. Ebből pedig látható, hogy a háló Hasse-diagramján
a relációt ábrázoló élek négyszögeket határolnak. Ha (D, MIN, MAX) háló egy rész-
hálóját tekintjük, aminek szuprémuma R = {ri1 , . . . , rim } ∈ D, akkor ez a részháló
egy G(ri1
+1),...,(rim +1) paraméterű rács. Ez a részháló a Pi1 , . . . , Pim láncok Descartes-
szorzataként állítható elő, melyeket rendre a ri1 , . . . , rim számoktól kisebb természetes
számokból képezzük, tehát
G(ri1
+1),...,(rim +1) = ×
i∈I
Pi,
ahol
Pi1 = ri1 , ri1 − 1, ri1 − 2, . . . , 1, 0 ,
...
Pim = rim , rim − 1, rim − 2, . . . , 1, 0 .
Ugyanakkor a (D, MIN, MAX) háló izomorf a (Z+
, lnko, lnkt) hálóval. A két algebrai
stukatúra közti megfeleltetés következőek szerint tehető meg. Az index halmaz I ⊂ P,
ahol P a prímek halmaza, egy d ∈ Z+
szám, pedig akkor feletethető meg az X ∈ D
halmazzal, ha d kanonikus alakjában pi ∈ P prím kitevője X halmaz azon eleme,
amelyiket pi prímmel indexeltük, azaz
d =
pi∈I
pxi
i = px1
1 . . . pxm
m ,
15
ahol xi ∈ X. Például a 3. fejezetben a 3.1. ábrán látható részháló izomorf 45000 osz-
tóinak részhálójával, ekkor az index halmaz 2, 3, 5 , ugyanakkor ha az index halmazt
másképpen választjuk meg, a részháló topológiája nem változik, így 67500 vagy 52272
osztóinak részhálója is izomorf az említett példával, ekkor az index halmaz 3, 2, 5
illetve 3, 11, 2 .
16
3. fejezet
A probléma algoritmikus megoldása
A 2. fejezetben megmutattuk, hogy a polihipergeometrikus eloszlás esetei megfeleltet-
hetőek egy indexelt halmazokból álló (D, MAX, MIN) algebrai struktúrával. Továbbá
erről a struktúráról megmutattuk, hogy háló, valamint azt is, hogyan használhatjuk fel
az esetek felsorolására és azok valószínűség értékeinek kiszámítására. Egyben a felsoro-
lás sorrendjével kapcsolatban további feltételeket szabtunk, annak érdekében, ha a háló
L(n−1)
illetve L(n)
szintjei azon esetek felsorolása, melyek rendre n − 1 illetve n elem
kihúzása révén keletkeznek, akkor ∀ X ∈ L(n−1)
, Y ∈ L(n)
esetekhez tartozó P(Y |X)
feltételes valószínűségeket mátrixba tudjuk foglalni. Ennek érdekében feltehetjük, hogy
Y indexét ismerjük, ami az átviteli súlymátrix sorvektorának indexével fog megegyezni.
Ekkor elő kell állítanunk az összes X eset L(n−1)
felsorolásban felvett indexét, amelyre
P(Y |X) = 0 azaz Y κX. Ezek az indexek lesznek a mátrix oszlop indexei. Ebben a
fejezetben ismertetünk egy lehetséges felsorolást, valamint megadjuk a fenti indexek
kiszámításának módját.
3.1. Az esetek felsorolása
A felsorolás algoritmusának megadásához előbb értelmezzünk azt a D × I halmazból
D ∪ {∅}-be történő hozzárendelést, ami egy elem kihúzását jelenti egy adott kategóri-
ából. Tehát X ∈ D halmaz egy adott i indexű elemének eggyel történő csökkentése,
hiszen X elemei az egyes kategóriákban szereplő elemek számával feleltettük meg.
3.1. definíció. Egy elem kihúzása az i indexű kategóriából a következőképpen adható
meg,
σ: D × I → D ∪ {∅},
σ(X, i) = X E,
ahol E ∈ A atom és ε(E) = i.
Továbbá, az L(n)
∈ D∗
, 0 n i∈I ri sorozatok elemenként történő megadása
érdekében szükségünk lesz a hozzáfűzés műveletére a D∗
sorozatok felett.
17
3.1. Az esetek felsorolása
3.2. definíció. Egy T = T1, . . . , Tk ∈ D∗
sorozat S = S1, . . . , Sl ∈ D∗
sorozat
végéhez fűzését adjuk meg a következőképpen:
⊕ : D∗
× D∗
→ D∗
,
⊕ (S, T) =
S, ha T = ,
⊕( S1, . . . , Sl, T1 , Q), különben,
ahol T = ⊕( T1 , Q), Q ∈ D∗
.
Továbbiakban a prefix jelölés helyett infixet fogunk használni. Valamint a D halmaz-
beli halmazokat egy hosszú sorozatokként tekintjük, illetve ∅ és között sem teszünk
különbséget, és értelmesnek tekintjük ezeknek egy D∗
sorozathoz történő hozzáfűzését.
A 3.1. és a 3.2. definíciók bevezetésével egyben egy elágazás leírását is leegyszerűsí-
tettük, hiszen X = {xi | i ∈ I} ∈ D esetén, ha xj = 0, j ∈ I, akkor S ⊕ σ(X, j) = S,
vagyis ha a j-edik kategória elemei elfogytak nem tudunk úgy húzni egy következő
elemet, hogy az a j-edikből kerüljön ki, így a felsoroláshoz sem fűzzünk újabb esetet.
Az előbbieket felhasználva, ha R = { ri1 , . . . , rim } a kiindulási halmaz, vagyis az
elemek darabszáma az egyes kategóriákban ri1 , . . . , rim , a felsorolást megtehetjük a kö-
vetkezők szerint:
1. algoritmus Enumeration
1. n = 0, L(n)
= R .
2. n = n + 1, L(n)
= .
3. Iteráljunk X ∈ L(n−1)
eseteken és állítsuk elő XκY eseteket a következő módon:
(a) j = 1.
(b) Y = σ(X, ij).
(c) Ha Y ∈ L(n)
, akkor L(n)
= L(n)
⊕ Y.
(d) j = j + 1 folytassuk a 3.(b) pontól, amíg j m egyébként a 4. ponttól.
4. Legyen X most a következő eset az L(n−1)
sorozatban és folytassuk a 3. ponttól,
ha nincs több menjünk az 5. pontra.
5. Ha n = i∈I ri készen vagyunk, egyébként folytassuk a 2. ponttól.
A fenti algoritmus 3.(b) pontjában szereplő feltétel vizsgálata számítástechnikai szem-
pontból nehézkes lenne, hiszen ehhez L(n)
összes már felsorolt elemét meg kellene
vizsgálnunk. Célszerű lenne a sorrendet úgy kialakítanunk, hogy j = 1 illetve i1
index helyett valamely magasabb indextől kezdjük Y = σ(X, ij) esetek előállítását
úgy, hogy ∀ik ∈ I, ik ij esetén σ(X, ik) biztosan szerepeljen L(n)
sorozatban, illetve
∀il ∈ I, il ij esetén σ(X, il) nem. Annak érdekében, hogy egy ilyen felsorolást tudjunk
megadni szükségünk lesz a következő segédváltozó bevezetésére.
18
3.1. Az esetek felsorolása
3.3. definíció. A γ segédváltozó legyen a következőek szerint értelmezve:
γ : D → I,
γ(X) =
i1 , ha n = 0,
ε (Yk X) , egyébként ,
ahol k = min { l | XκYl } , X ∈ L(n)
és Yk, Yl ∈ L(n−1)
.
Azaz γ(X), X ∈ L(n)
az az index, amelyik csökkentésével kaphatjuk meg az X halmazt
abból az Y halmazból, amelyikre teljesül XκY és az L(n−1)
sorozatban a legkisebb az
indexe. Ennek a segédvákozó segítségével megadható a következő algoritmus, melyben
L(n)
felsorolást L(n−1)
elemein történő iterációval állítjuk elő.
3.4. tétel. A (D, MIN, MAX) háló bármely részhálójának szintjei, aminek R ∈ D hal-
maz a szuprémuma, megadható azon L(n)
∈ D∗
, ahol n = 0, . . . , i∈I ri sorozatokkal,
melyeket következő képpen képzünk:
L(0)
= R ,
L(n)
=
X∈L(n−1)
im
j=γ(X)
σ(X, j),
ahol I = i1, . . . , im és 1 n m.
Bizonyítás. Ha n = 0, L(0) .
= R könnyen belátható, hogy teljes hiszen R annak a
részhálónak a szuprémuma melyeknek a felsorolását megadjuk.
Ha n = 1, mivel γ(R) = i1 ezért L(1)
= i∈I σ(R, i), vagyis rendre felsoroljuk azon
eseteket, mikor az egyes kategóriából húztunk ki egy elemet. Erről szintén könnyen
látható, hogy teljes.
Tegyük fel, hogy L(n−1)
teljes, 1 < n minri∈R ri = rmin esetén (biztosan lehet
húzni mindegyik kategóriából). Ekkor tekintsük Xr = { xi1 , xi2 , . . . , xir , . . . , xim } ∈
L(n−1)
elemet valamint legyen γ(Xr) = ir. Ahhoz, hogy meg tudjuk mutani, hogy L(n)
is teljes, be kell látnunk, hogy ∀ij < ir esetén a σ(Xr, ij) halmazok már szerepelnek
L(n)
sorozatban mikor a külső iterációban Xr-re kerül a sor. Mivel γ(Xr) = ir ezért
létezik Y ∈ L(n−2)
, és γ(Y ) = ip ir. Eszerint L(n−1)
sorozatban Xr halmaztól kisebb
indexszel szerepelnek a következő elemek:
Xp = σ(Y, ip) = { xi1 , . . . , xip − 1, xip+1 , . . . , xir−1 , xir + 1, . . . , xim },
Xp+1 = σ(Y, ip+1) = { xi1 , . . . , xip , xip+1 − 1, . . . , xir−1 , xir + 1, . . . , xim },
...
Xr−1 = σ(Y, ir−1) = { xi1 , . . . , xip , xip+1 , . . . , xir−1 − 1, xir + 1, . . . , xim },
ezért L(n)
felsorolásakor hamarább fogjuk valamilyen ip γ(Xj) ir indexszel venni
ezeket az elemeket. Ezért L(n)
sorozatban
σ(Xr, ip) = σ(Xp, ir) = { xi1 , . . . , xip − 1, xip+1 , . . . , xir−1 , xir , . . . , xim },
σ(Xr, ip+1) = σ(Xp+1, ir) = { xi1 , . . . , xip , xip+1 − 1, . . . , xir−1 , xir , . . . , xim },
...
σ(Xr, ir−1) = σ(Xr−1, ir) = { xi1 , . . . , xip , xip+1 , . . . , xir−1 − 1, xir , . . . , xim }
19
3.1. Az esetek felsorolása
elemek biztosan szerepelni fognak mielőtt Xr halmazra kerülne a sor. Ezt a gondolat
menetet addig ismételhetjük Y halmazra, míg ip = i1, aminek a révén belátható, hogy
mielőtt Xr-re kerül a sor σ(Xr, ij), ij ip halmazok is szerepelnek már a felsorolásban.
Tehát teljes az L(n)
felsorolása, ha az L(n−1)
sorozat is az.
A n > rmin esetén biztosan van legalább egy, olyan Z ∈ L(n−1)
, amelyre teljesül,
hogy legalább az egyik eleme 0, legyen ennek az indexe iz. Ezért σ(Z, iz) = ∅, amit
nem tudunk felírni az előző érvelésben a halmaz elemein végzett aritmetikai művelettel.
Egyébként az érvelés többi része továbbra is érvényes, hiszen az ⊕ művelet ∅ esetén
nem bővíti az L(n)
sorozatot. Tehát L(n)
felsorolása ebben az esetben is teljes.
A levezetésből az is kitűnik, hogy ha X ∈ L(n)
, Y ∈ L(n−1)
és X = σ(Y, i) valamint
L(n)
előállításakor X nem szerepel a felsorolásban, mikor Y sorra kerül akkor γ(X) = i,
hiszen ekkor Y = L
(n−1)
k , ahol k = min l | XκL
(n−1)
l . Ez alkalmat ad arra, hogy az
algoritmust ennek megfelelően szervezzük. A következőképpen: a külső ciklus L(n−1)
sorozatban felsorolt halmazokon iterál, jelöljük az éppen aktuális halmazt X-el, a bel-
ső ciklus változóját pedig j-vel, ezt indítsuk γ(X)-ről és fusson im-ig, a ciklusmagban
végezzük el egy húzást a σ(X, j) szerint, fűzzük az így előállított halmazt L(n)
soro-
zathoz, valamint ehhez a halmazhoz tároljuk j ciklusváltozót is. Így az eltárolt index a
következő szint felsorolásakor előhívható, amiről megmutattuk, hogy az éppen γ(X)-el
lesz egyenlő. Ezen kívül lehetőségünk van a bejárás szűkítésére is, ha megadunk egy
T ∈ D elemet ami a bejárt részhálónak, {0}m
helyett, infimuma lesz. Ekkor a bejárás
úgy módosul, hogy a R T szuprémummal és {0}m
infimummal rendelkező részhálóval
izomorf részhálót járunk be. Az algoritmus szemléletesebben, pszeudokóddal leírva a
következő (paraméterlistában a szögletes zárójelek közötti paraméterek opcionálisak):
2. algoritmus Enumeration
Require: L(n−1)
, [ T ]
1: L(n)
← list()
2: m ← length(L(n−1)
[1])
3: if T = ∅ then
4: T ← list()
5: for i ← 1 to m do
6: T.push(0)
7: end for
8: end if
9: for i ← 1 to length(L(n−1)
) do
10: for j ← 1 to m do
11: Y ← L(n−1)
[i]
12: if Y [j] > T[j] and j Y.gamma then
13: X ← copy(Y )
14: dec(X[j])
15: X.gamma ← j
16: L(n)
.push(X)
17: end if
18: end for
19: end for
20: return L(n)
20
3.2. Leszálló bejárás
A 3.4. tétel gondolatmenete szerint könnyen belátható a következő állítás is.
3.5. állítás. Az 1. illetve a 2. algoritmus az egyes szintek eseteit lexikografikus sor-
rendben sorolja fel.
3.2. Leszálló bejárás
Annak érdekében, hogy a valószínűségeket a 2.8. tétel szerint tudjuk kiszámítani azon-
ban nem elég az eseteket felsorolnunk. Ha W(n)
átviteli súlymátrixok oszlop- illetve
sorvektorait a felsorolásban előállított sorrendben írjuk, akkor az egyes feltételes való-
színűség oszlop indexe i azaz a 9. sorban szereplő külső ciklus ciklusváltozója lesz, a
sor index pedig j γ(X), X ∈ L(n−1)
esetén L(n)
már felsorolt elemeinek számából
állapítható meg, hiszen ekkor σ(X, j)-t fűzzük a felsorolás végéhez. Azonban j γ(X)
esetén, ha xj = 0, akkor σ(X, j) már szerepel a felsorolásban és ennek indexét is elő
kell állítanunk. Ennek a problémának illetve az eddigiek jobb megértése érdekében te-
kintsünk egy alkalmasan megválasztott példát. Legyen három kategóriánk és ezekben
rendre 3, 2 és 4 darab elem.
3,2,4
2,2,4 3,1,4 3,2,3
1,2,4 2,1,4 2,2,3 3,0,4 3,1,3 3,2,2
0,2,4 1,1,4 1,2,3 2,0,4 2,1,3 2,2,2 3,0,3 3,1,2 3,2,1
0,1,4 0,2,3 1,0,4 1,1,3 1,2,2 2,0,3 2,1,2 2,2,1 3,0,2 3,1,1 3,2,0
0,0,4 0,1,3 0,2,2 1,0,3 1,1,2 1,2,1 2,0,2 2,1,1 2,2,0 3,0,1 3,1,0
0,0,3 0,1,2 0,2,1 1,0,2 1,1,1 1,2,0 2,0,1 2,1,0 3,0,0
0,0,2 0,1,1 0,2,0 1,0,1 1,1,0 2,0,0
0,0,1 0,1,0 1,0,0
0,0,0
3.1. ábra.
21
3.2. Leszálló bejárás
A 3.1. ábrán az egyes esetek az algoritmus által megadott sorrendben láthatóak, n
értéke fentről lefelé növekszik. Az egyes esetek a még ki nem választott elemek számát
mutatják. Két szint egyes halmazait kössük össze, ha Y κX, illetve a vonal színe legyen
piros, ha ε(X Y ) γ(X), azaz éppen az átviteli súlymátrixok azon elemeinek meg-
feleltethető élek, amelyek indexét keressük. Ehhez a példához tartozó konkrét átviteli
súlymátrixokat megadjuk a 6. fejezetben.
Szemléletesebb ha az egyes szinteket külön ábrázoljuk mégpedig úgy, hogy az egyes
kategóriákból történő húzást különböző irányba rajzoljuk, jelöljük azokat az eseteket
is, ahol a 2. algoritmus 12. sorában lévő feltétel nem teljesül, azaz σ(X, j) = ∅. A
megelőző szint elemeit jelölje , az üres halmazokat pedig .
L(0)
L(1)
L(2)3,2,4
2,2,4
3,1,4 3,2,3
1,2,4
2,1,4 2,2,3
3,0,4 3,1,3 3,2,2
3.2. ábra.
Az L(n)
felsorolását Y ∈ L(n−1)
halmazokon történő iterációval végezzük, az egyes
halmazokból az I indexek sorrendjében húzunk ki egy-egy elemet γ(Y )-tól im-ig indexű
kategóriákból, ezért L(n)
sorrendje ciklikusan fogja az egyes kategóriákból történt hú-
zást tartalmazni. Jól látható, hogy ez nem függ attól, hogy hány kategória van.
L(3) L(4)0,2,4
1,1,4 1,2,3
2,0,4 2,1,3 2,2,2
∅ 3,0,3 3,1,2 3,2,1
∅
0,1,4 0,2,3
1,0,4 1,1,3 1,2,2
∅ 2,0,3 2,1,2 2,2,1
! 3,0,2 3,1,1 3,2,0
3.3. ábra.
Ennek következménye, hogy n rmin esetén, ha
L(n−1)
= Y1, Y2, . . . Yk ,
L(n)
= X1, X2, . . . , Xk, Xk+1, . . . Xl ,
akkor
ε(Yj Xj) = i1, j = 1, . . . , k.
22
3.2. Leszálló bejárás
Hasonlóképpen tetszőleges Yf halmazra, melyre γ(Yf ) = ir és σ(Yf , ir) = Xg, teljesül,
hogy létezik d ∈ N, hogy L(n−1)
sorozatban Yf halmaz után következő ∀ c < d, Yf+c
halmazokra γ(Yf+c) ir, és ekkor ε(Yf+c Xg+c) = ir. Ezért egy σ(Yf , ir) halmaznak
a felsoroláshoz történő hozzáfűzésekor érdemes egy v ∈ Nm
vektor ir koordinátájában
eltárolni g + 1-et, hiszen ε(Yf+1 σ(Yf , ir)) = ir, ha γ(Yf+1) ir, majd növelni ezt a
koordinátát eggyel minden Yf+c felsorolásánál.
L(5)
× ×
0,0,4 0,1,3 0,2,2
∅ 1,0,3 1,1,2 1,2,1
! 2,0,2 2,1,1 2,2,0
! 3,0,1 3,1,0 ∅
3.4. ábra.
Ha n > rmin, akkor van olyan kategória, amiből már nem tudunk húzni és emiatt a
sorrend is másként alakul, ezért a keresett indexek előállításánál ezt is figyelembe kell
venni.
3.6. definíció. Tekintsük a (H, MIN, MAX), H ⊆ D részhálót, ahol inf H = T =
{ti}. Valamint az X = {xi} ∈ H esetet, ahol i ∈ I. Jelöljük azon kategóriák száma,
amelyekből már nem tudunk több elemet ki húzni a következőképpen:
o(X, T) = |{i ∈ I | ti = xi}|.
Valamint ebből származtassuk a δ segédváltozót
δ(X, T) = |{ i ∈ I | i γ(X) }| − o(X, T)
szerint.
Ha a felsorolás során egy Y = {yi1 , . . . , yim } ∈ L(n−1)
halmazra kerül a sor és yi = 0
valamely i γ(X)-re, akkor megvizsgáljuk a δ(Xvi
, T) δ(Y, T), Xvi
∈ L(n)
és vi < g+
1 feltételeket. Ha ezek teljesülnek a v vektor i indexű koordinátáját átírjuk g+1-re, ahol
g az utolsó a felsoroláshoz már felhasznált halmaz indexe L(n−1)
sorozatban, egyébként
folytatjuk az iterációt Y -t követő esettel. Amennyiben a vi koordinátát átírtuk a 3.3.
illetve a 3.4. és a 3.5. ábrákon ! jellel jelöltük, illetve × jellel, ha nem.
Egy új opcionális d paramétert is megadhatunk, ami a wi,j súlyok közös nevezője.
Ezt abból a megfontolásból tettük, mivel L(0) .
= R és minden L(n)
felsorolásához
feltettük, hogy L(n−1)
sorozatot ismerjük, n = 1, . . . , N, ahol N = i∈I ri, ri ∈ R.
Azaz n iterációjával tudjuk a felsorolást megtenni, ekkor azonban d = N − n miatt
23
3.2. Leszálló bejárás
érdemes n helyett az iterációt d-vel végezni és ekkor a ciklus változó egyben megadja
a nevezőt is. Egy másik észrevétel, hogy W(n)
mátrixok inicializációja nem szerepel az
algoritmusban, illetve bizonyos indexű elemei kapnak értéket. Ennek oka, hogy W(n)
definíciójából, illetve az eddig elmondottakból is jól kitűnik, hogy W(n)
bármely sor
vektora, illetve oszlop vektora legfeljebb m számú 0-tól különböző elemet tartalmazhat,
ezért érdemes W(n)
tárolását ritka mátrixokra kidolgozott struktúrákkal megtenni. Ha
ez mégsem lenne megoldható, akkor L(n−1)
ismeretéből következik, hogy ismerjük L(n−1)
elemszámot is, és így |L(n−1)
| dimenziós oszlop vektorok összefűzésével is elő tudjuk
állítani W(n)
-t.
L(6)
L(7)
L(8)
L(9)
∅
× × ×
0,0,3 0,1,2 0,2,1
! 1,0,2 1,1,1 1,2,0
! 2,0,1 2,1,0 ∅
× 3,0,0 ∅
×
× × ×
0,0,2 0,1,1 0,2,0
! 1,0,1 1,1,0 ∅
× 2,0,0 ∅
× ∅
×
× × ×
0,0,1 0,1,0 ∅
× 1,0,0 ∅
× ∅
×
× ×
0,0,0 ∅
× ∅
3.5. ábra.
Az elmondottak alapján a 2. algoritmust ki tudjuk egészíteni úgy, hogy az új
algoritmus L(n−1)
esetein történő iteráció során minden elem esetén a kategóriákon is
végig iteráljon és megkeresse az aktuális elem már felsorolt deszcendenseinek indexét a
v vektor segítségével. Ezen módosításokat megadjuk a 3. algoritmusban. Érdemesnek
tartjuk megjegyezni, hogy az algoritmus a 17. és a 24. sor révén a δ függvényt értékét
implicit módon számítja.
24
3.3. Cikk-cakk bejárás
3. algoritmus Descend
Require: L(n−1)
, [ d ], [ T ]
1: L(n)
← list()
2: g ← 0
3: Y ← L
(n−1)
0
4: m ← length(Y )
5: if d = ∅ then
6: d ← m−1
i=0 Yi
7: end if
8: v ← list()
9: for i ← 0 to m − 1 do
10: v.push(0)
11: end for
12: if T = ∅ then
13: T ← copy(v)
14: end if
15: for i ← 0 to length(L(n−1)
)-1 do
16: Y ← L
(n−1)
i
17: o ← Y.gamma − Y.delta
18: for j ← 0 to m − 1 do
19: if j Y.gamma then
20: if Yj > Tj then
21: X ← copy(Y )
22: dec(Xj)
23: X.gamma ← j
24: X.delta ← j − o
25: L(n)
.push(X)
26: inc(g)
27: W
(n)
ig ← Yj/d
28: else
29: inc(o)
30: end if
31: vj ← g + 1
32: else
33: if Yj > Tj then
34: W
(n)
ivj
← Yj/d
35: inc(vj)
36: else if vj < g + 1 and L
(n)
vj .delta Y.delta then
37: vj ← g + 1
38: end if
39: end if
40: end for
41: end for
42: return L(n)
25
3.3. Cikk-cakk bejárás
3.3. Cikk-cakk bejárás
A 3. algoritmus az L(n−1)
szint ismeretében felsorolja az eloszlás L(n)
szinten lévő
eseteit, valamint ezzel párhuzamosan előállítja a W(n)
átviteli súlymátrixot. Ugyanak-
kor az L(n)
szint valószínűségeit tartalmazó p(n)
vektort csak a felsorolás végeztével,
vagyis a teljes W(n)
mátrix ismeretében tudjuk kiszámítani. Előnyösebb lenne, ha a
felsorolást leszálló bejárás helyett úgy tudnánk módosítani, hogy W(n)
mátrixot sor-
vektoronként állítjuk elő. Ebben az esetben a mátrix vektor szorzást a felsorolással
egy időben tudnánk elvégezni. Mint ahogy az a 2.8. tétel bizonyításából is kitűnik ez
megfelel az L(n)
szinten lévő esetek valószínűségeinek teljes valószínűség tétel szerint
történő kiszámításának.
A bejárás sorrendjének végiggondolása érdekében azonban továbbra is hasznos az
átviteli súlymátrix konstrukciója mentén gondolkodnunk. A W(n)
mátrix minden wY
sorvektora megfeleltethető egy Y ∈ L(n)
esetnek, illetve wY vektor egyes komponen-
sei P(Y |X) feltételes valószínűséggel, ahol X ∈ L(n−1)
. Ezen kívül P(Y |X) feltételes
valószínűség, akkor és csak akkor különbözik 0-tól, ha XκY . Az elmondottak alapján
az algoritmus bejárását úgy kell módosítanunk, hogy minden X ∈ L(n−1)
esethez és
i γ(X), i ∈ I indexhez, felsoroljuk σ(X, i) deszcendenseket, illetve ezen deszcenden-
sekhez megkeressük azon X ∈ L(n−1)
eseteket, melyekre X κσ(X, i) reláció teljesül.
Könnyen láthatjuk azt is, hogy ezen X esetek L(n−1)
szint felsorolásakor X eset után
kell következniük, valamint az is, hogy σ(X, i) = σ(X , j) csak j i, j ∈ I indexű
kategória esettén teljesülhet, illetve ebből j γ(Y ). Az Y deszcendens azon X aszcen-
denseinek indexét, melyekre még nem került sor a L(n−1)
szinten történő iteráció során,
a 3. algoritmushoz hasonlóan, kiszámíthatjuk egy v ∈ Nm
mutatóvektor segítségével,
ahol m a kategóriák száma.
Induljunk ki a 3.5. állításból, hogy a v mutatóvektort az új feltételeknek megfelelő-
en tudjuk kiszámítani. Amennyiben L(n−1)
és L(n)
sorozatok valamely (R, MIN, MAX)
háló n−1 illetve n szintjein lévő eseteinek lexikografikus felsorolása, létezik X ∈ L(n−1)
és Y ∈ L(n)
legkisebb illetve legnagyobb indexű elem, úgy, hogy L(n−1)
X-től nagyobb
indexű elemeinek i1 kategóriáját csökkentve eggyel L(n)
Y -tól kisebb indexű elemeit
kapjuk. Természetesen ez azt is jelenti, hogy X után pontosan annyi elem van mint Y
előtt. Ugyanakkor, ha n ri1 akkor X az első elem lesz az L(n)
felsorolásban. Egyéb-
ként, ha n > ri1 akkor X indexét úgy kaphatjuk meg, hogy kiszámoljuk, hány olyan
eset van L(n)
elején, ami 0-val kezdődik. Ezt könnyen megtehetjük, ha elhagyjuk R-ből
ri1 -et, és felsoroljuk R = {ri2 , ri3 , . . . , rim }-ből kiindulva az összes esetet, ezek elejére
írva az elhagyott 0-t éppen a keresett eseteket kapjuk. Azonban a konkrét esetekre
ezúttal nincs szükségünk csak a számukra, hogy megkapjuk a keresett X eset indexét.
A többi ij ∈ I kategória esetén az eddig elmondottakhoz hasonló számolhatunk, azzal
a különbséggel, hogy nem csak a felsorolás elején, lehet szükség, hogy bizonyos eseteket
L(n)
-ben átugorjunk, hanem a felsorolás belsejében is.
Annak érdekében, hogy az elmondottak alapján a kívánt algoritmust meg tudjuk
adni használjuk a következő jelölést.
3.7. definíció. Jelöljük a R ∈ D indexelt halmaznak azt a részhalmazát, amely az
i ∈ I indextől nagyobb indexű elemeit tartalmazza a következőképpen:
tail : D × I → D,
tail(R, ij) = {rij
, rij+1
, . . . , rim },
ahol R = {ri1 , ri2 , . . . , rij
, . . . , rim }.
26
3.3. Cikk-cakk bejárás
Az elmondott gondolatmenetet a 4. algoritmusban összegezzük.
4. algoritmus Zig-zag
1. n = 0, L(n)
= R .
2. n = n + 1, L(n)
= .
3. Inicializáljunk a p = L
(ni)
i
i∈I
mutató vektort, ahol ni = n − i
j=i1
rj,
valamint L
(ni)
i az éppen felsorolt hálónak az a részhálója, melynek szuprémuma
T = tail(R, i) infimuma pedig {0}|T|
.
4. Iteráljunk X ∈ L(n−1)
eseteken és legyen h X indexe L(n−1)
, ekkor állítsuk elő
XκY eseteket a következő módon:
(a) j = k, ahol ik = γ(X).
(b) Y = σ(X, ij).
(c) Ha Y = ∅, akkor L(n)
= L(n)
⊕ Y , és pj = pj + 1, ahol pj a p vektor j-edik
komponense.
(d) Számítsuk ki Y valószínűségét a teljes valószínűség tétele segítségével, ehhez
X κY : X ∈ L(n−1)
aszcendensek indexét L(n−1)
-ben a következők szerint
állíthatjuk elő:
I. l = 1.
II. Ha l = j és xl < rl.
A. Ha pl > h.
i. X ∈ L(n−1)
aszcendense Y -nak, és X indexe L(n−1)
-ben pl.
ii. pl = pl + 1.
B. Egyébként:
i. Ha n∗
> 0, ahol n∗
= n − l
j=i1
rj − yj,
pl = h + L∗(n∗)
, ahol L∗(n∗)
annak a részhálónak az n∗
-adik
szintje, aminek szuprémuma tail(R, il), és infimuma {0}m−l
.
ii. Egyébként pl = h + 1.
iii. X ∈ L(n−1)
aszcendense Y -nak, és X indexe L(n−1)
-ben pl.
iv. pl = pl + 1.
III. Ha l < m, akkor l = l + 1 és folytatjuk a 4.(d)II. ponttól, egyébként
a 4.(e) ponttól.
(e) j = j + 1 folytassuk a 4.(b) pontól, amíg j m egyébként az 5. ponttól.
5. Legyen X most a következő eset az L(n−1)
sorozatban és folytassuk a 4. ponttól,
ha nincs több menjünk a 6. pontra.
6. Ha n = i∈I ri készen vagyunk, egyébként folytassuk a 2. ponttól.
A 4.1. tételben megadunk egy lehetséges módszert a szintek hosszának kiszámítá-
sára anélkül, hogy felsorolnánk az egyes eseteket. Ugyanakkor az éppen felsorolt hálóból
27
3.3. Cikk-cakk bejárás
is kiolvashatjuk a keresett szintek hosszát, ha a gondolat meneten teszünk egy apró vál-
toztatást. Ha az eseteket 0 helyett ri1 -el egészítjük ki akkor jól látható, hogy ezek az
éppen felsorolás alatt lévő háló szintjeinek végén szereplő elemek. Tehát a felsorolás
során előállítható egy táblázat, amiben ezeknek az eseteknek az indexeit tároljuk.
5. algoritmus Zig-zag
Require: L(n−1)
, R, [ n ], [ T ]
1: L(n)
← list()
2: Y ← L
(n−1)
0
3: m ← length(Y )
4: if n = ∅ then
5: d ← m−1
l=0 Yl
6: n ← m−1
l=0 Rl − d
7: end if
8: v ← list()
9: for i ← 0 to m − 2 do
10: n∗
← n − i
l=0 Rl
11: if n∗
> 0 then
12: skip ← len_tab[i][n∗
]
13: else
14: skip ← 0
15: end if
16: v.push(skip)
17: end for
18: v.push(0)
19: if T = ∅ then
20: for i ← 0 to m − 1 do
21: T.push(0)
22: end for
23: end if
24: for i ← 0 to m − 1 do
25: flush[i] ← ∅
26: end for
27: for i ← 0 to length(L(n−1)
)-1 do
28: Y ← L
(n−1)
i
29: o ← γ(Y ) − δ(Y, T)
30: for j ← γ(Y ) to m − 1 do
31: flush[j − o] ← length(L(n)
)
32: if Yj > Tj then
33: p ← Y.P · Yj
34: inc(vj)
35: for k ← 0 to m − 1 do
36: if k = j and Yj < Rj then
37: if vk i then
38: n∗
← n − j
l=0 Rl +
γ(Y )
l=0 Yl
28
3.3. Cikk-cakk bejárás
39: if n∗
> 0 then
40: skip ← len_tab[j + 1][n∗
]
41: else
42: skip ← 1
43: end if
44: vk ← i + skip
45: end if
46: X ← L
(n−1)
vk
47: p ← p + X.P · Yk
48: inc(vk)
49: end if
50: end for
51: X ← copy(Y )
52: dec(Xj)
53: X.P ← p/d
54: L(n)
.push(X)
55: else
56: inc(o)
57: end if
58: end for
59: end for
60: for i ← 0 to m − 1 do
61: if flush[i] = ∅ then
62: len_tab[i].push(length(L(n)
)−flush[i])
63: end if
64: end for
65: return L(n)
29
4. fejezet
Az alkalmazás korlátai
Az alkalmazás területét egyfelől behatárolja a 2. fejezetben említett közelítési eljárások,
hiszen ezek számítás igénye jóval kisebb, azonban nem alkalmazhatóak minden eset-
ben. Elsősorban azon esetek kiszámításának hatékonyságát szükséges megvizsgálnunk,
ahol ezek nem alkalmazhatóak. A hatékonyság vizsgálatához érdemes a ciklusszámra
vonatkozóan számításokat végeznünk.
4.1. tétel. A (D, MAX, MIN) háló n. szintjén lévő, vagyis a L(n)
sorozatot alkotó hal-
mazok száma megadható
|L(n)
| =
J∈2I SJ −1<n
(−1)|J| m + n − 1 − SJ
n − SJ
, (4.1)
ahol
SJ =
j∈J
rj + |J|
összefüggéssel.
Bizonyítás. Tekintsük a
n min
ri∈R
ri
.
= rmin (4.2)
esetet, ekkor |L(n)
| megegyezik azzal, ha visszatevéses minta vételt alkalmaztunk vol-
na, vagyis a polinomiális eloszlás eseteinek számával, ami pedig megadható ismétléses
kombinációval a következőképpen:
|L(n)
| =
m + n − 1
n
,
ami megegyezik az állításban szereplő összeggel, hiszen n rmin esetén SJ − 1 < n
feltételt csak J = ∅ elégíti ki.
Ha a (4.2) feltétel nem teljesül, akkor azonban
|L(n)
| <
m + n − 1
n
,
mivel lesz legalább egy kategória, amiből nem tudjuk az összes elemet úgy kihúzni,
hogy másik kategóriából nem húzunk.
A különbséget szintén egy ismétléses kombinációval adhatjuk meg
n ri + rj + 1, ∀i, j ∈ I (4.3)
30
esetén
|L(n)
| =
m + n − 1
n
−
ri<n
m + n − ri − 2
n − ri − 1
(4.4)
szerint. Ez belátható, ha tekintjük a (D, MAX, MIN) hálót alkotó halmazokat. A már
említett szimmetria miatt, ezek elemei jelenthetik az egyes kategóriákból már kihúzott
elemek számát is, ekkor a háló infimumából, vagyis a csupa nullát tartalmazó halmaz-
ból, indulunk ki. Ekkor jól látható, hogy azok a halmazok amelyekben az i indexű
elem nagyobb az ri elemnél kívül esnek azon a részhálón, amelynek szuprémuma az
R halmaz. Ezek a részhálón kívüli halmazok is megadhatóak egy részhálóval, aminek
infimuma az a halmaz melynek elemei csupa nulla az i. kivételével, ami ri + 1. Vagyis
(4.4) valóban teljesül (4.3) esetén. Az is jól látszik, hogy amennyiben a (4.3) feltétel
teljesül az SJ − 1 < n feltételt csak |J| = 1 halmazok elégítik ki. Vagyis az állításban
szereplő képlet (4.3) esetén megegyezik (4.4)-el.
Amennyiben azonban ri + rj + 1 < n az említett a részhálók metszetik egymást
ezért
|L(n)
| >
m + n − 1
n
−
ri<n
m + n − ri − 2
n − ri − 1
,
mivel a metszetükben szereplő halmazokat kétszer vontuk le. A metszetük azonban
megint csak egy részháló, amit alkotó halmazok számát az eddigi gondolat menetet
követve meg tudjuk adni
|L(n)
| =
m + n − 1
n
−
ri<n
m + n − ri − 2
n − ri − 1
+
ri+rj+1<n
m + n − ri − rj − 3
n − ri − rj − 2
alakban, ha
n ri + rj + rk + 2, ∀ i, j, k ∈ I
teljesül.
A felváltott előjelű összegzést egészen m tagú összegig folytathatjuk, ami jól látha-
tóan meg felel magával az állítással.
Ennek ismeretében több megállapítást is tehetünk. Először is a γ és δ segédváltozók
miatt jól láthatóan az esetek számával lineárisan arányos overhead lép fel, ugyanakkor
δ(X, T) γ(X) im, miatt ezen változóknak elegendő kevés memória terület is, hiszen
a (4.1) képletből jól láthatóan O(m!) nagyságrendben nő az esetek száma. Ezért nagy
m értékek esetén nem lesz hatékony. Ennek fő oka, hogy a W(n)
mátrixok egy újabb
overhead-et képeznek, ami első közelítésben |Ln−1
| × |Ln−1
| méretű vagyis faktoriális
négyzetnek tűnik. Azonban láttuk, hogy ezek a mátrixok ritkák, minden sor és oszlop
vektoruk legfeljebb m számú nem 0 elemet tartalmaz. Ebből azt kapjuk W(n)
mérete
O(m · m!).
Összegezve az alkalmazás legerősebb korlátját a W(n)
mátrixok tárolása okozza.
A (4.1) képlet legnagyobb jelentőségét az adja, hogy segítségével pontosan megtudjuk
adni a számításhoz szükséges memória használat csúcsát a kiindulási adatok alapján.
A 3. algoritmus segítségével megtehetjük n = 0, ..., N iterációt. Ekkor könnyen be-
látható, hogy W(n)
mátrix mérete ˙n = N
2
esetén lesz a legnagyobb. A W( ˙n)
mátrixon
kívül tárolnunk szükséges L( ˙n−1)
és L( ˙n)
sorozatokat, illetve ezen felül a kimenő adato-
kat. Ezek méretét i∈I ri = N ismeretében előre ki tudjuk pontosan számítani a (4.1)
képlet segítségével. Amennyiben nincs szükségünk minden W(n)
által hordozott infor-
mációkra, csak az egyes esetek valószínűség értékére, minden új L(n)
szint felsorolása
31
után elvégezhető p(n)
= W(n)
p(n−1)
szorzás. Ekkor elég minden esethez magát a való-
színűség értékét tárolni.
Ez egyben rámutat egy másik problémára is egyúttal, nevezetesen, hogy egy L(n)
felsorolásához minden megelőző szintet is elő kell állítanunk, ami viszont akár túl nagy
költségnek is bizonyulhat. Mindazon által egy statisztikai vizsgálatnál nem biztos, hogy
haszontalan.
Érdemes továbbá a valószínűség értékek kiszámításának módját is megvizsgálnunk.
Első megállapításunk, hogy mikor a 3. algoritmus segítségével akarjuk elő állítani
L(n)
felsorolást akkor feltételezzük, hogy L(n−1)
ismert, ezért n változó szerinti iterá-
ciót párhuzamos feldolgozással nem tudjuk megtenni. Ugyanakkor a 15. sorban lévő,
L(n−1)
felsorolás elemein történő iterációt sem tudjuk párhuzamosan megtenni a v index
vektor koordinátáinak a 35. illetve a 37. sorokban történő írása miatt. A mátrix vek-
torainak szorzása viszont párhuzamosan elvégezhető. Illetve ez a megoldás numerikus
stabilitás szempontjából is kedvező, mivel a vektorokban szereplő hányadosok szorzat
összege állítja adja a valószínűség értékeket, szemben a (2.1) képlettel, aminek számítá-
sa felváltott szorzást és osztást igényel, annak érdekében, hogy az érték ne lépjen ki az
ábrázolási tartományból. Ugyanakkor a P(Y |X) nevezője (N − n), így P(Y |X)P(X)
nevezője pedig N!/n!, ahol X ∈ L(n−1)
, Y ∈ L(n)
. Azaz a mátrix műveletek valójában
a felváltott osztás és szorzás szervezését egyszerűsíti. Az mindenesetre jól látszik, hogy
többlet műveletet nem jelent a binomiális együtthatók számításához képest.
Ha a valószínűség-számítás és statisztika területétől tágabban tekintjük az alkalma-
zási lehetőségeket, akkor azt mondhatjuk, hogy kiválasztási, illetve oszthatósági prob-
lémák esetén kifejezetten előnyös lehet a (D, MIN, MAX) struktúra, illetve a probléma
megfogalmazása a segítségével. Ez a struktúra megkönnyítheti a részproblémákra tör-
ténő felbontást vagy az esetek felsorolását.
32
5. fejezet
Fejlesztői dokumentáció
Célunk, olyan algoritmus megalkotása volt, mely a 2. fejezetben ismertetett feladatot
képes megoldani. Vagyis képes a polihipergeometrikus eloszlás összes esetét felsorolni.
A fejlesztés MATLAB környezetben kezdtem az eredeti probléma két részre bontásával.
Ezek a kihúzott elemek számának m tagú összegre bontása, illetve a tagok permutálása
volt. A rész feladatok megoldására ismert algoritmusokat használtam[9, 5]. Az így elké-
szült algoritmus a valószínűség értékeket a (2.1) képlet szerint binomiális együtthatók
számításával adta meg.
Ez a megoldás bár a végleges algoritmustól gyökeresen különbözött, jó kiinduló-
pontot és tapasztalatot szolgáltatott a további vizsgálatokhoz. Elvezetett a probléma
a 2.3. tételben megadott hálóelméleti fogalmak segítségével történő átformálásához,
valamint a valószínűség értékek a 2.8. tételben megadott számítási módjához. Utób-
bi egyben új kritériumot is szolgáltatott a felsorolás indexelésével szemben. A további
munka elvezetett az itt tárgyalt algoritmushoz, ugyanakkor rámutatott arra az igényre
is, hogy objektum orientált környezetben valósítsuk meg.
A megoldás során a python programozási nyelvre[8] esett a választás. Ezt a dön-
tés egyfelől az említett irodalom ihlette. Másrészről a W(n)
átviteli súlymátrixokról
jól látszódott, hogy ritkák, ezért olyan környezetet kerestem, amelyben a ritka mátri-
xok kezelése megoldott. A python programozási nyelvhez elérhető a scipy csomag[4],
mely elterjedten használt és kész megoldást tartalmaz számos számítás elvégzéséhez,
köztük a ritka mátrixok kezelésére is. A python implementáció elkészítése, az objek-
tum orientáltságból adódóan, segítette a formalizált leírás letisztázását, a jobb meg-
értést. A fejlesztés során a git verzió követőt használtam, a programkód elérhető a
https://github.com/sulyi/multivariate-hypergeometric.git gyűjteményben.
Az elkészült implementáció egy mvhgd nevű python csomagból áll, melyet két alcso-
magra, core és algorithms, osztotam szét, illetve tartalmaz egy utils és egy tester
nevű modult. A csomag UML diagramja az 5.1. ábrán látható. A python nyelv saját-
ságai miatt szükségünk volt «utility» sztereotípiával ellátott pszeudoosztályok haszná-
latára is, melyek a modul szintű metódusokat tartalmazzák.
Az utils modul az ismétlés nélküli és ismétléses kombináció számítását végző nCk és
nCik metódusokat és a 4.1. tételben megadott képlet számítását végző LevelLength
osztályt tartalmaza. Ezenkívül az _f_nCk, _m_nCk védett és az __r_nCk privát mo-
dul szintű metódusok a binomiális együtthatót számítják faktoriális, multiplikatív és
33
rekurzív képlet szerint, melyek az (5.1) formulában láthatóak:
n
k
=
n!
k! · (n − k)!
n
k
=
n−k
i=1
k + 1
i
n
k
=
n − 1
k − 1
+
n − 1
k
.
(5.1)
Az utils modul önmagában is futtatható, ekkor a védett metódusokat dinamikusan
kigyűjti és a programkódban rögzített teszt adatokkal méri processzoridejüket. A rekur-
zív __r_nCk metódus nagy többletköltsége miatt privát minősítést kapott, amit a nyelv
konvenció szerint két _ jelöl. A modulban szereplő LevelLength osztály inicializáció
során hívja a power_set_ordered_by_sums metódust. Ami classmethod dekorátor-
ral láttam el, azaz osztály szintű vagy szingleton metódus. Ez felsorolja a konstruktor
paraméterlistájában megadott supremum összes részhalmazát az elemek összegének
sorrendjében és a _psobs privát adattagban eltárolja. Továbbiakban a példányosított
objektum precalculate_length metódusát meghívva a szint számával a (4.1) képlet-
ben szereplő binomiális együtthatókat kiszámítja és összegzi azokat, majd visszatér az
így kapott számmal, ami a szint hossza.
A tester modul az elkészült implementáció tesztelését, az azonos feladatot el-
látó részek összehasonlítását könnyíti meg. Három modulszintű metódust tartalmaz.
A generate_input_data teszt adatok előállítását végzi. A compare_test két meg-
adott implementációt az algorithms alcsomagból hasonlít össze, visszatérési értéké-
ben a két processzoridőt és a kiszámított valószínűségek eltérésének maximumát adja.
A cputime_test a nagyon rövid processzoridőket tudja mérni úgy, hogy addig növeli
tízszeresére a futtatások számát míg a futás idő mérhető méretű nem lesz.
A két alcsomag átlátszóra készült, vagyis az osztályaikat az importálás során a fe-
lette lévő csomag a saját névtartományába emeli. Így rejtve marad, hogy a csomagban
szereplő osztályokat külön modulban implementáltam és a névtartomány átláthatóbb.
A core nevű alcsomag négy osztályt tartalmaz, melyeknek Pretty, Draw, Grid és Level
a nevük. A Pretty és a Draw a list beépített osztály leszármazottjai. A Pretty mind-
össze a szöveges megjelenítés felül definiálását szolgálja, illetve a szülőosztály bizonyos
list típussal visszatérő metódusait definiálja felül, annak érdekében, hogy a vissza-
adott érték típusa Pretty maradjon. A Draw osztály a szülőosztályt egy gamma és P
adattaggal egészíti ki, utóbbi tárolja az eset valószínűségét. Az inicializáció során az
iterable paraméteren próbál iterálni és közben egyben elllenörzi, hogy az egyes tagok
számok. Továbbá felüldefiniálja az összehasonlító relációkat és a szöveges megjelenítést
végző metódusokat.
A Grid osztály tartalmaz többek között egy root adattagot, ami a bejárni kívánt
háló szuprémumát tárolja. A konstruktornak adott supremum paraméter validációja
megtörténik azáltal, hogy egy Draw objektumot példányosíásán keresztül, ez tárolódik
végül a root adattagban. A roof adattag ennek összegét tárolja, az m adattagban
pedig a hossza, a könnyebb elérés érdekében. Az algorithm adattag a konstruktor
másik paraméterét tárolja, de csak a Level osztályban történik meg a validációja.
Azonban a generator metódus használja a Level osztályt és a _generator adattag
az inicializáció során ez a metódus által visszaadott generátort tárolja. A _generator
átlátszó módon elérhető, amit a next és az __iter__ metódusok biztosítanak. Tehát a
34
5.1. ábra. mvhgd csomag UML diagramja
35
Grid példányok közvetlenül iterálhatóak. A limit_to metódus a _generator és ezáltal
a Grid példány iterációját korlátozza úgy, hogy vagy a bejárt szintek számát vagy egy
infimumot állít be a megadott target paraméternek megfelelően. A target paraméter
ellenőrzése természetesen nem csak addig terjed, hogy el lehessen dönteni a beállítani
kívánt korlát minőségét, de validáció is történik. Ennek érdekében használjuk a Draw
osztály összehasonlító relációit. Az _iroot adattag a 3.7. definícióban megadott
tail(R, i), i ∈ I halmazokat tárolja, ahol R a háló szuprémuma és I az index halmaz.
Végezetül a _len_tab adattag az 5. algoritmusban ismertetett táblázatot tárolja,
illetve a _read_len_tab metódus ezt a táblázatot olvassa úgy, hogy a 10. és a 38.
sorokban szereplő számításokat egyszerűsíti. A _len_tab és a _read_len_tab védett
elérésű hiszen előbbi az iteráció során kerül kitöltésre, ezért az olvasása kizárólag a
Level osztályon keresztül javasolt.
A Level osztály mindösszesen egy egységes felületet biztosít az algorithms alcso-
magban lévő osztályok számára, valamint néhány validációt végez, tehát egy polimorfi-
kus gyár (factory) osztály. Az inicializáció során a megkapott algorithm a Pretty egy
alosztályaként validálja és meghívja a konstruktorát a másik két megadott parent és
iterable paraméterekkel, végezetül a state adattagban tárolja. Az parent paramé-
tert Grid példányaként, az iterable paramétert pedig iterálhatóként validálja, mely-
nek minden tagjáról ellenőrzi, hogy a Draw osztály példánya. A P metódust property
dekorátorral láttuk el és ennek megfelelően az UML diagramon az attribútumok közé
került, egy generátort ad vissza, ami a state adattagon iterál és az egyes elemek P att-
ribútumát szolgáltatja. A next_level metódus a state adattag megfelelő metódusát
hívja, ha nincsen n és-vagy target paraméter megadva akkor maga állítja be azokat
a state számára. A __repr__ metódus a python konvencióknak megfelelő szöveges
reprezentációt add vissza. A többi metódus az __str__-t is beleértve azonban a state
adattag megfelelő metódusát hívják.
Az algorithms alcsomag három osztályt tartalmaz, melyek a Pretty osztály leszár-
mazottai. Mind a három osztály a hálót bejárását végző egyik algoritmus implemen-
tációja. Az Enumeration osztály a 3. fejezetben ismertetett felsorolást valósítja meg,
a valószínűség értékeket azonban a klasszikus (2.1) képlet szerint számítja. A Descend
és Zigzag osztályok pedig a 3. illetve az 5. algoritmusban ismertetett módon végzi
a bejárást és a valószínűségek számítását. Mindegyik változat rendelkezik egy parent
adattaggal, amin keresztül eléri a Grid példány szükséges attribútumait és metódu-
sait. A Descend osztály ezenkívül egy twmatrix adattaggal is rendelkezik, amiben a
szinthez tartozó átviteli súlymátrixot tárolja scipy.sparse.csc_matrix típussal. To-
vábbá mindegyik változat rendelkezik egy next_level függvénnyel, ami a következő
szint felsorolását végzi.
A csomag dokumentációja pydoc-ban is megtörtént, így az mind python nyelvhez
használt fejlesztői környezetekben könnyen használható mind a forrás jól értelmezhető,
de igény szerint interpreterből is lekérhető.
A python nyelvet több képszerkesztő is támogatja. Kézenfekvően adódott az igény,
hogy az elkészült csomag felhasználható legyen ábrák készítésére is. Ebből a meggon-
dolásból készült el a Dia programhoz egy bővítmény szkript. A Dia képszerkesztő nyílt
forrás kódú, fejlesztés és karbantartása a GNOME projekten belül történik. Tervezésé-
nek kulcs szempontja a rugalmasság, grafikus felülete Gtk+ alapú. Fordításkor kikap-
csolható a python támogatás, illetve léteznek ilyen előre fordított változatok, egyébként
feltételezi, hogy a rendszere python interpreter, illetve a szükséges python csomagok,
köztük a python-gtk2 telepítve van. Az elkészült bővítmény külön modulba szervez-
36
tük, ami egyrészt a Dia képszerkesztővel, másfelől az mvhgd modullal áll függőségben.
A fejlesztés a hálózaton megtalálható példa szkriptek valamint útmutatók segítségével
történt.
Az mvhgd_dia modul a Dia indulásakor regisztrálja az mvhgd_cb modulszintű me-
tódust egy a programkódba bedrótozott nevű menü pontba. Ennek aktiválásakor ez a
metódus példányosít egy CInputDialog osztályt. Ez a pygtk csomag segítségével meg-
jelenít egy párbeszéd ablakot, illetve az on_draw metódusa az itt megadott adatokat
előkészíti az mvhgd csomag számára, hiba üzenetet jelenít meg, ha ez kudarcot vall.
Egyébként a draw_lattice modul szintű metódust hívja, ami az mvhgd.Grid, illetve
az mvhgd.algorithms.Descend osztályokat használva, az általuk létrehozott adatok
alapján, megrajzolja a hálót.
37
6. fejezet
Az algoritmus tesztelése
A 2. fejezetben definiáltuk a W(n)
átviteli súlymátrixokat, melyek szorzatáról megmu-
tattuk, hogy a polihipergeometrikus eloszlás értékeivel egyezik meg. A 3. fejezetben,
pedig ismertettünk egy algoritmust, ami felsorolja a polihipergeometrikus eloszlás ese-
teit, illetve ezzel egy időben a W(n)
átviteli súlymátrixokat is kiszámolja. A 3.1. ábrán
megadtunk egy példát is, amiről leolvasható az esetek sorrendje. A következőkben ehhez
a példához tartozó W(n)
átviteli súlymátrixokat n = 0, . . . , 9 is megadjuk. Megmutat-
juk a n = 0, 1, 2 esetén, hogy szorzatuk a valószínűség értékekből képzett vektorral
megegyezik. Ehhez a (2.1) képlet segítségével is kiszámoljuk a valószínűség értékeket,
illetve n = 3 esetre csak a szorzás eredményét közöljük, terjedelmi megfontolásból.
Az implementáció megfelelő részéhez tartozó egységteszt tervezésekor ez a megol-
dás jó kiinduló pontként szolgál, azonban az esetleges hiba jellegéről keveset árul el.
Tehát érdemes további teszteseteket készíteni. Például ellenőrizni, hogy a W(n)
átviteli
súlymátrixok minden oszlop vektora, pontosan annyi nullától különböző értéket tartal-
maz, mint az azonos indexű eset az L(n−1)
felsorolásban. Továbbá L(n)
felsorolásban az
oszlop vektor nullától különböző értékeinek sor indexével azonos indexű elem valóban
követési relációban áll az oszlop vektorhoz tatozó elemmel.
W(0) .
= 1 = p(0)
=
3
0
2
0
4
0
9
0
,
W(1)
=




0, 3333
0, 2222
0, 4444



 =













3
1
2
0
4
0
9
1
3
0
2
1
4
0
9
1
3
0
2
0
4
1
9
1













,
p(1)
= W(1)
p(0)
= W(1)
W(0)
= W(1)
,
38
W(2)
=












0, 25 0 0
0, 25 0, 375 0
0, 5 0 0, 375
0 0, 125 0
0 0, 5 0, 25
0 0 0, 375












,
p(2)
= W(2)
p(1)
= W(2)
W(1)
W(0)
=
= 0, 0833 0, 1667 0, 3333 0, 0278 0, 2222 0, 1667 =
=
3
2
2
0
4
0
9
2
3
1
2
1
4
0
9
2
3
1
2
0
4
1
9
2
3
0
2
2
4
0
9
2
3
0
2
1
4
1
9
2
3
0
2
0
4
2
9
2
,
W(3)
=




















0, 1429 0 0 0 0 0
0, 2857 0, 2857 0 0 0 0
0, 5714 0 0, 2857 0 0 0
0 0, 1429 0 0, 4286 0 0
0 0, 5714 0, 2857 0 0, 4286 0
0 0 0, 4286 0 0 0, 4286
0 0 0 0, 5714 0, 1429 0
0 0 0 0 0, 4286 0, 2857
0 0 0 0 0 0, 2857




















,
p(3)
= W(3)
p(2)
= W(3)
W(2)
W(1)
W(0)
=
= 0, 0119 0, 0714 0, 1428 0, 0357 0, 2857 0, 2142 0, 0476 0, 1428 0, 0476 ,
W(4)
=

























0, 3333 0, 1667 0 0 0 0 0 0 0
0, 6667 0 0, 1667 0 0 0 0 0 0
0 0, 1667 0 0, 3333 0 0 0 0 0
0 0, 6667 0, 3333 0 0, 3333 0 0 0 0
0 0 0, 5 0 0 0, 3333 0 0 0
0 0 0 0, 6667 0, 1667 0 0, 5 0 0
0 0 0 0 0, 5 0, 3333 0 0, 5 0
0 0 0 0 0 0, 3333 0 0 0, 5
0 0 0 0 0 0 0, 5 0, 1667 0
0 0 0 0 0 0 0 0, 3333 0, 3333
0 0 0 0 0 0 0 0 0, 1667

























,
39
W(5)
=

























0, 2 0 0, 2 0 0 0 0 0 0 0 0
0, 8 0, 4 0 0, 2 0 0 0 0 0 0 0
0 0, 6 0 0 0, 2 0 0 0 0 0 0
0 0 0, 8 0, 2 0 0, 4 0 0 0 0 0
0 0 0 0, 6 0, 4 0 0, 4 0 0 0 0
0 0 0 0 0, 4 0 0 0, 4 0 0 0
0 0 0 0 0 0, 6 0, 2 0 0, 6 0 0
0 0 0 0 0 0 0, 4 0, 4 0 0, 6 0
0 0 0 0 0 0 0 0, 2 0 0 0, 6
0 0 0 0 0 0 0 0 0, 4 0, 2 0
0 0 0 0 0 0 0 0 0 0, 2 0, 4

























,
W(6)
=




















1 0, 25 0 0, 25 0 0 0 0 0 0 0
0 0, 75 0, 5 0 0, 25 0 0 0 0 0 0
0 0 0, 5 0 0 0, 25 0 0 0 0 0
0 0 0 0, 75 0, 25 0 0, 5 0 0 0 0
0 0 0 0 0, 5 0, 5 0 0, 5 0 0 0
0 0 0 0 0 0, 25 0 0 0, 5 0 0
0 0 0 0 0 0 0, 5 0, 25 0 0, 75 0
0 0 0 0 0 0 0 0, 25 0, 5 0 0, 75
0 0 0 0 0 0 0 0 0 0, 25 0, 25




















,
W(7)
=












1 0, 3333 0 0, 3333 0 0 0 0 0
0 0, 6667 0, 6667 0 0, 3333 0 0 0 0
0 0 0, 3333 0 0 0, 3333 0 0 0
0 0 0 0, 6667 0, 3333 0 0, 6667 0 0
0 0 0 0 0, 3333 0, 6667 0 0, 6667 0
0 0 0 0 0 0 0, 3333 0, 3333 1












,
W(8)
=




1 0, 5 0 0, 5 0 0
0 0, 5 1 0 0, 5 0
0 0 0 0, 5 0, 5 1



 ,
W(9)
= 1 1 1 .
40
A 6.1. ábrán közölöm a Dia bővítmény szkript egy futási képét is, amelyen egyszerre
látszik a menüpont, amin keresztül indítható, a beviteli ablak, amiben a kiindulási
adatokat megadhatjuk és a végeredményként megrajzolt diagram.
6.1. ábra. Dia képszerkesztő futási képe a bővítmény szkripttel
Amellett, hogy az algoritmus által adott eredmények helyességét vizsgáljuk, a ha-
tékonysága is érdekel minket. A futási idő függését mértem a bemenő adatok m és N
paraméterei, azaz a kategóriák száma és az elemek száma, szerint. Ennek érdekében
az algoritmusokat négy adatsorra futtattam le. Az egyes adatsorokban az m paramé-
ter értékei rendre 3, 6, 9 és 12 volt. Az első adatsorban a kezdeti adat: {3, 2, 4}, majd
minden iterációban a az egyes elemekhez hozzáadtuk a kezdeti adat megfelelő inde-
xű elemét, tehát az adatsor többi adata {6, 4, 8}, {9, 6, 12}, . . . . A többi adatsor kezdő
adatát, úgy állítottuk elő, hogy a {3, 2, 4} végéhez ismételten hozzá írtuk önmagát, az
így kapott adatok: {3, 2, 4, 3, 2, 4}, {3, 2, 4, 3, 2, 4, 3, 2, 4} és {3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4},
majd mindegyiknél az első adatsornál elmondottak szerint növeltük az elemek számát.
A tesztelés során az Enumeration algoritmusban a binomiális együtthatókat a mul-
tiplikatív képlet szerint számítottam, lásd az (5.1) formulát.
A teszt architektúra specifikációja:
Hardver
Processzor: IntelR
XeonR
E5500, 2.13 GHz
Memória: 3.9 Gbyte
Lapozóterület: 7.5 Gbyte
Szoftver
Operációs rendszer: Debian GNU/Linux 7.5 (wheezy), x86_64
Interpreter: Python 2.7.3
Használt csomagok: Scipy 0.10.1
Numpy 1.8.2 (libc6 2.15)
41
A következő grafikon a négy adatsor futási idejét mutatja az elemszám függvényé-
ben:
0 50 100 150 200 250 300 350 400 450
0,001
0,01
0,1
1
10
100
1 000
N
t[s]
m=3 m=6 m=9 m=12
Enumerate
Descend
Zig-zag
6.2. ábra. Futási idő logaritmusa elemszám függvényében
Bemenő adat N Processzoridők [s]
Enumerate Descend Zig-zag
m = 3
[ 3,2,4 ] 9 2 · 10−3 * 1 · 10−2 1 · 10−3 *
[ 6,4,8 ] 18 1 · 10−2 1 · 10−2 1 · 10−2
[ 9,6,12 ] 27 2 · 10−2 2 · 10−2 2 · 10−2
[ 12,8,16 ] 36 5 · 10−2 5 · 10−2 4 · 10−2
[ 15,10,20 ] 45 9 · 10−2 8 · 10−2 7 · 10−2
[ 18,12,24 ] 54 0,12 8 · 10−2 0,11
[ 21,14,28 ] 63 0,20 0,12 0,13
[ 24,16,32 ] 72 0,35 0,17 0,20
[ 27,18,36 ] 81 0,52 0,22 0,26
[ 30,20,40 ] 90 0,74 0,30 0,36
[ 33,22,44 ] 99 1,05 0,37 0,48
[ 36,24,48 ] 108 1,44 0,49 0,60
[ 39,26,52 ] 117 1,91 0,61 0,77
[ 42,28,56 ] 126 2,53 0,75 0,95
[ 45,30,60 ] 135 3,26 0,91 1,15
[ 48,32,64 ] 144 4,16 1,10 1,40
[ 51,34,68 ] 153 5,29 1,30 1,67
42
Bemenő adat N Processzoridők [s]
Enumerate Descend Zig-zag
[ 54,36,72 ] 162 6,57 1,52 1,98
[ 57,38,76 ] 171 8,11 1,79 2,33
[ 60,40,80 ] 180 9,88 2,08 2,72
[ 63,42,84 ] 189 11,97 2,40 3,14
[ 66,44,88 ] 198 14,40 2,76 3,58
[ 69,46,92 ] 207 17,22 3,14 4,07
[ 72,48,96 ] 216 20,42 3,55 4,63
[ 75,50,100 ] 225 24,07 4,03 5,24
[ 78,52,104 ] 234 28,17 4,53 5,88
[ 81,54,108 ] 243 32,98 5,07 6,56
[ 84,56,112 ] 252 37,90 5,64 7,31
[ 87,58,116 ] 261 43,76 6,29 8,15
[ 90,60,120 ] 270 50,30 6,97 9,02
[ 93,62,124 ] 279 57,59 7,69 9,95
[ 96,64,128 ] 288 65,69 8,46 10,88
[ 99,66,132 ] 297 74,71 9,29 11,95
[ 102,68,136 ] 306 84,43 10,18 13,08
[ 105,70,140 ] 315 95,42 11,15 14,29
[ 108,72,144 ] 324 106,95 12,08 15,52
[ 111,74,148 ] 333 120,25 13,14 16,82
[ 114,76,152 ] 342 134,32 14,24 18,21
[ 117,78,156 ] 351 149,84 15,43 19,75
[ 120,80,160 ] 360 166,08 16,65 21,27
[ 123,82,164 ] 369 184,46 17,96 22,96
[ 126,84,168 ] 378 203,91 19,30 24,58
[ 129,86,172 ] 387 225,71 20,73 26,59
[ 132,88,176 ] 396 248,33 22,24 28,34
[ 135,90,180 ] 405 272,82 23,72 30,39
[ 138,92,184 ] 414 299,40 25,38 32,29
[ 141,94,188 ] 423 328,90 27,17 34,53
[ 144,96,192 ] 432 357,93 28,97 36,69
[ 147,98,196 ] 441 390,51 30,86 39,12
[ 150,100,200 ] 450 425,51 32,82 41,56
[ 153,102,204 ] 459 462,78 34,96 44,12
[ 156,104,208 ] 468 502,03 37,17 46,76
m = 6
[ 3,2,4,3,2,4 ] 18 7 · 10−2 5 · 10−2 6 · 10−2
43
Bemenő adat N Processzoridők [s]
Enumerate Descend Zig-zag
[ 6,4,8,6,4,8 ] 36 2,26 1,48 1,90
[ 9,6,12,9,6,12 ] 54 21,39 13,28 16,45
[ 12,8,16,12,8,16 ] 72 121,64 68,28 80,76
[ 15,10,20,15,10,20 ] 90 485,94 247,61 286,02
[ 18,12,24,18,12,24 ] 108 1 519,78 704,73 806,68
[ 21,14,28,21,14,28 ] 126 4 046,23 1 693,17 1 948,48
[ 24,16,32,24,16,32 ] 144 OoM** OoM** 4 185,13
[ 27,18,36,27,18,36 ] 162 OoM** OoM** OoM**
m = 9
[ 3,2,4,3,2,4,3,2,4 ] 27 5,80 4,48 5,31
[ 6,4,8,6,4,8,6,4,8 ] 54 1 013,82 OoM** OoM**
[ 9,6,12,9,6,12,9,6,12 ] 81 OoM** OoM** OoM**
m = 12
[ 3,2,4,3,2,4,3,2,4,3,2,4 ] 36 454,61 OoM** 405,73
[ 6,4,8,6,4,8,6,4,8,6,4,8 ] 72 OoM** OoM** OoM**
*
10 futtatás átlaga
**
Out of Memory, 3Gb korlát
6.1. táblázat Futási idők
44
7. fejezet
Összefoglalás
Ebben a dolgozatban megvizsgáltam a polihipergeometrikus eloszlás eseteinek felsorolá-
sát és valószínűség értékeinek lehetséges számítás módjait. A 2.3. tételben megadtam
egy algebrai struktúrát, majd megmutattam, hogyan segíti a probléma megoldását.
Majd ezt felhasználva a 3. fejezetben leírtam két algoritmust, amelyek az említett háló
bejárását valósítják meg. A fejezet végén pedig utalást tettem a probléma számelmé-
leti vonatkozásaira is. Az 5. fejezetben ismertettem ezen algoritmusok általam python
nyelven elkészített implementációját, illetve az összehasonlításához szükséges eszközö-
ket. Továbbá említést tettem az irodalomban megtalálható algoritmusokról is, melyek
a munkám kiinduló pontjaként szolgáltak. Végezetül bemutattam a 6. fejezetben az
implementáció tesztelése során nyert adatokat.
A dolgozat hagyott nyitott kérdéseket, ezek a következőek:
• A 3. és az 5. algoritmus formális leírásából hiányzik az index számításának
pontos képlete, helyességük nincs bizonyítva.
• Az eloszlás eseteinek beszámozását az említett algoritmusok implicit módon old-
ják meg. A (4.1) formulában csak az utolsó elemek indexére, azaz a szintek hosszá-
ra adtunk explicit képletet.
Szeretném a második ponthoz megjegyezni, hogy a felsorolás a párhuzamos megvalósí-
tásához elengedhetetlen, hogy az esetek indexeit explicit módon tudjuk kiszámítani.
Ebben dolgozatban rámutattam egy hatékony módszer kidolgozásának lehetőségére,
mely a polihipergeometrikus eloszlás értékeit, olyan feltételek mellet is képes kiszámí-
tani, amikor közelítő eljárások nem alkalmazhatóak.
45
Irodalomjegyzék
[1] C. Huygens: Libellus De Ratiociniis in Ludo Aleæ, S. Keimer for T. Woodward,
London, 1714.
[2] A. Hald: History of Probability and Statistics and Their Applications before 1750,
Wiley-Interscience, New York, 1990.
[3] N. L. Johnson, S. Kotz, N. Balakrishnan, C. B. Read, B. Vidakovic: Encyclopedia
of statistical sciences, Wiley-Interscience, 2006., 3283–3292.
[4] E. Jones, T. Oliphant, P. Peterson, et al.: SciPy: Open Source Scientific Tools for
Python, (2001–), http://www.scipy.org
[5] J. Kelleher, B. O’Sullivan: Generating All Partitions: A Comparison Of Two
Encodings, arXiv:0909.2331 [cs.DS], 2009.
[6] Kiss Emil: Bevezetés az algebrába, Typotex, 2007., 480–488.
[7] K. Pearson: On Certain Properties of the Hypergeometrical Series, and on
the Fitting of such Series to Observation Polygons in the Theory of Chance,
Philosophical Magazine 5th Series, 47 (1899), 236–246.
[8] G. van Rossum, F. L. Drake: Python Reference Manual, PythonLabs, Virginia,
USA, 2001.
[9] A. Williams: Loopless Generation of Multiset Permutations using Constant Number
of Variables by Prefix Shifts, SODA ’09 Proceedings of the twentieth Annual
ACM-SIAM Symposium on Discrete Algorithms, (2009), 987–996.
46
Adathordozó használati útmutató
A mellékelt CD gyökérkönyvtárában megtalálható ez a dolgozat PDF formátumban
illetve a tex könyvtárban a LATEX forrásfájlok. A tex könyvárban három alkönyvtár
is található. Az include alkönyvtárban találhatóak az egyes fejezetek forrásfájljai. Az
images alkönyvtárban vannak a felhasznált PNG formátumú ábrák, illetve az 5.1. áb-
rának a Graphviz gv formátumú (a kiterjesztése .dot) forrása is. A data alkönyvtárban
a 6.1. táblázatban közölt adatok találhatóak CSV formátumban, egyrészről a tesztek
során közvetlenül nyert fájlok és az azokból összefűzött fájlok is.
Az multivariate-hypergeometric alkönyvtárban az elkészült implementáció ta-
lálható, a git metaadatokkal együtt (a .git alkönyvtárban). A gyökérkönyvtárban
található egy README.htm fájl, mely telepítési és használati segédletet tartalmaz.
47

Multivariate_Hypergeometric_Distribution

  • 1.
    Szakdolgozat Miskolci Egyetem A polihipergeometrikuseloszlás értékeinek algoritmikus számítása Készítette: Sülyi Ákos programtervező informatikus szak Témavezetők: Dr. Fegyverneki Sándor Dr. Karácsony Zsolt Miskolc, 2015
  • 2.
    Miskolci Egyetem Gépészmérnöki ésInformatikai Kar Alkalmazott Matematikai Tanszék Szám: Szakdolgozat Feladat Sülyi Ákos (QPATL4) programtervező informatikus jelölt részére. A szakdolgozat tárgyköre: Kombinatorikus leszámlálás A szakdolgozat címe: A polihipergeometrikus eloszlás értékeinek algoritmikus számítása A feladat részletezése: Egy sorrend megadása, mely az eloszlás összes esetét tartalmazza. A probléma hálóelméleti megfogalmazása és egy részben rendezés megadása. Megfelelő esetek a sorrendben felvett indexeinek számítása. Valószínűség értékek számítása a teljes valószínűség tételének segítségével. Algoritmus megadása. Az algoritmus implementációja python nyelven. Az algoritmus összeghasonlítása a kombinatorikus képlettel valószámítással. Témavezetők: Dr. Fegyverneki Sándor egyetemi docens, Dr. Karácsony Zsolt egyetemi docens A feladat kiadásának ideje: 2013. szeptember 10. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . szakfelelős 2
  • 3.
    Eredetiségi Nyilatkozat Alulírott .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; Neptun-kód: . . . . . . . . . . . . . . . . . . . a Miskolci Egyetem Gépészmérnöki és Informatikai Karának végzős . . . . . . . . . . . . . . . . . . . szakos hallgatója ezennel büntetőjogi és fegyelmi felelősségem tudatában nyilatkozom és aláírásommal igazolom, hogy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . című szakdolgozatom/diplomatervem saját, önálló munkám; az abban hivatkozott szak- irodalom felhasználása a forráskezelés szabályai szerint történt. Tudomásul veszem, hogy szakdolgozat esetén plágiumnak számít: • szószerinti idézet közlése idézőjel és hivatkozás megjelölése nélkül; • tartalmi idézet hivatkozás megjelölése nélkül; • más publikált gondolatainak saját gondolatként való feltüntetése. Alulírott kijelentem, hogy a plágium fogalmát megismertem, és tudomásul veszem, hogy plágium esetén szakdolgozatom visszautasításra kerül. Miskolc, . . . . . . . . . . . .év . . . . . . . . . . . .hó . . . . . . . . . . . .nap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Hallgató 3
  • 4.
    1. szükséges (módosítás különlapon) A szakdolgozat feladat módosítása nem szükséges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . dátum témavezető(k) 2. A feladat kidolgozását ellenőriztem: témavezető (dátum, aláírás): konzulens (dátum, aláírás): . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3. A szakdolgozat beadható: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . dátum témavezető(k) 4. A szakdolgozat . . . . . . . . . . . . . . . . . . . szövegoldalt . . . . . . . . . . . . . . . . . . . program protokollt (listát, felhasználói leírást) . . . . . . . . . . . . . . . . . . . elektronikus adathordozót (részletezve) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . egyéb mellékletet (részletezve) . . . . . . . . . . . . . . . . . . . tartalmaz. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . dátum témavezető(k) 5. bocsátható A szakdolgozat bírálatra nem bocsátható A bíráló neve: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . dátum szakfelelős 6. A szakdolgozat osztályzata a témavezető javaslata: . . . . . . . . . . . . . . . . a bíráló javaslata: . . . . . . . . . . . . . . . . a szakdolgozat végleges eredménye: . . . . . . . . . . . . . . . . Miskolc, . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a Záróvizsga Bizottság Elnöke 4
  • 5.
    Tartalomjegyzék Jelölések 6 1. Bevezetés7 2. A probléma megfogalmazása 8 3. A probléma algoritmikus megoldása 17 3.1. Az esetek felsorolása . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 3.2. Leszálló bejárás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 3.3. Cikk-cakk bejárás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 4. Az alkalmazás korlátai 30 5. Fejlesztői dokumentáció 33 6. Az algoritmus tesztelése 38 7. Összefoglalás 45 Irodalomjegyzék 46 Adathordozó használati útmutató 47 5
  • 6.
    Jelölések ∀ bármely (összes) ∃,∃! létezik, létezik pontosan egy N természetes számok (nemnegatív egészek) Z+ pozitív egész számok P prím számok ∅ üres halmaz × Decartes-féle szorzat ∪, ∩ halmazműveletek: unió, metszet ∈ halmazelméleti reláció: tartalmazza (eleme) ∨, ∧ hálóműveletek: egyesítés, metszet MIN, MAX indexenkénti minumum, maximum κ (közvetlen) követési reláció a1, . . . , an sorozat üres sorozat ⊕ hozzáfűzés , rendezési relációk: megelőző, követő <L , >L lexikografikus relációk: megelőző, követő , lényegesen (nagyságrenddel) kisebb, nagyobb . = definíció szerint egyenlő , összegzés, produktum n k binomiális együttható a! faktoriális quod erat demonstrandum 6
  • 7.
    1. fejezet Bevezetés A polihipergeometrikuseloszlás számos probléma megoldására használható. Könnyen találhatunk szerencsejátékok közt is olyat, ahol a lehetőségek valószínűségét ennek se- gítségével számolhatjuk. A történet írás szerint a probléma első megfogalmazása[1] is szerencsejátékhoz kötődik. A Huygens által felvetett problémát számos más egyén mel- lett James Bernoulli is megoldotta, ő azonban ezt a ma is használt általános alakban adta meg[2]. Magát a nevet azonban jóval később kapta Karl Pearson javasoltára[7]. A szerencsejátékon kívül azonban fontosak azok a statisztikai becslések is, melyeket ennek az eloszlás segítségével végezhetünk el. Például egy választáson induló pártok támogatottságára vagy egy élőlény populáció genetikai összetételére vonatkozó becslés. Ezen kívül homogenitási hipotézis eldöntésére is használhatjuk. Az eloszlás számítá- sát azonban több tényező is nehezíti. A legnyilvánvalóbb nehézség, hogy az általános problémában a változók száma kötetlen. Ebben a munkában rámutatok további nehézségekre is, melyek az esetek felsorolása kapcsán felmerülnek. Ugyanakkor ismertetem a probléma általam kidolgozott megfo- galmazását, aminek segítségével ezek a nehézségek kezelhetővé vállnak. Az új megköze- lítés egyben lehetővé teszi, hogy az eloszlás értékeit a klasszikus kombinatórikus képlet helyett, a teljes valószínűség tételének segítségével számoljuk ki. A számítás ilyen for- mában történő elvégzéséhez fontos a felsorolás sorendjének megfelelő megválasztása is. A számítási módszert algoritmikus formában is megadom. A dolgozat végén pe- dig ismertetem az általam python nyelven elkészített implementációt és az elvégzett futtatási tesztek eredményeit. Szeretnék személyes köszönetet mondani témavezető tanáraimnak, Dr. Fegyverneki Sándornak és Dr. Karácsony Zsoltnak nagy türelmükért, akiknek jó tanácsai és út- mutató kérdései nélkül ez a dolgozat nem készülhetett volna el. Továbbá középiskolai tanáromnak Dezsőfi Györgynek, hogy megmutatta számomra a matematika iránti ra- jongás és közös művelésének élvezetét. Valamint nem utolsó sorban szüleimnek töretlen bizalmukért. Ez a kutató munka a Miskolci Egyetem stratégiai kutatási területén működő Mechatronikai és Logisztikai Kiválósági Központ keretében valósult meg. 7
  • 8.
    2. fejezet A problémamegfogalmazása Tekintsük azt a helyzetet, melyben a következő feltételek teljesülnek: a) Adott egy N elemű halmaz. b) A halmaz elemei valamilyen tulajdonságuk alapján m ∈ Z+ számú kategóriába különíthetőek. Az egyes kategóriába tartozó elemek száma rendre n1, . . . , nm, azaz m i=1 ni = N. c) A halmazból egyszeri véletlenszerű húzással (visszatevés nélküli mintavétellel) K darab elemet emelünk ki. Legyen ξ1 . . . , ξm valószínűségi változók értéke a megfelelő kategóriába tartozó elemek száma a kihúzott elemek között. Ekkor a klasszikus valószínűségi modell szerint an- nak a valószínűsége, hogy ξ1 . . . , ξm valószínűségi változó rendre felveszi a k1, . . . , km, 0 ki ni, i = 1, . . . , m értéket: P(ξ1 =k1, . . . , ξm =km) = n1 k1 . . . nm km N K , (2.1) ahol m i=1 ki = K, m i=1 ni = N. A ξ1 . . . , ξm valószínűségi változók polihipergeomet- rikus eloszlásúak, illetve a változók eloszlását (2.1) szerint számolhatjuk [3]. Az alkalmazás szempontjából fontosabb eloszlásfüggvényt az eloszlás egyes változók szerinti összegzéseként kaphatjuk: P(ξ1 k1, . . . , ξm−1 km−1, K) = = k1 x1=0 · · · km−1 xm−1=0 n1 x1 . . . nm−1 xm−1 nm K − x1 − . . . − xm−1 N K = = 1 − K x1=k1+1 · · · K xm−1=km−1+1 n1 x1 . . . nm−1 xm−1 nm K − x1 − . . . − xm−1 N K , (2.2) ahol K m−1 i=1 ki. 8
  • 9.
    Fontos megjegyeznünk, hogyaz m = 2 speciális esetben egyszerűen hipergeomet- rikus eloszlásról beszélünk. Továbbá említésre méltó, hogy általában a tankönyvek di- daktikai szempontokból az említett két eloszlást fordított sorrendben tárgyalják, tehát a polihipergeometrikus eloszlást a hipergeometrikus általánosításaként. Az eloszlás, illetve az eloszlásfüggvény értékeinek megállapítása a binomiális együtt- hatók miatt nagy n1, . . . , nm esetén számítás technikailag több nehézséget is felvet. A binomiális együttható számlálója és nevezője a faktoriálisok miatt nagyságrendekkel nagyobb az együttható értékénél. Ez kiküszöbölhető, ha a számítás úgy szervezzük, hogy felváltva végzünk osztást és szorzást. Azonban az egyes együtthatók értékei még így is kívül eshetnek a rendelkezésre álló ábrázolási tartományból, ezért szükség lehet ennek a módszernek a kiterjesztésére a függvény által kijelölt osztás műveletekre is. Ez a módszer célra vezető lehet hiszen a függvény értéke 0 és 1 közé esik, ugyanakkor a tört számok ábrázolásából fakadó numerikus instabilitás valamint a nagy mennyiségű mű- velet igény továbbra is korlátozó tényező lehet. Az említett nehézségek áthidalhatóak, ha a (2.1) valamint a (2.2) pontos értéke helyett alkalmas közelítést használunk. Legkézenfekvőbb, ha a közelítés úgy tesszük, hogy eltekintünk a c) feltétel azon kikötésétől, hogy a K elemet egyszerre (visszatevés nélkül) húzzuk ki, helyette úgy tekintjük mintha az elemek kihúzása nem változtatná meg az egyes kategóriák arányát a teljes halmazhoz képest (visszatevéses mintavétel). Az így módosított feltételi körül- mények, pedig pontosan a polinomiális eloszlást eredményezik. Tehát a polinomiális eloszlás, ami P(ξ1 =k1, . . . , ξm =km) = K! k1! . . . km! n1 N k1 . . . nm N km , ahol K = m i=1 ki, valamint ennek eloszlásfüggvénye, ami P(ξ1 k1, . . . , ξm km−1, K) = = 1 − K x1=k1+1 · · · K xm−1=km−1+1 K! x1! . . . xm−1!(K − x1 − . . . − xm−1)! n1 N x1 . . . . . . nm−1 N xm−1 nm N K−x1−...−xm−1 , ahol K m−1 i=1 ki, használhatóak a polihipergeometrikus eloszlás közelítésére. A le- vezetésből az is kitűnik, hogy a közelítés akkor tekinthető jónak, ha N K vagy alkalmazás során ezt a feltételt K/N < 0.1 esetén tekintjük teljesítettnek. A polihipergeometrikus eloszlás m ∈ Z+ darab ξ1, . . . , ξm valószínűségi változó által felvett értékek valószínűségeit írja le. Ezen valószínűségi változók előállnak egy kezdeti urnából történő húzás során, mely urnában m kategóriába sorolható elemek vannak. Ekkor a valószínűségi változók jelölik, hogy a kihúzott elemek között, hány darab van az egyes kategóriából. Ezt úgy is megadhatjuk, hogy azt mondjuk meg, hogy hány darab maradt az egyes kategóriából a húzás után az urnában. Ez a megközelítés, olyan szem- pontból előnyösebb, hogy a kiindulási halmaz kategóriánkénti elemek számára minden- képpen szükség van. Célunk egy algoritmus megadása, mely a kezdeti elemszámokat csökkentve felsorolja az összes esetet, valamint az ezekhez tartozó valószínűségeket ki- számítja. A probléma jobban kezelhető hálóelmélet segítségével történő megfogalmazásban, mert a következőkben bevezetett algebrai struktúra megkönnyíti az algoritmikus felso- rolást. 9
  • 10.
    2.1. definíció. Azonosítsukaz X = { xi | xi ∈ N, i ∈ I } indexelt halmazokkal a po- lihipergeometrikus eloszlás eseteit, ahol ξi = xi a valószínűségi változók által felvett értékek, vagyis az egyes kategóriákba tartozó elemek darabszámai. Jelöljünk továbbá ezen X halmazok összességét D = X X ∈ × i∈I N , vagy egyszerűbben D = × i∈I N. Ez a megfogalmazás azért igen kellemes mivel jól leírja azt az előfeltételt, hogy a ξi, ξj illetve xi, xj változók felcserélését nem tekintjük külön esetnek. Ugyanakkor lehe- tővé teszi, hogy rögzítsük i1, . . . , im ∈ I indexek egy tetszőleges i1, . . . , im , sorozatát, ezzel megtartsuk sorrendjüket. Ezután D elemein adjunk meg egy részben rendezést. Ezt tegyük meg a következő D felett értelmezett két binér művelet bevezetésével. 2.2. definíció. Az X, Y ∈ D elemenként vett minimuma és maximuma X ∨ Y = MAX(X, Y ) = { max{xi, yi} | xi ∈ X, yi ∈ Y, i ∈ I }, X ∧ Y = MIN(X, Y ) = { min{xi, yi} | xi ∈ X, yi ∈ Y, i ∈ I }. 2.3. tétel. A (D, MIN, MAX) algebrai struktúra háló. Bizonyítás. A tétel állítás belátható, ha belátjuk a két műveletre a következő hat állítást[6]: ∀ A = {ai}, B = {bi}, C = {ci} ∈ D esetén, ahol i ∈ I, asszociatívak: MIN(A, MIN(B, C)) = MIN(MIN(A, B), C), (H1) MAX(A, MAX(B, C)) = MAX(MAX(A, B), C), (H2) kommutatívak: MIN(A, B) = MIN(B, A), (H3) MAX(A, B) = MAX(B, A), (H4) és abszorptívak: MIN(A, MAX(A, B)) = A, (H5) MAX(A, MIN(A, B)) = A. (H6) A (H1) eset bizonyítása: Legyen MIN(A, MIN(B, C)) = X = {xi}, MIN(B, C) = U = {ui}. 10
  • 11.
    A MIN definíciójaszerint ∀ i ∈ I, xi ai, (I) xi ui, (II) ui bi, (III) ui ci. (IV) A (II) és a (III) tulajdonságból valamint a (II) és a (IV) tulajdonságból xi bi , (V) xi ci , (VI) ugyanakkor az (I), az (V) és a (VI) alapján xi min{ai, bi, ci}, (VII) ebből azonban min{ai, bi, ci} ai (VIII) min{ai, bi, ci} bi, min{ai, bi, ci} ci vagyis min{ai, bi, ci} min{bi, ci}. (IX) Ezenkívül a (VIII) és a (IX) tulajdonságból min{ai, bi, ci} min{ai, min{bi, ci}} = xi, (X) végül a (VII) és a (X) tulajdonságból xi = min{ai, bi, ci} következik. Ezután (H1) igazolása érdekében belátjuk, hogy MIN(MIN(A, B), C) = Y = {yi} valamint MIN(A, B) = V = {vi} esetén yi = min{ai, bi, ci}, a következők szerint: yi ci, yi vi, vi ai, vi bi, tehát yi min{ai, bi, ci}, 11
  • 12.
    ugyanakkor min{ai, bi, ci}ai, min{ai, bi, ci} bi, min{ai, bi, ci} min{ai, bi}, min{ai, bi, ci} ci, vagyis min{ai, bi, ci} min{min{ai, bi}, ci} = yi, ezért yi = min{ai, bi, ci}, min{ai, min{bi, ci}} = xi = min{ai, bi, ci} = yi = min{min{ai, bi}, ci}, MIN(A, MIN(B, C)) = X = Y = MIN(MIN(A, B), C). A (H2) hasonlóan látható be mint a (H1) állítás, mindössze minimum helyett ma- ximumot valamint kisebb-egyenlő helyett nagyobb-egyenlőt kell írnunk. A (H3) és a (H4) állítás jól látszik, hiszen min{ai, bi} = min{bi, ai} illetve max{ai, bi} = max{bi, ai}. A (H5) állítást következők szerint kaphatjuk meg: MIN(A, MAX(A, B)) = Z = {zi}, ui ai, ui bi, zi ai, zi ui, zi = ai. A (H6) belátható, ha a (H5) állításon végrehajtjuk a (H2) állításnál említett átala- kításokat. Könnyen belátható, hogy a bevezetett részben rendezés valódi részhalmaza a lexi- kografikus rendezésnek, hiszen ∀X, Y ∈ D : ha MIN(X, Y ) = X =⇒ X ≤L Y, itt X ≤L Y reláció jelentése, hogy X a lexikografikus sorrendben megelőzi az Y hal- mazt. Az állítás megfordítva azonban nem igaz. Ezt is egyszerűen látható, hiszen a lexikografikus reláció teljes, azaz ∀X, Y ∈ D : X ≤L Y és Y ≥L X ⇐⇒ X = Y, ellenben a { (X, Y ) ∈ D × D | MIN(X, Y ) = X } relációra ez a kritérium nem teljesül. Mielőtt meg tudnánk mutatni, hogy a fenti struktúra, hogyan segít az eloszlás értékeinek számításában, szükséges lesz további jelölések bevezetése. 12
  • 13.
    2.4. definíció. AzX, Y ∈ D elemekről mondjuk azt, hogy Y követi X-et, illetve követési relációban van X-el, ha MIN(X, Y ) = Y és Z ∈ D, hogy MIN(X, Z) = Z és MAX(Y, Z) = Z. Jelöljük ezt a (X, Y ) ⊂ D × D relációt κ-val. Könnyen belátható, hogy Y κX =⇒ ∃! i : yi = xi − 1, és ∀ j = i : yj = xj, ahol xi, xj ∈ X, yi, yj ∈ Y, i, j ∈ I, azaz X pontosan egy eleme kisebb Y azonos indexű eleménél pontosan eggyel, a többi indexhez tartozóak pedig egyenlőek. 2.5. definíció. Jelöljük (D, MIN, MAX) háló atomjait A ⊂ D módon, melyekre A = { E ∈ D | Eκ{0}m }. Az atomokra teljesül, hogy ∀E ∈ A : ∃ ! i ∈ I, index, amelyre ej = 1, ha j = i, 0, egyébként, ahol ej ∈ E, j ∈ I. Az atomok segítségével fel tudunk írni egy függvényt, ami a nullától különböző elem indexét adja vissza: ε: A → I, ε (E) = i, ha ei = 1, ei ∈ E, ahol E ∈ A. (2.3) Ez a függvény, akkor lesz igazán hasznos, ha két indexelt halmaz különbségét is meg tudjuk adni. Ennek érdekében értelmezzük D felett a hozzárendelést a kivonás mű- veletének olyan módon történő a megkötésével, hogy az ne vezessen ki D halmazból. Hogy ezt elkerüljük rendeljük az ∅, üres halmazt az operandusokhoz, azaz: : D × D → D ∪ {∅}, (X, Y ) → {xi − yi | xi ∈ X, yi ∈ Y }, ha xi yi, ∀ i ∈ I ∅, különben. Tehát, ∀ Y κX =⇒ X Y ∈ A, ezért ε(X Y ) = i, esetén yi = xi − 1 és yj = xj, ahol X, Y ∈ D, xi, xj ∈ X, yi, yj ∈ Y i, j ∈ I, és i = j. Tehát ∀ X, Y ∈ D, Y κX hal- mazokról megtudjuk mondani azt az i ∈ I indexet, amelyhez tartozó elemeik eltérnek egymástól. Tekintsük (D, MAX, MIN) háló egy részhálóját, aminek legyen R = {ri | i ∈ I} ∈ D a szuprémuma. Ez a részháló tartalmazza az összes olyan X ∈ D esetet, melyek úgy állnak elő, hogy a kezdeti halmaz, amiből húzunk, az egyes kategóriában rendre ri darab elemet tartalmaz. Az általunk keresett algoritmus, ennek a részhálónak a szintenként történő bejárását hajtja végre. Tehát R halmazból kiindulva megadja azon sorozatokat, melyek az összes olyan halmazt tartalmazzák, amelyet úgy kaphatunk meg, hogy R halmazból n i∈I ri számú elemet húzunk ki. 13
  • 14.
    2.6. definíció. AD elemeiből képzett véges sorozatok halmaza D∗ , azaz D∗ = ∞ m=0 Dm , ahol D0 = , az üres sorozat. Továbbá az általunk bejárt részháló egy szintje: L(n) ∈ D∗ , L(n) = X ∈ D x∈X x = N − n , ahol N = i∈I ri az elemek száma a kezdeti halmazban. A 3. fejezetben a felsorolás megadásához fogjuk felhasználni a 2.4. definícióban megadott relációt illetve a (2.3) függvényt. Egyenlőre tegyük fel, hogy ismerjük az L(n) , n = 0, . . . , N szintek egy felsorolását. Ezt a sorrendet felhasználva P(Y |X) fel- tételes valószínűségeket, ahol X ∈ L(n−1) , Y ∈ L(n) , egy mátrixba tudjuk foglalni. 2.7. definíció. Nevezzük a W(n) mátrixot az L(n) szint átviteli súlymátrixának, ahol L(n) a (D, MAX, MIN) háló valamely részhálójának n. szintje. Az átvitelisúlyok legye- nek a következők: W(n) = [1], ha n = 0, W(n) = [P(Y |X) ]Y ∈L(n), X∈L(n−1) , egyébként. Ha a részháló szuprémuma R ∈ D, akkor n = 0, . . . N, ahol N = r∈R r. A W(n) oszlopai tehát az L(n−1) szinten található halmazokhoz rendelhetőek, míg sorai az L(n) szinten lévőkhöz. Az oszlopok és sorok sorrendje a megfelelő szintek felsorolá- sának sorrendjét követik. A feltételes valószínűségek értékei egyszerűen számíthatóak a következő képlet sze- rint: P(Y |X) =    xi x∈X x , ha Y κX, és i = ε(X Y ), 0, egyébként, ahol X ∈ L(n−1) , Y ∈ L(n) , illetve x∈X x = N − (n − 1). Egyben ez a képlet jól mutatja a κ reláció, és a feltételes valószínűségek közötti kap- csolatot. A feltételes valószínűségek ismeretében kiszámíthatjuk az egyes esetek valószínűsé- gét. Ennek érdekében az L(n) szint eseteinek valószínűségeit a sorrend megtartásával p(n) egy vektorba foglaljuk. 14
  • 15.
    2.8. tétel. Ap(n) = [P(Y )]Y ∈L(n) valószínűség értékekből képzett vektor előállítható p(n) = W(n) p(n−1) szorzat alakjában, ahol n = 1, . . . N p(0) . = [1] = W(0) p(n−1) = [P(X)]X∈L(n−1) , p(n) = [P(Y )]Y ∈L(n) . Bizonyítás. Bontsuk a W(n) = [wY ]Y ∈L(n) átviteli súlymátrixot sorvektoraira, ahol wY = [P(Y |X)]X∈L(n−1) , ekkor a tétel állítása szerint [P(Y )]Y ∈L(n) = [wY ]Y ∈L(n) p(n−1) , tehát ∀ Y ∈ L(n) P(Y ) = wY p(n−1) , P(Y ) = X∈L(n−1) P(Y |X)P(X). Tehát a tétel állítását visszavezettük a teljes valószínűség tételére. Annak érdekében, hogy a valószínűség értékeket a 2.8. tétel szerint tudjuk előállí- tani a felsorolás sorrendjét olyannak kell választanunk, hogy Y ∈ L(n) esetén elő tudjuk állítani ∀ X ∈ L(n−1) : Y κX eset az L(n−1) sorozatban felvett indexét, hiszen ez egyben W(n) oszlop indexe is. A (D, MIN, MAX) hálóról érdemesnek tartjuk megjegyezni, hogy m dimenziós rács. Ez az állítás könnyen látható, hiszen ∀ X ∈ D, X ∈ E, X = {0}m halmaz esetén ∀Yi, Yj ∈ D, Yi = Yj : YiκX, YjκX halmazokhoz, ∃ Z ∈ D, hogy ZκYi és ZκYj. Más- képpen fogalmazva, nem teszünk különbséget, hogy előbb az egyik majd a másik ka- tegóriából húzunk vagy fordítva. Ebből pedig látható, hogy a háló Hasse-diagramján a relációt ábrázoló élek négyszögeket határolnak. Ha (D, MIN, MAX) háló egy rész- hálóját tekintjük, aminek szuprémuma R = {ri1 , . . . , rim } ∈ D, akkor ez a részháló egy G(ri1 +1),...,(rim +1) paraméterű rács. Ez a részháló a Pi1 , . . . , Pim láncok Descartes- szorzataként állítható elő, melyeket rendre a ri1 , . . . , rim számoktól kisebb természetes számokból képezzük, tehát G(ri1 +1),...,(rim +1) = × i∈I Pi, ahol Pi1 = ri1 , ri1 − 1, ri1 − 2, . . . , 1, 0 , ... Pim = rim , rim − 1, rim − 2, . . . , 1, 0 . Ugyanakkor a (D, MIN, MAX) háló izomorf a (Z+ , lnko, lnkt) hálóval. A két algebrai stukatúra közti megfeleltetés következőek szerint tehető meg. Az index halmaz I ⊂ P, ahol P a prímek halmaza, egy d ∈ Z+ szám, pedig akkor feletethető meg az X ∈ D halmazzal, ha d kanonikus alakjában pi ∈ P prím kitevője X halmaz azon eleme, amelyiket pi prímmel indexeltük, azaz d = pi∈I pxi i = px1 1 . . . pxm m , 15
  • 16.
    ahol xi ∈X. Például a 3. fejezetben a 3.1. ábrán látható részháló izomorf 45000 osz- tóinak részhálójával, ekkor az index halmaz 2, 3, 5 , ugyanakkor ha az index halmazt másképpen választjuk meg, a részháló topológiája nem változik, így 67500 vagy 52272 osztóinak részhálója is izomorf az említett példával, ekkor az index halmaz 3, 2, 5 illetve 3, 11, 2 . 16
  • 17.
    3. fejezet A problémaalgoritmikus megoldása A 2. fejezetben megmutattuk, hogy a polihipergeometrikus eloszlás esetei megfeleltet- hetőek egy indexelt halmazokból álló (D, MAX, MIN) algebrai struktúrával. Továbbá erről a struktúráról megmutattuk, hogy háló, valamint azt is, hogyan használhatjuk fel az esetek felsorolására és azok valószínűség értékeinek kiszámítására. Egyben a felsoro- lás sorrendjével kapcsolatban további feltételeket szabtunk, annak érdekében, ha a háló L(n−1) illetve L(n) szintjei azon esetek felsorolása, melyek rendre n − 1 illetve n elem kihúzása révén keletkeznek, akkor ∀ X ∈ L(n−1) , Y ∈ L(n) esetekhez tartozó P(Y |X) feltételes valószínűségeket mátrixba tudjuk foglalni. Ennek érdekében feltehetjük, hogy Y indexét ismerjük, ami az átviteli súlymátrix sorvektorának indexével fog megegyezni. Ekkor elő kell állítanunk az összes X eset L(n−1) felsorolásban felvett indexét, amelyre P(Y |X) = 0 azaz Y κX. Ezek az indexek lesznek a mátrix oszlop indexei. Ebben a fejezetben ismertetünk egy lehetséges felsorolást, valamint megadjuk a fenti indexek kiszámításának módját. 3.1. Az esetek felsorolása A felsorolás algoritmusának megadásához előbb értelmezzünk azt a D × I halmazból D ∪ {∅}-be történő hozzárendelést, ami egy elem kihúzását jelenti egy adott kategóri- ából. Tehát X ∈ D halmaz egy adott i indexű elemének eggyel történő csökkentése, hiszen X elemei az egyes kategóriákban szereplő elemek számával feleltettük meg. 3.1. definíció. Egy elem kihúzása az i indexű kategóriából a következőképpen adható meg, σ: D × I → D ∪ {∅}, σ(X, i) = X E, ahol E ∈ A atom és ε(E) = i. Továbbá, az L(n) ∈ D∗ , 0 n i∈I ri sorozatok elemenként történő megadása érdekében szükségünk lesz a hozzáfűzés műveletére a D∗ sorozatok felett. 17
  • 18.
    3.1. Az esetekfelsorolása 3.2. definíció. Egy T = T1, . . . , Tk ∈ D∗ sorozat S = S1, . . . , Sl ∈ D∗ sorozat végéhez fűzését adjuk meg a következőképpen: ⊕ : D∗ × D∗ → D∗ , ⊕ (S, T) = S, ha T = , ⊕( S1, . . . , Sl, T1 , Q), különben, ahol T = ⊕( T1 , Q), Q ∈ D∗ . Továbbiakban a prefix jelölés helyett infixet fogunk használni. Valamint a D halmaz- beli halmazokat egy hosszú sorozatokként tekintjük, illetve ∅ és között sem teszünk különbséget, és értelmesnek tekintjük ezeknek egy D∗ sorozathoz történő hozzáfűzését. A 3.1. és a 3.2. definíciók bevezetésével egyben egy elágazás leírását is leegyszerűsí- tettük, hiszen X = {xi | i ∈ I} ∈ D esetén, ha xj = 0, j ∈ I, akkor S ⊕ σ(X, j) = S, vagyis ha a j-edik kategória elemei elfogytak nem tudunk úgy húzni egy következő elemet, hogy az a j-edikből kerüljön ki, így a felsoroláshoz sem fűzzünk újabb esetet. Az előbbieket felhasználva, ha R = { ri1 , . . . , rim } a kiindulási halmaz, vagyis az elemek darabszáma az egyes kategóriákban ri1 , . . . , rim , a felsorolást megtehetjük a kö- vetkezők szerint: 1. algoritmus Enumeration 1. n = 0, L(n) = R . 2. n = n + 1, L(n) = . 3. Iteráljunk X ∈ L(n−1) eseteken és állítsuk elő XκY eseteket a következő módon: (a) j = 1. (b) Y = σ(X, ij). (c) Ha Y ∈ L(n) , akkor L(n) = L(n) ⊕ Y. (d) j = j + 1 folytassuk a 3.(b) pontól, amíg j m egyébként a 4. ponttól. 4. Legyen X most a következő eset az L(n−1) sorozatban és folytassuk a 3. ponttól, ha nincs több menjünk az 5. pontra. 5. Ha n = i∈I ri készen vagyunk, egyébként folytassuk a 2. ponttól. A fenti algoritmus 3.(b) pontjában szereplő feltétel vizsgálata számítástechnikai szem- pontból nehézkes lenne, hiszen ehhez L(n) összes már felsorolt elemét meg kellene vizsgálnunk. Célszerű lenne a sorrendet úgy kialakítanunk, hogy j = 1 illetve i1 index helyett valamely magasabb indextől kezdjük Y = σ(X, ij) esetek előállítását úgy, hogy ∀ik ∈ I, ik ij esetén σ(X, ik) biztosan szerepeljen L(n) sorozatban, illetve ∀il ∈ I, il ij esetén σ(X, il) nem. Annak érdekében, hogy egy ilyen felsorolást tudjunk megadni szükségünk lesz a következő segédváltozó bevezetésére. 18
  • 19.
    3.1. Az esetekfelsorolása 3.3. definíció. A γ segédváltozó legyen a következőek szerint értelmezve: γ : D → I, γ(X) = i1 , ha n = 0, ε (Yk X) , egyébként , ahol k = min { l | XκYl } , X ∈ L(n) és Yk, Yl ∈ L(n−1) . Azaz γ(X), X ∈ L(n) az az index, amelyik csökkentésével kaphatjuk meg az X halmazt abból az Y halmazból, amelyikre teljesül XκY és az L(n−1) sorozatban a legkisebb az indexe. Ennek a segédvákozó segítségével megadható a következő algoritmus, melyben L(n) felsorolást L(n−1) elemein történő iterációval állítjuk elő. 3.4. tétel. A (D, MIN, MAX) háló bármely részhálójának szintjei, aminek R ∈ D hal- maz a szuprémuma, megadható azon L(n) ∈ D∗ , ahol n = 0, . . . , i∈I ri sorozatokkal, melyeket következő képpen képzünk: L(0) = R , L(n) = X∈L(n−1) im j=γ(X) σ(X, j), ahol I = i1, . . . , im és 1 n m. Bizonyítás. Ha n = 0, L(0) . = R könnyen belátható, hogy teljes hiszen R annak a részhálónak a szuprémuma melyeknek a felsorolását megadjuk. Ha n = 1, mivel γ(R) = i1 ezért L(1) = i∈I σ(R, i), vagyis rendre felsoroljuk azon eseteket, mikor az egyes kategóriából húztunk ki egy elemet. Erről szintén könnyen látható, hogy teljes. Tegyük fel, hogy L(n−1) teljes, 1 < n minri∈R ri = rmin esetén (biztosan lehet húzni mindegyik kategóriából). Ekkor tekintsük Xr = { xi1 , xi2 , . . . , xir , . . . , xim } ∈ L(n−1) elemet valamint legyen γ(Xr) = ir. Ahhoz, hogy meg tudjuk mutani, hogy L(n) is teljes, be kell látnunk, hogy ∀ij < ir esetén a σ(Xr, ij) halmazok már szerepelnek L(n) sorozatban mikor a külső iterációban Xr-re kerül a sor. Mivel γ(Xr) = ir ezért létezik Y ∈ L(n−2) , és γ(Y ) = ip ir. Eszerint L(n−1) sorozatban Xr halmaztól kisebb indexszel szerepelnek a következő elemek: Xp = σ(Y, ip) = { xi1 , . . . , xip − 1, xip+1 , . . . , xir−1 , xir + 1, . . . , xim }, Xp+1 = σ(Y, ip+1) = { xi1 , . . . , xip , xip+1 − 1, . . . , xir−1 , xir + 1, . . . , xim }, ... Xr−1 = σ(Y, ir−1) = { xi1 , . . . , xip , xip+1 , . . . , xir−1 − 1, xir + 1, . . . , xim }, ezért L(n) felsorolásakor hamarább fogjuk valamilyen ip γ(Xj) ir indexszel venni ezeket az elemeket. Ezért L(n) sorozatban σ(Xr, ip) = σ(Xp, ir) = { xi1 , . . . , xip − 1, xip+1 , . . . , xir−1 , xir , . . . , xim }, σ(Xr, ip+1) = σ(Xp+1, ir) = { xi1 , . . . , xip , xip+1 − 1, . . . , xir−1 , xir , . . . , xim }, ... σ(Xr, ir−1) = σ(Xr−1, ir) = { xi1 , . . . , xip , xip+1 , . . . , xir−1 − 1, xir , . . . , xim } 19
  • 20.
    3.1. Az esetekfelsorolása elemek biztosan szerepelni fognak mielőtt Xr halmazra kerülne a sor. Ezt a gondolat menetet addig ismételhetjük Y halmazra, míg ip = i1, aminek a révén belátható, hogy mielőtt Xr-re kerül a sor σ(Xr, ij), ij ip halmazok is szerepelnek már a felsorolásban. Tehát teljes az L(n) felsorolása, ha az L(n−1) sorozat is az. A n > rmin esetén biztosan van legalább egy, olyan Z ∈ L(n−1) , amelyre teljesül, hogy legalább az egyik eleme 0, legyen ennek az indexe iz. Ezért σ(Z, iz) = ∅, amit nem tudunk felírni az előző érvelésben a halmaz elemein végzett aritmetikai művelettel. Egyébként az érvelés többi része továbbra is érvényes, hiszen az ⊕ művelet ∅ esetén nem bővíti az L(n) sorozatot. Tehát L(n) felsorolása ebben az esetben is teljes. A levezetésből az is kitűnik, hogy ha X ∈ L(n) , Y ∈ L(n−1) és X = σ(Y, i) valamint L(n) előállításakor X nem szerepel a felsorolásban, mikor Y sorra kerül akkor γ(X) = i, hiszen ekkor Y = L (n−1) k , ahol k = min l | XκL (n−1) l . Ez alkalmat ad arra, hogy az algoritmust ennek megfelelően szervezzük. A következőképpen: a külső ciklus L(n−1) sorozatban felsorolt halmazokon iterál, jelöljük az éppen aktuális halmazt X-el, a bel- ső ciklus változóját pedig j-vel, ezt indítsuk γ(X)-ről és fusson im-ig, a ciklusmagban végezzük el egy húzást a σ(X, j) szerint, fűzzük az így előállított halmazt L(n) soro- zathoz, valamint ehhez a halmazhoz tároljuk j ciklusváltozót is. Így az eltárolt index a következő szint felsorolásakor előhívható, amiről megmutattuk, hogy az éppen γ(X)-el lesz egyenlő. Ezen kívül lehetőségünk van a bejárás szűkítésére is, ha megadunk egy T ∈ D elemet ami a bejárt részhálónak, {0}m helyett, infimuma lesz. Ekkor a bejárás úgy módosul, hogy a R T szuprémummal és {0}m infimummal rendelkező részhálóval izomorf részhálót járunk be. Az algoritmus szemléletesebben, pszeudokóddal leírva a következő (paraméterlistában a szögletes zárójelek közötti paraméterek opcionálisak): 2. algoritmus Enumeration Require: L(n−1) , [ T ] 1: L(n) ← list() 2: m ← length(L(n−1) [1]) 3: if T = ∅ then 4: T ← list() 5: for i ← 1 to m do 6: T.push(0) 7: end for 8: end if 9: for i ← 1 to length(L(n−1) ) do 10: for j ← 1 to m do 11: Y ← L(n−1) [i] 12: if Y [j] > T[j] and j Y.gamma then 13: X ← copy(Y ) 14: dec(X[j]) 15: X.gamma ← j 16: L(n) .push(X) 17: end if 18: end for 19: end for 20: return L(n) 20
  • 21.
    3.2. Leszálló bejárás A3.4. tétel gondolatmenete szerint könnyen belátható a következő állítás is. 3.5. állítás. Az 1. illetve a 2. algoritmus az egyes szintek eseteit lexikografikus sor- rendben sorolja fel. 3.2. Leszálló bejárás Annak érdekében, hogy a valószínűségeket a 2.8. tétel szerint tudjuk kiszámítani azon- ban nem elég az eseteket felsorolnunk. Ha W(n) átviteli súlymátrixok oszlop- illetve sorvektorait a felsorolásban előállított sorrendben írjuk, akkor az egyes feltételes való- színűség oszlop indexe i azaz a 9. sorban szereplő külső ciklus ciklusváltozója lesz, a sor index pedig j γ(X), X ∈ L(n−1) esetén L(n) már felsorolt elemeinek számából állapítható meg, hiszen ekkor σ(X, j)-t fűzzük a felsorolás végéhez. Azonban j γ(X) esetén, ha xj = 0, akkor σ(X, j) már szerepel a felsorolásban és ennek indexét is elő kell állítanunk. Ennek a problémának illetve az eddigiek jobb megértése érdekében te- kintsünk egy alkalmasan megválasztott példát. Legyen három kategóriánk és ezekben rendre 3, 2 és 4 darab elem. 3,2,4 2,2,4 3,1,4 3,2,3 1,2,4 2,1,4 2,2,3 3,0,4 3,1,3 3,2,2 0,2,4 1,1,4 1,2,3 2,0,4 2,1,3 2,2,2 3,0,3 3,1,2 3,2,1 0,1,4 0,2,3 1,0,4 1,1,3 1,2,2 2,0,3 2,1,2 2,2,1 3,0,2 3,1,1 3,2,0 0,0,4 0,1,3 0,2,2 1,0,3 1,1,2 1,2,1 2,0,2 2,1,1 2,2,0 3,0,1 3,1,0 0,0,3 0,1,2 0,2,1 1,0,2 1,1,1 1,2,0 2,0,1 2,1,0 3,0,0 0,0,2 0,1,1 0,2,0 1,0,1 1,1,0 2,0,0 0,0,1 0,1,0 1,0,0 0,0,0 3.1. ábra. 21
  • 22.
    3.2. Leszálló bejárás A3.1. ábrán az egyes esetek az algoritmus által megadott sorrendben láthatóak, n értéke fentről lefelé növekszik. Az egyes esetek a még ki nem választott elemek számát mutatják. Két szint egyes halmazait kössük össze, ha Y κX, illetve a vonal színe legyen piros, ha ε(X Y ) γ(X), azaz éppen az átviteli súlymátrixok azon elemeinek meg- feleltethető élek, amelyek indexét keressük. Ehhez a példához tartozó konkrét átviteli súlymátrixokat megadjuk a 6. fejezetben. Szemléletesebb ha az egyes szinteket külön ábrázoljuk mégpedig úgy, hogy az egyes kategóriákból történő húzást különböző irányba rajzoljuk, jelöljük azokat az eseteket is, ahol a 2. algoritmus 12. sorában lévő feltétel nem teljesül, azaz σ(X, j) = ∅. A megelőző szint elemeit jelölje , az üres halmazokat pedig . L(0) L(1) L(2)3,2,4 2,2,4 3,1,4 3,2,3 1,2,4 2,1,4 2,2,3 3,0,4 3,1,3 3,2,2 3.2. ábra. Az L(n) felsorolását Y ∈ L(n−1) halmazokon történő iterációval végezzük, az egyes halmazokból az I indexek sorrendjében húzunk ki egy-egy elemet γ(Y )-tól im-ig indexű kategóriákból, ezért L(n) sorrendje ciklikusan fogja az egyes kategóriákból történt hú- zást tartalmazni. Jól látható, hogy ez nem függ attól, hogy hány kategória van. L(3) L(4)0,2,4 1,1,4 1,2,3 2,0,4 2,1,3 2,2,2 ∅ 3,0,3 3,1,2 3,2,1 ∅ 0,1,4 0,2,3 1,0,4 1,1,3 1,2,2 ∅ 2,0,3 2,1,2 2,2,1 ! 3,0,2 3,1,1 3,2,0 3.3. ábra. Ennek következménye, hogy n rmin esetén, ha L(n−1) = Y1, Y2, . . . Yk , L(n) = X1, X2, . . . , Xk, Xk+1, . . . Xl , akkor ε(Yj Xj) = i1, j = 1, . . . , k. 22
  • 23.
    3.2. Leszálló bejárás Hasonlóképpentetszőleges Yf halmazra, melyre γ(Yf ) = ir és σ(Yf , ir) = Xg, teljesül, hogy létezik d ∈ N, hogy L(n−1) sorozatban Yf halmaz után következő ∀ c < d, Yf+c halmazokra γ(Yf+c) ir, és ekkor ε(Yf+c Xg+c) = ir. Ezért egy σ(Yf , ir) halmaznak a felsoroláshoz történő hozzáfűzésekor érdemes egy v ∈ Nm vektor ir koordinátájában eltárolni g + 1-et, hiszen ε(Yf+1 σ(Yf , ir)) = ir, ha γ(Yf+1) ir, majd növelni ezt a koordinátát eggyel minden Yf+c felsorolásánál. L(5) × × 0,0,4 0,1,3 0,2,2 ∅ 1,0,3 1,1,2 1,2,1 ! 2,0,2 2,1,1 2,2,0 ! 3,0,1 3,1,0 ∅ 3.4. ábra. Ha n > rmin, akkor van olyan kategória, amiből már nem tudunk húzni és emiatt a sorrend is másként alakul, ezért a keresett indexek előállításánál ezt is figyelembe kell venni. 3.6. definíció. Tekintsük a (H, MIN, MAX), H ⊆ D részhálót, ahol inf H = T = {ti}. Valamint az X = {xi} ∈ H esetet, ahol i ∈ I. Jelöljük azon kategóriák száma, amelyekből már nem tudunk több elemet ki húzni a következőképpen: o(X, T) = |{i ∈ I | ti = xi}|. Valamint ebből származtassuk a δ segédváltozót δ(X, T) = |{ i ∈ I | i γ(X) }| − o(X, T) szerint. Ha a felsorolás során egy Y = {yi1 , . . . , yim } ∈ L(n−1) halmazra kerül a sor és yi = 0 valamely i γ(X)-re, akkor megvizsgáljuk a δ(Xvi , T) δ(Y, T), Xvi ∈ L(n) és vi < g+ 1 feltételeket. Ha ezek teljesülnek a v vektor i indexű koordinátáját átírjuk g+1-re, ahol g az utolsó a felsoroláshoz már felhasznált halmaz indexe L(n−1) sorozatban, egyébként folytatjuk az iterációt Y -t követő esettel. Amennyiben a vi koordinátát átírtuk a 3.3. illetve a 3.4. és a 3.5. ábrákon ! jellel jelöltük, illetve × jellel, ha nem. Egy új opcionális d paramétert is megadhatunk, ami a wi,j súlyok közös nevezője. Ezt abból a megfontolásból tettük, mivel L(0) . = R és minden L(n) felsorolásához feltettük, hogy L(n−1) sorozatot ismerjük, n = 1, . . . , N, ahol N = i∈I ri, ri ∈ R. Azaz n iterációjával tudjuk a felsorolást megtenni, ekkor azonban d = N − n miatt 23
  • 24.
    3.2. Leszálló bejárás érdemesn helyett az iterációt d-vel végezni és ekkor a ciklus változó egyben megadja a nevezőt is. Egy másik észrevétel, hogy W(n) mátrixok inicializációja nem szerepel az algoritmusban, illetve bizonyos indexű elemei kapnak értéket. Ennek oka, hogy W(n) definíciójából, illetve az eddig elmondottakból is jól kitűnik, hogy W(n) bármely sor vektora, illetve oszlop vektora legfeljebb m számú 0-tól különböző elemet tartalmazhat, ezért érdemes W(n) tárolását ritka mátrixokra kidolgozott struktúrákkal megtenni. Ha ez mégsem lenne megoldható, akkor L(n−1) ismeretéből következik, hogy ismerjük L(n−1) elemszámot is, és így |L(n−1) | dimenziós oszlop vektorok összefűzésével is elő tudjuk állítani W(n) -t. L(6) L(7) L(8) L(9) ∅ × × × 0,0,3 0,1,2 0,2,1 ! 1,0,2 1,1,1 1,2,0 ! 2,0,1 2,1,0 ∅ × 3,0,0 ∅ × × × × 0,0,2 0,1,1 0,2,0 ! 1,0,1 1,1,0 ∅ × 2,0,0 ∅ × ∅ × × × × 0,0,1 0,1,0 ∅ × 1,0,0 ∅ × ∅ × × × 0,0,0 ∅ × ∅ 3.5. ábra. Az elmondottak alapján a 2. algoritmust ki tudjuk egészíteni úgy, hogy az új algoritmus L(n−1) esetein történő iteráció során minden elem esetén a kategóriákon is végig iteráljon és megkeresse az aktuális elem már felsorolt deszcendenseinek indexét a v vektor segítségével. Ezen módosításokat megadjuk a 3. algoritmusban. Érdemesnek tartjuk megjegyezni, hogy az algoritmus a 17. és a 24. sor révén a δ függvényt értékét implicit módon számítja. 24
  • 25.
    3.3. Cikk-cakk bejárás 3.algoritmus Descend Require: L(n−1) , [ d ], [ T ] 1: L(n) ← list() 2: g ← 0 3: Y ← L (n−1) 0 4: m ← length(Y ) 5: if d = ∅ then 6: d ← m−1 i=0 Yi 7: end if 8: v ← list() 9: for i ← 0 to m − 1 do 10: v.push(0) 11: end for 12: if T = ∅ then 13: T ← copy(v) 14: end if 15: for i ← 0 to length(L(n−1) )-1 do 16: Y ← L (n−1) i 17: o ← Y.gamma − Y.delta 18: for j ← 0 to m − 1 do 19: if j Y.gamma then 20: if Yj > Tj then 21: X ← copy(Y ) 22: dec(Xj) 23: X.gamma ← j 24: X.delta ← j − o 25: L(n) .push(X) 26: inc(g) 27: W (n) ig ← Yj/d 28: else 29: inc(o) 30: end if 31: vj ← g + 1 32: else 33: if Yj > Tj then 34: W (n) ivj ← Yj/d 35: inc(vj) 36: else if vj < g + 1 and L (n) vj .delta Y.delta then 37: vj ← g + 1 38: end if 39: end if 40: end for 41: end for 42: return L(n) 25
  • 26.
    3.3. Cikk-cakk bejárás 3.3.Cikk-cakk bejárás A 3. algoritmus az L(n−1) szint ismeretében felsorolja az eloszlás L(n) szinten lévő eseteit, valamint ezzel párhuzamosan előállítja a W(n) átviteli súlymátrixot. Ugyanak- kor az L(n) szint valószínűségeit tartalmazó p(n) vektort csak a felsorolás végeztével, vagyis a teljes W(n) mátrix ismeretében tudjuk kiszámítani. Előnyösebb lenne, ha a felsorolást leszálló bejárás helyett úgy tudnánk módosítani, hogy W(n) mátrixot sor- vektoronként állítjuk elő. Ebben az esetben a mátrix vektor szorzást a felsorolással egy időben tudnánk elvégezni. Mint ahogy az a 2.8. tétel bizonyításából is kitűnik ez megfelel az L(n) szinten lévő esetek valószínűségeinek teljes valószínűség tétel szerint történő kiszámításának. A bejárás sorrendjének végiggondolása érdekében azonban továbbra is hasznos az átviteli súlymátrix konstrukciója mentén gondolkodnunk. A W(n) mátrix minden wY sorvektora megfeleltethető egy Y ∈ L(n) esetnek, illetve wY vektor egyes komponen- sei P(Y |X) feltételes valószínűséggel, ahol X ∈ L(n−1) . Ezen kívül P(Y |X) feltételes valószínűség, akkor és csak akkor különbözik 0-tól, ha XκY . Az elmondottak alapján az algoritmus bejárását úgy kell módosítanunk, hogy minden X ∈ L(n−1) esethez és i γ(X), i ∈ I indexhez, felsoroljuk σ(X, i) deszcendenseket, illetve ezen deszcenden- sekhez megkeressük azon X ∈ L(n−1) eseteket, melyekre X κσ(X, i) reláció teljesül. Könnyen láthatjuk azt is, hogy ezen X esetek L(n−1) szint felsorolásakor X eset után kell következniük, valamint az is, hogy σ(X, i) = σ(X , j) csak j i, j ∈ I indexű kategória esettén teljesülhet, illetve ebből j γ(Y ). Az Y deszcendens azon X aszcen- denseinek indexét, melyekre még nem került sor a L(n−1) szinten történő iteráció során, a 3. algoritmushoz hasonlóan, kiszámíthatjuk egy v ∈ Nm mutatóvektor segítségével, ahol m a kategóriák száma. Induljunk ki a 3.5. állításból, hogy a v mutatóvektort az új feltételeknek megfelelő- en tudjuk kiszámítani. Amennyiben L(n−1) és L(n) sorozatok valamely (R, MIN, MAX) háló n−1 illetve n szintjein lévő eseteinek lexikografikus felsorolása, létezik X ∈ L(n−1) és Y ∈ L(n) legkisebb illetve legnagyobb indexű elem, úgy, hogy L(n−1) X-től nagyobb indexű elemeinek i1 kategóriáját csökkentve eggyel L(n) Y -tól kisebb indexű elemeit kapjuk. Természetesen ez azt is jelenti, hogy X után pontosan annyi elem van mint Y előtt. Ugyanakkor, ha n ri1 akkor X az első elem lesz az L(n) felsorolásban. Egyéb- ként, ha n > ri1 akkor X indexét úgy kaphatjuk meg, hogy kiszámoljuk, hány olyan eset van L(n) elején, ami 0-val kezdődik. Ezt könnyen megtehetjük, ha elhagyjuk R-ből ri1 -et, és felsoroljuk R = {ri2 , ri3 , . . . , rim }-ből kiindulva az összes esetet, ezek elejére írva az elhagyott 0-t éppen a keresett eseteket kapjuk. Azonban a konkrét esetekre ezúttal nincs szükségünk csak a számukra, hogy megkapjuk a keresett X eset indexét. A többi ij ∈ I kategória esetén az eddig elmondottakhoz hasonló számolhatunk, azzal a különbséggel, hogy nem csak a felsorolás elején, lehet szükség, hogy bizonyos eseteket L(n) -ben átugorjunk, hanem a felsorolás belsejében is. Annak érdekében, hogy az elmondottak alapján a kívánt algoritmust meg tudjuk adni használjuk a következő jelölést. 3.7. definíció. Jelöljük a R ∈ D indexelt halmaznak azt a részhalmazát, amely az i ∈ I indextől nagyobb indexű elemeit tartalmazza a következőképpen: tail : D × I → D, tail(R, ij) = {rij , rij+1 , . . . , rim }, ahol R = {ri1 , ri2 , . . . , rij , . . . , rim }. 26
  • 27.
    3.3. Cikk-cakk bejárás Azelmondott gondolatmenetet a 4. algoritmusban összegezzük. 4. algoritmus Zig-zag 1. n = 0, L(n) = R . 2. n = n + 1, L(n) = . 3. Inicializáljunk a p = L (ni) i i∈I mutató vektort, ahol ni = n − i j=i1 rj, valamint L (ni) i az éppen felsorolt hálónak az a részhálója, melynek szuprémuma T = tail(R, i) infimuma pedig {0}|T| . 4. Iteráljunk X ∈ L(n−1) eseteken és legyen h X indexe L(n−1) , ekkor állítsuk elő XκY eseteket a következő módon: (a) j = k, ahol ik = γ(X). (b) Y = σ(X, ij). (c) Ha Y = ∅, akkor L(n) = L(n) ⊕ Y , és pj = pj + 1, ahol pj a p vektor j-edik komponense. (d) Számítsuk ki Y valószínűségét a teljes valószínűség tétele segítségével, ehhez X κY : X ∈ L(n−1) aszcendensek indexét L(n−1) -ben a következők szerint állíthatjuk elő: I. l = 1. II. Ha l = j és xl < rl. A. Ha pl > h. i. X ∈ L(n−1) aszcendense Y -nak, és X indexe L(n−1) -ben pl. ii. pl = pl + 1. B. Egyébként: i. Ha n∗ > 0, ahol n∗ = n − l j=i1 rj − yj, pl = h + L∗(n∗) , ahol L∗(n∗) annak a részhálónak az n∗ -adik szintje, aminek szuprémuma tail(R, il), és infimuma {0}m−l . ii. Egyébként pl = h + 1. iii. X ∈ L(n−1) aszcendense Y -nak, és X indexe L(n−1) -ben pl. iv. pl = pl + 1. III. Ha l < m, akkor l = l + 1 és folytatjuk a 4.(d)II. ponttól, egyébként a 4.(e) ponttól. (e) j = j + 1 folytassuk a 4.(b) pontól, amíg j m egyébként az 5. ponttól. 5. Legyen X most a következő eset az L(n−1) sorozatban és folytassuk a 4. ponttól, ha nincs több menjünk a 6. pontra. 6. Ha n = i∈I ri készen vagyunk, egyébként folytassuk a 2. ponttól. A 4.1. tételben megadunk egy lehetséges módszert a szintek hosszának kiszámítá- sára anélkül, hogy felsorolnánk az egyes eseteket. Ugyanakkor az éppen felsorolt hálóból 27
  • 28.
    3.3. Cikk-cakk bejárás iskiolvashatjuk a keresett szintek hosszát, ha a gondolat meneten teszünk egy apró vál- toztatást. Ha az eseteket 0 helyett ri1 -el egészítjük ki akkor jól látható, hogy ezek az éppen felsorolás alatt lévő háló szintjeinek végén szereplő elemek. Tehát a felsorolás során előállítható egy táblázat, amiben ezeknek az eseteknek az indexeit tároljuk. 5. algoritmus Zig-zag Require: L(n−1) , R, [ n ], [ T ] 1: L(n) ← list() 2: Y ← L (n−1) 0 3: m ← length(Y ) 4: if n = ∅ then 5: d ← m−1 l=0 Yl 6: n ← m−1 l=0 Rl − d 7: end if 8: v ← list() 9: for i ← 0 to m − 2 do 10: n∗ ← n − i l=0 Rl 11: if n∗ > 0 then 12: skip ← len_tab[i][n∗ ] 13: else 14: skip ← 0 15: end if 16: v.push(skip) 17: end for 18: v.push(0) 19: if T = ∅ then 20: for i ← 0 to m − 1 do 21: T.push(0) 22: end for 23: end if 24: for i ← 0 to m − 1 do 25: flush[i] ← ∅ 26: end for 27: for i ← 0 to length(L(n−1) )-1 do 28: Y ← L (n−1) i 29: o ← γ(Y ) − δ(Y, T) 30: for j ← γ(Y ) to m − 1 do 31: flush[j − o] ← length(L(n) ) 32: if Yj > Tj then 33: p ← Y.P · Yj 34: inc(vj) 35: for k ← 0 to m − 1 do 36: if k = j and Yj < Rj then 37: if vk i then 38: n∗ ← n − j l=0 Rl + γ(Y ) l=0 Yl 28
  • 29.
    3.3. Cikk-cakk bejárás 39:if n∗ > 0 then 40: skip ← len_tab[j + 1][n∗ ] 41: else 42: skip ← 1 43: end if 44: vk ← i + skip 45: end if 46: X ← L (n−1) vk 47: p ← p + X.P · Yk 48: inc(vk) 49: end if 50: end for 51: X ← copy(Y ) 52: dec(Xj) 53: X.P ← p/d 54: L(n) .push(X) 55: else 56: inc(o) 57: end if 58: end for 59: end for 60: for i ← 0 to m − 1 do 61: if flush[i] = ∅ then 62: len_tab[i].push(length(L(n) )−flush[i]) 63: end if 64: end for 65: return L(n) 29
  • 30.
    4. fejezet Az alkalmazáskorlátai Az alkalmazás területét egyfelől behatárolja a 2. fejezetben említett közelítési eljárások, hiszen ezek számítás igénye jóval kisebb, azonban nem alkalmazhatóak minden eset- ben. Elsősorban azon esetek kiszámításának hatékonyságát szükséges megvizsgálnunk, ahol ezek nem alkalmazhatóak. A hatékonyság vizsgálatához érdemes a ciklusszámra vonatkozóan számításokat végeznünk. 4.1. tétel. A (D, MAX, MIN) háló n. szintjén lévő, vagyis a L(n) sorozatot alkotó hal- mazok száma megadható |L(n) | = J∈2I SJ −1<n (−1)|J| m + n − 1 − SJ n − SJ , (4.1) ahol SJ = j∈J rj + |J| összefüggéssel. Bizonyítás. Tekintsük a n min ri∈R ri . = rmin (4.2) esetet, ekkor |L(n) | megegyezik azzal, ha visszatevéses minta vételt alkalmaztunk vol- na, vagyis a polinomiális eloszlás eseteinek számával, ami pedig megadható ismétléses kombinációval a következőképpen: |L(n) | = m + n − 1 n , ami megegyezik az állításban szereplő összeggel, hiszen n rmin esetén SJ − 1 < n feltételt csak J = ∅ elégíti ki. Ha a (4.2) feltétel nem teljesül, akkor azonban |L(n) | < m + n − 1 n , mivel lesz legalább egy kategória, amiből nem tudjuk az összes elemet úgy kihúzni, hogy másik kategóriából nem húzunk. A különbséget szintén egy ismétléses kombinációval adhatjuk meg n ri + rj + 1, ∀i, j ∈ I (4.3) 30
  • 31.
    esetén |L(n) | = m +n − 1 n − ri<n m + n − ri − 2 n − ri − 1 (4.4) szerint. Ez belátható, ha tekintjük a (D, MAX, MIN) hálót alkotó halmazokat. A már említett szimmetria miatt, ezek elemei jelenthetik az egyes kategóriákból már kihúzott elemek számát is, ekkor a háló infimumából, vagyis a csupa nullát tartalmazó halmaz- ból, indulunk ki. Ekkor jól látható, hogy azok a halmazok amelyekben az i indexű elem nagyobb az ri elemnél kívül esnek azon a részhálón, amelynek szuprémuma az R halmaz. Ezek a részhálón kívüli halmazok is megadhatóak egy részhálóval, aminek infimuma az a halmaz melynek elemei csupa nulla az i. kivételével, ami ri + 1. Vagyis (4.4) valóban teljesül (4.3) esetén. Az is jól látszik, hogy amennyiben a (4.3) feltétel teljesül az SJ − 1 < n feltételt csak |J| = 1 halmazok elégítik ki. Vagyis az állításban szereplő képlet (4.3) esetén megegyezik (4.4)-el. Amennyiben azonban ri + rj + 1 < n az említett a részhálók metszetik egymást ezért |L(n) | > m + n − 1 n − ri<n m + n − ri − 2 n − ri − 1 , mivel a metszetükben szereplő halmazokat kétszer vontuk le. A metszetük azonban megint csak egy részháló, amit alkotó halmazok számát az eddigi gondolat menetet követve meg tudjuk adni |L(n) | = m + n − 1 n − ri<n m + n − ri − 2 n − ri − 1 + ri+rj+1<n m + n − ri − rj − 3 n − ri − rj − 2 alakban, ha n ri + rj + rk + 2, ∀ i, j, k ∈ I teljesül. A felváltott előjelű összegzést egészen m tagú összegig folytathatjuk, ami jól látha- tóan meg felel magával az állítással. Ennek ismeretében több megállapítást is tehetünk. Először is a γ és δ segédváltozók miatt jól láthatóan az esetek számával lineárisan arányos overhead lép fel, ugyanakkor δ(X, T) γ(X) im, miatt ezen változóknak elegendő kevés memória terület is, hiszen a (4.1) képletből jól láthatóan O(m!) nagyságrendben nő az esetek száma. Ezért nagy m értékek esetén nem lesz hatékony. Ennek fő oka, hogy a W(n) mátrixok egy újabb overhead-et képeznek, ami első közelítésben |Ln−1 | × |Ln−1 | méretű vagyis faktoriális négyzetnek tűnik. Azonban láttuk, hogy ezek a mátrixok ritkák, minden sor és oszlop vektoruk legfeljebb m számú nem 0 elemet tartalmaz. Ebből azt kapjuk W(n) mérete O(m · m!). Összegezve az alkalmazás legerősebb korlátját a W(n) mátrixok tárolása okozza. A (4.1) képlet legnagyobb jelentőségét az adja, hogy segítségével pontosan megtudjuk adni a számításhoz szükséges memória használat csúcsát a kiindulási adatok alapján. A 3. algoritmus segítségével megtehetjük n = 0, ..., N iterációt. Ekkor könnyen be- látható, hogy W(n) mátrix mérete ˙n = N 2 esetén lesz a legnagyobb. A W( ˙n) mátrixon kívül tárolnunk szükséges L( ˙n−1) és L( ˙n) sorozatokat, illetve ezen felül a kimenő adato- kat. Ezek méretét i∈I ri = N ismeretében előre ki tudjuk pontosan számítani a (4.1) képlet segítségével. Amennyiben nincs szükségünk minden W(n) által hordozott infor- mációkra, csak az egyes esetek valószínűség értékére, minden új L(n) szint felsorolása 31
  • 32.
    után elvégezhető p(n) =W(n) p(n−1) szorzás. Ekkor elég minden esethez magát a való- színűség értékét tárolni. Ez egyben rámutat egy másik problémára is egyúttal, nevezetesen, hogy egy L(n) felsorolásához minden megelőző szintet is elő kell állítanunk, ami viszont akár túl nagy költségnek is bizonyulhat. Mindazon által egy statisztikai vizsgálatnál nem biztos, hogy haszontalan. Érdemes továbbá a valószínűség értékek kiszámításának módját is megvizsgálnunk. Első megállapításunk, hogy mikor a 3. algoritmus segítségével akarjuk elő állítani L(n) felsorolást akkor feltételezzük, hogy L(n−1) ismert, ezért n változó szerinti iterá- ciót párhuzamos feldolgozással nem tudjuk megtenni. Ugyanakkor a 15. sorban lévő, L(n−1) felsorolás elemein történő iterációt sem tudjuk párhuzamosan megtenni a v index vektor koordinátáinak a 35. illetve a 37. sorokban történő írása miatt. A mátrix vek- torainak szorzása viszont párhuzamosan elvégezhető. Illetve ez a megoldás numerikus stabilitás szempontjából is kedvező, mivel a vektorokban szereplő hányadosok szorzat összege állítja adja a valószínűség értékeket, szemben a (2.1) képlettel, aminek számítá- sa felváltott szorzást és osztást igényel, annak érdekében, hogy az érték ne lépjen ki az ábrázolási tartományból. Ugyanakkor a P(Y |X) nevezője (N − n), így P(Y |X)P(X) nevezője pedig N!/n!, ahol X ∈ L(n−1) , Y ∈ L(n) . Azaz a mátrix műveletek valójában a felváltott osztás és szorzás szervezését egyszerűsíti. Az mindenesetre jól látszik, hogy többlet műveletet nem jelent a binomiális együtthatók számításához képest. Ha a valószínűség-számítás és statisztika területétől tágabban tekintjük az alkalma- zási lehetőségeket, akkor azt mondhatjuk, hogy kiválasztási, illetve oszthatósági prob- lémák esetén kifejezetten előnyös lehet a (D, MIN, MAX) struktúra, illetve a probléma megfogalmazása a segítségével. Ez a struktúra megkönnyítheti a részproblémákra tör- ténő felbontást vagy az esetek felsorolását. 32
  • 33.
    5. fejezet Fejlesztői dokumentáció Célunk,olyan algoritmus megalkotása volt, mely a 2. fejezetben ismertetett feladatot képes megoldani. Vagyis képes a polihipergeometrikus eloszlás összes esetét felsorolni. A fejlesztés MATLAB környezetben kezdtem az eredeti probléma két részre bontásával. Ezek a kihúzott elemek számának m tagú összegre bontása, illetve a tagok permutálása volt. A rész feladatok megoldására ismert algoritmusokat használtam[9, 5]. Az így elké- szült algoritmus a valószínűség értékeket a (2.1) képlet szerint binomiális együtthatók számításával adta meg. Ez a megoldás bár a végleges algoritmustól gyökeresen különbözött, jó kiinduló- pontot és tapasztalatot szolgáltatott a további vizsgálatokhoz. Elvezetett a probléma a 2.3. tételben megadott hálóelméleti fogalmak segítségével történő átformálásához, valamint a valószínűség értékek a 2.8. tételben megadott számítási módjához. Utób- bi egyben új kritériumot is szolgáltatott a felsorolás indexelésével szemben. A további munka elvezetett az itt tárgyalt algoritmushoz, ugyanakkor rámutatott arra az igényre is, hogy objektum orientált környezetben valósítsuk meg. A megoldás során a python programozási nyelvre[8] esett a választás. Ezt a dön- tés egyfelől az említett irodalom ihlette. Másrészről a W(n) átviteli súlymátrixokról jól látszódott, hogy ritkák, ezért olyan környezetet kerestem, amelyben a ritka mátri- xok kezelése megoldott. A python programozási nyelvhez elérhető a scipy csomag[4], mely elterjedten használt és kész megoldást tartalmaz számos számítás elvégzéséhez, köztük a ritka mátrixok kezelésére is. A python implementáció elkészítése, az objek- tum orientáltságból adódóan, segítette a formalizált leírás letisztázását, a jobb meg- értést. A fejlesztés során a git verzió követőt használtam, a programkód elérhető a https://github.com/sulyi/multivariate-hypergeometric.git gyűjteményben. Az elkészült implementáció egy mvhgd nevű python csomagból áll, melyet két alcso- magra, core és algorithms, osztotam szét, illetve tartalmaz egy utils és egy tester nevű modult. A csomag UML diagramja az 5.1. ábrán látható. A python nyelv saját- ságai miatt szükségünk volt «utility» sztereotípiával ellátott pszeudoosztályok haszná- latára is, melyek a modul szintű metódusokat tartalmazzák. Az utils modul az ismétlés nélküli és ismétléses kombináció számítását végző nCk és nCik metódusokat és a 4.1. tételben megadott képlet számítását végző LevelLength osztályt tartalmaza. Ezenkívül az _f_nCk, _m_nCk védett és az __r_nCk privát mo- dul szintű metódusok a binomiális együtthatót számítják faktoriális, multiplikatív és 33
  • 34.
    rekurzív képlet szerint,melyek az (5.1) formulában láthatóak: n k = n! k! · (n − k)! n k = n−k i=1 k + 1 i n k = n − 1 k − 1 + n − 1 k . (5.1) Az utils modul önmagában is futtatható, ekkor a védett metódusokat dinamikusan kigyűjti és a programkódban rögzített teszt adatokkal méri processzoridejüket. A rekur- zív __r_nCk metódus nagy többletköltsége miatt privát minősítést kapott, amit a nyelv konvenció szerint két _ jelöl. A modulban szereplő LevelLength osztály inicializáció során hívja a power_set_ordered_by_sums metódust. Ami classmethod dekorátor- ral láttam el, azaz osztály szintű vagy szingleton metódus. Ez felsorolja a konstruktor paraméterlistájában megadott supremum összes részhalmazát az elemek összegének sorrendjében és a _psobs privát adattagban eltárolja. Továbbiakban a példányosított objektum precalculate_length metódusát meghívva a szint számával a (4.1) képlet- ben szereplő binomiális együtthatókat kiszámítja és összegzi azokat, majd visszatér az így kapott számmal, ami a szint hossza. A tester modul az elkészült implementáció tesztelését, az azonos feladatot el- látó részek összehasonlítását könnyíti meg. Három modulszintű metódust tartalmaz. A generate_input_data teszt adatok előállítását végzi. A compare_test két meg- adott implementációt az algorithms alcsomagból hasonlít össze, visszatérési értéké- ben a két processzoridőt és a kiszámított valószínűségek eltérésének maximumát adja. A cputime_test a nagyon rövid processzoridőket tudja mérni úgy, hogy addig növeli tízszeresére a futtatások számát míg a futás idő mérhető méretű nem lesz. A két alcsomag átlátszóra készült, vagyis az osztályaikat az importálás során a fe- lette lévő csomag a saját névtartományába emeli. Így rejtve marad, hogy a csomagban szereplő osztályokat külön modulban implementáltam és a névtartomány átláthatóbb. A core nevű alcsomag négy osztályt tartalmaz, melyeknek Pretty, Draw, Grid és Level a nevük. A Pretty és a Draw a list beépített osztály leszármazottjai. A Pretty mind- össze a szöveges megjelenítés felül definiálását szolgálja, illetve a szülőosztály bizonyos list típussal visszatérő metódusait definiálja felül, annak érdekében, hogy a vissza- adott érték típusa Pretty maradjon. A Draw osztály a szülőosztályt egy gamma és P adattaggal egészíti ki, utóbbi tárolja az eset valószínűségét. Az inicializáció során az iterable paraméteren próbál iterálni és közben egyben elllenörzi, hogy az egyes tagok számok. Továbbá felüldefiniálja az összehasonlító relációkat és a szöveges megjelenítést végző metódusokat. A Grid osztály tartalmaz többek között egy root adattagot, ami a bejárni kívánt háló szuprémumát tárolja. A konstruktornak adott supremum paraméter validációja megtörténik azáltal, hogy egy Draw objektumot példányosíásán keresztül, ez tárolódik végül a root adattagban. A roof adattag ennek összegét tárolja, az m adattagban pedig a hossza, a könnyebb elérés érdekében. Az algorithm adattag a konstruktor másik paraméterét tárolja, de csak a Level osztályban történik meg a validációja. Azonban a generator metódus használja a Level osztályt és a _generator adattag az inicializáció során ez a metódus által visszaadott generátort tárolja. A _generator átlátszó módon elérhető, amit a next és az __iter__ metódusok biztosítanak. Tehát a 34
  • 35.
    5.1. ábra. mvhgdcsomag UML diagramja 35
  • 36.
    Grid példányok közvetlenüliterálhatóak. A limit_to metódus a _generator és ezáltal a Grid példány iterációját korlátozza úgy, hogy vagy a bejárt szintek számát vagy egy infimumot állít be a megadott target paraméternek megfelelően. A target paraméter ellenőrzése természetesen nem csak addig terjed, hogy el lehessen dönteni a beállítani kívánt korlát minőségét, de validáció is történik. Ennek érdekében használjuk a Draw osztály összehasonlító relációit. Az _iroot adattag a 3.7. definícióban megadott tail(R, i), i ∈ I halmazokat tárolja, ahol R a háló szuprémuma és I az index halmaz. Végezetül a _len_tab adattag az 5. algoritmusban ismertetett táblázatot tárolja, illetve a _read_len_tab metódus ezt a táblázatot olvassa úgy, hogy a 10. és a 38. sorokban szereplő számításokat egyszerűsíti. A _len_tab és a _read_len_tab védett elérésű hiszen előbbi az iteráció során kerül kitöltésre, ezért az olvasása kizárólag a Level osztályon keresztül javasolt. A Level osztály mindösszesen egy egységes felületet biztosít az algorithms alcso- magban lévő osztályok számára, valamint néhány validációt végez, tehát egy polimorfi- kus gyár (factory) osztály. Az inicializáció során a megkapott algorithm a Pretty egy alosztályaként validálja és meghívja a konstruktorát a másik két megadott parent és iterable paraméterekkel, végezetül a state adattagban tárolja. Az parent paramé- tert Grid példányaként, az iterable paramétert pedig iterálhatóként validálja, mely- nek minden tagjáról ellenőrzi, hogy a Draw osztály példánya. A P metódust property dekorátorral láttuk el és ennek megfelelően az UML diagramon az attribútumok közé került, egy generátort ad vissza, ami a state adattagon iterál és az egyes elemek P att- ribútumát szolgáltatja. A next_level metódus a state adattag megfelelő metódusát hívja, ha nincsen n és-vagy target paraméter megadva akkor maga állítja be azokat a state számára. A __repr__ metódus a python konvencióknak megfelelő szöveges reprezentációt add vissza. A többi metódus az __str__-t is beleértve azonban a state adattag megfelelő metódusát hívják. Az algorithms alcsomag három osztályt tartalmaz, melyek a Pretty osztály leszár- mazottai. Mind a három osztály a hálót bejárását végző egyik algoritmus implemen- tációja. Az Enumeration osztály a 3. fejezetben ismertetett felsorolást valósítja meg, a valószínűség értékeket azonban a klasszikus (2.1) képlet szerint számítja. A Descend és Zigzag osztályok pedig a 3. illetve az 5. algoritmusban ismertetett módon végzi a bejárást és a valószínűségek számítását. Mindegyik változat rendelkezik egy parent adattaggal, amin keresztül eléri a Grid példány szükséges attribútumait és metódu- sait. A Descend osztály ezenkívül egy twmatrix adattaggal is rendelkezik, amiben a szinthez tartozó átviteli súlymátrixot tárolja scipy.sparse.csc_matrix típussal. To- vábbá mindegyik változat rendelkezik egy next_level függvénnyel, ami a következő szint felsorolását végzi. A csomag dokumentációja pydoc-ban is megtörtént, így az mind python nyelvhez használt fejlesztői környezetekben könnyen használható mind a forrás jól értelmezhető, de igény szerint interpreterből is lekérhető. A python nyelvet több képszerkesztő is támogatja. Kézenfekvően adódott az igény, hogy az elkészült csomag felhasználható legyen ábrák készítésére is. Ebből a meggon- dolásból készült el a Dia programhoz egy bővítmény szkript. A Dia képszerkesztő nyílt forrás kódú, fejlesztés és karbantartása a GNOME projekten belül történik. Tervezésé- nek kulcs szempontja a rugalmasság, grafikus felülete Gtk+ alapú. Fordításkor kikap- csolható a python támogatás, illetve léteznek ilyen előre fordított változatok, egyébként feltételezi, hogy a rendszere python interpreter, illetve a szükséges python csomagok, köztük a python-gtk2 telepítve van. Az elkészült bővítmény külön modulba szervez- 36
  • 37.
    tük, ami egyrészta Dia képszerkesztővel, másfelől az mvhgd modullal áll függőségben. A fejlesztés a hálózaton megtalálható példa szkriptek valamint útmutatók segítségével történt. Az mvhgd_dia modul a Dia indulásakor regisztrálja az mvhgd_cb modulszintű me- tódust egy a programkódba bedrótozott nevű menü pontba. Ennek aktiválásakor ez a metódus példányosít egy CInputDialog osztályt. Ez a pygtk csomag segítségével meg- jelenít egy párbeszéd ablakot, illetve az on_draw metódusa az itt megadott adatokat előkészíti az mvhgd csomag számára, hiba üzenetet jelenít meg, ha ez kudarcot vall. Egyébként a draw_lattice modul szintű metódust hívja, ami az mvhgd.Grid, illetve az mvhgd.algorithms.Descend osztályokat használva, az általuk létrehozott adatok alapján, megrajzolja a hálót. 37
  • 38.
    6. fejezet Az algoritmustesztelése A 2. fejezetben definiáltuk a W(n) átviteli súlymátrixokat, melyek szorzatáról megmu- tattuk, hogy a polihipergeometrikus eloszlás értékeivel egyezik meg. A 3. fejezetben, pedig ismertettünk egy algoritmust, ami felsorolja a polihipergeometrikus eloszlás ese- teit, illetve ezzel egy időben a W(n) átviteli súlymátrixokat is kiszámolja. A 3.1. ábrán megadtunk egy példát is, amiről leolvasható az esetek sorrendje. A következőkben ehhez a példához tartozó W(n) átviteli súlymátrixokat n = 0, . . . , 9 is megadjuk. Megmutat- juk a n = 0, 1, 2 esetén, hogy szorzatuk a valószínűség értékekből képzett vektorral megegyezik. Ehhez a (2.1) képlet segítségével is kiszámoljuk a valószínűség értékeket, illetve n = 3 esetre csak a szorzás eredményét közöljük, terjedelmi megfontolásból. Az implementáció megfelelő részéhez tartozó egységteszt tervezésekor ez a megol- dás jó kiinduló pontként szolgál, azonban az esetleges hiba jellegéről keveset árul el. Tehát érdemes további teszteseteket készíteni. Például ellenőrizni, hogy a W(n) átviteli súlymátrixok minden oszlop vektora, pontosan annyi nullától különböző értéket tartal- maz, mint az azonos indexű eset az L(n−1) felsorolásban. Továbbá L(n) felsorolásban az oszlop vektor nullától különböző értékeinek sor indexével azonos indexű elem valóban követési relációban áll az oszlop vektorhoz tatozó elemmel. W(0) . = 1 = p(0) = 3 0 2 0 4 0 9 0 , W(1) =     0, 3333 0, 2222 0, 4444     =              3 1 2 0 4 0 9 1 3 0 2 1 4 0 9 1 3 0 2 0 4 1 9 1              , p(1) = W(1) p(0) = W(1) W(0) = W(1) , 38
  • 39.
    W(2) =             0, 25 00 0, 25 0, 375 0 0, 5 0 0, 375 0 0, 125 0 0 0, 5 0, 25 0 0 0, 375             , p(2) = W(2) p(1) = W(2) W(1) W(0) = = 0, 0833 0, 1667 0, 3333 0, 0278 0, 2222 0, 1667 = = 3 2 2 0 4 0 9 2 3 1 2 1 4 0 9 2 3 1 2 0 4 1 9 2 3 0 2 2 4 0 9 2 3 0 2 1 4 1 9 2 3 0 2 0 4 2 9 2 , W(3) =                     0, 1429 0 0 0 0 0 0, 2857 0, 2857 0 0 0 0 0, 5714 0 0, 2857 0 0 0 0 0, 1429 0 0, 4286 0 0 0 0, 5714 0, 2857 0 0, 4286 0 0 0 0, 4286 0 0 0, 4286 0 0 0 0, 5714 0, 1429 0 0 0 0 0 0, 4286 0, 2857 0 0 0 0 0 0, 2857                     , p(3) = W(3) p(2) = W(3) W(2) W(1) W(0) = = 0, 0119 0, 0714 0, 1428 0, 0357 0, 2857 0, 2142 0, 0476 0, 1428 0, 0476 , W(4) =                          0, 3333 0, 1667 0 0 0 0 0 0 0 0, 6667 0 0, 1667 0 0 0 0 0 0 0 0, 1667 0 0, 3333 0 0 0 0 0 0 0, 6667 0, 3333 0 0, 3333 0 0 0 0 0 0 0, 5 0 0 0, 3333 0 0 0 0 0 0 0, 6667 0, 1667 0 0, 5 0 0 0 0 0 0 0, 5 0, 3333 0 0, 5 0 0 0 0 0 0 0, 3333 0 0 0, 5 0 0 0 0 0 0 0, 5 0, 1667 0 0 0 0 0 0 0 0 0, 3333 0, 3333 0 0 0 0 0 0 0 0 0, 1667                          , 39
  • 40.
    W(5) =                          0, 2 00, 2 0 0 0 0 0 0 0 0 0, 8 0, 4 0 0, 2 0 0 0 0 0 0 0 0 0, 6 0 0 0, 2 0 0 0 0 0 0 0 0 0, 8 0, 2 0 0, 4 0 0 0 0 0 0 0 0 0, 6 0, 4 0 0, 4 0 0 0 0 0 0 0 0 0, 4 0 0 0, 4 0 0 0 0 0 0 0 0 0, 6 0, 2 0 0, 6 0 0 0 0 0 0 0 0 0, 4 0, 4 0 0, 6 0 0 0 0 0 0 0 0 0, 2 0 0 0, 6 0 0 0 0 0 0 0 0 0, 4 0, 2 0 0 0 0 0 0 0 0 0 0 0, 2 0, 4                          , W(6) =                     1 0, 25 0 0, 25 0 0 0 0 0 0 0 0 0, 75 0, 5 0 0, 25 0 0 0 0 0 0 0 0 0, 5 0 0 0, 25 0 0 0 0 0 0 0 0 0, 75 0, 25 0 0, 5 0 0 0 0 0 0 0 0 0, 5 0, 5 0 0, 5 0 0 0 0 0 0 0 0 0, 25 0 0 0, 5 0 0 0 0 0 0 0 0 0, 5 0, 25 0 0, 75 0 0 0 0 0 0 0 0 0, 25 0, 5 0 0, 75 0 0 0 0 0 0 0 0 0 0, 25 0, 25                     , W(7) =             1 0, 3333 0 0, 3333 0 0 0 0 0 0 0, 6667 0, 6667 0 0, 3333 0 0 0 0 0 0 0, 3333 0 0 0, 3333 0 0 0 0 0 0 0, 6667 0, 3333 0 0, 6667 0 0 0 0 0 0 0, 3333 0, 6667 0 0, 6667 0 0 0 0 0 0 0 0, 3333 0, 3333 1             , W(8) =     1 0, 5 0 0, 5 0 0 0 0, 5 1 0 0, 5 0 0 0 0 0, 5 0, 5 1     , W(9) = 1 1 1 . 40
  • 41.
    A 6.1. ábránközölöm a Dia bővítmény szkript egy futási képét is, amelyen egyszerre látszik a menüpont, amin keresztül indítható, a beviteli ablak, amiben a kiindulási adatokat megadhatjuk és a végeredményként megrajzolt diagram. 6.1. ábra. Dia képszerkesztő futási képe a bővítmény szkripttel Amellett, hogy az algoritmus által adott eredmények helyességét vizsgáljuk, a ha- tékonysága is érdekel minket. A futási idő függését mértem a bemenő adatok m és N paraméterei, azaz a kategóriák száma és az elemek száma, szerint. Ennek érdekében az algoritmusokat négy adatsorra futtattam le. Az egyes adatsorokban az m paramé- ter értékei rendre 3, 6, 9 és 12 volt. Az első adatsorban a kezdeti adat: {3, 2, 4}, majd minden iterációban a az egyes elemekhez hozzáadtuk a kezdeti adat megfelelő inde- xű elemét, tehát az adatsor többi adata {6, 4, 8}, {9, 6, 12}, . . . . A többi adatsor kezdő adatát, úgy állítottuk elő, hogy a {3, 2, 4} végéhez ismételten hozzá írtuk önmagát, az így kapott adatok: {3, 2, 4, 3, 2, 4}, {3, 2, 4, 3, 2, 4, 3, 2, 4} és {3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4}, majd mindegyiknél az első adatsornál elmondottak szerint növeltük az elemek számát. A tesztelés során az Enumeration algoritmusban a binomiális együtthatókat a mul- tiplikatív képlet szerint számítottam, lásd az (5.1) formulát. A teszt architektúra specifikációja: Hardver Processzor: IntelR XeonR E5500, 2.13 GHz Memória: 3.9 Gbyte Lapozóterület: 7.5 Gbyte Szoftver Operációs rendszer: Debian GNU/Linux 7.5 (wheezy), x86_64 Interpreter: Python 2.7.3 Használt csomagok: Scipy 0.10.1 Numpy 1.8.2 (libc6 2.15) 41
  • 42.
    A következő grafikona négy adatsor futási idejét mutatja az elemszám függvényé- ben: 0 50 100 150 200 250 300 350 400 450 0,001 0,01 0,1 1 10 100 1 000 N t[s] m=3 m=6 m=9 m=12 Enumerate Descend Zig-zag 6.2. ábra. Futási idő logaritmusa elemszám függvényében Bemenő adat N Processzoridők [s] Enumerate Descend Zig-zag m = 3 [ 3,2,4 ] 9 2 · 10−3 * 1 · 10−2 1 · 10−3 * [ 6,4,8 ] 18 1 · 10−2 1 · 10−2 1 · 10−2 [ 9,6,12 ] 27 2 · 10−2 2 · 10−2 2 · 10−2 [ 12,8,16 ] 36 5 · 10−2 5 · 10−2 4 · 10−2 [ 15,10,20 ] 45 9 · 10−2 8 · 10−2 7 · 10−2 [ 18,12,24 ] 54 0,12 8 · 10−2 0,11 [ 21,14,28 ] 63 0,20 0,12 0,13 [ 24,16,32 ] 72 0,35 0,17 0,20 [ 27,18,36 ] 81 0,52 0,22 0,26 [ 30,20,40 ] 90 0,74 0,30 0,36 [ 33,22,44 ] 99 1,05 0,37 0,48 [ 36,24,48 ] 108 1,44 0,49 0,60 [ 39,26,52 ] 117 1,91 0,61 0,77 [ 42,28,56 ] 126 2,53 0,75 0,95 [ 45,30,60 ] 135 3,26 0,91 1,15 [ 48,32,64 ] 144 4,16 1,10 1,40 [ 51,34,68 ] 153 5,29 1,30 1,67 42
  • 43.
    Bemenő adat NProcesszoridők [s] Enumerate Descend Zig-zag [ 54,36,72 ] 162 6,57 1,52 1,98 [ 57,38,76 ] 171 8,11 1,79 2,33 [ 60,40,80 ] 180 9,88 2,08 2,72 [ 63,42,84 ] 189 11,97 2,40 3,14 [ 66,44,88 ] 198 14,40 2,76 3,58 [ 69,46,92 ] 207 17,22 3,14 4,07 [ 72,48,96 ] 216 20,42 3,55 4,63 [ 75,50,100 ] 225 24,07 4,03 5,24 [ 78,52,104 ] 234 28,17 4,53 5,88 [ 81,54,108 ] 243 32,98 5,07 6,56 [ 84,56,112 ] 252 37,90 5,64 7,31 [ 87,58,116 ] 261 43,76 6,29 8,15 [ 90,60,120 ] 270 50,30 6,97 9,02 [ 93,62,124 ] 279 57,59 7,69 9,95 [ 96,64,128 ] 288 65,69 8,46 10,88 [ 99,66,132 ] 297 74,71 9,29 11,95 [ 102,68,136 ] 306 84,43 10,18 13,08 [ 105,70,140 ] 315 95,42 11,15 14,29 [ 108,72,144 ] 324 106,95 12,08 15,52 [ 111,74,148 ] 333 120,25 13,14 16,82 [ 114,76,152 ] 342 134,32 14,24 18,21 [ 117,78,156 ] 351 149,84 15,43 19,75 [ 120,80,160 ] 360 166,08 16,65 21,27 [ 123,82,164 ] 369 184,46 17,96 22,96 [ 126,84,168 ] 378 203,91 19,30 24,58 [ 129,86,172 ] 387 225,71 20,73 26,59 [ 132,88,176 ] 396 248,33 22,24 28,34 [ 135,90,180 ] 405 272,82 23,72 30,39 [ 138,92,184 ] 414 299,40 25,38 32,29 [ 141,94,188 ] 423 328,90 27,17 34,53 [ 144,96,192 ] 432 357,93 28,97 36,69 [ 147,98,196 ] 441 390,51 30,86 39,12 [ 150,100,200 ] 450 425,51 32,82 41,56 [ 153,102,204 ] 459 462,78 34,96 44,12 [ 156,104,208 ] 468 502,03 37,17 46,76 m = 6 [ 3,2,4,3,2,4 ] 18 7 · 10−2 5 · 10−2 6 · 10−2 43
  • 44.
    Bemenő adat NProcesszoridők [s] Enumerate Descend Zig-zag [ 6,4,8,6,4,8 ] 36 2,26 1,48 1,90 [ 9,6,12,9,6,12 ] 54 21,39 13,28 16,45 [ 12,8,16,12,8,16 ] 72 121,64 68,28 80,76 [ 15,10,20,15,10,20 ] 90 485,94 247,61 286,02 [ 18,12,24,18,12,24 ] 108 1 519,78 704,73 806,68 [ 21,14,28,21,14,28 ] 126 4 046,23 1 693,17 1 948,48 [ 24,16,32,24,16,32 ] 144 OoM** OoM** 4 185,13 [ 27,18,36,27,18,36 ] 162 OoM** OoM** OoM** m = 9 [ 3,2,4,3,2,4,3,2,4 ] 27 5,80 4,48 5,31 [ 6,4,8,6,4,8,6,4,8 ] 54 1 013,82 OoM** OoM** [ 9,6,12,9,6,12,9,6,12 ] 81 OoM** OoM** OoM** m = 12 [ 3,2,4,3,2,4,3,2,4,3,2,4 ] 36 454,61 OoM** 405,73 [ 6,4,8,6,4,8,6,4,8,6,4,8 ] 72 OoM** OoM** OoM** * 10 futtatás átlaga ** Out of Memory, 3Gb korlát 6.1. táblázat Futási idők 44
  • 45.
    7. fejezet Összefoglalás Ebben adolgozatban megvizsgáltam a polihipergeometrikus eloszlás eseteinek felsorolá- sát és valószínűség értékeinek lehetséges számítás módjait. A 2.3. tételben megadtam egy algebrai struktúrát, majd megmutattam, hogyan segíti a probléma megoldását. Majd ezt felhasználva a 3. fejezetben leírtam két algoritmust, amelyek az említett háló bejárását valósítják meg. A fejezet végén pedig utalást tettem a probléma számelmé- leti vonatkozásaira is. Az 5. fejezetben ismertettem ezen algoritmusok általam python nyelven elkészített implementációját, illetve az összehasonlításához szükséges eszközö- ket. Továbbá említést tettem az irodalomban megtalálható algoritmusokról is, melyek a munkám kiinduló pontjaként szolgáltak. Végezetül bemutattam a 6. fejezetben az implementáció tesztelése során nyert adatokat. A dolgozat hagyott nyitott kérdéseket, ezek a következőek: • A 3. és az 5. algoritmus formális leírásából hiányzik az index számításának pontos képlete, helyességük nincs bizonyítva. • Az eloszlás eseteinek beszámozását az említett algoritmusok implicit módon old- ják meg. A (4.1) formulában csak az utolsó elemek indexére, azaz a szintek hosszá- ra adtunk explicit képletet. Szeretném a második ponthoz megjegyezni, hogy a felsorolás a párhuzamos megvalósí- tásához elengedhetetlen, hogy az esetek indexeit explicit módon tudjuk kiszámítani. Ebben dolgozatban rámutattam egy hatékony módszer kidolgozásának lehetőségére, mely a polihipergeometrikus eloszlás értékeit, olyan feltételek mellet is képes kiszámí- tani, amikor közelítő eljárások nem alkalmazhatóak. 45
  • 46.
    Irodalomjegyzék [1] C. Huygens:Libellus De Ratiociniis in Ludo Aleæ, S. Keimer for T. Woodward, London, 1714. [2] A. Hald: History of Probability and Statistics and Their Applications before 1750, Wiley-Interscience, New York, 1990. [3] N. L. Johnson, S. Kotz, N. Balakrishnan, C. B. Read, B. Vidakovic: Encyclopedia of statistical sciences, Wiley-Interscience, 2006., 3283–3292. [4] E. Jones, T. Oliphant, P. Peterson, et al.: SciPy: Open Source Scientific Tools for Python, (2001–), http://www.scipy.org [5] J. Kelleher, B. O’Sullivan: Generating All Partitions: A Comparison Of Two Encodings, arXiv:0909.2331 [cs.DS], 2009. [6] Kiss Emil: Bevezetés az algebrába, Typotex, 2007., 480–488. [7] K. Pearson: On Certain Properties of the Hypergeometrical Series, and on the Fitting of such Series to Observation Polygons in the Theory of Chance, Philosophical Magazine 5th Series, 47 (1899), 236–246. [8] G. van Rossum, F. L. Drake: Python Reference Manual, PythonLabs, Virginia, USA, 2001. [9] A. Williams: Loopless Generation of Multiset Permutations using Constant Number of Variables by Prefix Shifts, SODA ’09 Proceedings of the twentieth Annual ACM-SIAM Symposium on Discrete Algorithms, (2009), 987–996. 46
  • 47.
    Adathordozó használati útmutató Amellékelt CD gyökérkönyvtárában megtalálható ez a dolgozat PDF formátumban illetve a tex könyvtárban a LATEX forrásfájlok. A tex könyvárban három alkönyvtár is található. Az include alkönyvtárban találhatóak az egyes fejezetek forrásfájljai. Az images alkönyvtárban vannak a felhasznált PNG formátumú ábrák, illetve az 5.1. áb- rának a Graphviz gv formátumú (a kiterjesztése .dot) forrása is. A data alkönyvtárban a 6.1. táblázatban közölt adatok találhatóak CSV formátumban, egyrészről a tesztek során közvetlenül nyert fájlok és az azokból összefűzött fájlok is. Az multivariate-hypergeometric alkönyvtárban az elkészült implementáció ta- lálható, a git metaadatokkal együtt (a .git alkönyvtárban). A gyökérkönyvtárban található egy README.htm fájl, mely telepítési és használati segédletet tartalmaz. 47