GRÁF GENERÁLÁS ÉS A KRUSKAL ALGORITMUS TANÍTÁSA EXCEL SEGÍTSÉGÉVEL GENERATING GRAPHS AND TEACHING THE KRUSKAL ALGORITHM USING EXCEL Kiss László Óbudai Egyetem, Rejtő Sándor Könnyűipari és Környezetmérnöki Kar, Médiatechnológai és Könnyűipari Intézet
KIVONAT Ebben a cikkben egyrészt arról szeretnék beszámolni, hogy milyen módszerek alkalmazásával lehet Excelben egy (súlyozott) szomszédsági mátrixból kiindulva generálni egy gráf ábráját. Milyen eszközeit használtam fel az Excelnek a pontok, az élek és az élhosszak kijelzésére. Másrészt arról írok, hogyan lehet – szerintem – elegáns számítógépes megoldást készíteni a Kruskal algoritmusra, amely annak szemléletes tanítását teszi lehetővé. Vázolom a megoldás nehézségeit, és az Excel hiányosságait. Az alkalmazást és használatát bemutatom, és továbbfejlesztésre minden érdeklődőnek, kérésére, rendelkezésére bocsátom. ABSTRACT This presentation demonstrates some methods to generate a graph image based on a (weighted) neighbourhood matrix in Excel; what Excel capabilities are required to display vertices, edges, and edge lengths. Also presented is an (in my opinion) elegant computerised solution of the Kruskal algorithm which can be used as a demonstration to aid with teaching. The implementation difficulties and imperfections of Excel encountered are shown. Included in the presentation are the complete Excel applications, available upon request. KULCSSZAVAK/KEYWORDS Gráfelmélet, programozás, algoritmusok, oktatásmódszertan Graph theory, programming, algorithms, teaching methodology MOTTÓ „annyiba kerül, amennyibe kerül, de megéri, próbáljuk meg érdekessé tenni az iskolát.” Karácsony Sándor [1] BEVEZETÉS Az egyetemeken, főiskolákon és néhány középiskolában különböző tárgyak keretein belül előkerül a gráfelmélet egyszerűbb algoritmusainak, köztük a minimális összértékű (hosszú, súlyú) feszítőfa meghatározásának oktatása. Két problémára kerestem a megoldást. Hogyan
You created this PDF from an application that is not licensed to print to novaPDF printer (http://www.novapdf.com)
felelhetnék meg a fenti pedagógiai elveknek, azaz hogyan segíthetném és tehetném érdekessé az algoritmus megértését és az önálló tanulást, illetve hogyan lehetne gyorsan és egyszerűen különböző feladatokat készíteni és a javításukat egyszerűsíteni. Alábbiakban ezekre igyekszem megadni a választ. A teljesen részletes megvalósítás leírására a cikk keretei nem adnak lehetőséget, de talán nincs is rá szükség. Akit a legapróbb részletek is érdekelnek, az elkészített Excel fájl használatával és a VBA kód áttanulmányozásával szerezhet további tapasztalatokat. A MEGVALÓSULT EXCEL ALKALMAZÁSRŐL Az alkalmazás a felhasználó számára három lapot láttat. A „Leírás” lapon a kezelési útmutatásokat olvashatjuk (lásd alább). A „Vezérlés” lapon (1. táblázat) néhány beállítható adat található, melyek közül lényegében azt a kettőt szükséges az adott feladathoz módosítanunk, amelyek meghatározzák a gráf pontjai számát, illetve azt, hogy irányított vagy irányítatlan gráfot szeretnénk-e ábrázolni. A többi adat kitöltésével ízlés szerint befolyásolhatjuk a gráf megjelenítésének színeit. A „Szomszédsági_mátrix” lapon kell elkészítenünk a gráf súlyozott szomszédsági mátrixát. Megtehetjük, hogy itt egy nagyobb mátrixot adunk meg, és a „pontok száma” adattal befolyásoljuk annak feldolgozási mértékét (2. táblázat). Irányítatlan esetben elegendő a felsőháromszög mátrixot elkészíteni, mert az alkalmazás ebben az esetben csak azt veszi figyelembe. Ha minden szükséges adatot kitöltöttünk, akkor különböző billentyűkombinációk megnyomása esetén 4 lehetőségünk van. 1. CTRL+SHIFT+G: megjelenítjük a gráf ábráját (1. és 2. ábra). 2. CTRL+SHIFT+K: a megjelenített gráf ábráján láttatjuk a Kruskal algoritmus eredményét. (3. ábra) 3. CTRL+SHIFT+L: megjelenítjük a gráf ábráját, egy léptető eszközt és egy szövegdobozt. Ezután a léptetőn előrelépve a szövegdobozban az algoritmuslépés sorszámát látjuk. Ha az algoritmus az adott lépésben vont be élt a feszítőfába, akkor a gráfon ennek eredményeként a bevont él megvastagítva jelenik meg. A léptetőn visszalépve az előző algoritmuslépés utáni állapothoz jutunk (5. és 6. ábra) 4. CTRL+SHIFT+M: megjelenítjük a gráf ábráját, egy léptető eszközt, és az élekre, s azok bevonására vonatkozó információkat tartalmazó táblázatot. Ezután a léptetőn előrelépve a táblázatban a sorrendben következő él adatait színezéssel emeljük ki. Ha az algoritmus az adott élt bevonta a feszítőfába, akkor a gráfon ennek eredményeként az él megvastagítva jelenik meg. A léptetőn visszalépve az előző algoritmuslépés utáni állapothoz jutunk (7. és 8. ábra). A 2., 3. és 4. esetben az algoritmus végállapotának megfelelő ábrán egy párbeszédpanel jelenik meg, amin a lehetséges feszítőfák összértékének minimumát, mint az algoritmussal előállt feszítőfa összértékét láthatjuk. Az „OK” gombra (4. ábra) kattintás, vagy az „Enter” billentyű megnyomása után a párbeszédpanel eltűnik a képernyőről. GRÁFGENERÁLÁS A gráfok ábrájának generálására az Excelben nincs direkt eszköz. A problémát a grafikonkészítés, az Excel 2003 (10-es verzió) makrórögzítési lehetősége és a VBA programozás alkalmazásával oldottam meg. A magyarázat során megadom a fontosabb VBA metódusokat, és néhány változó nevét. A gráfpontok ábrázolásához buborékgrafikont készítettem. Meghatároztam egy egységsugarú körön elhelyezkedő szabályos sokszög koordinátáit (X, Y). Elhelyeztem őket a „Gráfpontadatok” lap 2. és 3. oszlopában, kiegészítettem egy 1-eseket tartalmazó oszloppal (5. táblázat), és az egymást követő 3 oszlop megfelelő részét átadtam a grafikonkészítőnek
You created this PDF from an application that is not licensed to print to novaPDF printer (http://www.novapdf.com)
(Charts.Add). Hogy az ábra valóban szabályos sokszög legyen („ne essen szét”), ahhoz a programban, a gráfpontok számától függően, be kellett állítani a BubbleScale tulajdonságot. Ezzel a beállítással együtt eldőlt a gráfpontok sugarának mérete is (Pont_R). Szükséges volt még megadni a rajzterület szélességét, magasságát és a diagramterület tetejétől és baloldalától mért távolságát. Ezek alapján meghatározhatók az ábra középpontjának koordinátái (OX, OY). A középpont segítségével kikísérletezhető az a sugár érték (R), amellyel és a tárolt grafikon pontkoordinátákkal továbbszámolva előállnak az egyes gráfpontok (buborékok) középpontjainak koordinátái. Ezeket a 7. és 8. oszlopban tároltam (5. táblázat). A gráfpontok indexeléséhez páratlan számú gráfpont esetén a középső, páros esetén a két középső közül a kisebb indexű koordinátapár előtti oszlopba (6. oszlop) az 1, az azt követő elé a 2, az azt megelőző elé a 3 került, és így tovább felváltva. Ezután rendeztem (Selection.Sort) erre a megelőző oszlopra (5. táblázat) a három adathalmazt. Az így kapott koordináták alapján a gráf ábráján minden gráfpontba a szükséges eltolással (X_eltolás, Y_eltolás) – hogy a számozás valóban a buborékba (körbe) kerüljön – elhelyeztem egy szövegdobozt (ActiveChart.Shapes.AddTextbox) a megfelelő indexszel. Így a gráfpontok az ábrában balról jobbra, fentről lefelé felváltva indexeltek. A gráf éleinek megrajzolásához (ActiveChart.Shapes.AddLine) meghatároztam azok kezdő- és végpont koordinátáit. A gráfpontok középpontjai koordinátáinak ismeretében kiszámítható a két középpontot összekötő él egyenesének meredeksége. Felhasználva, hogy ismerjük a gráfpontok sugarát, meghatározhatjuk az él végpontjainak megfelelő kerületi pontokat. Hasonlóképpen számolhatók az élre kerülő élhosszak szövegdobozaihoz a koordináták, természetesen ebben az esetben is eltolást alkalmazva. Az élhossz adatot az élen a kiinduló ponthoz közel helyeztem el. Mivel az Excel VBA a különböző objektumokat általában létrehozásuk sorrendjében indexeli, ezért, hogy a későbbiekben hivatkozhassunk rájuk – mivel nincs minden objektumnak név tulajdonsága -, szükséges azok indexeit tárolni. Az élek esetében erre egy „Élindexek” lapot használtam, ahol a súlyozott szomszédsági mátrixnak megfelelően tároltam az indexeket (3. illetve 4. táblázat). Az irányítatlan, az irányított egyirányú és irányított, de „oda-vissza” irányú éleket is egy-egy élobjektumként kezeltem, csak a tulajdonságaikat változtattam meg. Az élek rajzolása közben a Kruskal algoritmus számára oszlopban tároltam azok hossz, kezdő- és végpont adatait, továbbá egy 0 értéket (5. táblázat, 9-12. oszlop), és rendeztem a tárolt adatokat az élhossz oszlopa alapján. A KRUSKAL ALGORITMUSRÓL Az algoritmus célja egy egyszerű, összefüggő, irányítatlan gráf egy olyan feszítőfájának előállítása, amelynek összértéke (súlya) minimális. Tanítása - tapasztalatom szerint jellemzően kétféleképpen történik. Az egyik: bevonjuk a feszítőfába sorban az éleket valamilyen tetszőleges rendszerben, és ha egy új él bevonása után kör keletkezik, akkor elhagyjuk a körből a legnagyobb értékű élek közül az egyiket. Ha minden élt vettünk és minden pontból indul ki él, akkor a lehetséges minimális összértékű feszítőfák egyikéhez jutottunk. A másik: először a legkisebb értékű éleket vonjuk be a feszítőfába. Ha egy új él bevonása kört eredményezne, akkor elhagyjuk. Majd növekvő értéksorrendben ugyanezt tesszük a többi éllel. Hasonlóképpen, ha minden élt vettünk és minden pontból indul ki él, készen vagyunk. A két módszer lényegében nem különbözik, csak az élek feldolgozási sorrendjében. Így, bár a feszítőfa összértéke minkét esetben a lehetséges legkisebb lesz, a keletkezett feszítőfa egészen eltérő lehet. Utóbbi módszer kiválóan programozható is. Rendezzük az éleket értéküknek megfelelően nagyság szerint növekvő sorrendbe. Ha ezen belül az élek kezdőpontjára, s azon belül
You created this PDF from an application that is not licensed to print to novaPDF printer (http://www.novapdf.com)
végpontjára is rendezünk, akkor a második módszernek egy egyértelmű megoldásához jutunk. Mivel így egy feladat megoldása - feltéve, hogy létezik - minden hallgatónál azonos kell, hogy legyen, az könnyen ellenőrizhető. A szakirodalom valójában ezt a változatot nevezi Kruskal algoritmusnak [2]. A számítógépes algoritmus természetesen ebben az esetben sem egyértelműen meghatározott. Választhatjuk úgy, hogy kezdetben minden pont egy erdő különböző fájában (komponensében) legyen. Kap egy egyszerű indexet, növekvő sorrendben. Lehet ez az index például magának a pontnak az indexe. Ebben az esetben egy él feldolgozása során, ha a két végpontja különböző komponensbe tartozik, akkor a nagyobb indexű és minden vele azonos komponensbe tartozó pont indexét a kisebb indexre változtatjuk. Ha a végpontok azonos komponensbe tartoznak, akkor az élet nem vesszük be a feszítőfába, hiszen azzal kör keletkezne. Így minden élet feldolgozva elértük célunkat. Másik módszer lehet (és ezt programoztam be), hogy kezdetben egyik pont sem tartozik komponenshez (nullát rendelünk hozzá). Egy él feldolgozása során ilyenkor több eset lehetséges. A végpontok egyike sem tartozik komponenshez. Mindkettő ugyanazt a - következő lehetséges - komponensértéket kapja. Az él bekerül a feszítőfába. A végpontok közül az egyik komponenshez tartozik, a másik nem. Ekkor a komponensbe nem tartozó a másik komponensébe kerül. Az él a feszítőfa része lesz. A végpontok különböző komponenshez tartoznak. Ez esetben a nagyobb indexű és minden vele azonos komponensbe tartozó a kisebbik indexet kapja. Az él bekerül a feszítőfába. A végpontok azonos komponensbe tartoznak. Az élet nem vesszük figyelembe. Ha számoljuk a komponensbe bevont pontokat és a komponensek számát, akkor, ha az összes pontot bevontuk és a komponensek száma 1, készen vagyunk, a további éleket nem szükséges feldolgoznunk. A gráf komponensei számát a következőképpen határozhatjuk meg: (pontok száma) – (komponensbe bevont pontok száma) + (élek komponensei száma). Ha ez a szám nem 1, akkor a gráf több komponensből áll, nem összefüggő. Azt, hogy egy pont melyik komponensbe tartozik, a „Gráfpontadatok” lap 5. oszlopában láthatjuk. A 12. oszlop mutatja, hogy egy él bekerül, vagy sem a feszítőfába (0 vagy 1). Az utolsó bevont él indexét, a feszítőfa összértékét, és a komponensek számát a 13. oszlopban tároltam (6. táblázat). A LÉPTETŐ ALGORITMUSOKRÓL A lépésenkénti végrehajtás a gráf feszítőfáját meghatározó algoritmus végeredményén alapszik. Felhasználja, hogy már tudjuk, hogy létezik a feszítőfa, vagy sem. Ha igen, akkor az is rendelkezésünkre áll, hogy melyik élt vontuk be, és melyiket nem. Ismerjük az utolsó bevont él indexét és a feszítőfa összértékét is. A léptető számára tehát megadhatjuk a minimális (=0) és maximális értéket (utolsó bevont él indexe), a léptetési távolságot (=1) és egy cellacsatolást, ahová az aktuális lépés sorszámát elhelyezi. Ez utóbbira a „Gráfpontadatok” lap „E2” celláját használtam. Szükséges még a léptető létrehozásakor (ActiveSheet.Spinners.Add) hozzárendelni a makrót (programot) is. A szövegdobozt használó léptetés számára pedig tárolni kell a szövegdoboz létrehozási indexét, hogy később hivatkozhassunk rá a léptetőhöz hozzárendelt programban. Ezt az adatot a „Gráfpontadatok” lap „M2” cellájában helyeztem el. Hogy az algoritmusban előre- vagy visszalépünk, azt abból
You created this PDF from an application that is not licensed to print to novaPDF printer (http://www.novapdf.com)
tudhatjuk, hogy a léptető lépéssorszámát viszonyítjuk egy tárolt sorszámhoz, ami kezdetben nulla, később, egy léptetés feldolgozása után, annak lépéssorszámával lesz egyenlő. Ez az érték a „Gráfpontadatok” lap „M3” cellájában található (6. táblázat). EXCEL KOMPATIBILITÁSI PROBLÉMÁK Előrebocsátom, hogy a problémákat a magyar verziókban tapasztaltam, az eredeti verziókkal kapcsolatosan nincsenek ilyen irányú ismereteim. Az Excel 2007 (12-es verzió) és az Excel 2003 (10-es verzió) nem teljesen kompatibilisek. Az Excel 2007-ben számtalan objektum programozását nem lehet makrórögzítéssel megoldani. Ilyen például egy vonal megrajzolása. Az Excel 2003-ban a vonal rajzolásakor rögzített makró viszont csak módosítással fut Excel 2007-ben. Különbözik a vonal (él) VBA elnevezése. Az Excel 2003 „Line” szavát Excel 2007-ben „Egyenes összekötő”-re cserélték. A két verzió másként kezeli az objektumok indexelését. Egy léptető az előbbi verzióban egy vonal vagy szövegdoboz létrehozásától függően folyamatos sorszámozás alapján, az utóbbiban attól függetlenül kap indexet. Ha a képernyőn az oszlopokat számozással jelenítjük meg, akkor nem működik a léptető programból generálása. Át kell váltani betűs kijelzési módra, generálni a léptetőt, és visszaváltani a számozásos oszlopkijelzésre. A verziók eltérően kezelik a szövegdobozokat. Azonos méretű számokat különböző méretű szövegdobozban lehet megjeleníteni. Ugyanaz a színkód mást eredményez a két verzióban. Egy verzión belül pedig a pontok és élek azonos színkód mellett különböző színűek lesznek, és különbözik az egyes esetekben a lehetséges kódok mennyisége. Mást eredményez az egyes verziókban a diagram másolása és munkalapra beillesztése is. ÖSSZEFOGLALÁS/KÖVETKEZTETÉS Mindenekelőtt el kell fogadni azt a tényt, hogy az elkészült alkalmazás nem teljesen általános. Sokpontú, élekkel sűrűn behálózott gráf ábrázolására nem alkalmas, hiszen az éleken lévő értékek helyzetükből adódóan egymásra íródhatnak. Általában 4-10 pont esetén viszont szép ábrához juthatunk. Az éleken megjeleníthető értékek nagysága is korlátozott, legfeljebb 2 számjegyű lehet. A kitűzött célt mégis elértük. A megadott korlátokkal szépen ábrázolhatunk gráfokat, jól szemléltethetjük rajtuk a Kruskal algoritmust, a diákok önállóan és – reményeim szerint örömmel tanulhatnak a segítségével. Az érdeklődőbbek a VBA kód tanulmányozásával szerezhetnek tapasztalatokat. Ismertettünk egy lehetséges megoldási módszert gráfok generálására, és feltártunk néhány hiányosságot az Excel 2003 és 2007 verzióiban. Szerző reméli, hogy az alkalmazást minél szélesebb körben igénylik, és valóban használni fogják az oktatásban.
You created this PDF from an application that is not licensed to print to novaPDF printer (http://www.novapdf.com)
IRODALOMJEGYZÉK [1] Hatvany László: KARÁCSONY SÁNDOR PEDAGÓGIAI ÍRÁSAIBÓL (9 tanulmány, 1922-1946), Csökmei Kör, 1994 [2] Cormen, Leiserson, Rivest: Algoritmusok, Műszaki Könyvkiadó, 2003, ISBN: 9789631630299 [3] Szakács Attila, Szakácsné Nagy Szilvia: A gazdaság matematikai és az informatikai tárgyak oktatásának tapasztalatairól a Tessedik Sámuel Főiskola Gazdasági Főiskolai Karán, Felsőoktatási matematika-, fizika-, és számítástechnika oktatók XXXI. Konferenciája, Dunaújváros, 2007. augusztus 2325. SZERZŐ Kiss László, főiskolai docens, ÓE RKK MKI,
[email protected]
You created this PDF from an application that is not licensed to print to novaPDF printer (http://www.novapdf.com)
1. táblázat. A „Vezérlés” lap adatai
2. táblázat. A „Szomszédsági_mátrix” lap adatai. A súlyozott szomszédsági mátrixhoz a „Vezérlés” lapon, a mátrix méreteként megadott számú sort és oszlopot veszünk figyelembe.
3. és 4. táblázat. Az elrejtett „Élindexek” lapon látható irányított illetve irányítatlan gráfnak megfelelő élindexek a későbbi hivatkozáshoz.
You created this PDF from an application that is not licensed to print to novaPDF printer (http://www.novapdf.com)
5. táblázat. .Számított adatok a gráf rajzolásához.
6. táblázat. .Számított adatok a gráf rajzolásához és a léptető algoritmusokhoz.
7. táblázat. .Számított adatok a gráf rajzolásához és a léptető algoritmusokhoz, egy nem összefüggő gráf esetén.
You created this PDF from an application that is not licensed to print to novaPDF printer (http://www.novapdf.com)
1. és 2. ábra. Az irányított és az irányítatlan gráf. (CTRL+SHIFT+G esetén).
3. és 4. ábra. Az algoritmus eredménye (CTRL+SHIFT+K esetén) és az OK gombos párbeszédpanel.
You created this PDF from an application that is not licensed to print to novaPDF printer (http://www.novapdf.com)
5. ábra. Az algoritmus eredményét lépésenként láttató, szövegdobozzal, kezdési állapotban (CTRL+SHIFT+L esetén).
6. ábra. Az algoritmus eredményét lépésenként láttató, szövegdobozzal, befejezési állapotban (CTRL+SHIFT+L esetén).
You created this PDF from an application that is not licensed to print to novaPDF printer (http://www.novapdf.com)
7. ábra. Az algoritmus eredményét lépésenként láttató, táblázattal, kezdési állapotban.
8. ábra. Az algoritmus eredményét lépésenként láttató, táblázattal, befejezési állapotban.
You created this PDF from an application that is not licensed to print to novaPDF printer (http://www.novapdf.com)