===================================================================== mfng - Multifraktálhálózat-generátor ===================================================================== TelepÃtése és frissÃtése ================================ Töltsük le a ``cxnet``-et a bazaar-os tárolóból:: bzr branch http://www.arek.uni-obuda.hu/repo/cxnet Ezentúl, ha a frissebb változatot szeretnénk letölteni, azt a következÅ‘ paranccsal tehetjük majd meg, ha a most létrehozott (külsÅ‘) ``cxnet`` könyvtár bármely alkönyvtárában állunk:: bzr pull Használata ================ Lépjünk bele a ``cxnet/mfng`` könyvtárba:: cd cxnet/mfng Elvileg futtathatnánk közvetlenül is az ``mfngrun.py`` fájlt, de azzal gondok lehetnek, ha frissÃteni szeretnénk a tárolóból a ``cxnet`` csomagot. Ezért célravezetÅ‘bb egy másolatot készÃteni róla és azt futtatni. Másoljuk át tehát az ``mfngrun.py`` fájlt ``mrun.py`` névre:: cp mfngrun.py mrun.py Szerkesszük át kedvünkre az ``mrun.py`` fájlt. Ehhez a következÅ‘ szakaszban található segÃtség. Ãtszerkesztés után futtathatjuk:: python mrun.py A futtatás eredményei ilyenkor a projektkönyvtár ``runs.py``, ``runs.json`` és ``runs.self`` fájljaiba kerülnek. Az elsÅ‘ kettÅ‘ sÃma szövegfájl, bármely szövegszerkesztÅ‘vel megtekinthetÅ‘. A részletek ilyenkor a képernyÅ‘re kerülnek. A részletes adatok minden egyes lépésre tartalmazzák a valószÃnűségeket és az osztópontokat, valamint a kiszámÃtott energiát, és hogy elfogadta-e a program az új generáló mértéket. Ezt a kimenetet UNIX és Linux alatt átirányÃthatjuk egy tetszÅ‘leges fájlba. Például:: python mrun.py >> project_base/details.txt Ãgy, dupla kacsacsÅ‘rrel (``>>``), az eredeti fájl végéhez illeszti az új adatokat, egyszeres kacsacsÅ‘rrel (``>``) mindig felülÃrja. Az mfngrun.py (mrun.py) fájlban szereplÅ‘ paraméterek ====================================================== Az ``mrun.py`` fájlban a Python teljes fegyverzetét felhasználhatjuk. Az alábbiakban pár alapvetÅ‘ dolgot Ãrunk le a nyelvvel és konkrétan a szimulációval kapcsolatban. Fontos tudnunk, hogy a Python nyelvben az utasÃtások csoportosÃtását behúzásokkal végezzük el. AmÃg például a for cikluson belül egyforma mértékben vannak behúzva a sorok, addig azok a for ciklus magjához tartoznak. Mihelyt visszatérünk a for ciklus vonalában, az az utasÃtás már nem lesz ciklusban. A Python programnyelvrÅ‘l magyar nyelven a http://www.arek.uni-obuda.hu/cxnet/ oldalról érhetÅ‘ el egy kisfilm, illetve a http://pythontutorial.pergamen.hu/downloads/html/tut/ oldalon érhetÅ‘ el oktatóanyag, angolul pedig a http://python.org hivatalos honlapról. A generator objektum fontosabb paraméterei. +-------------+----------------------------------------------------+ | Név | leÃrás | +=============+====================================================+ | T0 | kezdeti hÅ‘mérséklet | +-------------+----------------------------------------------------+ | Tlimit | eddig az értékig csökken a hÅ‘mérséklet | +-------------+----------------------------------------------------+ | steps | a lépések száma | +-------------+----------------------------------------------------+ | K | az iterációk száma | +-------------+----------------------------------------------------+ | m | a beosztások száma a kezdeti divs-ben | +-------------+----------------------------------------------------+ | n | a csúcsok száma a generált hálózatokban | +-------------+----------------------------------------------------+ | nps | a lépésenként generált hálózatok száma | +-------------+----------------------------------------------------+ | npsfactor | ennyiszer több hálózatot generál E+T energia alatt | +-------------+----------------------------------------------------+ | divexponent | az osztópontok áthelyezésénél szereplÅ‘ kitevÅ‘ | +-------------+----------------------------------------------------+ Egy vagy több paramétert ciklussal is lehet változtatni, és a különbözÅ‘ paraméterekkel egy-egy futtatást végrehajtani. A mfngrun.py-ben található példából kitalálható a for-ciklus működése. A ``generator.append_property`` metódussal tetszÅ‘leges tulajdonságot adhatunk a generátorunkhoz (jelenleg a ``MaxDegree`` és ``AverageDegree`` érhetÅ‘ el). Például, ha azt szeretnénk, hogy a cél az legyen, hogy a maximális fokszám 50 legyen, akkor az alábbi sor kell:: generator.append_property(MaxDegree(50)) Ha azt szeretnénk, hogy a cél az átlagos fokszámra 20 legyen, akkor pedig ez:: generator.append_property(AverageDegree(20)) Egyszerre több tulajdonságot is tudunk optimalizálni, például a fenti kettÅ‘ egymás után is végrehajtható. A nem kÃvánt törlése helyett érdemes lehet inkább megjegyzésbe rakni, azaz ``#``-et rakni elé. .. Tartós futtatás távoli szerveren =================================== Ha egy szerveren futtatjuk, és nem szeretnénk bejelentkezve maradni, akkor a nohup utasÃtással indÃthatjuk. Ennek két változatát mutatjuk be. Az elsÅ‘ esetben közvetlenül hÃvom meg a nohup-ot, a másodikban egy futtatható fájllal (shell-szkripttel) egyszerűbben csináljuk ugyanezt. Az nohup-pal követlenül Ãgy csinálhatjuk:: nohup ./mrun.py avgdeg >> runs/avgdeg_details.txt 2>> runs/avgdeg_err.txt < /dev/null & Ekkor az eredetileg képernyÅ‘re kerülÅ‘ adatok a ``avgdeg_details.txt`` fájlba kerülnek. A generálás végeredménye továbbra is a ``runs.py`` fájlba kerül. Ezt érjük el akkor is, ha az ``mfngnohup.sh`` szkriptet hÃvjuk meg a következÅ‘képpen:: ./mfngnohup.sh avgdeg A részleteredmények ======================== A futtatás egyes dupla lépései két lépést tartalmaznak. ElsÅ‘ben a valószÃnűségeket változtatjuk, a másodikban az osztópontok helyeit. A részleteket alapból a képernyÅ‘n látjuk, de az mfngnohup.sh külön fájlba irányÃtja át. Az eredményfájl ================ Az eredményfájl tartalmazza többek között: - a futtatás fontosabb paramétereit - a kapott divs és probs értékeket, valamint - a futás idÅ‘tartamát. Tartalmazza azt is, hogy az egyes lépésekben mikor utasÃtotta el (``.`` azaz pont) illetve mikor fogadta el (``A``, accept) az új generáló mértéket. Azt, amikor úgy fogadta el az új mértéket, hogy az új mértékhez tartozó energia nagyobb lett, (kicsi) ``a`` jelöli. Az eredmények kiértékelése =========================== Az ``analyzer`` nevű fejlesztés alatt álló modullal egyszerűen megtudhatjuk a kapott generáló mérték pár fontos tulajdonságát. A továbbiakban egy mintát mutatunk, hogyan használhatjuk ``ipython`` parancsértelmezÅ‘vel. Az alábbiaknál feltételezzük, hogy az ipythont a ``-pylab`` opcióval indÃtottuk Ãgy:: ipython -pylab (A hagyományos python-parancssor nem képes több grafikont egy grafikonra rajzolni, a továbbiak közül nem minden fog vele működni.) Az ``In [x]`` és ``Out [x]`` kezdetű sorokban a beÃrt parancsok, illetve a visszatérési értékeik találhatóak. :: In [1]: import analyzer I have found an rc file: /home/ha/.cxnetrc.py. The graph_module was set in the rc file to "igraph". I will use igraph. (It have been imported.) Tájékoztat minket arról, hogy az ``igraph``-ot vagy a ``networkx``-et fogja-e használni. Az ``mfng``-hez az igraph szükséges. :: In [2]: r=analyzer.Runs("runs") # Uses the runs.py file. Alapból a ``runs.py`` fájlba menti az adatokat, ilyenkor a ``"runs"`` paraméter el is hagyható. ElÅ‘fordulhat viszont, hogy egy másik géprÅ‘l akarjuk áthozni a futási eredményeinek (mert esetleg ott esetleg nincs telepÃtve a kiértékeléshez szükséges matplotlib könyvtár). Ilyenkor általában nem szeretnénk felülÃrni a helyi ``runs.py`` fájlt, ezért más nevet adhatunk a fájlnak. Ha ``otherruns.py`` néven másoljuk be a ``cxnet/mfng`` könyvtárba (a ``.py`` kiterjesztés fontos), akkor paraméterként az ``"otherruns"`` sztringet adjuk meg. :: In [3]: r.set_labels("3500_001") Out[3]: ['3500_001'] Ha például egy 3500 csúcsponttal végeztem szimulációt, akkor az elsÅ‘ futtatás cÃmkéje '3500_001' lesz, a másodiké '3500_002' és Ãgy tovább. Ezt a cÃmkét kell beÃrni argumentumként. Meg lehet adni cÃmkék listáját is. Ilyen esetben olyan vizsgálatoknál, ahol értelme van, mindegyik futáson végigmegy az analÃzis, más esetekben csak az elsÅ‘ cÃmkével foglalkozik. (Pythonban a sztringek megadásánál az egyszeres és dupla idézÅ‘jel (``'`` illetve ``"``) között nincs különbség. Listák megadása szögletes zárójelben, vesszÅ‘vel elválasztva történik. Pl. ``['3500_001', '3500_002']``) Amennyiben a set_labelsnek nem adunk meg paramétert, azaz ``r.set_labels()`` formában hÃvjuk meg, akkor az fájlban szereplÅ‘ összes cÃmkét berakja a listába. Pár alaptulajdonság meghatározása sok hálózat generálásából ------------------------------------------------------------ :: In [4]: r.properties(n=50) ==================== label = 3500_001 ==================== number of generated networks = 50 divs = [0.90256203480899999, 1.0], probs=[[ 0.15533352 0.31063345] [ 0.31063345 0.22339959]] avg max deg = 105.14+-9.68485036181, avg average deg=21.5726628571+-0.301747377812 Itt a generáló mértékbÅ‘l n=50 darab hálózatot állÃtottunk elÅ‘, és abból vizsgáltuk a kapott hálózatok jellemzÅ‘it. Fokszámeloszlás meghatározása, egyszerűbb változat ---------------------------------------------------- Miután ``r.set_labels`` függvénnyel beállÃtottuk a vizsgálni kÃvánt futásokat, kirajzoltathatjuk a fokszámeloszlást loglog skálán a következÅ‘ sorral:: In [14]: r.loglog() Az ábra cÃmét és egyéb dolgokat ugyanúgy megváltoztathatjuk, mint a `Fokszámeloszlás meghatározása, rugalmasabb de hosszadalmasabb változat`_ fejezetben látható. Az energia és az osztópontok változása a futás során ------------------------------------------------------ Az energia változását a futás során a :obj:`mfng.analyzer.Runs.plot_energy_list` függvénnyel rajzoltathatjuk fel:: In [3]: r.set_labels(["3500_001", "3500_002"]) ["3500_001", "3500_002"] In [4]: r.plot_energy_list() Ekkor az összes beállÃtott cÃmkére ábrázolni fogja egy ábrán az energiaváltozást. Az osztópontok változását :obj:`mfng.analyzer.Runs.plot_divs_list` függvénnyel ábrázolhatjuk, de ez csak a legelsÅ‘ cÃmkére fogja kirajzoltatni:: In [5]: r.plot_divs_list() Fokszámeloszlás meghatározása, rugalmasabb de hosszadalmasabb változat ------------------------------------------------------------------------ :: In [5]: dd=r.degdist() Ez a metódus egy :class:`cxnet.DegreeDistribution` osztályból származó objektummal tér vissza, amely leÃrása a ``cxnet`` modul leÃrásánál szerepel. Az alábbiak megértéséhez azt érdemes átnézni. :: In [6]: dd.set_binning("all") In [7]: dd.loglog() Out[7]: [<matplotlib.lines.Line2D object at 0xf8ac3ac>] A továbbiakban összehasonlÃtásként a kiinduló generáló mértékbÅ‘l is készÃthetünk fokszámeloszlást, hogy lássuk, mi változott. Ha az ipythont a ``-pylab`` opcióval indÃtottuk, akkor ugyanarra az ábrára rá tudjuk helyezni ezt az eloszlást is:: In [8]: ddi=r.degdist(initial=True) # The distribution of random network (original prob. measure) In [9]: ddi.set_binning("all") In [10]: ddi.loglog() Out[10]: [<matplotlib.lines.Line2D object at 0xfe4afac>] A ``matplotlib`` csomag, illetve annak része a ``pylab`` modul lehetÅ‘séget ad arra, hogy a grafikont tovább módosÃtsuk. Ezek leÃrását a ``matplotlib`` oldalán megtalálhatjuk. BeállÃthatjuk például kedvünk szerint az ábra cÃmét, az egyes függvényekhez tartozó magyarázatot, és végül elmenthetjük egy fájlba. Érdemes vektorgrafikus formátumot választani: a ``pdf`` a ``pdflatex``-hez, az ``eps`` a ``latex``-hez lehet hasznos, a pixelgrafikus ``png`` pedig weboldalhoz. Fontos ábrákat érdemes lehet rögtön mindháromba menteni:: In [11]: title("""m=2, K=3, n=3500, maxdeg=85, avgdeg=20""") Out[11]: <matplotlib.text.Text object at 0xf8a63ac> In [12]: legend(("result", "random"),loc="upper left") Out[12]: <matplotlib.legend.Legend object at 0xfcb5c0c> In [13]: savefig("3500_001degdist.pdf") # pdf helyett lehet pl. png és eps is Ez utóbbi az alábbihoz hasonló ábrát ad eredményül. .. figure:: mfng/3500_001degdist.png :scale: 70% .. Az eredmények kiértékelése „kézzel†========================================== A továbbiakban azt tárgyaljuk, hogy mit csinálhatunk, ha olyan dolgokat szeretnénk megtudni a kapott eredményrÅ‘l, amelyre az ``analyzer`` modul nincs felkészÃtve. A kapott valószÃnűségi mértéket beolvashatjuk a Python parancsértelmezÅ‘jébe, és tovább elemezhetjük. Az eredményfájlból másoljuk ki a divs és probs paramétereket, majd hozzuk létre a valószÃnűségi mátrixot, iteráljuk K-szor, és hozzunk létre az iterált valószÃnűségi mértékbÅ‘l (angolul ezt úgy hÃvják: link probability measure) ``n`` csúcsú hálózatot. ``K`` és ``n`` értéke megvan az eredményfájlban:: divs = ... probs = ... K = ... n = ... import mfng pm = mfng.ProbMeasure(divs, probs) lpm = pm.iterate(K) nw = lpm.generate(n) Ezt a hálózatot már vizsgálhatjuk az ``igraph``-fal és/vagy a ``cxnet``-tel. Például kirajzoltathatjuk a fokszámeloszlását:: import cxnet dd = cxnet.DegreeDistribution(nw) dd.set_binning("all") # nagyobb hálózatoknál all helyett log lehet dd.loglog() A fokszámeloszlás vizsgálatáról bÅ‘vebben a cxnet leÃrásában olvashatunk. Ha a tulajdonságoknak nagyobb statisztikai ingadozása van, a hálózat létrehozását és vizsgálatát ciklusban érdemes végezni. Az alábbi példába például 20 előállÃtott hálózatra átlagolja a maximális fokszámot. Az elején a 0.0, vagy más hasonló trükk fontos, különben az ``avgmaxdeg`` egész lesz, és egész-osztást fog végezni az utolsó sorban a ``/=`` nél. :: avgmaxdeg = 0.0 for i in range(20): nw = lpm.generate(n) avgmaxdeg += max(nw.degree()) avgmaxdeg /= 20