ˇ – Technicka´ univerzita Ostrava VSB Fakulta elektrotechniky a informatiky Katedra informatiky
Objektoveˇ orientovana´ ´ implementace skyline systemu ´ an´ ´ ı rˇ´ıdkych uklad ´ matic ´ rska´ prace ´ Bakalaˇ
2008
Martin Stachonˇ
´ ı Zadan´ T´ema: Diplomant: Vedouc´ı: Akad. rok: Obor:
Objektovˇe orientovan´a implementace skyline syst´emu ukl´ad´an´ı rˇ´ıdkych ´ matic Martin Stachonˇ Doc. Mgr. V´ıt Vondr´ak, Ph.D. 2007 / 2008 1103R021 Poˇc´ıtaˇcov´a matematika
´ ´ ı Zasady pro vypracovan´ ´ V n´aroˇcnych inˇzenyrsk uloh´ ach se velmi cˇ asto objevuj´ı rozs´ahl´e syst´emy soustav ´ ´ ych ´ ˚ Tyto matice line´arn´ıch rovnic jejichˇz matice obsahuj´ı velk´e mnoˇzstv´ı nulovych prvku. ´ ´ se nazyvaj´ bude ´ ı rˇ´ıdk´e a je pochopiteln´e, zˇ e kl´ıcˇ ovou roli v efektivnosti rˇ eˇsen´ı tˇechto uloh hr´at rychlost pˇri pr´aci s tˇemito maticemi. Dalˇs´ı nem´enˇe vyznamnou roli pak hraje i ve´ likost pamˇeti, kterou tato struktura pˇri bˇezˇ nych ´ maticovych ´ operac´ıch zab´ır´a. Jednou z velmi pouˇz´ıvanych ´ struktur je tzv. skyline syst´em ukl´ad´an´ı matic, ktery´ spoleˇcnˇe se Sloanovym ´ algoritmem pro pˇreˇc´ıslov´an´ı matic je velmi hojnˇe pouˇz´ıv´an pˇredevˇs´ım tam, kde je zapotˇreb´ı rychl´a LU cˇ i Cholesk´eho faktorizace. Pr´ace se d´a rozloˇzit do n´asleduj´ıc´ıch ˚ bodu: ˚ algoritmus pro sn´ızˇ en´ı profilu matic • Sloanuv • Objektovˇe orientovany´ n´avrh implementace skyline syst´emu ukl´ad´an´ı matic • Implementace vyˇ ´ se uveden´eho v jazyce C++
Prohlaˇsuji, zˇ e jsem tuto bakal´arˇ skou pr´aci vypracoval samostatnˇe. Uvedl jsem vˇsechny liter´arn´ı prameny a publikace, ze kterych ´ jsem cˇ erpal.
V Ostravˇe 2. kvˇetna 2008
.............................
Zde bych r´ad podˇekoval Ing. Pavle Kabel´ıkov´e a Doc. Mgr. V´ıtu Vondr´akovi, Ph.D. za poskytnut´ı literatury, konzultac´ı a pˇr´ıkladu˚ pro testov´an´ı. Pˇri tvorbˇe t´eto pr´ace jsem mnohokr´at pouˇzil GNU Octave, dˇekuji vˇsem, kteˇr´ı se pod´ılej´ı na vyvoji tohoto volnˇe ´ sˇ iˇriteln´eho softwaru.
Abstrakt Tato bakal´arˇ sk´a pr´ace se zabyv´ ´ a Skyline syst´emem ukl´ad´an´ı rˇ´ıdkych ´ matic a jeho objek˚ tovˇe orientovanou implementac´ı v programovac´ım jazyce C++. D´ale popisuje Sloanuv ´ celem sn´ızˇ en´ı profilu a jeho implementaci v proalgoritmus pro pˇreˇc´ıslov´an´ı matice za uˇ gramovac´ım jazyce C++. ˇ a´ slova: Sloanuv ˚ algoritmus, rˇ´ıdk´e, matice, skyline, C++ Kl´ıcov
Abstract This thesis describes the Skyline system of sparse matrix storage and its object-oriented implementation in C++ programming language. Also, Sloan’s algorithm for matrix reordering for lower matrix profile is described and implemented in C++. Keywords: Sloan’s algorithm, sparse, matrix, skyline, C++
Seznam pouˇzitych ´ zkratek a symbolu˚ OOSol
–
RCM
–
Object Oriented SOLvers, objektovˇe orientovan´a knihovna v programovac´ım jazyce C++ pro numerick´e vypoˇ ´ cty Reverse Cuthill–McKee, algoritmus pro pˇreˇc´ıslov´an´ı vrcholu˚
1
Obsah 1
´ Uvod
2
Skyline matice 2.1 Z´akladn´ı pojmy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ˇ ıdk´e matice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 R´ 2.3 Skyline matice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7 7 9 10
3
Syst´em ukl´ad´an´ı Skyline matic 3.1 Datov´e struktury . . . . . . . . . . . . . . . . . . . . . 3.2 Pamˇet’ov´a n´aroˇcnost . . . . . . . . . . . . . . . . . . . ˚ 3.3 Pˇr´ıstup k prvkum . . . . . . . . . . . . . . . . . . . . . 3.4 Sestaven´ı skyline syst´emu . . . . . . . . . . . . . . . . 3.5 Implementace skyline syst´emu pro knihovnu OOSol .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
12 12 13 13 13 14
Grafy 4.1 Z´akladn´ı pojmy z teorie grafu˚ . . . . . . . . 4.2 Souvislost mezi grafem a strukturou matice 4.3 Ukl´ad´an´ı grafu pomoc´ı seznamu sousedu˚ . 4.4 Sestaven´ı seznamu sousedu˚ . . . . . . . . . ´ ˇ a struktura . . . . . . . . 4.5 Koˇrenov´a urov nov´
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
18 18 19 20 20 20
Sloanuv ˚ algoritmus ˚ eru . . . . . . . . . . . . . . . . . . . 5.1 Urˇcen´ı pseudoprumˇ 5.2 Pˇreˇc´ıslov´an´ı vrcholu˚ . . . . . . . . . . . . . . . . . . . . 5.3 Hodnoty parametru˚ W1 a W2 . . . . . . . . . . . . . . . 5.4 Implementace sloanova algoritmu pro knihovnu OOSol
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
22 22 22 24 25
4
5
6
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
6
Testov´an´ı a vysledky ´
28
7
Z´avˇer
33
8
Reference
34
Pˇr´ılohy
34
A Zdrojov´e kody ´
35
2
Seznam tabulek 1 2
Testovac´ı matice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Vysledn´ e profily . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ´
31 31
3
´ u˚ Seznam obrazk 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
ˇ e kˇr´ızˇ ky reprezentuj´ı nenulovy´ prvek. Vystup pˇr´ıkazu spy. Sed´ ´ Uk´azka matice se skyline profilem. . . . . . . . . . . . . . . . . . Uk´azka matice se symetrickym ´ skyline profilem. . . . . . . . . . Hierarchie tˇr´ıd reprezentuj´ıc´ıch matice v knihovnˇe OOSol . . . Pˇr´ıklad grafu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Stavy vrcholu˚ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S´ıt’ matice ctverec1 . . . . . . . . . . . . . . . . . . . . . . . . . S´ıt’ matice ctverec3 . . . . . . . . . . . . . . . . . . . . . . . . . S´ıt’ matice krychle1 . . . . . . . . . . . . . . . . . . . . . . . . . S´ıt’ matice krychle2 . . . . . . . . . . . . . . . . . . . . . . . . . S´ıt’ matice krychle3 . . . . . . . . . . . . . . . . . . . . . . . . . S´ıt’ matice krychle4 . . . . . . . . . . . . . . . . . . . . . . . . . S´ıt’ matice UF871 - helikopt´era Commanche . . . . . . . . . . . . ˚ Puvodn´ ı profil matice krychle4 . . . . . . . . . . . . . . . . . . Profil matice krychle4 po pˇreˇc´ıslov´an´ı sloanovym ´ algoritmem Profil matice krychle4 po pˇreˇc´ıslov´an´ı algoritmem RCM . . . ˚ Puvodn´ ı profil matice ctverec3 . . . . . . . . . . . . . . . . . . Profil matice ctverec3 po pˇreˇc´ıslov´an´ı sloanovym ´ algoritmem
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
10 10 11 17 19 24 29 29 29 29 29 30 30 30 32 32 32 32
4
Seznam algoritmu˚ 1 2 3 4
˚ matice ve skyline syst´emu Pˇr´ıstup k prvkum ´ ˇ e struktury . . . Sestaven´ı koˇrenov´e urov nov´ ˚ eru grafu . . . . . . . . Nalezen´ı pseudoprumˇ ˚ algoritmus pro pˇreˇc´ıslov´an´ı vrcholu˚ Sloanuv
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
14 21 23 27
5
´ ´ Seznam vypis ´ u˚ zdrojoveho kodu 1 2 3 4
Soubor OOSmatricesSkylineStatic.h . Soubor OOSmatricesSkylineStatic.cpp Soubor OOSgraph.cpp . . . . . . . . . Soubor OOSgraph.h . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
36 39 58 65
6
1
´ Uvod
Ve vˇedeck´e a technick´e praxi se, napˇr´ıklad pˇri rˇ eˇsen´ı soustav parci´alnˇe diferenci´aln´ıch ˚ cˇ asto objevuj´ı rˇ´ıdk´e matice, tedy matice s mnoha rovnic metodou koneˇcnych prvku, ´ nulovymi prvky. Pro efektivn´ı uloˇzen´ı tˇechto rozs´ahlych matic a manipulaci s nimi je ´ ´ vyhodn´ e a u rozs´ahlejˇs´ıch probl´emu˚ nutn´e, pouˇz´ıvat efektivn´ı datov´e struktury. V t´eto ´ bakal´arˇ sk´e pr´aci pop´ısˇ i jednu z tˇechto struktur, takzvany´ Skyline storage, ktery´ je vyhodn y´ ´ pro rˇ´ıdk´e matice s nenulovymi prvky soustˇredˇenymi okolo diagon´aly. ´ ´ Jelikoˇz ne kaˇzd´a rˇ´ıdk´a matice m´a uspoˇra´ d´an´ı vhodn´e pro Skyline storage, pouˇz´ıvaj´ı se pˇreˇc´ıslovac´ı algoritmy, kter´e pˇreuspoˇra´ daj´ı rˇ a´ dky a sloupce matice tak, aby se sn´ızˇ il jejich profil a t´ım p´adem i pamˇet’ potˇrebn´a pro jejich uloˇzen´ı. Jedn´ım z nejefektivnˇejˇs´ıch je algoritmus, jehoˇz autorem je S. W. Sloan a tento algoritmus zde pop´ısˇ i. Souˇca´ st´ı t´eto pr´ace je i implementace vyˇ ´ se uveden´eho v jazyce C++ pro knihovnu OOSol.
7
2 2.1
Skyline matice ´ Zakladn´ ı pojmy
Definujme nˇekolik z´akladn´ıch pojmu˚ tykaj´ ´ ıc´ıch se matic, kter´e pak budou v t´eto pr´aci d´ale pouˇzity. Definice 2.1 Matic´ı rozum´ıme tabulku matematick´ych v´yrazu˚ o m rˇa´ dc´ıch a n sloupc´ıch. a11 a12 . . . a1n a21 a22 . . . a2n A= . .. .. .. . . am1 am2 . . . amn aij pak oznaˇcujeme jako prvek matice A na i-t´em rˇa´ dku a j-t´em sloupci. V t´eto pr´ac´ı se budeme zabyvat pouze re´aln´ymi maticemi, to jest takovymi, jejichˇz ´ ´ prvky jsou pouze re´aln´a cˇ ´ısla, aij ∈ R Pozn´amka 2.1 V matematice byv´ ´ a zvykem pouˇz´ıvat indexy zaˇc´ınaj´ıc´ı od jedniˇcky. V po˚ zpusobu ˚ pisu C++ programu se kvuli indexace pol´ı v tomto jazyce pouˇz´ıvaj´ı indexy zaˇc´ınaj´ıc´ı od nuly. ˇ Definice 2.2 Ctvercov a´ matice je takov´a, kter´a m´a stejn´y poˇcet rˇa´ dku˚ jako sloupcu, ˚ m=n Definice 2.3 Symetricka´ matice je matice, kter´a je cˇ tvercov´a a nav´ıc plat´ı aij = aji pro vˇsechna 1 ≤ i ≤ n, 1 ≤ j ≤ n ´ Definice 2.4 i-ty´ rˇadek rA (i) matice A je vektor rA (i) =
ai1 , ai2 , . . . , ain
Definice 2.5 j-ty´ sloupec sA (i) matice A je vektor a1j a2j sA (i) = . ..
amj ´ ı prvek aij matice A je takov´y prvek, pro kter´y plat´ı i = j. Definice 2.6 Diagonaln´ ´ matice A je vektor vˇsech diagon´aln´ıch prvku˚ Definice 2.7 Diagonala diag(A) = a11 , a22 , . . . , akk kde k = min{m, n}
8
´ ´ jsou prvky nad diagon´alou, tedy takov´e aij , pro kter´e Definice 2.8 Horn´ı trojuheln´ ıkova´ cˇ ast plat´ı i < j. ´ ´ jsou prvky pod diagon´alou, tedy takov´e aij , pro kter´e Definice 2.9 Doln´ı trojuheln´ ıkova´ cˇ ast plat´ı i > j. Pˇr´ıklad 2.1 Ukaˇzme si tyto pojmy na konkr´etn´ı matici.
1 2 3 A= 4 5 6 7 8 9
Tato matice m´a 3 sloupce a 3 rˇ a´ dky, je cˇ tvercov´a. Prvek v druh´em rˇ a´ dku, tˇret´ım sloupci: a2,3 = 6 Tˇret´ı rˇ a´ dek matice : rA (3) = 7 8 9 1 A 4 Prvn´ı sloupec matice : s (1) = 7 Diagon´ala matice : diag(A) = 1 5 9 2 3 ´ 6 Horn´ı trojuheln´ ıkov´a cˇ a´ st U = ´ Doln´ı trojuheln´ ıkov´a cˇ a´ st L = 4 7 8
Definice 2.10 Symetrickou permutac´ı cˇ tvercov´e matice o rozmˇeru m permutaˇcn´ım vektorem p d´elky m, nazveme zobrazen´ı A˜ = symperm(A, p), takov´e zˇ e, a ˜i,j = api ,pj ˚ Napˇr´ıklad pro Pozn´amka 2.2 Permutaˇcn´ı vektor p ud´av´a nov´e poˇrad´ı rˇ a´ dku˚ a sloupcu. matici A z pˇredchoz´ıch pˇr´ıkladu˚ bude symetrick´a permutace vektorem p = (3, 1, 2) : 9 7 8 A˜ = 3 1 2 6 4 5 Nˇekdy se m´ısto permutaˇcn´ıho vektoru pouˇz´ıv´a takzvany´ inverzn´ı permutaˇcn´ı vektor, ktery´ m´ısto poˇrad´ı sloupcu˚ a rˇ a´ dku˚ ud´av´a na pozici i novy´ index pro i-ty´ sloupec nebo rˇ a´ dek. Inverzn´ı permutaˇcn´ı vektor pro vektor p je p¯ = (2, 3, 1). Permutaci lze tak´e zav´est pomoc´ı permutaˇcn´ı matice P , a permutaci pak lze zapisovat jako n´asoben´ı matic. Tento pˇr´ıstup se ale v praktick´e implementaci nepouˇz´ıv´a.
9
2.2
ˇ ıdke´ matice R´
Definice 2.11 Jako nenulovy´ prvek oznaˇcujeme takov´y prvek matice aij , pro kter´y plat´ı aij 6= 0, Naproti tomu Definice 2.12 Jako nulovy´ prvek oznaˇcujeme takov´y prvek matice aij , pro kter´y plat´ı aij = 0, Definice 2.13 Necht’ je d´ana matice A o m rˇa´ dc´ıch a n sloupc´ıch. Pak definujeme poˇcet nenulov´ych prvku˚ nnz(A) = ||{aij : 1 ≤ i ≤ m, 1 ≤ j ≤ n, aij 6= 0}|| Poˇcet nulovych ´ prvku je potom roven m · n − nnz(A) ˚ zeme definovat rˇ´ıdkou matici jako matici, kter´a m´a mnohem m´enˇe nenuNyn´ı jiˇz muˇ lovych ´ prvku˚ neˇz je celkovy´ poˇcet prvku˚ v matici. Definice 2.14 Matice A o m rˇa´ dc´ıch a n sloupc´ıch se naz´yv´a rˇı´dka´ matice, jestliˇze nnz(A) m·n Pˇr´ıklad 2.2 Pˇr´ıklad rˇ´ıdk´e matice s tˇremi nenulovymi prvky ´ S=
0 0 2 0 0
0 0 0 0 0
0 0 0 0 0
0 1 0 0 3
0 0 0 0 0
, nnz(S) = 3
Pˇri z´apisu v tabulce se pro pˇrehlednost nuly na m´ıstˇe nulovych ´ prvku nevypisuj´ı. Tak tomu bude nad´ale i v t´eto pr´aci. ˇ ıdk´e matice muˇ ˚ zeme vizu´alnˇe interpretovat tak, zˇ e matici zobraz´ıme jako obr´azek R´ o m · n bodech, pˇriˇcemˇz kaˇzdy´ bod reprezentuje jeden prvek matice a barevnˇe odliˇs´ıme nulov´e a nenulov´e prvky. V prostˇred´ı Matlab nebo Octave k tomu lze pouˇz´ıt pˇr´ıkaz spy(A). Pˇr´ıklad takov´eho zobrazen´ı je na obr´azku 1. Pozn´amka 2.3 Pˇri z´apisu rˇ´ıdkych ´ matic se, zejm´ena v matematick´em softwaru pouˇz´ıv´a z´apis pomoc´ı tˇr´ı vektoru˚ i, j, c. Vˇsechny tˇri vektory maj´ı stejny´ poˇcet sloˇzek jako poˇcet nenulovych ´ prvku˚ matice. k-ty´ nenulovy´ prvek v matici je pak na rˇ a´ dku ik , sloupci jk a m´a hodnotu vk . Ostatn´ı prvky matice jsou implicitnˇe nulov´e. Napˇr´ıklad pro vyˇ ´ se uvedenou matici S : i = (2, 3, 5), j = (4, 1, 4), v = (1, 2, 3) ˚ matice s2,4 = 1, s3,1 = 2, s5,4 = 3 Coˇz odpov´ıd´a nenulovym ´ prvkum
10
ˇ e kˇr´ızˇ ky reprezentuj´ı nenulovy´ prvek. Obr´azek 1: Vystup pˇr´ıkazu spy. Sed´ ´ S=
2 1 2 1 1
1 1 2 1 1 1 0
1 2 0 0 1
1 1 1 1 2 0 1 0 2 0 1 0 0 2 0 2
Obr´azek 2: Uk´azka matice se skyline profilem.
2.3
Skyline matice
V t´eto pr´aci se budu d´ale zabyvat speci´aln´ım druhem rˇ´ıdkych matic, takzvan´e Sky´ ´ line matice. Tyto se vyznaˇcuj´ı t´ım, zˇ e nenulov´e prvky jsou soustˇredˇeny okolo diagon´aly. N´azev je odvozen z toho, zˇ e prvky nad diagon´alou pˇripom´ınaj´ı siluetu mˇesta s mrakodrapy - anglicky skyline. Uk´azka takov´e matice je na obr´azku 2 . Pro pˇresnˇejˇs´ı popis skyline matice si definujme pojmy : profil rˇ a´ dku, profil sloupce, ˚ vektor sloupcovych ˚ rˇ a´ dkovy´ profil, sloupcovy´ profil, vektor rˇ a´ dkovych ´ profilu, ´ profilu, ˚ zit´e pro urˇcen´ı profil matice a matice se symetrickym ´ profilem. Tyto pojmy budou duleˇ poˇzadovan´e velikosti pamˇeti, kter´a je potˇrebn´a pro uloˇzen´ı matice ve skyline syst´emu. Definice 2.15 Profil j-t´eho sloupce sp (j) matice A rozmˇerech (m, n) definujeme jako sp (j) = j − min{i : aij 6= 0, 1 ≤ i ≤ j} ˚ zeme vyj´adˇrit jako poˇcet prvku˚ v j-t´em sloupci nad Slovnˇe profil j-t´eho sloupce muˇ ´ diagon´aln´ım prvkem (v horn´ı trojuheln´ ıkov´e cˇ a´ sti) aˇz do prvn´ıho nenulov´eho (s nejniˇzsˇ´ım rˇ a´ dkovym ´ indexem), vˇcetnˇe. Obdobn´a je definice rˇ a´ dkov´eho profilu, kter´a odpov´ıd´a
11
2 1 3 2 1 1 2 T = 1 1 1
7 1 2 0 1
1 1 3 2 3 0 2
Obr´azek 3: Uk´azka matice se symetrickym ´ skyline profilem. ´ poˇctu prvku˚ v i-t´em rˇ a´ dku nalevo od diagon´aln´ıho prvku v doln´ı trojuheln´ ıkov´e cˇ a´ sti aˇz po nenulovy´ prvek s nejniˇzsˇ´ım sloupcovym ´ indexem. Definice 2.16 Profil i-t´eho rˇa´ dku rp (i) matice A rozmˇerech (m, n) definujeme jako rp (i) = i − min{j : aij 6= 0, 1 ≤ j ≤ i} ˚ Vektor rˇ a´ dkovych ´ profilu˚ je pak vektor, jehoˇz sloˇzky jsou profily jednotlivych ´ rˇ a´ dku, ˚ vektor sloupcovych ´ profilu˚ pak obsahuje profily sloupcu. Definice 2.17 Vektor rˇa´ dkov´ych profilu˚ rh matice o rozmˇerech (m,n) je vektor d´elky m, rhi = rp (i), 1 ≤ i ≤ m. Vektor sloupcov´ych profilu˚ sh matice je vektor d´elky n, shi = sp (i), 1 ≤ i ≤ n ˇ adkov´y profil matice o rozmˇerech (m,n) je roven souˇctu profilu˚ vˇsech rˇa´ dku˚ maDefinice 2.18 R´ m n P P tice. rs = rp (i). Sloupcov´y profil je roven souˇctu profilu˚ vˇsech sloupcu. ˚ ss = sp (j) i=1
j=1
Definice 2.19 Matice m´a symetrick´y profil, pokud jsou si rovny vektory rˇa´ dkov´ych a sloupcov´ych profilu, ˚ rh = sh . Definice 2.20 Profil p matice je roven souˇctu rˇa´ dkov´eho a sloupcov´eho profilu p = rs + ss . Definice 2.21 Prvek aij leˇz´ı uvnitˇr profilu matice, pokud : • i=j • i < j (horn´ı trojuheln´ ´ ıkov´a cˇ a´ st) : i ≥ j − sp (j) • i > j (doln´ı trojuheln´ ´ ıkov´a cˇ a´ st) : j ≥ i − rp (i) Pˇr´ıklad 2.3 Vektory profilu˚ pro matici S na obr´azku 2 jsou, rˇ a´ dkovy´ : rh = (0, 0, 1, 2, 2, 4, 3, 0) a sloupˇ adkovy´ profil : rs = 12, sloupcovy´ profil : ss = 13. Celcovy´ sh = (0, 1, 2, 1, 3, 0, 3, 3). R´ kovy´ profil matice p = 12 + 13 = 25. Matice nem´a symetricky´ profil. Pˇr´ıklad matice se symetrickym ´ profilem je na obr´azku 3.
12
´ uklad ´ an´ ´ ı Skyline matic System
3
Skyline syst´em vyuˇz´ıv´a profilu matice, a ukl´ad´a pouze prvky na diagon´ale, prvky v pro´ filu kaˇzd´eho sloupce v horn´ı trojuheln´ ıkov´e cˇ a´ sti a prvky v profilu kaˇzd´eho rˇ a´ dku doln´ı ´ trojuheln´ ıkov´e cˇ a´ sti. Nulov´e prvky matice mimo profil se neukl´ad´aj´ı, ale uvnitˇr profilu ano. Pro matici s rozmˇery (m,n) jsou pouˇzity tyto datov´e struktury :
3.1
Datove´ struktury
• Pole celych ´ cˇ ´ısel diag d´elky min{m, n} slouˇz´ı k ukl´ad´an´ı prvku˚ na diagon´ale. Diagon´aln´ı prvek aii je na i-t´e pozici v poli. • Celoˇc´ıseln´a promˇenn´a luc je rovna sloupcov´emu profilu ss matice. • Pole re´alnych ´ cˇ ´ısel uc d´elky luc obsahuje postupnˇe (prvky jsou rˇ azeny s rostouc´ım rˇ a´ dkovym ´ indexem) po sloupc´ıch vˇsechny prvky uvnitˇr sloupcov´eho profilu. • Pole celych ´ cˇ ´ısel iuc d´elky n + 1 obsahuje indexy zaˇca´ tku˚ sloupcu˚ v poli uc. Prvky ´ v profilu j-t´eho sloupce horn´ı trojuheln´ ıkov´e cˇ a´ sti matice tedy nalezneme v poli uc na indexech iuc[j] aˇz iuc[j+1]-1. Profil j-t´eho sloupce sp (j) = iuc[j + 1] − iuc[j] • Celoˇc´ıseln´a promˇenn´a llr je rovna rˇ a´ dkov´emu profilu rs matice. • Pole re´alnych ´ cˇ ´ısel lr d´elky llr obsahuje postupnˇe (prvky jsou rˇ azeny s rostouc´ım sloupcovym ´ indexem) po rˇ a´ dc´ıch vˇsechny prvky uvnitˇr rˇ a´ dkov´eho profilu. • Pole celych ´ cˇ ´ısel ilr d´elky m + 1 obsahuje indexy zaˇca´ tku˚ rˇ a´ dku˚ v poli lr. Prvky v ´ profilu i-t´eho rˇ a´ dku doln´ı trojuheln´ ıkov´e cˇ a´ sti matice tedy nalezneme v poli lr na indexech ilr[i] aˇz ilr[i+1]-1. Profil i-t´eho rˇ a´ dku rp (i) = ilr[i + 1] − ilr[i] Pˇr´ıklad 3.1 ˇ Ukaˇzme si obsah tˇechto datovych zˇ e indexy ´ struktur na uk´azkov´e matici. Upozornuji, zaˇc´ınaj´ı od nuly. Mˇejme matici 1 6 9 2 7 0 13 3 8 0 A= 14 4 12 15 16 5 Potom obsah datovych ´ struktur v skyline syst´emu bude : • diag = {1, 2, 3, 4, 5} • luc = 7 • uc = {6, 3, 7, 8, 9, 0, 0, 12} • iuc = {0, 0, 1, 2, 4, 8}
13
• llr = 4 • lr = {13, 14, 15, 16} • ilr = {0, 0, 0, 1, 2, 4}
Pozn´amka 3.1 Tento syst´em je statick´y. Jakmile je obsah datovych struktur sestaven v ´ pamˇeti, nˇekter´e operace, jako je napˇr´ıklad zmˇena profilu matice pˇrid´an´ım nov´eho prvku mimo profil, nebo rˇ a´ dkov´a cˇ i sloupcov´a permutace je nemoˇzn´e prov´est bez realokace a znovusestaven´ı datovych ´ struktur. Alternativou by byl dynamick´y syst´em, ve kter´em by prvky v profilu matice nebyly uloˇzeny v jednom poli, ale kaˇzdy´ rˇ a´ dek a sloupec by byl dynamicky alokovan´e pole a m´ısto pole indexu˚ by se pouˇz´ıvalo pole ukazatelu˚ na tyto alokovan´e pole. D´elka jednotlivych ´ pol´ı by se musel uchov´avat v samostatn´em poli, jelikoˇz tuto informaci by uˇz nebylo moˇzn´e z´ıskat z pole indexu˚ jako u statick´eho syst´emu. V tomto dynamick´em syst´emu by byly nˇekter´e operace spojen´e se zmˇenou profilu mnohem m´enˇe n´akladn´e, protoˇze pro zmˇenu profilu jednotliv´eho rˇ a´ dku cˇ i sloupce staˇc´ı realokovat pouze pˇr´ısluˇsn´e pole a aktualizovat ukazatel, m´ısto realokace cel´e matice. Tento syst´em m´a i sv´e nevyhody : vˇetˇs´ı pamˇet’ov´a n´aroˇcnost vlivem fragmentace ´ ˚ pamˇeti a niˇzsˇ´ı efektivita skal´arn´ıch operac´ı s matic´ı (m´ısto jednoho pˇr´ım´eho pruchodu pole je tˇreba proch´azet vˇsechny pole). Vzhledem k tomu, zˇ e Skyline syst´em se pouˇz´ıv´a vˇetˇsinou v aplikac´ıch, kter´e zachov´avaj´ı profil matice (Cholesk´eho faktorizace), implementoval jsem v t´eto pr´aci staticky´ syst´em.
3.2
ˇ ’ova´ naro ´ cnost ˇ Pamet
Pro uloˇzen´ı matice o rozmˇerech (m, n) ve skyline struktuˇre je potˇreba p + min{m, n} slov pamˇeti pro desetinn´a cˇ ´ısla (uloˇzen´ı prvku˚ matice v profilu a na diagon´ale) a m + n + 2 ˚ slov pamˇeti pro cel´a cˇ ´ısla (uloˇzen´ı indexu).
3.3
Pˇr´ıstup k prvkum ˚
Pˇr´ıstup k prvku na i-t´em rˇ a´ dku a j-t´em sloupci je pˇr´ımoˇcary´ - staˇc´ı zjistit, zda prvek nen´ı na diagon´ale, pˇr´ıpadnˇe mimo profil, a spoˇc´ıtat index, na kter´em je uloˇzen v konkr´etn´ım poli. Pˇr´ıstup je pops´an v algoritmu 1.
3.4
´ Sestaven´ı skyline systemu
˚ Implementoval jsem dva zpusoby sestaven´ı skyline matice - z pln´e matice, a z vektoru˚ i, j, v (viz pozn´amka 2.3). Princip je u obou stejny´ : v prvn´ım kroku jsou urˇceny vektory sloupcovych ´ a rˇ a´ dkovych ´ profilu˚ (urˇcen´ı nenulov´eho prvku s minim´aln´ım sloupcovym, ´ pˇr´ıpadnˇe rˇ a´ dkovym ´ indexem). Pot´e je jiˇz moˇzn´e alokovat datov´e struktury a prvky matice um´ıstit na pˇr´ısluˇsn´a m´ısta v pamˇeti.
14
˚ matice ve skyline syst´emu Algoritmus 1 Pˇr´ıstup k prvkum Require: 0 ≤ i < m and 0 ≤ j < n 1: if i = j then {diagon´ aln´ı prvek} 2: return diag[i] ´ 3: else if i < j then {horn´ı trojuheln´ ıkov´a cˇ a´ st} 4: if j − i > cp (j) then {mimo profil} 5: return 0 6: else 7: return uc[iuc[j + 1] − j + i] 8: end if ´ 9: else {doln´ı trojuheln´ ıkov´a cˇ a´ st} 10: if i − j > rp (i) then {mimo profil} 11: return 0 12: else 13: return lr[ilr[i + 1] − i + j] 14: end if 15: end if
3.5
´ Implementace skyline systemu pro knihovnu OOSol
Implementaci skyline syst´emu jsem prov´adˇel do jiˇz existuj´ıc´ı knihovny OOSol. Skyline storage a z´akladn´ı operace s matic´ı jsou implementov´any v tˇr´ıdˇe OOSspSkylineStatic. Syst´em ukl´ad´an´ı je vyˇ ´ se popsany´ staticky´ skyline syst´em. Tˇr´ıda OOSspSkylineStatic je zaˇrazena do tˇr´ıdn´ı hierarchie knihovny OOSol, jako potomek abstraktn´ı tˇr´ıdy reprezentuj´ıc´ı rˇ´ıdk´e matice OOSspMatrix. OOSspMatrix je potomek tˇr´ıdy OOSspMatrix, abstraktn´ı obecn´e matice. Knihovna jiˇz obsahovala implementaci pln´e matice v tˇr´ıdˇe OOSfullMatrix a syst´emu ukl´ad´an´ı rˇ´ıdk´e matice Compressed Row Storage v tˇr´ıdˇe OOSspMatrixStatic. Hierarchie tˇr´ıd je na obr´azku 4. Pozn´amka 3.2 TIND je v knihovnˇe OOSol datovy´ typ pro celoˇc´ıseln´e indexy. Implementov´any jsou n´asleduj´ıc´ı metody : • OOSspSkylineStatic(TIND ndim) konstruktor, alokuje datov´e struktury pro nulovou cˇ tvercovou matici. • OOSspSkylineStatic(TIND nrow, TIND ncol) konstruktor, alokuje datov´e struktury pro nulovou obd´eln´ıkovou matici. • OOSspSkylineStatic(OOSfullMatrix &mat) konstruktor, sestav´ı skyline matici z pln´e matice mat. • OOSspSkylineStatic(TIND nrow,TIND ncol, OOSindexArray& I, OOSindexArray& J, OOSvectorD& V) konstruktor, sestav´ı skyline matici, kter´a m´a nenulov´e prvky dan´e indexy ve vektorech I a J a jejich hodnoty ve V .
15
• OOSspSkylineStatic(TIND nrow, OOSindexArray& I, OOSindexArray& J, OOSvectorD& V, OOSindexArray& p) konstruktor, sestav´ı skyline matici, kter´a m´a nenulov´e prvky dan´e indexy ve vektorech I a J a jejich hodnoty ve V , permutovanou podle permutaˇcn´ıho vektoru p. • void clean() uvoln´ı vˇsechny asociovan´e datov´e struktury a zavol´a init(). • void init() nastav´ı matici na nulovou o rozmˇerech (0, 0). Datov´e struktory jsou nastaveny na nulovy´ ukazatel. • void resize(TIND ndim) uvoln´ı datov´e struktury a realokuje je pro cˇ tvercovou matici o rozmˇeru ndim. Prvky matice jsou nastaveny na nulov´e hodnoty. • void resize(TIND nrow, TIND ncol) uvoln´ı datov´e struktury a realokuje je pro obd´elnikovou matici o rozmˇerech (nrow, ncol). Prvky matice jsou nastaveny na nulov´e hodnoty. • double get(TIND i,TIND j) vrac´ı hodnotu prvku matice na rˇ a´ dku i a sloupci j. • void set(TIND i,TIND j,const double& nval) nastav´ı hodnotu prvku matice na rˇ a´ dku i a sloupci j na nval. Pokud je prvek uvnitˇr profilu, je operace trivi´aln´ı. Pokud je ovˇsem prvek mimo profil, je realokov´ana cel´a struktura pˇr´ısluˇsn´eho horn´ıho nebo doln´ıho profilu, a jsou pˇrepoˇc´ıt´any indexy. • void copy(OOSspSkylineStatic& mat, const double& alpha) nastav´ı matici jako kopii matice mat, skal´arnˇe vyn´asobenou hodnotou alpha (A = αB). • void copyt(OOSspSkylineStatic& mat, const double& alpha) nastav´ı matici jako transponovanou kopii matice mat, skal´arnˇe vyn´asobenou hodnotou alpha (A = αB T ). • void trans() transponuje matici. Tato operace je trivi´aln´ı, protoˇze staˇc´ı pouze ´ prohodit ukazatele na pole pro horn´ı a doln´ı trojuheln´ ıkovou cˇ a´ st. • void swap(OOSspSkylineStatic& mat) vymˇen´ı ukazatel na matici s ukazatelem na matici mat. • void operator=(OOSspSkylineStatic& mat) nastav´ı tuto matici jako mˇelkou kopii matice mat (tzn. jsou zkop´ırov´any pouze ukazatele) a zavol´a clean() na matici mat. • void operator*=(const double& alpha) provede na matici operaci skal´arn´ıho n´asoben´ı re´alnym ´ cˇ ´ıslem (A = αA). • void operator/=(const double& alpha) provede na matici operaci skal´arn´ıho dˇelen´ı re´alnym ´ cˇ ´ıslem (A = α1 A).
16
• void operator-=(const double& alpha) provede na matici operaci skal´arn´ıho n´asoben´ı cˇ ´ıslem -1 (A = −A). • double norm 1() vrac´ı sloupcovou normu matice. Sloupcov´a norma je definov´ana m P jako kAk1 = max |aij |). 1≤j≤n i=1
ˇ adkov´a norma je definov´ana • double norm inf() vrac´ı rˇ a´ dkovou normu matice. R´ n P jako kAk∞ = max |aij |. 1≤i≤m j=1
• double norm s F() vrac´ı Frobeniovu normu matice. Frobeniova norma je definov´ana m P n P jako kAkF = |aij |2 . i=1 j=1
• double norm(const char i) vrac´ı jednu z vyˇ ´ se uvedenych ´ norem, podle hodnoty agrumentu. Pro i = 0 Frobeniovu, pro i = 1 sloupcovou, pro i = 3 rˇ a´ dkovou. ˚ typ • double diagNorm(const type) vrac´ı normu vektoru diagon´aln´ıch prvk P u, normy je d´an argumentem type. Pro hodnotu 1 se vrac´ı norma ||v||1 = |vi |, 1≤i≤dim v P pro hodnotu 2 norma ||v||2 = vi2 , pro hodnotu 3 norma ||v||∞ = max{|vi | : 1≤i≤dim v
1 ≤ i ≤ dim v} • ostream& operator<<(ostream& os, OOSspSkylineStatic& mat) vyp´ısˇ e matici mat do streamu os. Slouˇz´ı pˇredevˇs´ım k informaˇcn´ımu vypisu napˇr´ıklad do ´ cout • istream& operator>>(istream& is,OOSspSkylineStatic& mat) naˇcte matici ze souborov´eho streamu is. Form´at je textovy´ nebo bin´arn´ı (lze nastavit zavol´an´ım metody setText() nebo setBinary()), stejny´ jako pouˇz´ıv´a tˇr´ıda OOSspMatrixStatic. • ofstream& operator<<(ofstream& os,OOSspSkylineStatic& mat) naproti tomu zap´ısˇ e matici do souborov´eho streamu os tak, aby ji bylo moˇzn´e naˇc´ıst ˚ ze byt oper´atorem >>. Form´at muˇ ´ rovnˇezˇ textovy´ nebo bin´arn´ı. Tˇr´ıda obsahuje nav´ıc metody : • symmetricProfile vrac´ı true, pokud m´a matice symetricky´ profil. • TIND columnHeight(TIND i) vrac´ı profil i-t´eho sloupce. • TIND rowHeight(TIND i) vrac´ı profil i-t´eho rˇ a´ dku. • static int profile(TIND nrow, OOSindexArray& I, OOSindexArray& J, OOSvectorD& V, OOSindexArray& p) statick´a metoda, slouˇz´ıc´ı k urˇcen´ı
17
Obr´azek 4: Hierarchie tˇr´ıd reprezentuj´ıc´ıch matice v knihovnˇe OOSol profilu skyline matice dan´e indexy prvku˚ v I a J, jejich hodnotami ve V a permutaˇcn´ım vektorem p. Data pro matici nejsou alokov´ana, pouze se poˇc´ıtaj´ı rˇ a´ dkov´e ˚ ze slouˇzit napˇr´ıklad k vhodn´emu urˇcen´ı parametru˚ W1 a W2 a sloupcov´e profily. Muˇ sloanova algoritmu.
18
4
Grafy
˚ algoritmus, stejnˇe jako napˇr´ıklad algoritmus Cuthill–McKee, je zaloˇzen na repreSloanuv zentaci matici neorientovanym ´ grafem. Nov´e indexy vrcholu˚ jsou urˇceny pˇri postupn´em ˚ nezbytn´e pro poproch´azen´ı grafu. V n´asleduj´ıc´ıch sekc´ıch uvedu pojmy z teorie grafu, ˚ pis tohoto algoritmu, pot´e pop´ısˇ i zpusob ukl´ad´an´ı grafu v poˇc´ıtaˇcov´e pamˇeti pomoc´ı ˚ N´asleduje popis samotn´eho algoritmu a koment´arˇ e k implementaci. seznamu sousedu.
4.1
´ Zakladn´ ı pojmy z teorie grafu˚
Definice 4.1 Jednoduchy´ neorientovany´ graf je uspoˇra´ dan´a dvojice G = (V, E) kde V je mnoˇzina vrcholu˚ a E je mnoˇzina hran. Hrany jsou neuspoˇra´ dan´e dvojice ruzn´ ˚ ych vrcholu. Poˇcet vrcholu˚ ||V || oznaˇcujeme jako stupenˇ grafu G. Hranu mezi vrcholy u a v ∈ V znaˇc´ıme (u, v) a rˇ´ık´ame, zˇ e vrcholy u a v jsou sousedn´ı. Nejsou povoleny hrany spojuj´ıc´ı vrchol s´am se sebou nebo v´ıce neˇz jedna hrana mezi dvˇema dan´ymi vrcholy. ˚ zeme graficky zn´azornit tak, zˇ e vrcholy zobraz´ıme jako body, a vrcholy mezi Graf muˇ ´ ckou. kterymi existuje hrana, spoj´ıme useˇ ´ Definice 4.2 Stupenˇ vrcholu u oznaˇcujeme jako poˇcet hran obsahuj´ıc´ıch tento vrchol. Definice 4.3 Sled v grafu G je posloupnost vrcholu˚ a hran P = (v0 , e1 , v1 , . . . , en , vn ), pro kterou plat´ı ei = (vi−1 , vi ). (Existuje tedy hrana mezi vrcholem a n´asleduj´ıc´ım vrcholem v posloupnosti) Definice 4.4 Cesta v grafu G je sled, pro kter´y plat´ı vi 6= vj pro i 6= j (ˇza´ dn´y vrchol se neopakuje). Lemma 1 Mˇejme relaci ∼ na mnoˇzinˇe vrcholu˚ libovoln´eho grafu G. Pro dva vrcholy u ∼ v, pr´avˇe kdyˇz existuje v G cesta zaˇc´ınaj´ıc´ı v u a konˇc´ıc´ı ve v. Pak ∼ je relac´ı ekvivalence. ˚ Dukaz je trivi´aln´ı. Definice 4.5 Tˇr´ıdy ekvivalence relace ∼ popsan´e v lemma 1 se naz´yvaj´ı komponenty souvislosti grafu. ´ Definice 4.6 Vzdalenost mezi vrcholy u a v oznaˇcujeme jako poˇcet hran nejkratˇs´ı moˇzn´e cesty spojuj´ıc´ı tyto vrcholy. Definice 4.7 Pr˚ umˇer grafu je takov´a dvojice vrcholu˚ (u, v), kter´a ma ze vˇsech moˇzn´ych dvojic vrcholu˚ v grafu nejvˇetˇs´ı vzd´alenost
19
Obr´azek 5: Pˇr´ıklad grafu
4.2
Souvislost mezi grafem a strukturou matice
˚ zeme reprezentovat pomoc´ı symetrick´e matice A Jednoduchy´ neorientovany´ graf G muˇ ˚ n´asleduj´ıc´ım zpusobem : • Matice A je cˇ tvercov´a matice o rozmˇerech (n, n), kde n je stupenˇ grafu G. • Pokud v grafu G existuje hrana mezi vrcholy u a v, pak auv = avu = 1, jinak auv = avu = 0 • Vˇsechny diagon´aln´ı prvky jsou rovny jedn´e aii = 1, 1 ≤ i ≤ n Tuto matici nazyv´ ´ ame matic´ı sousednosti. Pˇr´ıklad 4.1 Na obr´azku 5 je pˇr´ıklad jednoduch´eho neorientovan´eho grafu. Odpov´ıdaj´ıc´ı matice sousednosti k tomuto grafu je pak :
1 1 A= 1 1
1 1 1 0
1 1 1 0
1 0 0 1
Vˇsimnˇeme si, zˇ e stupenˇ vrcholu i je roven nnz(riA ) − 1 = nnz(sA i )−1 ˚ zeme pˇriˇradit graf G Obr´acenˇe pak cˇ tvercov´e matici A se symetrickym ´ profilem muˇ ˚ t´ımto zpusobem : ˚ kde n je poˇcet rˇ a´ dku˚ matice A • Graf G m´a n vrcholu, • V grafu G je hrana mezi vrcholy i a j, pokud je prvek matice aij = aji , j 6= i nenulovy. ´
20
4.3
´ an´ ´ ı grafu pomoc´ı seznamu sousedu˚ Uklad
Pouˇz´ıvat pro ukl´ad´an´ı grafu rˇ´ıdk´e matice plnou matici sousednosti by bylo neefektivn´ı, ˚ proto se v implementaci sloanova algoritmu pouˇz´ıv´a alternativn´ı zpusob reprezentace grafu : seznam sousedu, ˚ pro jehoˇz uloˇzen´ı je potˇreba pouze v+1+2e celoˇc´ıselnych ´ jednotek pamˇeti, kde v je poˇcet vrcholu˚ a e je poˇcet hran grafu (naproti tomu uloˇzen´ı pln´e matice sousednosti vyˇzaduje v 2 jednotek). Seznam sousedu˚ je do jist´e m´ıry podobny´ syst´emu ˚ pouze jejich indexy. ukl´ad´an´ı rˇ´ıdkych ´ matic, nepotˇrebujeme ale hodnoty prvku, Seznam sousedu˚ je implementov´an pomoc´ı dvou pol´ı : • Pole adj d´elky 2e slouˇz´ı k ukl´ad´an´ı indexu˚ sousedn´ıch vrcholu˚ pro vˇsechny vrcholy • Pole iadj je pole indexu˚ pro pole adj. Sousedn´ı vrcholy k vrcholu i najdeme v poli adj na indexech iadj[i] aˇz iadj[i+1]-1. Stupenˇ vrcholu i je tedy roven iadj[i+1]-iadj[i] Kaˇzd´a hrana je tedy uchov´av´ana dvakr´at pro jednoduchost programu a rychlost pˇr´ıstupu.
4.4
Sestaven´ı seznamu sousedu˚
˚ Stejnˇe jako u sestaven´ı skyline syst´emu jsem implementoval dva zpusoby sestaven´ı seznamu sousedu˚ - z pln´e matice a z vektoru˚ i, j, v. Sestaven´ı prob´ıh´a ve dvou kroc´ıch - nej˚ ktery´ je d´an poˇctem nenulovych prve je urˇcen stupenˇ kaˇzd´eho vrcholu, ´ prvku pˇr´ısluˇsn´eho rˇ a´ dku nebo sloupce mimo diagon´alu. V pˇr´ıpadˇe pln´e matice se proch´az´ı cel´a matice a testuje se, zda je prvek nulovy´ nebo nenulovy. ´ Hranu v grafu ukl´ad´ame, pokud je alesponˇ jeden z prvku˚ (aij , aji ) nenulovy´ - to znamen´a, zˇ e sestaven´ı grafu funguje i pro matice s nesymetrickym ´ profilem. Pouˇz´ıv´a se ovˇsem profil, ktery´ je maximem profilu pˇr´ısluˇsn´eho rˇ a´ dku a sloupce. Pˇri sestaven´ı grafu z vektoru˚ i, j, v proch´az´ıme pouze vektory i a j, tˇemito jsou jiˇz d´any hrany v grafu (ik , jk ). ˚ je aloPot´e, co je urˇcen celkovy´ poˇcet hran v grafu a stupnˇe jednotlivych vrcholu, ´ ˚ ˚ kov´ano pole adj a v dalˇs´ım kroku je dalˇs´ım pruchodem naplnˇeno indexy vrcholu.
4.5
ˇ a´ struktura Koˇrenova´ urov ´ nov
˚ algoritmus pouˇz´ıv´a v prvn´ım kroku takzvanou koˇrenovou urov Sloanuv ´ novou ˇ strukturu. ´ ˇ a´ struktura pˇr´ısluˇs´ıc´ı vrcholu r je posloupnost V nepr´azdn´ych Definice 4.8 Koˇrenova´ urov nov mnoˇzin vrcholu. ˚ V1 = {r}, Vi obsahuje vˇsechny vrcholy, kter´e soused´ı s vrcholy ve Vi−1 a pˇritom nejsou v zˇ a´ dn´e z mnoˇzin V1 , . . . , Vi−1 . Vi se oznaˇcuje jako i-t´a urove ´ n. ˇ ´ ˇ e struktury pro vrPoˇcet prvku˚ posloupnosti V oznaˇcujeme jako hloubku koˇrenov´e urov nov´ chol r. Poˇcet prvku˚ mnoˇziny ||Vi || oznaˇcujeme jako sˇ´ırˇku i-t´e urovnˇ ´ e. max ||Vi ||, maximum sˇ´ırˇek jednot´ ˇ e struktury pro vrchol r. liv´ych urovn´ ´ ı oznaˇcujeme jako sˇ´ırˇ ku koˇrenov´e urov nov´
21
´ ˇ a struktura tedy na sv´e i-t´e urovni ´ Koˇrenov´a urov nov´ obsahuje vrcholy, jejichˇz vzd´alenost ´ ˇ e struktury odpov´ıd´a od vrcholu r je i − 1. Algoritmus 2 pro sestaven´ı koˇrenov´e urov nov´ proch´azen´ı grafu do sˇ´ırˇ ky. Jiˇz navˇst´ıven´e vrcholy jsou oznaˇceny v maskovac´ım vektoru, aby se zabr´anilo zacyklen´ı. ´ ˇ a struktura implementov´ana jako dvˇe pole. Pole rls V C++ je pak koˇrenov´a urov nov´ obsahuje vˇsechny prvky struktury, pole irls jsou indexy v poli rls, kde zaˇc´ınaj´ı jednot´ liv´e urovnˇ e. Vytvoˇren´ı struktury zajiˇst’uje metoda OOSgraph::rootLevelStructure ´ ˇ e struktury Algoritmus 2 Sestaven´ı koˇrenov´e urov nov´ Require: r {poˇca´ teˇcn´ı vrchol} Require: n {stupenˇ grafu} ´ 1: w ← 1 {ˇs´ırˇ ka souˇcasn´e urovnˇ e} 2: wmax ← w {maxim´ aln´ı sˇ´ırˇ ka} 3: V1 ← {r} 4: d ← 1 {hloubka} 5: m = (0, . . . , 0), dim m = n {maskovac´ı vektor} 6: while w > 0 do 7: w←0 8: for all p in Vd do 9: s ← vrcholy soused´ıc´ı s p 10: for all si in s do 11: if msi = 0 then {dosud nenavˇst´ıveny´ vrchol} 12: w ←w+1 13: msi ← 1 ´ 14: insert si into Vd+1 {pˇr´ıd´an´ı vrcholu do souˇcasn´e urovnˇ e} 15: end if 16: end for 17: end for 18: if w > 0 then 19: d←d+1 20: end if 21: wmax ← max{w, wmax } 22: end while 23: return V, d, wmax
22
5
Sloanuv ˚ algoritmus
˚ algoritmus, popsany´ v cˇ l´anku [2], s menˇs´ımi upravami ´ Sloanuv v [3] slouˇz´ı ke sn´ızˇ en´ı ´ ˚ algoritmus je vyprofilu matice. Minimalizace profilu je NP-upln y´ probl´em [4]. Sloanuv ˚ lepˇsen´ım oproti pˇredchoz´ım algoritmum, jako je RCM (Reverse Cuthill–McKee). Vstupem sloanova algoritmu je graf G, vystupem je permutaˇcn´ı vektor p takovy, ´ ´ zˇ e symetrick´a permutace odpov´ıdaj´ıc´ı matice vektorem p m´a pokud moˇzno niˇzsˇ´ı profil. Al˚ eru grafu a pˇreˇc´ıslov´an´ı vrgoritmus se d´a rozdˇelit do dvou cˇ a´ st´ı - urˇcen´ı pseudoprumˇ ˚ cholu.
5.1
ˇ ı pseudoprum ˇ Urcen´ ˚ eru
˚ algoritmus vyˇzaduje dva vrcholy, kter´e urˇcuj´ı poˇca´ tek a konec cˇ ´ıslov´an´ı. Ide´alnˇe Sloanuv ˚ er grafu, urˇcen´ı prumˇ ˚ eru grafu je vˇsak pˇr´ıliˇs vypoˇ jsou tyto vrcholy prumˇ ´ cetnˇe n´aroˇcn´e. ˚ algoritmus proto pouˇz´ıv´a takzvany´ pseudoprumˇ ˚ jejichˇz Sloanuv ˚ er, coˇz je dvojice vrcholu, ˚ eru grafu. vzd´alenost je velmi bl´ızk´a, nebo rovna vzd´alenost´ı vrcholu˚ prumˇ ˚ eru slouˇz´ı heuristicky´ algoritmus 3, ktery´ se snaˇz´ı naj´ıt dvojici K nalezen´ı pseudoprumˇ vrcholu˚ s maxim´aln´ı vzd´alenost´ı a minim´aln´ı sˇ´ırˇ kou grafu. Algoritmus vˇetˇsinou najde ˚ er v nˇekolika m´alo iterac´ıch. V C++ je tento algoritmus implementov´an v pseudoprumˇ ´ metodˇe OOSgraph::pseudoDiameter. K setˇr´ıdˇen´ı posledn´ı urovnˇ e je pouˇzit insertion ˚ sort, jelikoˇz tato m´a obvykle nˇekolik m´alo vrcholu.
5.2 5.2.1
ˇ ıslovan´ ´ ı vrcholu˚ Pˇrec´ Stav vrcholu
˚ algoritmus jeden z tˇechto stavu˚ : postactive, Bˇehem pˇreˇc´ıslov´an´ı vrcholu˚ pˇriˇrazuje sloanuv active, preactive, inactive. Jejich vyznam jsou: ´ • Vrchol m´a stav postactive, pokud mu jiˇz bylo pˇriˇrazeno nov´e cˇ ´ıslo. • Vrcholy, kter´e soused´ı s postactive vrcholy, ale jeˇstˇe jim nebylo pˇriˇrazeno cˇ ´ıslo, jsou active. • Vrcholy, kter´e soused´ı s vrcholy stavu preactive, a pˇritom nejsou postactive ani active, maj´ı stav preactive • Ostatn´ı vrcholy maj´ı stav inactive. Stavy vrcholu˚ tvoˇr´ı vektor σ. Uk´azka stavu vrcholu˚ je na obr´azku 6. 5.2.2
´ ı stupenˇ vrcholu Momentaln´
Kaˇzd´emu vrcholu i je tak´e pˇriˇrazen moment´aln´ı stupen, ˇ mi ktery´ je definov´an takto : • Vrchol stavu postactive m´a mi = 0
23
˚ eru grafu Algoritmus 3 Nalezen´ı pseudoprumˇ 1: s ← vrchol s nejniˇ zsˇ´ım stupnˇem {odhad poˇca´ teˇcn´ıho vrcholu} 2: snew ← 1 3: while snew = 1 do {dokud je volen novy ´ poˇca´ teˇcn´ı bod} 4: snew ← 0 ´ ˇ a struktura z vrcholu s o hloubce d a sˇ´ırˇ ce w 5: V ← koˇrenov´a urov nov´ 6: setˇrid’ Vd podle stupnˇe vrcholu ´ ´ 7: Q ← Vd tak, zˇ e r neobsahuje dva vrcholy stejn´e urovnˇ e {zkr´acen´ı posledn´ı urovnˇ e} 8: wmin = ∞ 9: for all qi in Q do ´ ˇ a struktura z vrcholu qi o hloubce dq a sˇ´ırˇ ce wq 10: U ← koˇrenov´a urov nov´ 11: if wq < wmin then {nalezena struktura s menˇs´ı sˇ´ırˇ kou } 12: if dq > d then 13: s ← qi {novy´ poˇca´ teˇcn´ı vrchol} 14: snew ← 1 15: d ← dq 16: break 17: else 18: e ← qi {novy´ koncovy´ vrchol} 19: wmin ← wq 20: end if 21: end if 22: end for 23: end while 24: return s, e ˚ • Moment´aln´ı stupenˇ vrcholu se stavem active je roven poˇctu jeho preactive sousedu. • Stupenˇ preactive vrcholu je roven souˇctu inactive a preactive sousedu˚ plus jedna. • Pro vrcholy stavu inactive, je moment´aln´ı stupenˇ roven stupni vrcholu plus jedna. Na zaˇca´ tku algoritmu maj´ı vˇsechny vrcholy moment´aln´ı stupenˇ roven stupni vrcholu plus jedna, a s postupem algoritmu, kdyˇz jsou oˇc´ıslov´av´any sousedn´ı vrcholy, moment´aln´ı stupenˇ kles´a. Na konci algoritmu maj´ı vˇsechny vrcholy nulovy´ moment´aln´ı ˇ stupen. Napˇr´ıklad na obr´azku 6 jsou moment´aln´ı stupnˇe vrcholu˚ m1 = 0, m2 = 0, m3 = 0, m4 = 2, m5 = 2, m6 = 3, m7 = 4, m8 = 3, m9 = 5, m10 = 6, m11 = 4, m12 = 4. 5.2.3
Priorita vrcholu
Pˇri volbˇe dalˇs´ıho vrcholu urˇcen´eho k pˇreˇc´ıslov´an´ı je rozhoduj´ıc´ı priorita vrcholu. Kaˇzd´emu vrcholu je pˇriˇrazena priorita, kter´a je d´ana dvˇema sloˇzkami - moment´aln´ım stupnˇem a
24
Obr´azek 6: Stavy vrcholu˚ vzd´alenost´ı od koncov´eho vrcholu. Priorita vrcholu i je definov´ana jako pi = W1 · δi − W2 · mi ´ ˇ e kde δi je vzd´alenost vrcholu od koncov´eho vrcholu (tu zjist´ıme z koˇrenov´e urov nov´ struktury sestaven´e z koncov´eho vrcholu), mi je moment´aln´ı stupenˇ vrcholu, a W1 , W2 jsou v´ahov´e parametry. 5.2.4
Algoritmus
˚ algoritmus pro pˇreˇc´ıslov´an´ı vrcholu. ˚ Vstupem Algoritmus 4 popisuje samotny´ sloanuv ˚ eru grafu. Vystupem algoritmu je graf G a poˇca´ teˇcn´ı a koncov´e vrcholy psedoprumˇ algo´ ˚ kter´e by mˇelo sn´ızˇ it profil odpov´ıdaj´ıc´ı matice. Bˇehem ritmu je nov´e oˇc´ıslov´an´ı vrcholu, bˇehu algoritmu se udrˇzuje fronta vrcholu˚ q se stavem preactive nebo active urˇcenych ´ k pˇreˇc´ıslov´an´ı, z nich se vˇzdy vybere ten s maxim´aln´ı prioritou a ten je oˇc´ıslov´an. Pot´e se aktualizuje stav a priorita sousedn´ıch vrcholu˚ a vrcholy, jejichˇz stav se zmˇenil z inactive na preactive jsou pˇrid´any do fronty. Algoritmus konˇc´ı, kdyˇz jsou pˇreˇc´ıslov´any vˇsechny ˚ vrcholy, vystupem je inverzn´ı permutaˇcn´ı vektor η urˇcuj´ıc´ı nov´e oˇc´ıslov´an´ı vrcholu. ´
5.3
Hodnoty parametru˚ W1 a W2
Volba hodnot parametru˚ W1 a W2 je z´asadn´ı pro kvalitu vysledn´ eho pˇreˇc´ıslovan´ı. Pa´ rametr W1 v prioritn´ı funkci urˇcuje glob´aln´ı prioritu, jenˇz je nemˇenn´a bˇehem cel´eho alˇ goritmu a upˇrednostnuje vrcholy vzd´alenˇejˇs´ı od koncov´eho vrcholu. Zat´ımco parametr ˇ W2 reprezentuje lok´aln´ı prioritu, upˇrednostnuje vrcholy s n´ızkym ´ stupnˇem soused´ıc´ı s jiˇz oˇc´ıslovanymi vrcholy. Pokud zvol´ ı me W = 6 0, W = 0 algoritmus funguje velmi podobnˇe ´ 1 2 jako RCM. Sloan [3] doporuˇcuje na z´akladˇe empirickych ´ testu˚ hodnoty W1 = 1, W2 = 2, kter´a jsou vhodn´e pro mnoho matic.
25
˚ e typy matic. V kapitole 6 je Optim´aln´ı hodnoty ovˇsem mohou byt ´ jin´e pro ruzn´ napˇr´ıklad matice, kter´a m´a s parametry W1 = 1, W2 = 1 niˇzsˇ´ı vysledn y´ profil neˇz pˇri ´ pouˇzit´ı parametru˚ W1 = 1, W2 = 2. ˚ e Pˇri praktick´em vyuˇzit´ı Sloanova algoritmu je tedy vhodn´e nejprve vyzkouˇset ruzn´ W2 pomˇery hodnot W1 a vybrat hodnoty parametru˚ optim´aln´ı pro dany´ typ probl´emu, nebo automaticky vybrat z nˇekolika pˇredem urˇcenych ´ hodnot ty, pro kter´e je profil nejmenˇs´ı.
5.4
Implementace sloanova algoritmu pro knihovnu OOSol
˚ algoritmus pro pˇreˇc´ıslov´an´ı vrcholu˚ jsem implementoval v Sestaven´ı grafu a sloanuv tˇr´ıdˇe OOSgraph. Tato tˇr´ıda reprezentuje jednoduchy´ neorientovany´ graf pomoc´ı seznamu ˚ Tˇr´ıda d´ale obsahuje metody pro sestaven´ı koˇrenov´e urov ´ ˇ e struktury, nalesousedu. nov´ ˚ eru a koneˇcnˇe nalezen´ı permutaˇcn´ıho vektoru sloanovym zen´ı pseudoprumˇ ´ algoritmem. Tato implementace dok´azˇ e zpracovat grafy s v´ıce neˇz jednou komponentou souvislosti, vˇcetnˇe osamocenych ´ vrcholu˚ (vrcholy stupnˇe nula). Osamocen´e vrcholy jsou vˇzdy oˇc´ıslov´any aˇz jako posledn´ı. Oznaˇcov´an´ı jednotlivych ´ komponent je rˇ eˇseno pomoc´ı maskovac´ıho vektoru, kterym ´ jsou oznaˇceny jiˇz oˇc´ıslovan´e vrcholy grafu. Fronta vrcholu˚ s preactive a active stavem q je implementov´ana jako pole. Pˇrid´an´ı a odebr´an´ı vrcholu je operace se sloˇzitost´ı O(1), vyhled´an´ı prvku s nejvyˇssˇ´ı prioritou m´a sloˇzitost O(n). Tato implementace je dostaˇcuj´ıc´ı pro grafy s nˇekolika tis´ıci vrcholy, pro rozs´ahlejˇs´ı probl´emy je vhodnˇejˇs´ı pouˇz´ıt sofistikovanˇejˇs´ı datovou strukturu, napˇr´ıklad bin´arn´ı strom. Seznam priv´atn´ıch metod tˇr´ıdy OOSgraph : • TIND nodeDegree(TIND i) vrac´ı stupenˇ vrcholu i. • void sortNodeByDegree(TIND* array, TIND start, TIND end) slouˇz´ı ˚ eru. Je k setˇr´ıdˇen´ı vrcholu˚ podle jejich stupnˇe pˇri algoritmu hled´an´ı pseudoprumˇ ´ pouˇzit insertion sort, jelikoˇz ve zkr´acen´e posledn´ı urovn´ ı byv´ ´ a obvykle jen nˇekolik ˚ i. m´alo vrcholu. • void rootLevelStructure(TIND root, TIND* mask, TIND* rls, TIND* irls, TIND &rlslen, TIND &depth, TIND &width ) slouˇz´ı k se´ ˇ e struktury z vrcholu root. staven´ı koˇrenov´e urov nov´ • number(int W1, int W2, TIND s, TIND* rls, TIND rlslen, int *status, TIND *q, int *priority, int &labeled) implementuje ˚ algoritmus pro jednu komponentu souvislosti grafu. Pole jsou samotny´ sloanuv pˇred´av´any jako ukazatele, aby se zamezilo jejich nˇekolikan´asobn´e alokaci bˇehem bˇehu sloanova algoritmu pro graf s nˇekolika komponentami souvislosti. Veˇrejn´e metody jsou : • OOSgraph(OOSmatrix &mat) konstruktor - sestav´ı graf z pln´e cˇ tvercov´e matice mat
26
• OOSgraph(TIND nrow, OOSindexArray& I, OOSindexArray& J, OOSvectorD& V) konstruktor - sestav´ı graf z matice dan´e indexovymi vektory I, J a vektorem ´ hodnot V ˚ algoritmus pro tento graf s hodno• OOSindexArray* sloan() provede sloanuv tami parametru˚ W1 = 1, W2 = 2. Vrac´ı ukazatel na permutaˇcn´ı vektor. ˚ algoritmus se spe• OOSindexArray* sloan(int W1, int W2) provede sloanuv ˚ cifikovanymi hodnotami parametru. ´
27
˚ algoritmus pro pˇreˇc´ıslov´an´ı vrcholu˚ Algoritmus 4 Sloanuv ˚ er grafu} Require: (s, e) {pseudoprumˇ ´ ˇ a struktura z vrcholu e 1: V ← koˇrenov´ a urov nov´ 2: for all Vi in V do 3: for all sj in Vi do ´ 4: δsi ← i {urˇcen´ı vzd´alenosti vrcholu od koncov´eho vrcholu e podle jeho urovnˇ e ´ ˇ e struktuˇre} v koˇrenov´e urov nov´ 5: end for 6: end for ´ teˇcn´ı priority a stavu} 7: for i = 1 to n do {pˇriˇrazen´ı poˇca 8: pi ← W1 · δi − W2 · mi 9: σi ← inactive 10: end for ˚ eru} 11: insert s into q {pˇreˇc´ıslov´ an´ı zaˇc´ın´a od poˇca´ teˇcn´ıho vrcholu psedoprumˇ 12: σs ← preactive 13: l ← 1 {nov´e cˇ ´ıslo vrcholu} 14: while q not empty do {dokud jsou ve frontˇe vrcholy k pˇreˇc´ıslov´ an´ı} 15: m, takovy´ vrchol v q, pro ktery´ je pqi maxim´aln´ı 16: delete m from q 17: if σm = preactive then 18: for all j soused´ıc´ı s m do 19: pj ← pj + W2 {coˇz odpov´ıd´a sn´ızˇ en´ı moment´aln´ıho stupnˇe mj o 1} 20: if σj = inactive then 21: insert j into q 22: σj ← preactive 23: end if 24: end for 25: end if 26: ηi ← l 27: l ←l+1 28: for all i soused´ıc´ı s m do 29: if σj = preactive then 30: pj ← pj + W2 31: σj ← active 32: for all k soused´ıc´ı s j do 33: p j ← p j + W2 34: if σk = inactive then 35: σj ← preactive 36: insert k into q 37: end if 38: end for 39: end if 40: end for 41: end while 42: return η
28
6
´ ı a vysledky Testovan´ ´
Implementaci algoritmu jsem otestoval na nˇekolika rˇ´ıdkych uv´ad´ım ´ matic´ıch, vysledky ´ ˚ v tabulce 2. Tabulka obsahuje puvodn´ ı profil matice, profil po sloanovˇe pˇreuspoˇra´ d´an´ı s parametry W1 , W2 a pro srovn´an´ı profil po symetrick´em RCM pˇreuspoˇra´ d´an´ı, tak jak je implementov´ano v Octave. Nˇekter´e matice jsou vygenerovan´e s´ıtˇe, jin´e jsou re´aln´e matice pˇrevzat´e z kolekce rˇ´ıdkych ´ matic University of Florida Sparse Matrix Collection dostupn´e na adrese http://www.cise.ufl.edu/research/sparse/matrices/. U dvou matic je uvedeno grafick´e zn´azornˇen´ı pomoc´ı pˇr´ıkazu spy. Vysledky ukazuj´ı, zˇ e pro matice s velmi jednoduchou strukturou, jako je obdelnik ´ ˚ algoritmus a RCM stejny´ vysledn nebo krychle1 d´av´a sloanuv y´ profil. U matic se ´ sloˇzitˇejˇs´ım profilem se jiˇz projevuje vyhoda pˇriˇrazen´ı priority vrcholu˚ (algoritmus RCM ´ ˚ algoritmus znatelnˇe niˇzsˇ´ı propouze proch´az´ı graf do hloubky), a pro tyto d´av´a sloanuv fil. Za povˇsimnut´ı stoj´ı matice UF52, kter´a pro hodnoty parametru˚ W1 = 1, W2 = 2 m´a ˚ vyˇssˇ´ı profil neˇz puvodn´ ı matice, zato s parametry W1 = 1, W2 = 1 niˇzsˇ´ı profil neˇz RCM. To ukazuje, zˇ e hodnoty parametru˚ W1 = 1, W2 = 2 nejsou univerz´aln´ı pro vˇsechny typy ˚ e hodnoty parametru. ˚ matic a je vhodn´e pro konkr´etn´ı typy matic otestovat ruzn´ Seznam pouˇzitych ´ matic je uveden v tabulce 1.
29
Obr´azek 7: S´ıt’ matice ctverec1
Obr´azek 8: S´ıt’ matice ctverec3
Obr´azek 9: S´ıt’ matice krychle1
Obr´azek 10: S´ıt’ matice krychle2
Obr´azek 11: S´ıt’ matice krychle3
30
Obr´azek 12: S´ıt’ matice krychle4
Obr´azek 13: S´ıt’ matice UF871 - helikopt´era Commanche
˚ Obr´azek 14: Puvodn´ ı profil matice krychle4
31
sˇ sˇ´ı matice obdelnik
rozmˇer 4000
nnz 27122
ctverec1 ctverec3 krychle1 krychle2 krychle3 krychle4 UF52
60 12054 21 195 1581 12294 28924
370 78518 39 1471 13263 142442 2043492
UF111
1007
8575
UF267
479
1888
UF871
7920
31680
popis obd´eln´ık o 200 × 20 vrcholech spo˚ jenych ıkovou s´ıt´ı. ´ trojuheln´ diskretizace 2D cˇ tverce. Viz obr. 7 diskretizace 2D cˇ tverce. Viz obr. 8 diskretizace 3D krychle. Viz obr. 9 diskretizace 3D krychle. Viz obr. 10 diskretizace 3D krychle. Viz obr. 11 diskretizace 3D krychle. Viz obr. 11 STIFFNESS MATRIX FOR OFFSHORE GENERATOR PLATFORM (MSC NASTRAN) - PATTER SYMMETRIC CONNECTION TABLE FROM DTNSRDC, WASHINGTON U 8 STAGE COLUMN SECTION, ALL SECTIONS RIGOROUS ( CHEM. ENG. ), nesymetrick´a matice, velmi obt´ızˇ n´a pro iteraˇcn´ı numerick´e metody S´ıt’ helikopt´ery Commanche, viz obr. 13
Tabulka 1: Testovac´ı matice matice obdelnik ctverec1 ctverec1 ctverec3 ctverec3 krychle1 krychle2 krychle3 krychle4 UF52 UF52 UF111 UF267 UF871
profil 1527960 2150 2150 114487702 114487702 18 24786 1685816 110541680 31373936 31373936 51572 77693 33086588
W1 , W2 1,2 1,2 1,1 1,2 1,1 1,2 1,2 1,2 1,2 1,2 1,1 1,2 1,2 1,2
profil sloan 155020 806 822 2164978 2250146 18 6146 169992 5455392 34510616 28365376 43480 57268 860070
profil RCM 155020 914 914 2469134 2469134 18 6878 245034 8529714 44006432 44006432 47522 81110 1059214
Tabulka 2: Vysledn´ e profily ´
pozn´amka
obr. 17, 18
obr. 14, 15, 16
32
Obr´azek 15: Profil matice krychle4 po pˇreˇc´ıslov´an´ı sloanovym ´ algoritmem
Obr´azek 16: Profil matice krychle4 po pˇreˇc´ıslov´an´ı algoritmem RCM
˚ Obr´azek 17: Puvodn´ ı profil matice ctverec3
Obr´azek 18: Profil matice ctverec3 po pˇreˇc´ıslov´an´ı sloanovym ´ algoritmem
33
7
´ er ˇ Zav
˚ algoritmus se uk´azal jako velmi vhodny´ pro pˇreuspoˇra´ d´an´ı matic pˇred jejich Sloanuv ˚ zeme takto efektivnˇe uloˇzit i velmi rozs´ahl´e rˇ´ıdk´e mauloˇzen´ım ve skyline syst´emu. Muˇ tice, kter´e by bylo nemoˇzn´e uloˇzit v poˇc´ıtaˇcov´e pamˇeti jako pln´e matice. Velikost profilu je z´avisl´a na volbˇe hodnot parametru˚ W1 , W2 , jenˇz nelze urˇcit uni˚ e matice. verz´alnˇe a jejichˇz optim´aln´ı hodnoty se liˇs´ı pro ruzn´ Knihovnu OOSol by bylo moˇzn´e d´ale rozˇs´ırˇ it o efektivn´ı implementace nˇekterych ´ ˚ kter´e zachov´avaj´ı skyline profil, napˇr´ıklad cholesk´eho faktorizace nebo LU algoritmu, rozklad a umoˇznit tak praktick´e pouˇzit´ı skyline syst´emu pro rˇ eˇsen´ı line´arn´ıch soustav. ˚ algoritmus by bylo moˇzno d´ale zefektivnit vylepˇsen´ım datov´e struktury Sloanuv fronty, nab´ızej´ı se i experimenty s prioritn´ı funkc´ı. Algoritmus by bylo moˇzn´e rozˇs´ırˇ it z neorientovan´eho grafu na orientovany´ graf reprezentuj´ıc´ı matice s nesymetrickym ´ profilem. V cˇ l´anku [4] je pops´ano rozˇs´ırˇ en´ı algoritmu na ohodnocen´e grafy. Martin Stachonˇ
34
8
Reference
ˇ [1] Zdenˇek Dost´al, Line´arn´ı algebra, VSB-TUO 2000 [2] S. W. Sloan, An algorithm for profile and wavefront reduction of sparse matrices, International Journal for Numerical Methods in Engineering Vol. 23, John Wiley & Sons, Ltd., 1986 [3] S. W. Sloan, A Fortran program for profile and wavefront reduction, International Journal for Numerical Methods in Engineering Vol. 28, John Wiley & Sons, Ltd., 1989 [4] Gary Kumfert, Alex Pothen, Two improved algorithms for envelope and wavefront reduction, NASA, 1997
35
A
´ Zdrojove´ kody
´ ˚ algoritmus v V pˇr´ıloze uv´ad´ım zdrojov´e kody implementuj´ıc´ı skyline storage a sloanuv r´amci knihovny OOSol.
36
5
10
15
/********************************************************************/ /* */ /* OOSol2 2005 */ /* Dept. of Applied Mathematics, */ /* Technical University in Ostrava, Czech Rep. */ /* */ /* Filename: OOSmatricesSkylineStatic.h */ /* Created by Martin Stachon, 2008 */ /* */ /* List of updates: */ /* Date Author Description */ /* */ /********************************************************************/ #ifndef OOSMATRICESSKYLINESTATIC_H #define OOSMATRICESSKYLINESTATIC_H #include "OOSmatrices.h" namespace oosol {
20 class OOSspSkylineStatic: public OOSspMatrix { friend class OOSgraph; 25
/** diagonal elements */ double *diag; /** upper triangle columns */ double *uc;
30 /** index */ TIND *iuc;
35
/** number of upper triangle items */ TIND luc; /** lower triangle rows */ double *lr;
40
/** index */ TIND *ilr; /** number of lower triangle items */ TIND llr;
45 public: /** Default constructor - initiates empty matrix */ OOSspSkylineStatic(): OOSspMatrix() {}; 50 /** Constructor - initiates square matrix */ OOSspSkylineStatic(TIND ndim);
37
55
/** Constructor - initates rectangular matrix */ OOSspSkylineStatic(TIND nrow,TIND ncol); /** Constructor - creates sparse matrix from full matrix mat */ OOSspSkylineStatic(OOSfullMatrix &mat);
60
65
70
75
80
85
90
95
100
/** Copy constructor - copies all member data from the matrix mat */ OOSspSkylineStatic(OOSspSkylineStatic& mat): OOSspMatrix(mat) {init(); copy(mat);} /** Constructor - assembles matrix with nonzeros given by vectors of indices I, J and values V */ OOSspSkylineStatic(TIND nrow,TIND ncol, OOSindexArray& I, OOSindexArray& J, OOSvectorD& V); /** Constructor - assembles rectangular matrix with nonzeros given by vectors of indices I, J and values V, rows and columns are permuted with permutation verctor p */ OOSspSkylineStatic(TIND nrow, OOSindexArray& I, OOSindexArray& J, OOSvectorD& V, OOSindexArray& p); /** Destructor - deallocates memory reserved for member data */ virtual ˜OOSspSkylineStatic(); /** CLEAN deallocates memory reserved for member data and initiates them by 0 or NULL */ virtual void clean(); /** INIT initiates all member data by 0 or NULL */ virtual void init(); /** RESIZE(NDIM) removes allocated matrix structures and resizes matrix to the square one with ndim rows and columns */ virtual void resize(TIND ndim); /** RESIZE(NROW,NCOL) removes allocated matrix structures and resizes matrix to the one with nrow rows and ncol columns */ virtual void resize(TIND nrow,TIND ncol); /** SPCONVERT converts the nonzero entries described by vectors I,J,V to sparse matrix */ void spconvert(OOSindexArray& I, OOSindexArray& J, OOSvectorD& V, TIND nrow, TIND ncol) {OOSspSkylineStatic mat(nrow,ncol, I,J,V); *this=mat;} /** SLOAN converts the nonzero entries described by vectors I,J,V to sparse matrix, using Sloan’s algorithm to reoder matrix */ OOSindexArray* sloan(OOSindexArray& I, OOSindexArray& J, OOSvectorD& V, TIND nrow); /** GET virtual /** SET virtual
returns value from the i-th row and the j-th column */ double get(TIND i, TIND j); sets value in the i-th row and the j-th column to value nval */ void set(TIND i, TIND j, const double& nval);
/** COPY matrix copy and scale MatS <- alpha*mat */ void copy(OOSspSkylineStatic& mat, const double& alpha=1.0);
38
105
110
115
120
125
130
135
140
145
150
/** COPY transposed matrix copy and scale MatS <- alpha*matˆT */ void copyt(OOSspSkylineStatic& mat, const double& alpha=1.0); /** SWAP swaps matrices MatS <-> mat */ void swap(OOSspSkylineStatic& mat); /* MATRIX OPERATIONS */ /* ================= */ /** OPERATOR= (MatS=mat) assigns member data from the matrix mat to MatS and initiates mat to empty vector */ void operator=(OOSspSkylineStatic& mat); /** OPERATOR*=(mat) cummulative matrix-matrix multiplication MatS<-MatS *mat */ void operator*=(OOSspSkylineStatic& mat) {cmm(mat);} /** OPERATOR*=(alpha) matrix-scalar multiplication MatS<-alpha*MatS */ virtual void operator*=(const double& alpha); /** OPERATOR/=(alpha) matrix-scalar dividing MatS<-MatS/alpha */ virtual void operator/=(const double& alpha); /** OPERATOR˜ matrix transposition MatS <- MatSˆT */ virtual void operator˜() {copyt(*this);}; /** TRANS matrix transposition MatS <- MatSˆT */ virtual void trans(); /** OPERATOR- (unary) changes the signs of the vector entries MatS <(-MatS) */ virtual void operator-();
/* MATRIX NORMS */ /* ============ */ /** NORM_1 returns the row norm */ virtual double norm_1(); /** NORM_2 returns the spectral norm */ /** NORM_INF returns the column norm */ virtual double norm_inf(); /** NORM_F returns the Frobenius norm */ virtual double norm_F(); /** NORM matrix norm ||A||_i i==0 ... ||A||_F (Frobenius norm) i==1 ... ||A||_1 (row norm) i==2 ... ||A||_2 (spectral norm) i==3 ... ||A||_inf (column norm) */ virtual double norm(const char i=0); /** NORM returns a norm of the diagonal, type defines type of the norm type==1 -> l_1 type==2 -> l_2 type==3 -> l_inf <default> */ virtual double diagNorm(const char type=3); /** returns true if the matrix is square and has a symmetric profile */ virtual bool symmetricProfile(); /** skylineProfile returns the size of skyline profile */ TIND skylineProfile() { return luc+llr;
39
155
}
160
/** columnHeight return the column profile for column i */ TIND columnHeight(TIND i) { ASSERT(i>=0 && i
165
/** columnHeight return the column row for row i */ TIND rowHeight(TIND i) { ASSERT(i>=0 && i
170
/** return the profile of Skyline matrix given by vectors I,J,V and permutation vector p*/ static int profile(TIND nrow, OOSindexArray& I, OOSindexArray& J, OOSvectorD& V, OOSindexArray& p); 175
};
/* STREAM OPERATORS OVERLOADING */ /* ============================ */ 180
185
190
/** Overloaded input stream operator */ istream& operator>>(istream& is, OOSspSkylineStatic& mat); /** Overloaded output stream operator */ ostream& operator<<(ostream& os, OOSspSkylineStatic& mat); /** Overloaded input file stream operator */ ifstream& operator>>(ifstream& is, OOSspSkylineStatic& mat); /** Overloaded output file stream operator */ ofstream& operator<<(ofstream& os, OOSspSkylineStatic& mat); } #endif /*OOSMATRICESSKYLINESTATIC_H*/
Vypis 1: Soubor OOSmatricesSkylineStatic.h ´
3
8
/********************************************************************/ /* */ /* OOSol2 2005 */ /* Dept. of Applied Mathematics, */ /* Technical University in Ostrava, Czech Rep. */ /* */ /* Filename: OOSmatricesSkylineStatic.cpp */ /* Created by Martin Stachon, 2008 */ /* */ /* List of updates: */ /* Date Author Description */
40
13
/* */ /********************************************************************/ #include "OOSmatricesSkylineStatic.h" namespace oosol {
18
23
/*******************************************************************/ /* */ /* Method definitions of class OOSmatricesSkylineStatic */ /* */ /*******************************************************************/ /* Constructor - initiates square matrix */ OOSspSkylineStatic::OOSspSkylineStatic(TIND ndim): OOSspMatrix(ndim) {
28 if (row==0 && col==0) init(); else { diag = new double[row]; ASSERT(diag!=NULL); iuc = new TIND[row+1]; ASSERT(iuc!=NULL); ilr = new TIND[row+1]; ASSERT(ilr!=NULL); llr = 0; luc = 0;
33
for (TIND i=0; i
38
43 } }
48
53
/** Constructor - initates rectangular matrix */ OOSspSkylineStatic::OOSspSkylineStatic(TIND nrow, TIND ncol): OOSspMatrix( nrow, ncol) { if (row==0 && col==0) init(); else { TIND i; row = nrow; col = ncol; diag = new double[MIN(row,col)]; ASSERT(diag!=NULL); iuc = new TIND[col+1]; ASSERT(iuc!=NULL); ilr = new TIND[row+1]; ASSERT(ilr!=NULL);
58
63
for (i=0; i<MIN(row,col); i++) { diag[i] = 0; } for (i=0; i<=col; i++) iuc[i] = 0;
41
for (i=0; i<=row; i++) ilr[row] = 0; } 68
73
78
83
} /* Constructor - creates sparse matrix from full matrix mat */ OOSspSkylineStatic::OOSspSkylineStatic(OOSfullMatrix &mat) { TIND i,j; TIND ucpos=0, lrpos=0; bool inSkyline; double v; row = mat.getRows(); col = mat.getCols(); diag = new double[MIN(row,col)]; ASSERT(diag!=NULL); iuc = new TIND[col+1]; ASSERT(iuc!=NULL); ilr = new TIND[row+1]; ASSERT(ilr!=NULL); // copy diagonal for (i=0; i<MIN(row,col); i++) { diag[i] = mat(i,i); }
88
93
98
103
108
113
118
luc = llr = 0; // find number of elements under skyline profile in upper triangle for (j=1; j
42
inSkyline = true; if (inSkyline) uc[ucpos++] = v; } } iuc[col] = ucpos; // store non-zero elements in lower triangle for (i=1; i
123
128
133
138
143
148
153
158
} /* Constructor - assembles matrix with nonzeros given by vectors of indices I, J and values V */ OOSspSkylineStatic::OOSspSkylineStatic(TIND nrow,TIND ncol, OOSindexArray& I, OOSindexArray& J, OOSvectorD& V): OOSspMatrix(nrow,ncol) { TIND i, N=I.getDim(); if (row==0 && col==0) init(); else { row = nrow; col = ncol; diag = new double[MIN(row,col)]; ASSERT(diag!=NULL); iuc = new TIND[col+1]; ASSERT(iuc!=NULL); ilr = new TIND[row+1]; ASSERT(ilr!=NULL); luc = 0; llr = 0; // initialize diagonal for (i=0; i<MIN(row,col); i++) { diag[i] = 0.0; }
163 TIND* ch = new TIND[col]; // column heights TIND* rh = new TIND[row]; // row heights TIND h; 168
for (i=0; i
43
173
178
183
188
193
198
203
208
213
218
223
for (i=0; i
=0 && Ii= 0 && Ji < ncol); // in first pass, we place items on diagonal, and determine // the heights of skyline profile if (Ii == Ji) { // diagonal diag[Ii] = V(i); } else if (V(i) != 0.0) { if (Ii<Ji) { // upper triangle h = Ji-Ii; if (h>ch[Ji]) ch[Ji] = h; } else { // lower triangle h = Ii-Ji; if (h>rh[Ii]) rh[Ii] = h; } } } // now we can construct skyline storage iuc[0] = 0; ilr[0] = 0; for (i=1; i<=col; i++) { iuc[i] = iuc[i-1]+ch[i-1]; } for (i=1; i<=row; i++) { ilr[i] = ilr[i-1]+rh[i-1]; } luc = iuc[col]; llr = ilr[row]; uc = new double[luc]; lr = new double[llr]; for (i=0; i
44
delete[] ch; delete[] rh; } 228
}
233
/** Constructor - assembles rectangular matrix with nonzeros given by vectors of indices I, J and values V, rows and columns are permuted with permutation verctor p */ OOSspSkylineStatic::OOSspSkylineStatic(TIND nrow, OOSindexArray& I, OOSindexArray& J, OOSvectorD& V, OOSindexArray& p): OOSspMatrix(nrow) { TIND i, N=I.getDim(); TIND ii, ji;
238 ASSERT(p.getDim() == nrow); ASSERT(I.getDim() == J.getDim()); // inverse permutation vector OOSindexArray ip(nrow); for (i=0; i
243
248
OOSindexArray Ip(N), Jp(N);
253
// renumber indexes for (i=0; i
258
OOSspSkylineStatic(nrow, nrow, Ip, Jp, V); }
263
268
273
/* Destructor - deallocates memory reserved for member data */ OOSspSkylineStatic::˜OOSspSkylineStatic() { delete[] diag; delete[] uc; delete[] lr; delete[] iuc; delete[] ilr; } /* CLEAN deallocates memory reserved for member data and initiates them by 0 or NULL */ void OOSspSkylineStatic::clean() { delete[] diag; delete[] uc; delete[] lr;
45
278
delete[] iuc; delete[] ilr; init(); }
283
288
293
298
/* INIT initiates all member data by 0 or NULL */ void OOSspSkylineStatic::init() { row=0; col=0; diag = NULL; iuc = NULL; ilr = NULL; uc = NULL; lr = NULL; llr = 0; luc = 0; }
/* RESIZE(NDIM) removes allocated matrix structures and resizes matrix to the square one with ndim rows and columns */ void OOSspSkylineStatic::resize(TIND ndim) { ASSERT(ndim>=0);
303
clean(); if (ndim>0) { row = col = ndim; diag = new double[ndim]; ASSERT(diag!=NULL); iuc = new TIND[ndim+1]; ASSERT(iuc!=NULL); ilr = new TIND[ndim+1]; ASSERT(ilr!=NULL);
308
for (TIND i=0; i
313
318
} }
323
328
/** RESIZE(NROW,NCOL) removes allocated matrix structures and resizes matrix to the one with nrow rows and ncol columns */ void OOSspSkylineStatic::resize(TIND nrow,TIND ncol) { ASSERT(nrow>=0 && ncol>=0); clean(); if (nrow>0 || ncol>0) { TIND i; row = nrow;
46
col = ncol; diag = new double[MIN(row,col)]; ASSERT(diag!=NULL); iuc = new TIND[col+1]; ASSERT(iuc!=NULL); ilr = new TIND[row+1]; ASSERT(ilr!=NULL);
333
for (i=0; i<MIN(row,col); i++) { diag[i] = 0; } for (i=0; i<=col; i++) iuc[i] = 0; for (i=0; i<=row; i++) ilr[i] = 0;
338
343 } } 348
/* GET returns value from the i-th row and the j-th column */ double OOSspSkylineStatic::get(TIND i,TIND j) { ASSERT(i>=0 && i=0 && j
353
if (i == j ) { // on diagonal return diag[i]; } else if (i < j) { // upper triangle if ((j-i) > columnHeight(j)) // above skyline profile return 0; else return uc[iuc[j+1]-j+i]; } else { // lower triangle if ((i-j) > rowHeight(i)) // above skyline profile return 0; else return lr[ilr[i+1]-i+j]; }
358
363
368
} 373
/* SET sets value in the i-th row and the j-th column to value nval */ void OOSspSkylineStatic::set(TIND i,TIND j,const double& nval) { TIND diff, ci, ri, ni; ASSERT(i>=0 && i=0 && j
378
383
if (i == j ) { // on diagonal diag[i] = nval; } else if (i < j) { // upper triangle diff = (j-i) - columnHeight(j); if (diff > 0 && nval != 0.0) {
47
388
393
398
403
408
413
418
423
428
433
// above skyline profile, need to reallocate columns double *newuc = new double[luc+diff]; // allocate new array for column items for (ci=0; ci 0 && nval != 0.0) { // above skyline profile, need to reallocate rows double *newlr = new double[llr+diff]; // allocate new array for row items for (ri=0; ri
48
438
llr += diff; } else { lr[ilr[i+1]-i+j] = nval; } }
443
448
453
458
463
} /* COPY matrix copy and scale MatS <- alpha*mat */ void OOSspSkylineStatic::copy(OOSspSkylineStatic& mat, const double& alpha ) { if (this==&mat) *this*=alpha; else if (mat.isempty()) clean(); else if (ABS(alpha)<=OOSZERO) {resize(mat.row,mat.col);} else { clean(); TIND i; row = mat.getRows(); col = mat.getCols(); diag = new double[MAX(row,col)]; ASSERT(diag!=NULL); iuc = new TIND[col+1]; ASSERT(iuc!=NULL); ilr = new TIND[row+1]; ASSERT(ilr!=NULL); llr = mat.llr; luc = mat.luc; uc = new double[luc]; lr = new double[llr]; for (i=0; i<MAX(row,col); i++) { diag[i] = alpha*(mat.diag[i]); }
468
for (i=0; i<=col; i++) iuc[i] = mat.iuc[i]; for (i=0; i<=row; i++) ilr[i] = mat.ilr[i]; for (i=0; i
473
478
} }
483
488
/* COPY transposed matrix copy and scale MatS <- alpha*matˆT */ void OOSspSkylineStatic::copyt(OOSspSkylineStatic& mat, const double& alpha) { if (this==&mat) *this*=alpha; else if (mat.isempty()) clean(); else if (ABS(alpha)<=OOSZERO) {resize(mat.row,mat.col);} else { clean();
49
TIND i; row = mat.col; col = mat.row; diag = new double[MAX(row,col)]; ASSERT(diag!=NULL); iuc = new TIND[col+1]; ASSERT(iuc!=NULL); ilr = new TIND[row+1]; ASSERT(ilr!=NULL); llr = mat.luc; luc = mat.llr; uc = new double[luc]; lr = new double[llr];
493
498
for (i=0; i<MAX(row,col); i++) { diag[i] = alpha*(mat.diag[i]); }
503
for (i=0; i<=col; i++) iuc[i] = mat.ilr[i]; for (i=0; i<=row; i++) ilr[i] = mat.iuc[i]; for (i=0; i
508
513 } }
518
523
/* matrix transposition */ void OOSspSkylineStatic::trans() { if (!isempty()) { TIND tmp; TIND* tmpi; double* tmpp; tmp = row; row = col; col = tmp;
528
tmpi = iuc; iuc = ilr; ilr = tmpi; 533 tmp = llr; llr = luc; luc = tmp; 538
tmpp = uc; uc = lr; lr = tmpp; } }
543
50
548
/* SWAP swaps matrices MatS <-> mat */ void OOSspSkylineStatic::swap(OOSspSkylineStatic& mat) { if (this!=&mat) { OOSspSkylineStatic temp; temp=*this; *this=mat; mat=temp; } }
553
558
563
568
/** returns true if the matrix is square and has a symmetric profile */ bool OOSspSkylineStatic::symmetricProfile() { TIND i; if (row != col) return false; if (llr != luc) return false; for (i=0; i<=row; i++) if (iuc[i] != ilr[i]) return false; return true ; } /** return the profile of Skyline matrix given by vectors I,J,V and permutation vector p*/ static int profile(TIND nrow, OOSindexArray& I, OOSindexArray& J, OOSvectorD& V, OOSindexArray& p) { ASSERT(I.getDim() == J.getDim()); TIND N = I.getDim(); TIND i;
573 int* ch = new int[nrow]; int* rh = new int[nrow];
578
583
588
593
for (int i=0; i
51
// diagonal } else if (V(i) != 0.0) { if (Ii<Ji) { // upper triangle h = Ji-Ii; if (h>ch[Ji]) ch[Ji] = h; } else { // lower triangle h = Ii-Ji; if (h>rh[Ii]) rh[Ii] = h; } }
598
603
608 }
int sum = 0; for (i=0; i
613
618 }
623
628
633
638
643
648
/* MATRIX OPERATIONS */ /* ================= */ /* OPERATOR= (MatS=mat) assigns member data from the matrix mat to MatS and initiates mat to empty vector */ void OOSspSkylineStatic::operator=(OOSspSkylineStatic& mat) { clean(); // Remove allocated arrays of *this // Shallow copy: *this <- mat row=mat.row; col=mat.col; binary=mat.binary; diag = mat.diag; uc = mat.uc; lr = mat.lr; iuc = mat.iuc; ilr = mat.ilr; luc = mat.luc; llr = mat.llr; // Reset mat to empty matrix mat.clean(); }; /* OPERATOR*=(alpha) matrix-scalar multiplication MatS<-alpha*MatS */ void OOSspSkylineStatic::operator*=(const double& alpha) { TIND i;
52
if (alpha!=1.0) { if (alpha!=1.0) { for (i=0; i
653
658
663
} 668
673
/* OPERATOR/=(alpha) matrix-scalar dividing MatS<-MatS/alpha */ void OOSspSkylineStatic::operator/=(const double& alpha) { TIND i; ASSERT(ABS(alpha)>OOSZERO); if (alpha!=1.0) { for (i=0; i
678
683
688
693
698
}
/* OPERATOR- (unary) changes the signs of the vector entries MatS <- (MatS) */ void OOSspSkylineStatic::operator-() { TIND i; for (i=0; i
53
703
lr[i] = -lr[i]; } }
708
713
718
/* MATRIX NORMS */ /* ============ */ /* NORM_1 returns the column norm */ double OOSspSkylineStatic::norm_1() { TIND i,j,ind; if (isempty()) return 0.0; else { OOSvectorD y(col,0.); for (j=0; j
723
728
733 return y(y.max()); } } 738
743
748
753
/* NORM_INF returns the row norm */ double OOSspSkylineStatic::norm_inf() { TIND i,j,ind; if (isempty()) return 0.0; else { OOSvectorD y(col,0.); for (i=0; i
54
y(i) += ABS(get(i,j)); 758
} } return y(y.max()); }
763
768
} /* NORM_F returns the Frobenius norm */ double OOSspSkylineStatic::norm_F() { if (isempty()) return 0.0; else { TIND i; double s;
773 s=0.; // sum upper triangle for (i=0; i
778
783
788
return sqrt(s); } }
793
798
/* NORM matrix norm ||A||_i i==0 ... ||A||_F (Frobenius norm) i==1 ... ||A||_1 (row norm) i==2 ... ||A||_2 (spectral norm) i==3 ... ||A||_inf (column norm) */ double OOSspSkylineStatic::norm(const char i) { ASSERT(i>=0 && i<=3); switch (i) { case 0: return norm_F(); case 1: return norm_1(); case 2: return norm_2(); case 3: return norm_inf(); default: return OOSINF; }
803
808 }
55
813
818
/** NORM returns a norm of the diagonal, type defines type of the norm type==1 -> l_1 type==2 -> l_2 type==3 -> l_inf <default> */ double OOSspSkylineStatic::diagNorm(const char type) { ASSERT(type>=1 && type<=3); TIND i, m=getRows(), n=getCols(), d; double res=0, w, temp;
823
d=MIN(m,n); switch (type) { case 1: for(i=d-1;i>=0;i--) {w=diag[i]; if (w<0.0) res-=w; else res+=w;}; break; case 2: for(i=d-1;i>=0;i--) {w=diag[i]; res+=w*w;}; break; case 3: for(i=d-1;i>=0;i--) {w=diag[i]; if (res<(temp=ABS(w))) res=temp;}; break; default: res=OOSINF; } return res;
828
833 }
838
843
848
/* STREAM OPERATORS OVERLOADING */ /* ============================ */ /* Overloaded output stream operator */ ostream& operator<<(ostream& os, OOSspSkylineStatic& mat) { TIND i, j, lrow=mat.getRows(), lcol=mat.getCols(); double v; if (mat.isempty()) { os << endl << "Empty matrix!" << endl; ASSERT(os.good()); return os; } os << endl << "Matrix type (" << lrow << "," << lcol << ")" << endl; ASSERT(os.good()); for (i=0; i
853
858
}
56
863
/* Overloaded input file stream operator */ istream& operator>>(istream& is,OOSspSkylineStatic& mat) { TIND i, j, k, lrow, lcol, lnnz; double v;
868 if (mat.isBinary()) { is.read((char*)&lrow,sizeof(TIND)); is.read((char*)&lcol,sizeof(TIND)); is.read((char*)&lnnz,sizeof(TIND)); } else { is >> lrow >> lcol >> lnnz; } ASSERT(is.good()&&lrow>=0&&lcol>=0&&lnnz>=0);
873
878 OOSindexArray I(lnnz), J(lnnz); OOSvectorD V(lnnz); if (lrow>0 && lcol>0 && lnnz>0) { if (mat.isBinary()) { ASSERT(is.good()); is.read((char*)I.getInd(),lnnz*sizeof(TIND)); is.read((char*)J.getInd(),lnnz*sizeof(TIND)); is.read((char*)V.getVal(),lnnz*sizeof(double)); } else for (k=0; k> i >> j >> v; I(k)=i; J(k)=j; V(k)=v; }
883
888
893
898
mat.spconvert(I,J,V,lrow,lcol); } return is; }
903
908
913
/* Overloaded output file stream operator */ ofstream& operator<<(ofstream& os,OOSspSkylineStatic& mat) { TIND i, j, k, c, n, lrow=mat.getRows(), lcol=mat.getCols(), lnnz=mat.skylineProfile()+MIN(lrow,lcol); double v; if (mat.isBinary()) { os.write((const char*)&lrow,sizeof(TIND)); os.write((const char*)&lcol,sizeof(TIND)); os.write((const char*)&lnnz,sizeof(TIND));
57
} else os << lrow << ’\t’ << lcol << ’\t’ << lnnz << endl; ASSERT(os.good());
918
OOSindexArray I(lnnz), J(lnnz); OOSvectorD V(lnnz); 923
c=0; TIND rh, ch; // diagonal elements for (i=0; i<MIN(lrow, lcol); i++) { I(c) = i; J(c) = i; V(c) = mat.get(i,i); c++; } // upper triangle elements for (j=0; j=(j-ch);i++) { I(c) = i; J(c) = j; V(c) = mat.get(i,j); c++; } } // lower triangle elements for (i=0; i=(i-rh);j++) { I(c) = i; J(c) = j; V(c) = mat.get(i, j); c++; } } if (mat.isBinary()) { os.write((const char*)I.getInd(),lnnz*sizeof(TIND)); os.write((const char*)J.getInd(),lnnz*sizeof(TIND)); os.write((const char*)V.getVal(),lnnz*sizeof(double)); ASSERT(os.good()); } else { for (k=0; k
928
933
938
943
948
953
958
963
} }
Vypis 2: Soubor OOSmatricesSkylineStatic.cpp ´
58
#include "OOSgraph.h" namespace oosol { 5
10
OOSgraph::OOSgraph(OOSmatrix &mat) { ASSERT((n = mat.getRows()) == mat.getCols()); TIND i,j; TIND adjpos=0; iadj = new TIND[n+1]; ASSERT(iadj!=NULL); for (i=0; i<=n; i++) iadj[i] = 0;
15
ladj = 0; // find number of non-zero elements for (j=0; j
20
25
30
35
40
} 45
OOSgraph::OOSgraph(TIND nrow, OOSindexArray& I, OOSindexArray& J, OOSvectorD& V) { TIND i, N=I.getDim(); ASSERT((N == J.getDim()) && (J.getDim() == V.getDim()));
50 n = nrow; iadj = new TIND[n+1]; TIND* adjlen = new TIND[n];
59
ladj = 0; 55 for (i=0; i
TIND ii, ji; double vi; for (i=0; i= 0) && (ii <= nrow) && (ji >= 0) && (ji <= nrow));
65
if (vi != 0.0) { if (ii < ji) { // count only nodes in upper triangle ladj+=2; // every edge will be stored twice adjlen[ii]++; adjlen[ji]++; } }
70
75
} iadj[0] = 0; for (i=1; i<=n; i++) iadj[i] = iadj[i-1]+adjlen[i-1]; 80 adj = new TIND[ladj]; for (i=0; i
95
100
} delete[] adjlen; }
105
void OOSgraph::sortNodeByDegree(TIND* array, TIND start, TIND end) { int i, j, key, v; for (j=start+1; j<end; j++) { v = array[j];
60
key = nodeDegree(v); for(i=j-1; (i>=start) && (nodeDegree(array[i])>key); i--) { array[i+1] = array[i]; } array[i+1] = v;
110
} } 115
120
125
130
135
140
145
150
155
void OOSgraph::rootLevelStructure( TIND root, // root node TIND* mask, // masking vector TIND* rls, // root level structure TIND* irls, // index to root level structure TIND &rlslen, // length of root level structure TIND &depth, // depth of root level structure TIND &maxwidth) // maximal width of root level structure) { TIND i, j, parent, nb; TIND curwidth = 1; // width of current level TIND lvls, lvle; // start and end of level depth = 1; rls[0] = root; irls[0] = 0; irls[1] = 1; lvle = 0; rlslen = 1; mask[root] = 1; maxwidth = 1; while (1) { lvls = lvle; lvle = lvls+curwidth; curwidth = 0; // for every node in previous depth level for (i=lvls; i
160
depth++; irls[depth] = rlslen;
61
maxwidth = MAX(curwidth, maxwidth); } 165
// reset mask for nodes in root level structure for (i=0; i
170
175
180
185
190
195
200
205
void OOSgraph::pseudoDiameter(TIND* mask, TIND &s, TIND* rls, TIND* irls, TIND &rlslen) { TIND e; // ending node TIND sd; TIND szd; TIND d; TIND i,j; TIND* q; // shrunken last level TIND qdepth; TIND qwidth; TIND minwidth; TIND node; TIND depth; sd = n; // first guess for starting node // find node with smallest degree for (i=0; i
210
while (news) { // sort last level by node degree sortNodeByDegree(rls, irls[depth-1], irls[depth]); // shrink last level - create list with one node of each degree q = new TIND[irls[depth]-irls[depth-1]];
62
215
TIND ql = 1; TIND degree; q[0] = rls[irls[depth-1]]; degree = nodeDegree(q[0]); for (i=irls[depth-1]+1; i degree) { degree = d; q[ql++] = node; } }
220
225
minwidth = n+1; 230
news = false; // generate root level structure for each node in shrunken level for (i=0; i depth) { // level structure with greater depth, new starting node s = node; depth = qdepth; news = true; break; } else { // new ending node e = node; minwidth = qwidth; } } } delete[] q;
235
240
245
250
} if (e != node) { // generate root level structure from end node rootLevelStructure(e, mask, rls, irls, rlslen, qdepth, qwidth); } // store distances from end node for each node // nodes that are not part of this component will have // zero for (i=0; i<depth; i++) { for (j=irls[i]; j
255
260
} 265
void OOSgraph::number(int W1, int W2, TIND s, TIND* rls, TIND rlslen, int *status, TIND *q, int *priority, int &labeled) { TIND i, j; TIND node;
63
TIND qlen; // lenght of queue 270
275
// initialize node status and priority for (i=0; i
280
q[0] = s; qlen = 1; int maxp; TIND maxpi;
285
290
295
while (qlen > 0) { // find node with max priority maxp = priority[q[0]]; maxpi = 0; for (i=1; i maxp) { maxp = priority[node]; maxpi = i; } } node = q[maxpi];
300
// delete node from queue q[maxpi] = q[qlen-1]; qlen--; TIND nb, anb;
305
310
// preactive node, search neighbors if (status[node] == PREACTIVE) { for (i=iadj[node]; i
315
} } 320 // assign new node number, status is now postactive
64
labeled++; status[node] = labeled; 325
// search preactive neighbors for (i=iadj[node]; i
330
// search neighbors of active neighbor for (j=iadj[nb]; j
335
340
} 345
} } }
350 OOSindexArray* OOSgraph::sloan() { return sloan(1, 2); } 355
360
365
OOSindexArray* OOSgraph::sloan(int W1, int W2) { TIND s; // start node of pseudo-diamater TIND i; TIND labeled; // number of nodes already labeled TIND *rls = new TIND[n+1]; // root level structure items TIND *irls = new TIND[n+1]; // index do root level structure TIND *q = new TIND[n]; // priority queue int *status = new int[n]; // status of node (or new label) int *priority = new int[n]; // node priority TIND componentLen; // number of nodes in this graph component OOSindexArray *perm; // result permutation vector // initialize status vector for (i=0; i
370 labeled = 0; // while there is unlabelled component of graph while (labeled < n) { pseudoDiameter(status, s, rls, irls, componentLen); 375
65
number(W1, W2, s, rls, componentLen, status, q, priority, labeled); }
380
perm = new OOSindexArray(n); for (i=0; iset(status[i]-1, i);
385
delete[] delete[] delete[] delete[] delete[]
priority; status; rls; irls; q;
return perm; 390
395
} OOSgraph::˜OOSgraph() { delete[] adj; delete[] iadj; } }
Vypis 3: Soubor OOSgraph.cpp ´ 2
7
12
/********************************************************************/ /* */ /* OOSol2 2008 */ /* Dept. of Applied Mathematics, */ /* Technical University in Ostrava, Czech Rep. */ /* */ /* Filename: OOSgraph.h */ /* Created by Martin Stachon, 2008/05 */ /* */ /* List of updates: */ /* Date Author Description */ /* */ /********************************************************************/ #ifndef OOSGRAPH_H_ #define OOSGRAPH_H_
17 #include "OOSobjects.h" #include "OOSmatrices.h" namespace oosol { 22 class OOSgraph { /** adjacency list */ TIND* adj; 27 /** length of adjacency list */
66
TIND ladj; /** index of adjacency list */ TIND* iadj;
32
/** number of nodes in graph */ TIND n; 37
/** returns the degree of node i */ TIND nodeDegree(TIND i) { return iadj[i+1]-iadj[i]; }
42
/** Sloan algorithm node status */ //POSTACTIVE > 0 // label already assigned #define ACTIVE (0) // adjacement to a postactive node #define PREACTIVE (-1) // adjacement to an active node #define INACTIVE (-2) // none of above
47 void pseudoDiameter(TIND* mask, TIND &s, TIND* rls, TIND *irls, TIND & rlslen); void sortNodeByDegree(TIND* array, TIND start, TIND end); 52
void rootLevelStructure(TIND root, TIND* mask, TIND* rls, TIND* irls, TIND &rlslen, TIND &depth, TIND &width ); void number(int W1, int W2, TIND s, TIND* rls, TIND rlslen, int *status, TIND *q, int *priority, int &labeled); public:
57 /** Constructor - constructs graph from full rectangular matrix */ OOSgraph(OOSmatrix &mat); /** Constructor - constructs graph from rectangular matrix with nonzeros given by vectors of indices I, J */ OOSgraph(TIND nrow, OOSindexArray& I, OOSindexArray& J, OOSvectorD& V);
62
˜OOSgraph(); OOSindexArray* sloan(); 67 OOSindexArray* sloan(int W1, int W2);
}; 72 } #endif /*OOSGRAPH_H_*/
Vypis 4: Soubor OOSgraph.h ´