ΔΙΚΤΥΑ ΑΙΣΘΗΤΗΡΩΝ - IKEE

223
Αριστοτέλειο Πανεπιστήμιο Θεσσαλονίκης Πτυχιακή Εργασία Τμήματος Πληροφορικής της Φοιτήτριας Λάτσιου Γεωργία, ΑΕΜ: 921|Μάρτιος 2009 ΛΑΤΣΙΟΥ ΓΕΩΡΓΙΑ ΔΙΚΤΥΑ ΑΙΣΘΗΤΗΡΩΝ

Transcript of ΔΙΚΤΥΑ ΑΙΣΘΗΤΗΡΩΝ - IKEE

Δίκτυα Αισθητήρων

1

Αριστοτέλειο Πανεπιστήμιο Θεσσαλονίκης

Πτυχιακή Εργασία Τμήματος Πληροφορικής της ΦοιτήτριαςΛάτσιου Γεωργία, ΑΕΜ: 921|Μάρτιος 2009

ΛΑΤΣΙΟΥ

ΓΕΩΡΓΙΑΔΙΚΤΥΑ ΑΙΣΘΗΤΗΡΩΝ

Δίκτυα Αισθητήρων

2

Δίκτυα Αισθητήρων

3

Θα ήθελα να ευχαριστήσω τον καθηγητή κύριο Απόστολο Παπαδόπουλοκαι τον Αλέξη Παπαδημητρίου για την καθοδήγηση και την βοήθεια τουςστην κατά τη διάρκεια της διεκπεραίωσης της πτυχιακής μου εργασίας.Επιπλέον θα ήθελα να ευχαριστήσω την οικογένειά μου και τους φίλους

μου για την πολύτιμη υποστήριξή τους.

Δίκτυα Αισθητήρων

4

ΠΕΡΙΕΧΟΜΕΝΑ

1. ΕΙΣΑΓΩΓΗ 9

Α’ ΜΕΡΟΣ ΘΕΩΡΗΤΙΚΟ ΥΠΟΒΑΘΡΟ

2. ΕΛΑΧΙΣΤΑ ΖΕΥΓΝΥΟΝΤΑ ΔΕΝΔΡΑ 112.1 Εισαγωγή 112.2 Ιστορία 122.3 Ιδιότητες 122.4 Ψευδοκώδικας 172.5 Αλγόριθμοι 172.6 Εφαρμογές 202.7 Παρόμοια Προβλήματα 21

3. Ο ΑΛΓΟΡΙΘΜΟΣ ΤΟΥ KRUSKAL 233.1 Γενικά 233.2 Λίγα Λόγια για τον Joseph Kruskal … 233.3 Ο Αλγόριθμος 243.4 Απόδειξη της Ορθότητας 273.5 Απόδοση 28

4. Ο ΑΛΓΟΡΙΘΜΟΣ ΤΟΥ PRIM 294.1 Γενικά 294.2 Λίγα Λόγια για τον Robert Prim … 294.3 Ο Αλγόριθμος 304.4 Απόδειξη της Ορθότητας 334.5 Απόδοση 34

5. Ο ΑΛΓΟΡΙΘΜΟΣ ΤΟΥ BORVKA 365.1 Γενικά 365.2 Λίγα Λόγια για τον Otakar Boruvka … 365.3 Ο Αλγόριθμος 365.4 Απόδειξη της Ορθότητας 395.5 Απόδοση 40

6. Ο ΑΛΓΟΡΙΘΜΟΣ REVERSE-DELETE 416.1 Γενικά 416.2 Απόδειξη της Ορθότητας 41

Δίκτυα Αισθητήρων

5

6.3 Ο Αλγόριθμος 436.4 Απόδοση 43

7. Ο ΑΛΓΟΡΙΘΜΟΣ ΤΟΥ CHAZELLE 44

8. Ο ΥΒΡΙΔΙΚΟΣ ΑΛΓΟΡΙΘΜΟΣ 45

9. ΕΥΚΛΕΙΔΙΟ ΕΛΑΧΙΣΤΟ ΖΕΥΓΝΥΟΝ ΔΕΝΔΡΟ 469.1 Γενικά 469.2 Ο Αλγόριθμος 469.3 Απόδοση 48

10. ΣΥΓΚΡΙΣΗ ΑΛΓΟΡΙΘΜΩΝ 49

11. GABRIEL ΓΡΑΦΟΣ 5111.1 Γενικά 5111.2 Voronoi και Gabriel Γράφοι 5111.3 Αλγόριθμος Ωμής Βίας 5311.4 Ευριστικός Αλγόριθμος 5311.5 Monte – Carlo Εξομοίωση 55

12. ΚΕΝΤΡΙΚΟΤΗΤΑ 5712.1 Γενικά 5712.2 Ο Αλγόριθμος Betweenness Centrality 5712.3 O Αλγόριθμος Random Walk Betweenness Centrality 5812.4 Ο Αλγόριθμος HITS 58

13. ΔΙΚΤΥΑ ΑΙΣΘΗΤΗΡΩΝ 6013.1 Γενικά 6013.2 Ο Αισθητήρας Κόμβος 6113.3 Χαρακτηριστικά Δικτύων Αισθητήρων 6213.4 Εφαρμογές 6213.5 Κατανάλωση Ενέργειας 6413.6 Επίλογος 64

Β’ ΜΕΡΟΣ ΑΝΑΠΤΥΞΗ ΠΡΟΓΡΑΜΜΑΤΟΣ

14. ΣΧΕΔΙΑΣΗ ΠΡΟΓΡΑΜΜΑΤΟΣ67

13.1 Γενικά 6713.2 Διάγραμμα Κλάσεων 67

Δίκτυα Αισθητήρων

6

15. ΣΥΓΓΡΑΦΗ ΠΡΟΓΡΑΜΜΑΤΟΣ 6914.1 Επιλογή Γλώσσας Προγραμματισμού 6914.2 Επιπρόσθετες Βιβλιοθήκες 6914.3 Κλάσεις Συστήματος 70

16. ΛΕΙΤΟΥΡΓΙΕΣ ΤΟΥ ΣΥΣΤΗΜΑΤΟΣ 82

17. ΕΙΔΙΚΑ ΘΕΜΑΤΑ 10216.1 Γραφικό Περιβάλλον Εφαρμογής 10216.2 Οι Ενέργειες 107

18. SCREENSHOTS ΕΦΑΡΜΟΓΗΣ 110

19. J – SIM 12217.1 Γενικά 12217.2 Αρχιτεκτονική Αυτόνομων Συστατικών 12217.3 Προγραμματισμός 123

20. ΕΠΙΛΟΓΟΣ 125

ΒΙΒΛΙΟΓΡΑΦΙΑ 126

ΠΑΡΑΡΤΗΜΑΤΑ 128Παράρτημα Α - Λίστα Εμπορικών Αισθητήρων 129Παράρτημα Β - Κώδικας Προγράμματος 133

Δίκτυα Αισθητήρων

7

Δίκτυα Αισθητήρων

8

1. ΕΙΣΑΓΩΓΗ

Σήμερα οι γράφοι χρησιμοποιούνται για να μοντελοποιήσουν πολλές καταστάσειςκαι προβλήματα του πραγματικού κόσμου, και σε τέτοιες συνθήκες η θεωρείαγράφων εξυπηρετεί σαν μία θεμελιώδη δομή η οποία βοήθα να εξηγήσουμε τονκόσμο που ζούμε. Μία πολύ ενδιαφέρουσα εφαρμογή της θεωρίας γράφων είναι ημελέτη των δικτύων.

Από την άλλη, τα δίκτυα αισθητήρων έχουν αποτελέσει μία μόδα τα τελευταίαχρόνια, επιλύοντας πολλές εφαρμογές δικτύων διαφορετικών πεδί ων έρευνας. Στησημερινή εποχή, οι ερευνητές εστιάζουν την μελέτη τους, όσων αφορά τα δίκτυααισθητήρων, στα ακόλουθα θέματα:

Επίγνωση ενέργειας/αποδοτική διανομή ενέργειας στα δίκτυα αισθητήρων Ανάπτυξη διαμοιραζόμενης αρχιτεκτονικής των δικτύων αισθητήρω ν Διαμοιραζόμενη ενσωμάτωση εφαρμογών Σχεδίαση αλγορίθμων για καλύτερη αποδοτικότητα ενέργειας

Στην παρούσα μελέτη, προσπαθούμε να προσεγγίσουμε κάποια από ταπροβλήματα των δικτύων αισθητήρων με τη βοήθεια της θεωρίας γράφων. Στο πρώτομέρος, αναλύονται κάποιες σημαντικές έννοιες της θεωρίας γράφων και των δικτύωναισθητήρων, ενώ στο δεύτερο μέρος αναλύεται το πρόγραμμα το οποίο αναπτύχθηκε .

Εικόνα: Παράδειγμα χρήσης δικτύων αισθητήρων

Δίκτυα Αισθητήρων

9

Α’ΜΕΡΟΣ

ΘΕΩΡΗΤΙΚΟΥΠΟΒΑΘΡΟ

Δίκτυα Αισθητήρων

10

2. ΕΛΑΧΙΣΤΑ ΖΕΥΓΝΥΟΝΤΑ ΔΕΝΔΡΑ

2.1 Εισαγωγή

Ένα δένδρο ορίζεται σαν ένας μη κατευθυνόμενος, άκυκλος, συνδεδεμένος γράφος(ή πιο απλά, ένας γράφος στον οποίο υπάρχει μόνο ένα μονοπάτι που ενώνει κάθεζεύγος κόμβων). Δεδομένου ενός συνδεδεμένου, μη κατευθυνόμε νου γράφου, τοζευγνύον δένδρο αυτού του γράφου είναι ένας υπογράφος ο οποίος είναι δένδρο καισυνδέει όλους τους κόμβους του αρχικού γράφου μαζί. Ένας γράφος μπορεί να έχειπερισσότερα από ένα ζευγνύον τα δένδρα, όπως φαίνεται και στην παρακάτω εικόνα.

Εικόνα: Ένας γράφος(αριστερά) και κάποια από τα πιθανά ζευγνύοντα υποδένδρα του(δεξιά).

Επιπλέον, σε κάθε ακμή μπορεί να ανατεθεί ένα βάρος, το οποίο είναι ένααριθμός, και χρησιμοποιείται για να κοστολογήσουμε το ζευγνύον δένδρο ,υπολογίζοντας το άθροισμα των βαρών όλων των ακμών του δένδρου. Το ελάχιστοζευγνύον δένδρο ή το ελάχιστο επικαλύπτον δένδρο (minimum spanning tree,minimal spanning tree, minimum-weight spanning tree) είναι το ζευγνύον δένδρο μετο ελάχιστο συνολικό βάρος απ’ όλα τα ζε υγνύοντα δένδρα. Ενώ εάν υπάρχουν ακμέςμε ίσα βάρη, ένας γράφος μπορεί να μην έχει μόνο ένα ΕΖΔ. Στην ακόλουθη εικόναπαρουσιάζεται ένας συνδεδεμένος ζυγισμένος γράφος και το ελάχιστο ζευγνύονδένδρο του.

Εικόνα :Ένας ζυγισμένος συνδεδεμένος γράφος και το ελάχι στο ζευγνύον δένδρο τουΑυτό το παράδειγμα επεξηγεί πως το ΕΖΔ δεν είναι απαραίτητα μοναδικό, εάν τα βάρη τωνακμών είναι ίσα: έχουμε ένα ΕΖΔ με την ακμή 3-4 (όπως φαίνεται στην εικόνα) και ένα

Δίκτυα Αισθητήρων

11

διαφορετικό ΕΖΔ περιέχει την ακμή 0-5 (αν και η 7-6, η οποία έχει το ίδιο βάρος όπως αυτές οιδύο ακμές, δεν είναι στο ΕΖΔ).

Εάν ο γράφος δεν είναι συνδεδεμένος, τότε διαθέτει ένα ελάχιστο ζευγνύον δένδρογια κάθε συνιστώσα του γράφου, έτσι παράγεται ένα ελάχιστο ζευγνύον δάσος.Το πρόβλημα του ελάχιστου ζευγνύοντο ς δένδρου συχνά ορίζεται με γεωμετρικούςόρους, όπου το V είναι ένα σύνολο από σημεία σε έναν χώρο των d διαστάσεων καιτα βάρη των ακμών αντικατοπτρίζουν την Ευκλείδεια απόσταση.

Εικόνα: Ένας ζυγισμένος μη κατευθυνόμενος γράφος και το ΕΖΔ τουΈνας ζυγισμένος μη κατευθυνόμενος γράφος είναι ένα σύνολο από ακμές με βάρη. Το ΕΖΔ

είναι ένα σύνολο από ακμές με το ελάχιστο συνολικό βάρος που ενώνει όλους τους κόμβους(μαύρες στη λίστα με τις ακμές, οι χοντρές γραμμές στον γράφο). Σε αυτόν τον συγκεκριμένο

γράφο, θεωρούμε τα βάρη αντικατοπτρίζουν τις αποστάσεις μεταξύ των κόμβων

2.2 Ιστορία

Το πρόβλημα του ελάχιστου επικαλύπτοντος δένδρου αναγνωρίστηκε ως ένα απότα πρώτα συνδυαστικά προβλήματα. Διατυπώθηκε επίσημα από τον Boruvka το 1926(προμηνύοντας τα πεδία της υπολογιστικής θεωρίας, της συνδυαστικήςβελτιστοποίησης και ακόμη περισσότερο της θεωρίας γράφων) και από τότε οαρχικός του αλγόριθμος έχει προκαλέσει το συνεχές ενδιαφέρον για το πρόβλημα. Τοπρόβλημα του ΕΖΔ έχει παρακινήσει την έρευνα για την ανάπτυξη πιο αποδοτικώνδομών δεδομένων, και πιο συγκεκριμένα των ουρών προτεραιότητας.

2.3 Ιδιότητες

Μία από τις πιο σημαντικές ιδιότητες ενός δένδρου είναι , ότι η προσθήκη μίαςακμής σε ένα ελάχιστο επικαλύπτον δένδρο δημιουργεί ένα μοναδικό κύκλο.

Ιδιότητα ΕΖΔ

Δίκτυα Αισθητήρων

12

Έστω G = (V, E) ένας συνδεδεμένος γράφος με συνάρτηση κόστους η οποίαορίζεται στις ακμές. Έστω U είναι ένα υποσύνολο των κορυφών V. Εάν (u, v) είναιμία ακμή ελάχιστου κόστους τέτοια ώστε u U και v V-U, τότε υπάρχει ένα ΕΖΔπου περιέχει την (u, v) σαν ακμή.

Απόδειξη: Αρχικά υποθέτουμε το αντίθετο, δηλαδή ότι δεν υπάρχει ΕΖΔ του G πουνα περιέχει την ακμή (u, v). Έστω το T είναι ένα οποιοδήποτε ζευγνύον δένδρο τουG. Θα αποδειχτεί πως το Τ δεν είναι ελάχιστο ζευγνύον δένδρο. Επειδή το Τ π εριέχειένα μονοπάτι από τον κόμβο u στον κόμβο v (αφού είναι ζευγνύον δένδρο), ηπροσθήκη της ακμής (u, v) σε αυτό θα προκαλέσει έναν κύκλο. Η ( u, v) αποτελείμέρος του κύκλου αυτού. Επομένως θα πρέπει να υπάρχει μία άλλη ακμή ( u', v') στοT τέτοια ώστε το u' U και v' V-U, όπως φαίνεται στην εικόνα

Διαφορετικά δεν θα υπήρχε τρόπος για τον κύκλο να πάει από u στο v χωρίς ναακολουθήσει την ακμή (u, v) για δεύτερη φορά. Η διαγραφή της ακμής ( u', v') σπάειτον κύκλο και δίνει ένα ΕΖΔ T', του οποίου το κόστος δεν είναι υψηλότερο από τοκόστος του T , αφού υποθέσαμε πως το κόστος της ( u,v) είναι ελάχιστο, άρα c(u, v)≤c(u', v'). Επομένως αποδείχτηκε το αντίθετο, αφού το ΕΖΔ πρέπει να περιέχει τηνακμή (u, v).

Αυτή η ιδιότητα είναι η βάση για να αποδείξ ουμε δύο βασικές ιδιότητες των ΕΖΔ.Πολλοί αλγόριθμοι βασίζονται σε μία ή και στις δύο ιδιότητες. Η πρώτη ιδιότηταείναι η ιδιότητα της τομής και η δεύτερη είναι η ιδιότητα του κύκλου.

Μοναδικότητα

Εάν κάθε ακμή έχει μοναδικό βάρος, τότε θα υπάρχει ένα μον αδικό ελάχιστοζευγνύον δένδρο του γράφου.

Απόδειξη: Η παραπάνω ιδιότητα θα αποδειχθεί με επαγωγή. Έστω ότι έχουμε έναναλγόριθμο ο οποίος βρίσκει το ΕΖΔ, το οποίο ονομάζεται A, βασιζόμενος στη δομήτου γράφου και στην σειρά των ακμών , όταν αυτές ταξινομούνται σύμφωνα με τοβάρος. Υποθέτουμε προς στιγμή , ότι αυτό το ελάχιστο επικαλύπτων δένδρο δεν είναιμοναδικό και ότι υπάρχει ένα άλλο ζευγνύον δένδρο, B, με ίσο βάρος. Εάν υπάρχουνn κόμβοι στο γράφο, τότε κάθε δένδρο έχει n-1 ακμές. Υπάρχουν μερικές ακμ ές πουανήκουν στο B αλλά όχι στο A. Τι συμβαίνει εάν μειώσουμε το βάρος σε μία απόαυτές τις ακμές κατά ένα πολύ μικρό ποσό so έτσι ώστε να μην αλλάξουμε την ολικήσειρά των ακμών του γράφου όταν ταξινομούνται σύμφωνα με το βάρος τους; (Αυτόείναι πιθανό επειδή όλα τα βάρη διαχωρίζονται από θετικά ποσά.) Δεν θα αλλάξει τοαποτέλεσμα του αλγορίθμου μας, ο οποίος ακόμα δίνει το δένδρο A. Αλλά το δένδρο

Δίκτυα Αισθητήρων

13

B τώρα θα έχει βάρος ε λιγότερο απ’ ότι είχε πιο πριν, το οποίο σημαίνει ότι το A δενείναι ελάχιστο, ενάντια στην υπόθεση που είχαμε κάνει. Εξαιτίας αυτής τηςαντίφασης, καταλήγουμε πως η υπόθεση ότι υπάρχει ένα δεύτερο ΕΖΔ είναιλανθασμένη.

Ιδιότητα της τομής

Η ιδιότητα της τομής έχει να κάνει με τον προσδιορισμό των ακμών που πρέπει ναανήκουν σε ένα MST ενός γράφου. Δεδομένης οποιασδήποτε τομής σε ένα γράφο,κάθε ελάχιστη ακμή διασταυρώσεως ανήκει σε κάποιο ΕΖΔ του γράφου, και κάθεΕΖΔ περιέχει μία ελάχιστη ακμή διασταυρώσεως .

Απόδειξη: Θα προσπαθήσουμε να αποδείξουμε το αντίθετο. Αρχικά υποθέτουμε πωςη ακμή e είναι μία ελάχιστη ακμή διασταυρώσεως που δεν βρίσκεται σε κανένα ΕΖΔ,και το Τ είναι κάποιο ΕΖΔ, ή υποθέτουμε πως το Τ είναι ένα ΕΖΔ που δεν περιέχεικάποια ελάχιστη ακμή διασταυρώσεως. Σε οποιαδήποτε περίπτωση, το Τ είναι έναΕΖΔ που δεν περιέχει την ελάχιστη ακμή διασταυρώσεως e. Τώρα θεωρούμε τονγράφο που σχηματίζεται προσθέτοντας την ακμή e στο T. Αυτός ο γράφος έχει ένανκύκλο που περιέχει την e, και πως ο κύκλος αυτός πρέπει να περιέχει τουλάχιστον μίαάλλη ακμή διασταυρώσεως έστω f, η οποία έχει ίδιο ή μεγαλύτερο βάρος από την e(αφού η e είναι ελάχιστη). Μπορούμε να πάρουμε ένα ζευγνύον δένδρο ίσο ή μελιγότερο βάρος διαγράφοντας την f και προσθέτοντας την e, το οποίο έρχεται σεαντίθεση είτε με την ελαχιστοποίηση του Τ ή με την υπόθεση ότι το e δεν είναι στο T.

Εάν τα βάρη των ακμών είναι διακριτά, τότε υπάρχει ένα μοναδικό ΕΖΔ και ηιδιότητα της τομής λέει ότι η μικρότερη ακμή διασταυρώσεως κάθε τομής, πρέπει ναείναι στο ΕΖΔ. Όταν ίσα βάρη είναι παρόντα, μπορεί να έχουμε πολλαπλές ελάχιστ εςακμές διασταυρώσεως. Τουλάχιστον μία από αυτές θα είναι σε οποιοδήποτε ΕΖΔ καιοι άλλες μπορεί είτε να είναι παρούσες είτε να μην είναι εκεί..

Η παρακάτω εικόνα καταγράφει κάποια παραδείγματα της ιδιότητας της τομής.Σημειώστε πως δεν υπάρχει κάποιος περιορισμός ότι η ελάχιστη ακμή είναι η μόνηακμή του ΕΖΔ που ενώνει τα δύο σύνολα. Στην πραγματικότητα, για τυπικές τομέςυπάρχουν μερικές ακμές των ΕΖΔ που ενώνουν έναν κόμβο στο ένα σύνολο με ένανκόμβο στο άλλο σύνολο.

Δίκτυα Αισθητήρων

14

Εικόνα: Η ιδιότητα της τομήςΑυτά τα τέσσερα παραδείγματα επεξηγούν την ιδιότητα. Εάν χρωματίσουμε το ένα σύνολο μεγκρι χρώμα και το άλλο σύνολο με άσπρο, τότε η ακμή με το λιγότερο βάρος που ενώνει έναν

γκρι κόμβο με έναν άσπρο ανήκει στο ΕΖΔ.

Ιδιότητα του κύκλου

Η ιδιότητα του κύκλου έχει να κάνει με την αναγνώριση των ακμών που δενχρειάζεται να βρίσκονται στο ΕΖΔ ενός γράφου. Άρα εάν αγνοήσουμε τις ακμέςαυτές, καταλήγουμε σε ΕΖΔ. Δεδομένου ενός γράφου G, θεωρούμε τον γράφο G', οοποίος ορίζεται από την προσθήκη της ακμής e στον G. Η προσθήκη της e σε έναΕΖΔ του G και η διαγραφή μίας μέγιστης ακμής στον παράγοντα κύκλο δίνει έναΕΖΔ του G'.

Απόδειξη : Εάν η e είναι μεγαλύτερη από όλες τις άλλες ακμές του κύκλου, δενμπορεί να ανήκει στο ΕΖΔ του G', εξαιτίας της ιδιότητας της τομή ς: η αφαίρεση της eαπό οποιοδήποτε τέτοιο ΕΖΔ θα χώριζε το τελευταίο σε δύο κομμάτια, και η e δεν θαήταν η μικρότερη ακμή που θα ένωνε τις κορυφές σε κάθε ένα από τα δύο κομμάτια ,επειδή κάποια άλλη ακμή στον κύκλο θα το κάνει αυτό. Διαφορετικά, έστω το t είναι

Δίκτυα Αισθητήρων

15

μία μέγιστη ακμή στον κύκλο ο οποίος δημιουργήθηκε με την προσθήκη της e στοΕΖΔ του G. Η αφαίρεση του t θα χώριζε το αρχικό ΕΖΔ σε δύο κομμάτια και οιακμές του G που ενώνουν αυτά τα κομμάτια δεν είναι πιο μικρές α πό την ακμή t.Επομένως, η e είναι μία ελάχιστη ακμή στο G', η οποία ενώνει τις κορυφές σε αυτάτα δύο κομμάτια. Οι υπογράφοι , που προκλήθηκαν από τα δύο υποσύνολα τωνκόμβων, είναι πανομοιότυποι για το G και το G', άρα το ΕΖΔ για το G' αποτελείταιαπό την e και τα ΕΖΔ αυτών των δύο υποσ υνόλων. Πιο συγκεκριμένα , σημειώστεπως αν η e είναι η μέγιστη στον κύκλο, τότε έχουμε δείξει ότι υπάρχει ένα ΕΖΔ τουG'που δεν περιέχει την e (το ΕΖΔ του G).

Η παρακάτω εικόνα επεξηγεί την ιδιότητα του κύκλου. Παρατηρείστε πως ότανπαίρνουμε ένα ζευγνύον δένδρο, προσθέτουμε μία ακμή που δημιουργεί κύκλο, καιμετά διαγράφουμε μία μέγιστη ακμή σε αυτόν τον κύκλο, δίνει ένα ζευγνύον δένδρομε βάρος λιγότερο ή ίσο με το βάρος του αρχικού ζευγνύοντος δένδρου. Το βάροςτου νέου δένδρου θα είναι λιγότερο από το αρχικό, εάν και μόνο εάν η ακμή πουπροστέθηκε είναι φτηνότερη από κάποια ακμή στον κύκλο.

Δίκτυα Αισθητήρων

16

Εικόνα: Ιδιότητα του κύκλουΗ προσθήκη της ακμής 1-3 στον γράφο (δεύτερο από την κορυφή) ανατρέπει το ΕΖΔ τηςκορυφής. Για να βρούμε το ΕΖΔ του νέου γράφου, πρ οσθέτουμε τη νέα ακμή στο ΕΖΔ του

παλιού γράφου, η οποία δημιουργεί κύκλο (τρίτο από την κορυφή). Η διαγραφή τηςακριβότερης ακμής στον κύκλο (4-7) παράγει το ΕΖΔ του νέου γράφου (κάτω). Ένας τρόπος για

να επαληθεύσουμε ότι το ζευγνύον δένδρο είναι το ελάχ ιστο είναι να ελέγξουμε αν κάθε ακμήπου δεν ανήκει στο ΕΖΔ έχει το μέγιστο βάρος στον κύκλο που δημιουργείτε με τις ακμές του

δένδρου. Για παράδειγμα, στον κάτω γράφο, η ακμή 4-6 έχει το μεγαλύτερο βάρος στον κύκλο4-6-7-1-3-4.

Η ιδιότητα της τομής και η ιδιότητα του κύκλου αποτελούν την βάση για κάποιουςκλασσικούς αλγορίθμους , τους οποίους μελετάμε για το πρόβλημα του ΕΖΔ. Οιακμές μελετώνται μία την φορά, χρησιμοποιώντας την ιδιότητα της τομής για να τιςδεχτούμε σαν ακμές του ΕΖΔ ή την ιδιότητα του κύ κλου για να τις απορρίψουμε. Οιαλγόριθμοι διαφέρουν στις προσεγγίσεις τους στην αποδοτική αναγνώριση τωνκύκλων και των τομών. Στη συνέχεια ακολουθούν κάποιες επιπλέον ιδιότητες τωνελάχιστων ζευγνυόντων δένδρων.

Δυνατή Πολλαπλότητα

Μπορεί να υπάρχουν διάφορα ελάχιστα ζευγνύοντα δένδρα με το ίδιο βάρος , αυτόσυμβαίνει γιατί μπορεί να υπάρχουν διαφορετικές ακμές με το ίδιο βάρος.

Ελάχιστο Βάρος Υπογράφου

Εάν τα βάρη είναι μη αρνητικά, τότε το ελάχιστο ζευγνύον δένδρο είναι στηνπραγματικότητα ένας υπογράφος με το ελάχιστο συνολικό κόστος το οποίο συνδέειόλους τους κόμβους, αφού οι υπογράφοι οι οποίοι περιέχουν κύκλους απαραιτήτωςέχουν μεγαλύτερο συνολικό βάρος.

2.4 Ψευδοκώδικας

Στην πιο γενική περίπτωση ο ψευδοκώδικας των ΕΖΔ είναι ο παρακάτω

Function MST(G,W):1. T = {}2. Όσο το Τ δεν δημιουργεί ένα ζευγνύον δένδρο:3. Βρες μία ακμή στο Ε που είναι ασφαλής για το Τ4. T = T ένωση {(u,v)}5. Επέστρεψε το T,όπου το "ασφαλής" σημαίνει ότι δημιουργεί ένα MST.

2.5 Αλγόριθμοι

Το πρόβλημα του ελάχιστου ζευγνύοντος δένδρου είναι ένα από τα προβλήματαπου έχουν μελετηθεί πολύ. Οι αλγόριθμοι των ΕΖΔ έχουν μία μεγάλη και πλούσιαιστορία , η οποία αναπτύσσεται ακόμα και σήμερα. Βασικές προσεγγίσεις για την

Δίκτυα Αισθητήρων

17

λύση του προβλήματος ανακαλύφθηκα ν πολύ καιρό πριν την ανάπτυξη τωνμοντέρνων δομών δεδομένων και των νέων τεχνικών για την ανάλυση της απόδοσηςτων αλγορίθμων ∙ σε ένα καιρό όπου η εύρεση του ΕΖΔ ενός γράφου με χιλιάδεςακμές ήταν μία εκφοβιστική εργασία. Πραγματικά, αυτές οι μέθοδοι πε ριγράφηκανγια πρώτη φορά στη δεκαετία του 1920, προμηνύοντας την ανάπτυξη τωνυπολογιστών όπως τους ξέρουμε σήμερα. Μερικοί νέοι αλγόριθμοι διαφέρουν απότους παλιούς ειδικά στην χρήση και στην υλοποίηση τους, έτσι ώστε να μπορούν ναυπολογιστούν τα ελάχιστα ζευγνύοντα δένδρα με εκατομμύρια ή και δισεκατομμύριαακμές. Η επιλογή του αλγορίθμου και των δομών δεδομένων έχει ουσιώδη επιρροήστην απόδοση και για αυτό το λόγο, στα πρόσφατα χρόνια , η έρευνα πάνω στοπρόβλημα του ΕΖΔ έχει συγκεντρωθεί σε τέτοι α θέματα υλοποίησης.

Ο πρώτος αλγόριθμος για την εύρεση του ΕΖΔ αναπτύχτηκε από τον Τσέχοεπιστήμονα Otakar Borůvka το 1926. Ο σκοπός του ήταν μία επαρκής ηλεκτρικήκάλυψη της περιοχής της Μοράβια. Σήμερα υπάρχουν δύο πιο δημοφιλείςαλγόριθμοι, ο αλγόριθμος του Prim και ο αλγόριθμος του Kruskal. Και οι τρεις είναιάπληστοι αλγόριθμοι οι οποίοι τρέχουν σε πολυωνυμικό χρόνο, έτσι το πρόβληματης εύρεσης τέτοιων δένδρων είναι σε FP, και σχετιζόμενα προβλήματα απόφασης ,όπως το να ορίσουμε αν μια ακμή ανήκει στο ΕΖΔ ή να ορίσουμε εάν το συνολικόελάχιστο βάρος υπερβαίνει μία συγκεκριμένη τιμή, είναι σε P. Ένας άλλος άπληστοςαλγόριθμος ,που δεν χρησιμοποιείται τόσο συχνά, είναι ο reverse-delete αλγόριθμος,ο οποίος είναι το αντίθετο του αλγορίθμου του Kruskal. Οι παραπάνω αλγόριθμοιείναι κλασσικοί αλγόριθμοι και προϋποθέτουν μερικές αφαιρετικές λειτουργί εςυψηλού επιπέδου, όπως οι ακόλουθες:

o Βρες την ελάχιστη ακμή που ενώνει δύο υποδένδρα.o Όρισε εάν η προσθήκη της ακμής δημιουργεί κύκλο.o Διέγραψε τη μεγαλύτερη ακμή στον κύκλο.

Πρόκληση πλέον αποτελεί η ανάπτυξη αλγορίθμων και δομών δεδομένων που ναυλοποιούν αυτές τις λειτουργίες αποδοτικά.

Πολλοί κλασσικοί αλγόριθμοι έχουν αναπτυχθεί για το πρόβλημα του ΕΖΔ, οιοποίοι δίνουν μία πιο γενική προσέγγιση , αλλά οι νέοι αλγόριθμοι και οι δομέςδεδομένων μπορούν να μας δώσουν συμπαγείς και αποτελεσματικές υ λοποιήσεις.Υπάρχουν διάφοροι καλύτεροι αλγόριθμοι, ανάλογα με τις υποθέσεις που γίνονται.Ποιος είναι όμως ο γρηγορότερος δυνατός αλγόριθμος για αυτό το πρόβλημα; Αυτόαποτελεί και ένα από τα πιο παλιά ανοιχτά ερωτήματα στην επιστήμη τωνυπολογιστών. Υπάρχει ένα γραμμικό κατώτατο όριο, αφού πρέπει οπωσδήποτε ναελέγξουμε όλα τα βάρη. Εάν τα βάρη των ακμών είναι ακέραιοι με συγκεκριμένα bitμάκρους, τότε οι ντετερμινιστικοί αλγόριθμοι είναι γνωστοί με γραμμικό χρόνοεκτέλεσης.

Για γενικευμένα βάρη , υπάρχο υν randomized αλγόριθμοι, των οποίων ο χρόνοςείναι γραμμικός, για παράδειγμα ο αλγόριθμος των Karger, Klein και Tarjan. (Karger,Klein, and Tarjan, "A randomized linear -time algorithm to find minimum spanningtrees", J. ACM, vol. 42, 1995, pp. 321 -328). Εάν τα βάρη είναι μικροί ακέραιοι τοπρόβλημα του ΕΖΔ μπορεί να λυθεί σε γραμμικό χρόνο χειρότερης περίπτωσης μετον αλγόριθμο των Fredman και Willard. (Fredman and Willard, "Trans -dichotomousalgorithms for minimum spanning trees and shortest paths", 31st IEEE Symp.

Δίκτυα Αισθητήρων

18

Foundations of Comp. Sci., 1990, pp. 719—725). Διαφορετικά, η καλύτερη λύσηείναι πολύ κοντά στον γραμμικό χρόνο, αλλά όχι ακριβώς γραμμικό και διατυπώθηκεαπό τους Gabow, Galil, Spencer, και Tarjan. Το ακριβές όριο είναι O(m logbeta(m,n)), όπου η συνάρτηση beta έχει τον εξής πολύπλοκο ορισμό: το μικρότερο iτέτοιο ώστε το log(log(log(...log (n)...))) να είναι λιγότερο από το m/n, όπου τα logsείναι φωλιασμένα i φορές. (Gabow, Galil, Spencer, and Tarjan, Efficient algorithmsfor finding minimum spanning trees in undirected and directed graphs.Combinatorica, vol. 6, 1986, pp. 109—122). Αυτοί οι αλγόριθμοι είναι αρκετάπολύπλοκοι, και πιθανώς δεν έχουν μεγάλη πρακτική εφαρμογή εκτός και αν έχουμεμεγάλους γράφους.

Κατά πόσο υπάρχει ένας ντετερμι νιστικός αλγόριθμος με γραμμικό χρόνοεκτέλεσης για πιο γενικευμένα βάρη είναι ένα ανοιχτό ερώτημα. Παρ’ όλα αυτά, οιSeth Pettie και Vijaya Ramachandran έχουν βρει έναν οπτιμιστικό ντετερμινιστικόαλγόριθμο για την εύρεση του ΕΖΔ, του οποίου η χρονική πολ υπλοκότητα είναιάγνωστη.

Ένας άλλος γρήγορος αλγόριθμος για την εύρεση του ΕΖΔ αναπτύχθηκε από τονBernard Chazelle, ο οποίος βασίζεται στο Soft Heap, μία προσεγγιστική ουράπροτεραιότητας. Ο χρόνος εκτέλεσης του είναι O(Εα(Ε,V)), όπου E είναι ο αριθμόςτων ακμών, V είναι ο αριθμός των κόμβων και α είναι η αντίστροφη συνάρτηση τηςσυνάρτησης Ackermann. Η συνάρτηση α μεγαλώνει πάρα πολύ αργά, επομένως γιαπρακτικούς λόγους μπορεί να θεωρηθεί σαν σταθερά, όχι μεγαλύτερη από το 4. Άρα,ο αλγόριθμος του Chazelle θέλει σχεδόν γραμμικό χρόνο.

Άλλοι ειδικευμένοι αλγόριθμοι έχουν σχεδιαστεί για να υπολογίζουν τα MST ενόςγράφου τόσο μεγάλου έτσι ώστε νε χρειάζεται να αποθηκεύεται στο δ ίσκο τηνπερισσότερη ώρα. Αυτοί οι αλγόριθμοι εξωτερικής αποθήκευσης, για παράδειγμαόπως περιγράφεται στο "Engineering an External Memory Minimum Spanning TreeAlgorithm" του Roman Dementiev et al., μπορούν να λειτουργήσουν 2 με 5 φορές πιοαργά από έναν αλγόριθμο εσωτερικής μνήμης. Υποστηρίζουν ότι μαζικά προβλήματαΕΖΔ που γεμίζουν μερικούς δίσκους μπορούν να λυθούν μέσα σε μια νύχτα στο PC."Βασίζονται σε επαρκείς αλγορίθμους ταξινόμησης εξωτερικής αποθήκευσης και σετεχνικές συμπίεσης των γράφων για να μειώσουν το μέγεθος τους επαρκώς.

Πιο πρόσφατα, η έρευνα έχει εστιαστεί στο να λύσει το πρόβλημα του ελάχιστουζευγνύοντος δένδρου με υψηλά παραλληλισμένο τρόπο. Με ένα γραμμικό αριθμόαπό επεξεργαστές είναι πιθανό να λυθεί το πρόβλημα σε χρόνο O(logn). Έναακαδημαϊκό άρθρο του 2003 " Fast Shared-Memory Algorithms for Computing theMinimum Spanning Forest of Sparse Graphs" από τους David A. Bader και GuojingCong, επιδεικνύει έναν πραγματιστικό αλγόριθμο, ο οποίος μπορεί να υπολογίσει ταΕΖΔ πέντε φορές πιο γρήγορα με 8 επεξεργαστές απ’ ότι ένας ακολουθιακόςαλγόριθμος βελτιστοποίησης. Τυπικά, οι παράλληλοι αλγόριθμοι βασίζονται στοναλγόριθμο του Boruvka- ο αλγόριθμος του Prim και ειδικά του Kruskal δενθεωρούνται κατάλληλοι για την παράλληλη επεξεργασία.

Μέχρι στιγμής, για την ανάλυση και τη σχεδίαση αλγορίθμων παραμένει άλυτοθέμα το εξής: οι αλγόριθμοι ΕΖΔ με γραμμική πολυπλοκότητα . Η ανάπτυξη ενόςαλγορίθμου που να προσφέρει με βεβαιότητα γραμμικό χρόνο εκτέλεσης για αραιούςγράφους αποτελεί ακόμα έναν στόχο της έρευνας. Πέρα από την αναζήτηση του

Δίκτυα Αισθητήρων

19

καλύτερου αλγορίθμου για αυτό το βασικό πρόβλημα, η μελέτη των αλγορίθμων τωνελάχιστων επικαλυπτόντων δένδρων υπογραμμίζει το πόσο σημαντικό είναι νακατανοήσουμε τα βασικά χαρακτηριστικά της απόδοσης των βα σικών αλγορίθμων.

2.6 Εφαρμογές

Τα ελάχιστα ζευγνύοντα δένδρα χρησιμοποιούνται από την σημερινή κοινωνία σεπολύ μεγάλο βαθμό. Μία από τις πιο συχνές εφαρμογές τους αποτελούν τα δίκτυα.Κύριο θέμα της μελέτης αυτής αποτελούν τα δίκτυα αισθητήρων, στα ο ποία καιβρίσκουν εφαρμογή τα ελάχιστα ζευγνύοντα δένδρα, μειώνοντας την κατανάλωσηενέργειας των αισθητήρων.

Χαρακτηριστικό παράδειγμα για τη χρήση των ελάχιστων επικαλυπτόντωνδένδρων είναι η σχεδίαση ενός τηλεφωνικού δικτύου. Οι κόμβοι του γράφουαναπαριστούν τις πόλεις και οι ακμές τις πιθανές διασυνδέσεις μεταξύ των πόλεων.Το κόστος το οποίο σχετίζεται με κάθε ακμή, μπορεί να αναπαριστά το κόστοςεπιλογής της συγκεκριμένης σύνδεσης για το δίκτυο. Το ελάχιστο ζευγνύον δένδροαναπαριστά το δίκτυο επικοινωνίας το οποίο ενώνει όλες τις πόλεις με το ελάχιστοκόστος. Αν και το ΕΖΔ δεν ασχολείται με την απόσταση από τον ένα κόμβο στονάλλο, μπορεί να χρησιμοποιηθεί για να οριστούν τα μονοπάτια με το λιγότερο κόστοςχωρίς κύκλους στο δίκτυο, και ενώνοντας κά θε κόμβο.

Μία άλλη πρακτική εφαρμογή των ΕΖΔ είναι η εγκατάσταση καλωδιακήςτηλεόρασης σε κάποια περιοχή. Εάν τα καλώδια πρέπει να τοποθετηθούν σεσυγκεκριμένα μονοπάτια, τότε υπάρχει ένας γράφος, ο οποίος αναπαριστά ποιασημεία (κόμβοι) ενώνονται από τα μονοπάτια (ακμές). Μερικά από αυτά ταμονοπάτια μπορεί να είναι πιο ακριβά, επειδή είναι πιο μακριά, ή απαιτούν τοκαλώδιο να θαφτεί πιο βαθιά , και μπορούν να αναπαρασταθούν από ακμές μεμεγαλύτερα βάρη. Ένα ελάχιστο ζευγνύον δένδρο για αυτό τον γράφο θα είναι έναυποσύνολο αυτών των μονοπατιών που δεν έχει κύκλους, αλλά θα ενώνεται με κάθεσημείο και θα έχει το λιγότερο κόστος.

Τα ελάχιστα ζευγνύοντα δένδρα χρησιμοποιούνται επιπλέον για την εύρεση τωναεροπορικών γραμμών. Οι κόμβοι του γράφου αναπαριστού ν τις πόλεις, και οι ακμέςτις διαδρομές μεταξύ των πόλεων. Προφανώς όσο πιο μακριά είναι το ταξίδι, τόσοπιο πολύ θα κοστίσει, έτσι το ΕΖΔ μπορεί να χρησιμοποιηθεί για την βελτιστοποίησητων αεροπορικών γραμμών, βρίσκοντας τα λιγότερο ακριβά μονοπάτια χωρ ίςκύκλους.

Εικόνα: Τα σημεία στον γράφο αναπαριστούν τις πόλεις και οι γραμμές τις αποστάσεις μεταξύτων πόλεων. Δεδομένου ενός τέτοιου γράφου, μπορείτε να απαντήσετε σε πολλές ερωτήσεις

Δίκτυα Αισθητήρων

20

όπως «Ποια είναι η πιο κοντινή απόσταση μεταξύ του LAX και του JFK?» ή «Ποια είναι ησυντομότερη διαδρομή που επισκέπτεται όλες τις πόλεις;».

Μία εφαρμογή του ΕΖΔ η οποία δεν είναι και τόσο εμφανής είναι ότι μπορεί ναχρησιμοποιηθεί, για να λύσει προσεγγιστικά το πρόβλημα του περιοδεύον πωλητή.Ένας βολικός και τυπικός τρόπος για να οριστεί το πρόβλημα είναι να βρεθεί τοσυντομότερο μονοπάτι που επισκέπτεται κάθε κόμβο τουλάχιστον μία φορά.Σημειώστε ότι αν έχετε ένα μονοπάτι που επισκέπτεται όλους τους κόμβους ακριβώςμία φορά, είναι ένα ειδικό είδος δένδρου. Εάν υπ άρχει ένα μονοπάτι που επισκέπτεταικάποιες κορυφές περισσότερο από μία φορά, μπορούμε να αφήσουμε κάποιες ακμέςγια να έχουμε δένδρο. Έτσι γενικά το βάρος του ΕΖΔ είναι μικρότερο από το βάροςτου TSP , εξαιτίας της ελαχιστοποίησης ενός μεγάλου συνόλου.

Τα ηλεκτρικά κυκλώματα είναι ακόμα ένα ολοφάνερο παράδειγμα των ελάχιστωνζευγνυόντων δένδρων. Ένα ηλεκτρικό κύκλωμα μπορούμε να το δούμε σαν γράφοόπως φαίνεται στην παρακάτω εικόνα, όπου οι αντιστάσεις, οι πυκνωτές , γενικά τασυστατικά του κυκλώματος αν απαρίστανται από ακμές, και οι κόμβοι δείχνουν τασημεία στα οποία συνδέονται τα συστατικά (καλώδια). Δεδομένου ενός τέτοιουγράφου μπορούμε να απαντήσουμε ερωτήματα όπως «Ποιές είναι οι εξισώσειςβρόγχων που περιγράφουν την συμπεριφορά του κυκλώματος;», « Συνδέονται όλα τασυστατικά μεταξύ τους;» ή και πιο πολύπλοκες ερωτήσεις όπως «Εάν δημιουργηθείτο κύκλωμα, θα λειτουργήσει;».

Εικόνα: Ηλεκτρικό κύκλωμα και ο γράφος που το αναπαριστά

Ένας άλλος τρόπος αναπαράστασης του κυκλώματος είναι ο εξής: τα συσ τατικάτου κυκλώματος(αντιστάσεις κ.τ.λ.) αναπαρίστανται από τους κόμβους και τακαλώδια από τις ακμές, ενώ τα βάρη των ακμών μπορούν να είναι τα μήκη τωνακμών, ή το κόστος τους ή ο χρόνος που χρειάζεται για να μεταδοθεί το σήμα μέσααπό τις ακμές/καλώδια.

Ένα ακόμα παράδειγμα των ΕΖΔ είναι ο προγραμματισμός εργασιών ή “ jobscheduling,” όπου οι κόμβοι είναι οι εργασίες που πρέπει να εκτελεσθούν, οι ακμέςδείχνουν ποιες εργασίες πρέπει να γίνουν πριν από άλλες , ενώ τα βάρη αναπαριστούντον χρόνο ή το κόστος της εκτέλεσης αυτών των εργασιών.

2.7 Παρόμοια Προβλήματα

Ο related graph είναι ένα κ-ελάχιστο ζευγνύον δένδρο (k-MST), το οποίο είναι έναδένδρο που ενώνει κάποιο υποσύνολο των κ κόμβων στο γράφο με το ελάχιστοβάρος. Το σύνολο των κ- ελαχίστων ζευγνυόντων δένδρων είναι ένα υποσύνολο τωνκ ζευγνυόντων δένδρων (από όλα τα πιθανά ζευγνύοντα δένδρα) έτσι ώστε κανέναάλλο ζευγνύον δένδρο εκτός του υποσυνόλου να έχει μικρότερο βάρος (Σημειώστε

Δίκτυα Αισθητήρων

21

ότι αυτό το πρόβλημα δεν έχει σχέση με το κ -ελάχιστο ζευγνύον δένδρο.) . ΤοΕυκλείδειων ελάχιστο ζευγνύον δένδρο ( Euclidean minimum spanning tree) είναιένα ζευγνύον δένδρο του γράφ ου με βάρη ακμών που αντιπροσωπεύουν τηνΕυκλείδεια απόσταση μεταξύ των κόμβων. Για κατευθυνόμενους γράφους, τοπρόβλημα του ελάχιστου ζευγνύοντος δένδρου μπορεί να λυθεί σε κυβικό χρόνοχρησιμοποιώντας τον Αλγόριθμο Chu–Liu/Edmonds.

Δίκτυα Αισθητήρων

22

3. Ο ΑΛΓΟΡΙΘΜΟΣ ΤΟΥ KRUSKAL

3.1 Γενικά

Ο αλγόριθμος του Kruskal είναι ένας απλός αλγόριθμος στη θεωρεία γράφων, οοποίος χρησιμοποιείται για την εύρεση ελάχιστων ζευγνυόντων δένδρων ή για τηνεύρεση ελάχιστων γεννητορικών δένδρων σε ένα γράφο με βάρη. Αυτό σημαίνει πωςβρίσκει ένα υποσύνολο των ακμών του γράφου, έτσι ώστε να δημιουργήσει έναδένδρο το οποίο περιέχει κάθε κόμβο, και το συνολικό βάρος όλων των ακμών τουδένδρου ελαχιστοποιείται. Εάν ο γράφος δεν είναι συνδεδεμένος τότε βρίσκει τοελάχιστο ζευγνύον δάσος (ένα ελάχιστο ζευγνύον δένδρο για κάθε συ νιστώσα τουγράφου). Ο αλγόριθμος αυτός πρωτοεμφανίστηκε στο Proceedings of the AmericanMathematical Society, pp. 48–50 το 1956, και γράφτηκε από τον Joseph Kruskal.

Η βασική ιδέα του αλγορίθμου είναι ότι «χτίζει» το ΕΖΔ σταδιακά, εξετάζονταςμία προς μία τις ακμές του γράφου κατά αύξουσα τιμή βάρους. Πιο συγκεκριμένα σεκάθε βήμα επιλέγεται η ακμή με το μικρότερο κόστος και της οποίας η προσθήκηστις ήδη επιλεγμένες ακμές δεν δημ ιουργεί κύκλο. Ο αλγόριθμος του Kruskalαποτελεί ένα χαρακτηριστικό παράδειγμα άπληστου αλγορίθμου.

3.2 Λίγα Λόγια για τον Joseph Kruskal…

Ο Joseph Bernard Kruskal Jr, γεννημένος στις 29Ιανουαρίου του 1928 στη Νέα Υόρκη είναι έναςδιακεκριμένος μαθηματικός και στατιστικολόγος. Υπήρξεφοιτητής στο Πανεπιστήμιο του Σικάγο και στο PrincetonUniversity όπου και ολοκλήρωσε το Ph.D του 1954. Είναιμέλος της American Statistical Association, δημιουργόςκαι πρόεδρος της Psychometric Society και τηςClassification Society of North America.

Στη επιστήμη των υπολογιστών, η πιο γνωστή τουπροσφορά υπήρξε ο αλγόριθμος του Kruskal για τον υπολογισμό του ελάχιστουζευγνύοντος δένδρου ενός ζυγισμένου γράφου. Εντύπωση προκαλεί πως οαλγόριθμος αυτός ανακαλύφθηκε από τον Joseph Kruskal όταν ήταν μόλιςδευτεροετής μεταπτυχιακός φοιτητής.

Δίκτυα Αισθητήρων

23

3.3 Ο Αλγόριθμος

Μπορούν να βρεθούν εκατοντάδες υλοποιήσεις του αλγορίθμου του Kruskal, λόγωτης ευρείας αποδοχής του και της απλότητας του στην κατανόηση. Μία σύντομηεκδοχή του αλγορίθμου παρατίθεται παρακάτω.

Αλγόριθμος (σύντομη εκδοχή)

1. Το Τ είναι άδειο //Τ: ελάχιστο ζευγνύον δένδρο2. Ταξινόμησε τις ακμές του γράφου G3. Για κάθε ακμή του αρχικού γράφου G κάνε {

a. Αν η εισαγωγή της ακμής e στο Τ δεν προκαλεί κύκλο τότεπροσθέτουμε την e στο Τ, δηλαδή Τ:=Τ˅{e}.

4. Επέστρεψε το Τ

Η ταξινόμηση των ακμών είναι απλή , και ο αλγόριθμος ταξινόμησης ο οποίος θαχρησιμοποιηθεί είναι απόφαση του προγραμματιστή. Επιπλέον μπορεί ναχρησιμοποιηθεί μία ουρά προτεραιότητας. Το βασικό πρόβλημα το οποίο προκ ύπτειαπό τον αλγόριθμο του Kruskal είναι πώς θα βρεθεί αποδοτικά εάν μία ακμή μπορείνα δημιουργήσει κύκλο.

Εικόνα: Ο αλγόριθμος του KruskalΗ εικόνα δείχνει το 1/4, το 1/2, τα 3/4, και ολόκληρο το ΕΖΔ όπως εξελίσσεται.

Δίκτυα Αισθητήρων

24

Μία λύση για το παραπάνω πρόβλημ α είναι η εξής: Κατά την εκκίνηση του, οαλγόριθμος δημιουργεί ένα δάσος από | V| δένδρα, όπου |V| είναι το πλήθος τωνκόμβων του γράφου. Κάθε δένδρο αποτελείται από έναν κόμβο και μόνο. Στησυνέχεια οι ακμές του γράφου ταξινομούνται, για να εξεταστούν σε αύξουσα σειράβάρους. Σε κάθε βήμα του αλγορίθμου δύο διαφορετικά δένδρα του δάσουςενώνονται σε ένα μεγαλύτερο δένδρο. Επομένως όσο εκτελείται ο αλγόριθμοςέχουμε λιγότερα και μεγαλύτερα δένδρα στο δάσος, μέχρι να καταλήξουμε σε έναδένδρο το οποίο και αποτελεί το ελάχιστο ζευγνύον δένδρο (εικόνα επάνω). Σε κάθεβήμα διαλέγουμε την ακμή με το λιγότερο βάρος, το οποίο και σημαίνει ότιακολουθούμε άπληστη πολιτική. Εάν η επιλεγμένη ακμή ενώνει δύο κόμβους πουανήκουν στο ίδιο δένδρο, η ακμή απορρίπτεται και δεν την εξετάζουμε ξανά, επειδήπαράγει κύκλο και θα καταστρέψει το ΕΖΔ. Από την άλλη, εάν η ακμή ενώνει δύοκόμβους οι οποίοι βρίσκονται σε διαφορετικά δένδρα, τότε δεν προκαλεί κύκλο καιως εκ τούτου θα προστεθεί στο ΕΖΔ.

Παρακάτω παρατίθεται μία πιο αν αλυτική εκδοχή του αλγορίθμου του Kruskal.

Αλγόριθμος (αναλυτική εκδοχή)

Kruskal (graph G(V,E){

1. Tree={}; //Το ΕΓΔ: Ένα σύνολο ακμών (αρχικά είναι άδειο)2. TID[|V|]={}; //Πίνακας που κρατά το TreeID του κάθε κόμβου3. Count=0; //Μετρητής που κρατά πόσες κορυφές πέρασα4. sortEdges(E); //Ταξινόμηση ακμών σε χρόνο O(|E|log|E|)//Δημιουργούμε ένα δάσος από δένδρα μεγέθους 15. For(i=0;i<|V|;i++){6. TID[i]=i; //Χρόνο Θ(|V|)

}8. For(i=0;i<|E|;i++) //Χρόνος Ο(|Ε|){

//ανάκτηση επόμενης (μικρότερης ακμής)9. (u,v)=nextEdge(); //χρόνος Θ(1)10. If(TID[u]!=TID[v]){ //Αν ανήκουν σε διαφορετικά δένδρα

11. Tree=Tree˅{(u,v)} //Προσθήκη ακμής//Μετρούμε ποιος από τους u ,v εμφανίζεται περισσότερο στο//TID και επιστρέφουμε το μεγαλύτερ ο σαν TreeID x12. X=occurrence(TID,u,v); // Χρόνος Ο(|V|)//Ανάθεση TreeID x σε όλους που έχουν TID[u] ή TID[v]13. Merge(TID[u],TID[v]);14. Count ++;

}15. If(count==|V|) break;

}}

Εδώ χρησιμοποιείται ένας πίνακας TID[n](TreeID) ο οποίος μας υποδεικνύει γιακάθε κορυφή ν σε ποιο δένδρο ανήκει. Παραδείγματος χάριν εάν θέλω να προσθέσω

Δίκτυα Αισθητήρων

25

μία ακμή (u,v) ,και η u και η v ανήκουν στο ίδιο δένδρο (TID[u]=TID[v]), τότε αυτήη ακμή θα δημιουργήσει κύκλο. Επομένως δεν θα προσθέσω την ακμή ( u,v) στοδένδρο. Η συγκεκριμένη υλοποίηση του αλγορίθμου μπορεί να δεχθεί σαν είσοδοέναν μη συνδεδεμένο γράφο. Το αποτέλεσμα θα είναι ένα δάσος από ελάχισταζευγνύοντα δένδρα, ένα για κάθε συνιστώσα του γράφου.

Ένα παράδειγμα του αλγορίθμου του Kruskal φαίνεται στην παρακάτω εικόνα

Εικόνα: Ο αλγόριθμος του KruskalΗ εικόνα δείχνει βήμα πρόβλημα ένα παράδειγμα της λειτουργίας του αλγορίθμου του Kruskal.

Δεδομένης μίας λίστας από ακμές ενός γράφου σε τυχαία σειρά, (αριστερή λίστα ακμών), τοπρώτο βήμα του αλγορίθμου του Kruskal είναι να ταξινομήσει τις ακμές κατά βάρος (δεξιά

λίστα ακμών). Έπειτα, εξετάζονται οι ακμές στη λίστα ε τη σειρά των βαρών τους,προσθέτοντας ακμές που δεν δημιουργούν κύκλο στο ΕΖΔ. Η ακμή 5-3 προστίθεται (η

φτηνότερη ακμή), μετά η 7-1, μετά η 7-6 (αριστερά),έπειτα η 0-2 (δεξιά, πάνω) και η 0-7(δεξιά , δεύτερη από την κορυφή). Η ακμή με το αμέσως μεγαλύτερο βάρος, η 0-1, δημιουργεί

Δίκτυα Αισθητήρων

26

κύκλο και δεν εμπεριέχεται. Οι ακμές οι οποίες και δεν προστίθενται στο ΕΖΔ χρωματίζονταιμε γκρι χρώμα στην ταξινομημένη λίστα. Μετά προσθέτουμε την 4-3 (δεξιά, τρίτη από πάνω).Στη συνέχεια, απορρίπτουμε την 5-4, επειδή σχηματίζει κύκλο , και ύστερα προστίθεται η 7 -4

(δεξιά, κάτω). Μόλις το ΕΖΔ είναι έτοιμο, οποιεσδήποτε κορυφές με μεγαλύτερα βάρη θαπροκαλέσουν κύκλους και απορρίπτονται (ο αλγόριθμος σταματάει όταν έχουν προστεθεί V – 1

ακμές στο ΕΖΔ). Αυτές οι ακμές σημειώνονται με αστερίσκο στην ταξινομημένη λίστα .

3.4 Απόδειξη της ορθότητας

Η απόδειξη , ότι ο αλγόριθμος του Kruskal δημιουργεί ένα ελάχιστο ζευγνύονδένδρο, αποτελείται από δύο μέρη. Πρώτα αποδεικνύεται ότι ο αλγόριθμος παράγειένα ζευγνύον δένδρο και έπειτα ότι το κατασκευασμένο ζευγνύον δένδρο είναι αυτόμε το ελάχιστο βάρος.

Ζευγνύον Δένδρο

Έστω ο P είναι ένας συνδεδεμένος γράφος με βάρη, και το Y είναι έναςυπογράφος του P, ο οποίος παρήχθη από τον αλγόριθμο. Το Y δεν γίνεται να έχεικύκλο, αφού η τελευταία ακμή που προστέθηκε σε αυτό τον κύκλο θα ήταν σε έναυπό-δένδρο και όχι ανάμεσα σε δύο διαφορετικά δένδρα. Το Y δεν γίνεται να μηνείναι συνδεδεμένο, αφού η πρώτη ακμή που συνδέει δύο συστατικά του Υ θα είχεπροστεθεί από τον αλγόριθμο. Επομένως το Υ είναι ζευγνύον δένδρο του Ρ.

Ελάχιστο Ζευγνύον Δένδρο

Για να αποδείξουμε το γεγονός, πως ο αλγόριθμος του Kruskal βρίσκει τοελάχιστο ζευγνύον δένδρο θα χρησιμοποιήσουμε την μέθοδο της «εις άτοποαπαγωγή». Υποθέτουμε ότι το Υ δεν είναι το ΕΖΔ και ανάμεσα σε όλα τα ζευγνύονταδένδρα με ελάχιστα βάρη διαλέγουμε το Y1 , το οποίο έχει το μικρότερο πλήθοςακμών που δεν ανήκουν στο Υ. Θεωρούμε την ακμή e η οποία ήταν η πρώτη ακμήπου προστέθηκε από τον αλγόριθμο στο Υ , και δεν ανήκει στο Y1.

Ο γράφος έχει κύκλο. Αφού το Υ είναι ένα δένδρο, δεν μπορεί να περιέχειόλες τις ακμές αυτού του κύκλου. Επομένως η ακμή f , η οποία αποτελεί μέρος τουκύκλου, δεν ανήκει στο Y. Ο γράφος είναι επίσης ένα ζευγνύονδένδρο, ως εκ τούτου τα βάρη του δεν μπορεί να είναι λιγότερα από το Y1 καιεπομένως το βάρος της e δεν μπορεί να είναι λιγότερο από το βάρος της f.

Χρησιμοποιώντας και πάλι την μ έθοδο της «εις άτοπο απαγωγή» θα αποδείξουμεότι το βάρος της f δεν μπορεί να είναι λιγότερο από το βάρος της e. Υποθέτουμε τοαντίθετο και λαμβάνουμε υπόψη πως όλες οι ακμές θα προστεθούν στο Υ κατάαύξουσα σειρά βάρους. Επομένως ο αλγόριθμος θα είχε προσ θέσει την f στο μεγάλοβρόγχο πριν την e, πχ θα ελεγχόταν για προσθήκη στο υπό -δάσος (η eείναι η πρώτη ακμή του Y που δεν είναι στο Y1). Αλλά η f δεν δημιουργεί κύκλο στοY1, άρα δεν μπορεί να δημιουργήσει κύκλο στο Y3, και θα είχε προστεθεί στο δένδρο.

Το παραπάνω υποδηλώνει ότι τα βάρη e και f είναι ίσα, και επομένως το Y2 είναιεπίσης ένα ελάχιστο ζευγνύον δένδρο. Αλλά το Y2 έχει μία παραπάνω ακμή από

Δίκτυα Αισθητήρων

27

κοινού με τοY απ’ ότι με το Y1, το οποίο αντικρούει την επιλογή του Y1.Το ζητούμενοαποδείχθηκε.

3.5 Απόδοση

Η απόδοση του αλγορίθμου του Kruskal εξαρτάται από τις δομές δεδομένων πουχρησιμοποιούνται, αλλά και από τον αλγόριθμο ταξινόμησης.

Στη γενική περίπτωση ο αλγόριθμος κατασκευάζει ένα ΕΖΔ εντός χρόνουO(ElogE), όπου το Ε είναι το πλήθος των ακμώ ν του γράφου. Η ιδιότητα αυτή είναισυνέπεια της γενικότερης παρατήρησης ότι ο χρόνος εκτέλεσης του αλγορίθμου τουKruskal εξαρτάται από το κόστος ταξινόμησης των Ε ακμών συν το κόστος των Εαναζητήσεων και V-1 ενώσεων. Οι λειτουργίες της αναζήτησης και τη ς ένωσηςθεωρούνται «βαριές» λειτουργίες. Μία ουρά προτεραιότητας μπορεί ναχρησιμοποιηθεί για την ταξινόμηση των ακμών και θεωρείται σαν τηνκαταλληλότερη λύση. Επομένως, η εισαγωγή μίας ακμής στην ουρά χρειάζεταιΟ(logΕ) χρόνο. Η διαδικασία αυτή θα εκτελ εστεί Ε φορές και ως εκ τούτου ηδημιουργία της ουράς προτεραιότητας και άρα και η ταξινόμηση των ακμών έχεικόστος Ο(ΕlogΕ). Η εξαγωγή της πιο «φτηνής» ακμής από την ουρά έχει κόστοςΟ(logΕ). Επομένως ο αλγόριθμος του Kruskal χρειάζεται Ο(ΕlogE) χρόνο για ναεκτελεστεί.

Αξίζει να σημειωθεί πως η πολυπλοκότητα αυτή μπορεί να βελτιωθεί. Εάνχρησιμοποιηθεί ταξινόμηση βάσεως ( radix sort), ο χρόνος διατάξεων των ακμώνγίνεται γραμμικός. Με συνέπεια, κυρίαρχες πράξεις να είναι πλέον αυτές τηςδιαχειρίσεως συνόλων. Οπότε ο χρόνος εκτέλεσης του αλγορίθμου βελτιώνεται σεO(Elog*E).

Από την άλλη, αν χρησιμοποιηθεί μία δομή ουρά προτεραιότητας με γραμμικόχρόνο κατασκευής, τότε το στάδιο ταξινομήσεως των ακμών παραλείπεται. Και έτσιη διαδικασία απαιτεί χρόνο Ο(Ε) γ ια την προεπεξεργασία των ακμών, Ε πράξειςευρέσεως ελάχιστης ακμής, Ε πράξεις ευρέσεως συνόλου και V-1 πράξεις ενώσεωςσυνόλου, όπου Ε το πλήθος των ακμών με βάρος μικρότερο από το μέγιστο βάροςακμής στο τελικό ΕΖΔ. Ήτοι συνολικά χρόνο Ο( E+ElogV).

Δίκτυα Αισθητήρων

28

4. Ο ΑΛΓΟΡΙΘΜΟΣ ΤΟΥ PRIM

4.1 Γενικά

Ο αλγόριθμος του Prim είναι ίσως ο απλούστερος αλγόριθμος για την εύρεση ενόςελάχιστου ζευγνύοντος δένδρου σε έναν συνδεδεμένο γράφο με βάρη. Ο αλγόριθμοςαυτός πρωτοειπώθηκε από τον μαθηματικό Vojtěch Jarník το 1930. Το 1957 ομαθηματικός και πληροφορικός Robert C. Prim διατύπωσε εκ νέου τον αλγόριθμο, οοποίος και ξαναανακαλύφθηκε το 1959 από τον Edsger Dijkstra. Για τον λόγο αυτό, οαλγόριθμος του Prim ονομάζεται και DJP αλγόριθμος ή ο αλγόριθμος του Jarník ή οαλγόριθμος των Prim-Jarník. Ο Prim δημοσίευσε τον αλγόριθμο του στο « R.C. Prim.Shortest connection networks and some generalizations. Bell System TechnicalJournal, Volume 36, pp. 1389-1401, 1957».

Η κύρια ιδέα του αλγορίθμου είναι παρόμοια με αυτή τ ου αλγορίθμου τουDijkstra, για την εύρεση του συντομότερου μονοπατιού σε ένα γράφο. Ο αλγόριθμοςτου Prim ξεκινά με ένα δένδρο το οποίο περιέχει έναν μόνο κόμβο, και συνεχώςαυξάνει το μέγεθός του, επιλέγοντας την κοντινότερη διαθέσιμη ακμή που μπορεί ναεπεκτείνει το δένδρο με έναν επιπλέον κόμβο. Ο αλγόριθμος τερματίζεται όταν έχουνπροστεθεί όλοι οι κόμβοι στο δένδρο.

4.2 Λίγα Λόγια για τον Robert Prim…

Ο Robert Clay Prim, γεννημένος το 1921 στοSweetwater του Τέξας, είναι ένας αμερικανόςμαθηματικός και επιστήμονας της Πληροφορικής.Σπούδασε Electrical Engineering στο Πανεπιστήμιοτου Princeton, όπου και αργότερα το 1949 έλαβε τοPh.D. στα μαθηματικά. Κατά τη διάρκεια τουδευτέρου Παγκοσμίου πολέμου (1941 -1944) ο Primεργάστηκε σαν μηχανικός στην Γε νική Ηλεκτρική(General Electric). Μετέπειτα εργάστηκε στο UnitedStates Naval Ordnance Lab σαν μηχανικός καιαργότερα σαν Μαθηματικός. Στα Bell Laboratories,ήταν υπεύθυνος της έρευνας των μαθηματικών απότο 1958 μέχρι το 1961. Μετά τα Bell Laboratories, οPrim έγινε πρόεδρος έρευνας στα Sandia NationalLaboratories.

Κατά την διάρκεια της καριέρας του στα Bell Laboratories, ο Robert Prim μαζί μετον συνάδελφό του Joseph Kruskal δημιούργησαν δύο διαφορετικούς αλγορίθμουςγια την εύρεση ΕΖΔ σε έναν γράφο με βάρη. Ο Prim ανακάλυψε τον αλγόριθμο το1957.

Δίκτυα Αισθητήρων

29

4.3 Ο Αλγόριθμος

Ο αλγόριθμος του Prim ανήκει στην κατηγορία των άπληστων αλγορίθμων. Αν καιη κεντρική ιδέα δεν αλλάζει, οι υλοποιήσεις του αλγορίθμου μπορούν να ποικίλουνανάλογα με τις δομές δεδομένων που επιλέγονται.

Ακολουθεί ένας ψευδοκώδικας του αλγορίθμου:1.//Είσοδος: Ένας ζυγισμένος συνδεδεμένος γράφος G=(V,E)2.//Έξοδος: το σύνολο ΕT, το σύνολο των ακμών του G,3.//οι οποίες αποτελούν το ελάχιστο επικαλύπτον δένδρο.4.VT←{v0} //το σύνολο των κορυφών του δένδρου μπορεί5.ET←null //να αρχικοποιηθεί με μία οποιαδήποτε κορυφή6. For i←1 to |V|-1 do7. Βρες μια ακμή ελαχίστου βάρους e*=(v*,u*),8. μεταξύ όλων των ακμών (v,u), τέτοια ώστε v VT και u V-VT

9. VT←VT {u*}

10. ET←ET {e*}

11.}12. Return ET

Κατά την εκτέλεση του αλγορίθμου, διατηρούμε μία τομή του γράφου πουαποτελείται από τους κόμβους του δένδρου (αυτούς που επιλέχθηκαν για το ΕΖΔ) καιαπό την άλλη υπάρχουν οι κόμβοι που δεν ανήκουν στο δένδρο ακόμα. Στην αρχήεπιλέγεται τυχαία ένας κόμβος ο οποίος και τοποθετείται στο ελάχιστο επικαλύπτονδένδρο. Κατόπιν επιλέγεται η πιο φτηνή ακμή, η οποία ενώνει τον αρχικό κόμβο μεκάποιον άλλο, και προστίθεται στο ΕΖΔ. Η διαδικασία αυτή επαναλαμβάνεται V – 1φορές, μέχρις ότου προστεθούν όλοι οι κόμβοι στο ελάχιστο ζευγνύον δένδρο.

Το κύριο πρόβλημα του αλγορίθμου είναι να βρεθεί η ακμή με το μικρότερο βάροςπου συνδέεται με έναν συγκεκριμένο κόμβο. Είναι σημαντικό να βρεθεί η πιοκοντινή( ή η φτηνότερη) απόσταση από μία κορυφή που ανήκει στ ο δένδρο με μίακορυφή η οποία δεν ανήκει ακόμα στο δένδρο. Για να βρούμε αυτή την ακμή,μπορούμε να εξετάσουμε όλες τις ακμές που ενώνουν μία κορυφή του δένδρου μεμία κορυφή που δεν ανήκει στο δένδρο, και μετά επιλέγουμε την φτηνότερη. Αυτόμπορεί να επιτευχθεί διατηρώντας δύο σύνολα: τη ζώνη επέκτασης(« fringe») και τοάδηλον («unseen»). Η ζώνη επέκτασης περιέχει μόνο τις κορυφές εκείνες, οι οποίεςδεν ανήκουν μεν στο δένδρο, αλλά γειτονεύουν με τουλάχιστον μία κορυφή τουδένδρου. Αυτές είναι και οι υποψή φιες, από τις οποίες θα επιλεγεί η επόμενη κορυφήπου θα ενσωματωθεί στο δένδρο. Οι άδηλες κορυφές είναι όλες οι υπόλοιπες κορυφέςτου γραφήματος, οι οποίες ονομάζονται έτσι , επειδή δεν έχουν επηρεαστεί ακόμααπό τον αλγόριθμο, είναι «άγνωστες» σε αυτόν.

Παρακάτω ακολουθεί ένα παράδειγμα του αλγορίθμου του Prim.

Δίκτυα Αισθητήρων

30

Εικόνα: Ο αλγόριθμος του PrimΤο πρώτο βήμα στον υπολογισμό του ΕΖΔ με τον αλγόριθμο του Prim είναι να προσθέσουμε

τον κόμβο 0 στο δένδρο. Έπειτα βρίσκουμε όλες τις ακμές που συνδέουν τον κόμβο 0 με άλλουςκόμβους( που δεν είναι ακόμα στο δένδρο) και έχουμε υπόψη την συντομότερη(πάνω

αριστερά). Οι ακμές που ενώνουν τους κόμβους του δένδρου με κόμβους που δεν ανήκουν στοδένδρο έχουν γκρι σκιά και γράφονται σε λίστα κάτω από κάθ ε γράφο. Για απλότητα σε αυτή

την εικόνα, βάζουμε στη λίστα αυτές τις ακμές σε σειρά των βαρών έτσι ώστε η μικρότερη ακμήνα είναι πρώτη στη λίστα. Διάφορες υλοποιήσεις του αλγόριθμου του Prim χρησιμοποιούν

διαφορετικές δομές δεδομένων για να διατηρήσουν α υτή τη λίστα και να βρουν την ελάχιστηακμή. Το δεύτερο βήμα είναι να μετακινήσουμε την μικρότερη ακμή 0 -2 (μαζί με τον κόμβο)

από την λίστα στο δένδρο (δεύτερο από πάνω, αριστερά).Τρίτο, μετακινούμε την ακμή 0-7 απότη λίστα στο δένδρο, αντικαθιστώντας τ ην ακμή 0-1με την 7-1 και την 0-6 με την 7-6 στη λίστα

Δίκτυα Αισθητήρων

31

(επειδή η προσθήκη του κόμβου 7στο δένδρο φέρνει τον κόμβο 1 και τον κόμβο6 πιο κοντά στοδένδρο) και προσθέτει την ακμή 7-4 στη λίστα (επειδή η προσθήκη του κόμβου 7 κάνει τη 7 -4μία ακμή που ενώνει έναν κόμβο του δένδρου με έναν κόμβο εκτός δένδρου) (τρίτο από πάνω,

αριστερά). Μετά, μετακινούμαι την ακμή 7 -1 στο δένδρο (κάτω, αριστερά). Για ναολοκληρώσουμε τον υπολογισμό , παίρνουμε τις 7-6, 7-4, 4-3,και 3-5 από την ουρά,

ενημερώνοντας την λίστα μετά από κάθε εισαγωγή γα να αντικατοπτρίζεται κάθε συντομότερο ήνέο μονοπάτι(δεξιά, από πάνω μέχρι κάτω).

Εικόνα: αλγόριθμος του ΕΖΔΑυτή η ακολουθία δείχνει πως μεγαλώνει το ΕΖΔ όσο ο αλγόριθμος του Prim ανακαλύπτει το

1/4, 1/2, 3/4, και όλες τις ακμές στο ΕΖΔ (από την κορυφή έως κάτω). Μία κατευθυνόμενηαναπαράσταση ολόκληρου του ΕΖΔ φαίνεται στα δεξιά.

Δίκτυα Αισθητήρων

32

Διαλέγοντας τη σωστή δομή δεδομένων, ο αλγόριθμος μπορεί να γίνειευκολότερος και απλούστερος. Για να υλοποιήσουμε τον αλγόριθμο, χρει αζόμαστεδομές δεδομένων που μπορούν να αποθηκεύσουν με αποδοτικό τρόπο τα ακόλουθα:

τις ακμές που ανήκουν στο δένδρο τη συντομότερη ακμή που ενώνει κάθε κορυφή του δένδρου με μία κορυφή

που δεν ανήκει ακόμα στο δένδρο το μήκος αυτής της ακμή

Μετά την προσθήκη μίας καινούριας ακμής (και κόμβου) στο δένδρο, έχουμε δύοπράγματα να κάνουμε:

1. Ελέγχουμε αν η προσθήκη της νέας ακμής έφερε πιο κοντά στο δένδρο μίαακμή που δεν ανήκει σε αυτό.

2. Να βρούμε την επόμενη ακμή που θα προσθέσουμε στο δένδρο.

4.4 Απόδειξη της ορθότητας

Ο αλγόριθμος του Prim δημιουργεί ένα ζευγνύον δένδρο, επειδή δεν μπορούν ναδημιουργηθούν κύκλοι με την προσθήκη ακμών μεταξύ κόμβων του δένδρου καικόμβων εκτός αυτού. Παρ’ όλα αυτά , γιατί θα έπρεπε αυτό το ζευγνύον δένδρο ναέχει το μικρότερο συνολικό βάρος απ’ όλα τα ζευγνύοντα δένδρα του γράφου;

Έστω το Π ένας συνδεδεμένος γράφος με βάρη. Σε κάθε επανάληψη τουαλγορίθμου , πρέπει να βρεθεί μία ακμή, που να ενώνει έναν κόμβο του υπογράφουμε έναν κόμβο που δεν ανήκει ακόμα στον υπογράφο. Αφού το Π είναι συνδεδεμένος,θα υπάρχει πάντα ένα μονοπάτι για κάθε κόμβο. Η έξοδος Υ του αλγορίθμου είναιένα δένδρο, επειδή η ακμή και ο κόμβος που προστίθενται στο Υ είναι συνδεδεμένα.Έστω το Y1 είναι ένα ΕΖΔ του Π. Εάν το Y1=Y, τότε το Υ είναι ΕΖΔ. Διαφορετικάέστω e είναι η πρώτη ακμή που προστίθεται κατά την κατασκευή του Υ που δεν είναιόμως στο Y1, και V είναι το σύνολο των κόμβων που συνδέονται από τις ακμές πουπροστέθηκαν πριν την e. Έπειτα ένα άκρο της ακμής e είναι στον V και το άλλο όχι.Αφού το Y1 είναι ζευγνύον δένδρο του Π, υπάρχει ένα μονοπάτι στο Υ1 που ενώνειτα δύο άκρα. Όσο κάποιος διασχίζει το μονοπάτι, κάποιος πρέπει να αντιμετωπίσειμία ακμή f που ενώνει έναν κόμβο στο V με έναν άλλο που δεν ανήκει στο V. Τώρα,στην επανάληψη όπου η ακμή e προστέθηκε στο Y, η f θα μπορούσε επίσης να είχεπροστεθεί και θα αντικαθιστούσε την e εάν το βάρος της είναι λιγότερο από αυτό τηςe. Αφού το f δεν προστέθηκε καταλήγουμε ότι,

w(f) ≥ w(e).

Έστω το Y2 είναι ο γράφος που παίρνουμε αν α φαιρέσουμε την ακμή f καιπροσθέσουμε την e από τοY1. Είναι εύκολο να δείξουμε ότι το Y2 είναι συνδεδεμένο,έχει τον ίδιο αριθμό ακμών με το Y1,και το συνολικό βάρος των ακμών του δεν είναιμεγαλύτερο από αυτό του Y1, επομένως είναι επίσης ΕΖΔ του Π και πε ριέχει τηνακμή e και όλες οι ακμές που προστέθηκαν πριν , κατά την κατασκευή του V. Ανεπαναλάβουμε αυτά τα βήματα, θα αποκτήσουμε τελικά ένα ΕΖΔ του Π και είναι ίδιομε το Υ. Αυτό δείχνει ότι το Υ είναι ΕΖΔ.

Δίκτυα Αισθητήρων

33

4.5 Απόδοση

Το πόσο αποδοτικός είναι ο αλγόρι θμος του Prim εξαρτάται από τις δομέςδεδομένων που θα χρησιμοποιηθούν στην υλοποίηση του αλγορίθμου. Οι δομέςδεδομένων θα χρησιμοποιηθούν για την αναπαράσταση των κορυφών που δεν έχουνπροστεθεί στο δένδρο, και των αποστάσεων των κορυφών αυτών από τις κο ρυφές τουδένδρου.

Δομή Δεδομένων Πολυπλοκότητα ΧρόνουΠίνακας γειτνίασης Θ(V2)

Δυαδικός σωρός και λίστα γειτνίασης O(E log(V))Σωρός Fibonacci και λίστα γειτνίασης O(E + V log(V))

D - Σωρός O(ElogdV)E/V σωρός, E<2V VlogV

Στην περίπτωση που θα χρησιμοποιηθεί ένας πίνακας γειτνίασης για τηναναπαράσταση των κορυφών εκτός δένδρου, τότε ο χρόνος εκτέλεσης τουαλγορίθμου θα είναι Θ(V2), όπου V είναι το πλήθος των κορυφών. Πράγματι, σεκαθεμία από τις |V|-1 επαναλήψεις, διατρέχουμε τον πίνακα αυτό, για να βρούμε καινα διαγράψουμε από αυτόν την ελάχιστη (λιγότερο σημαντική) κορυφή , και κατόπινενημερώνουμε, εάν αυτό είναι αναγκαίο, τις προτεραιότητες των κορυφών πουαπομένουν. Η υλοποίηση με πίνακες γειτνίασης αποτελεί καλή επιλογή για πυκνούςγράφους.

Χρησιμοποιώντας έναν απλό δυαδικό σωρό ( binary heap) και μία λίσταγειτνίασης, ο αλγόριθμος του Prim αποδεικνύεται ότι εκτελείται σε χρόνο O(E log V)όπου E είναι το πλήθος των ακμών και V το πλήθος των κόμβων. Αυτό συμβαίνειεπειδή ο αλγόριθμος επιτελεί |V| -1 διαγραφές του μικρότερου στοιχείου, |E|επαληθεύσεις και πιθανόν μεταβάλλει την προτεραιότητα ενός στοιχείου στον σωρόμεγέθους το πολύ |V|. Καθεμία από αυτές τις λειτουργίες είναι κλάσης O(logV).Επομένως ο συνολικός χρόνος για την εκτέλεση θα είν αι:(|V|-+|E|)O(logV)=O(ElogV)

Εναλλακτικά χρησιμοποιώντας μία πιο πολύπλοκη δομή δεδομένων, όπως οσωρός Fibonacci, μία επέκταση της διωνυμικής ουράς, ο χρόνος εκτέλεσης τουαλγορίθμου μπορεί να μειωθεί σε O(E + V log V). Η υλοποίηση αυτή είναι ταχύτερηαπό τις υπόλοιπες υλοποιήσεις, όταν ο γράφος είναι πυκνός έτσι ώστε το E να είναιΩ(V log V). Από την άλλη όμως, εάν ο γράφος είναι αραιός, τότε ο σωρός Fibonacciδεν αποτελεί την καλύτερη επιλογή. Τέλος, οι σωροί Fibonacci είναι πιο πολύπλοκοιαπό τις διωνυμικές ουρές και είναι κάπως δύσχρηστοι στην πράξη.

Αν και η χρήση d-σωρών στον αλγόριθμο μπορεί να δώσει γραμμικήπολυπλοκότητα, εάν ο γράφος είναι πυκνός , δεν είναι αποτελεσματική για αραιούςγράφους, επειδή το d πρέπει να είναι ακέραιος μεγαλύτερος ή ίσος του 2.Για τυπικούς

Δίκτυα Αισθητήρων

34

γράφους, η μείωση του d του σωρού δεν έχει κάποια συνέπεια στον χρόνο εκτέλεσηςκαι η χρήση ενός πολύ μεγάλου d μπορεί να μειώσει ελαφρά την υλοποίηση.

Τέλος εάν το d δηλώνει την πυκνότητα E/V και d < 2, τότε ο χρόνος εκτέλεσηςτου αλγορίθμου του Prim εξαρτάται από την ποσότητα V lg V. Διαφορετικά,μπορούμε να βελτιώσουμε το χρόνο χειρότερης περίπτωσης κατά ένα παράγονταlg(E/V) χρησιμοποιώντας ένα E/V σωρό για την ουρά προτεραιότητας. Αυτόσυμβαίνει διότι, ο αριθμός των βημάτων είναι VdlogdV + ElogdV (πολυπλοκότηταυλοποίησης d-σωρού), επομένως ο χρόνος εκτέλεσης είναι ElogdV=(E lg V)/lgd.

Δίκτυα Αισθητήρων

35

5.Ο ΑΛΓΟΡΙΘΜΟΣ ΤΟΥ BORUVKA

5.1 Γενικά

Ένας από τους παλιότερους αλγορίθμους για την εύρεση ενός ΕΖΔ είναι οαλγόριθμος του Boruvka. Δημοσιεύτηκε για πρώτη φορά το 1926 από τον OtakarBoruvka, σαν μία μέθοδος για την κατασκευή ενός αποδοτικού δικτύου ηλεκτρισμούπου θα εφαρμοζόταν στην Moravia.

Ο αλγόριθμος του Boruvka, αν και κάπως δυσνόητος, υλοποιείται ευκολότερα απόοποιονδήποτε άλλο αλγόριθμο της ίδιας κατηγορίας, αφού δεν χρειάζεται πολύπλοκεςδομές δεδομένων. Ο αλγόριθμος διατηρεί ένα σύνολο από ΕΖΔ τα οποία στην πορείασυνενώνονται σε ένα μεγαλύτερο δένδρο. Σε κάθε βήμα, κάθε ελάχιστο επικαλύπτονδένδρο συνδέεται με το κοντινότερο προς αυτό ΕΕΔ, βάση των βαρών.

5.2 Λίγα Λόγια για τον Otakar Boruvka…

Ο Otakar Boruvka , γεννημένος στις 10 Μαΐου του 1899στο Uherský Ostroh, ήταν ένας Τσέχος μαθηματικός, πολύγνωστός για την έρευνα και την εργασία του στη θεωρίαγράφων.

Το 1926 δημοσίευσε την έρευνα « O jistém problémuminimálním» («Ένα συγκεκριμένο πρόβλημαελαχιστοποίησης», στα ελληνικά), στην οποία ο Boruvkaπεριέγραψε έναν αλγόριθμο για την εύρεση του ελάχι στουεπικαλύπτοντος δένδρου ενός δικτύου ηλεκτρισμού, γνωστόςπλέον σαν τον αλγόριθμο του Boruvka. Ο αλγόριθμοςανακαλύφθηκε ξανά από τον Choquet το 1938, και ύστερα το1951 από τους Florek, Łukasiewicz, Perkal, Steinhaus, καιZubrzycki και τέλος από τον Sollin στα τέλη της δεκαετίαςτου 1960.

Στις 22 Ιουλίου του 1995 ο Boruvka απεβίωσε στο Brno.

5.3 O Αλγόριθμος

Ενώ οι αλγόριθμοι του Prim και του Kruskal προσθέτουν μία ακμή τη φορά στοΕΖΔ, υπάρχει η δυνατότητα προσθήκης περισσότερων ακμών σε κάθε βήμα χω ρίς ναυπάρχει κίνδυνος το αποτέλεσμα να μην είναι βέλτιστο. Αυτή είναι και η κεντρικήιδέα του αλγορίθμου. Ο αλγόριθμος του Boruvka λειτουργεί ως εξής:

Δίκτυα Αισθητήρων

36

1. Αντέγραψε τους κόμβους του G σε έναν νέο γράφο, L, χωρίς ακμές, όπουκάθε κόμβος είναι και ένα δένδρο.

2. Όσο το L δεν είναι συνδεδεμένο (έχει δηλαδή περισσότερα από ένα δένδρο)κάνε

a. Για κάθε δένδρο Τ στο L, βρες την μικρότερη ακμή στο G, η οποίαενώνει έναν κόμβο στο T με έναν κόμβο εκτός δένδρου(G-T).

b. Πρόσθεσε αυτή την ακμή στο L, ελαττώνοντας τον αριθμών τωνδένδρων στο L κατά ένα

Εικόνα: Ο αλγόριθμος του BoruvkaΤο γράφημα στην κορυφή δείχνει μία κατευθυνόμενη ακμή από κάθε κόμβο στον πλησιέστερο

γείτονά του. Αυτές οι ακμές δείχνουν πως η 0-2, η 1-7, και η 3-5 είναι καθεμία η φτηνότερηακμή προσκείμενη και στις δύο κορυφές, η ακμή 6-7 είναι η φτηνότερη ακμή του κόμβου 6 ,

και η 4-3 είναι η φτηνότερη ακμή του4 . Αυτές οι ακμές όλες ανήκουν στο ΕΖΔ καιεμπεριέχονται σε ένα δάσος από ΕΖΔ υποδένδρα (στο κέντρο), όπως υπολογίστηκαν από τηνπρώτη φάση του αλγορίθμου. Στη δεύτερη φάση, ο αλγόριθμος ολοκληρώνει τον υπολογισμό

του ΕΖΔ (κάτω) προσθέτοντας την ακμή 0-7, η οποία είναι η φτηνότερη ακμή που προσπίπτεισε οποιοδήποτε κόμβο των υποδένδρων τα οποία συνδέει, και η ακμή 4-7, η οποία είναι η

Δίκτυα Αισθητήρων

37

φτηνότερη προσπίπτουσα σε οποιοδήποτε κόμβο στο κάτω υποδένδρο . Αριστερά στην εικόναβρίσκονται τα βάρη των ακμών.

Οι λειτουργίες οι οποίες εκτελούνται για κάθε ακμή είναι οι εξής:

Εάν ενώνει δύο κόμβους του ίδιου δένδρου, αφαίρεσε την. Διαφορετικά έλεγξε τις αποστάσεις του κοντινότερου γείτονα μεταξύ δύο

δένδρων που η ακμή ενώνει και ενημέρωσέ τα αν είναι απαραίτητο.

Μετά την εξέταση όλων των ακμών του γράφου , θα πρέπει να συγχωνεύσουμεκάποια υποδένδρα, ενώνοντας έναν κόμβο με τον πλησιέστερο γείτονά του.

Εικόνα: Ο αλγόριθμος του BoruvkaΤο ΕΖΔ εξελίσσεται σε 4 στάδια για αυτό το παράδειγμα(από πάνω προς τα κάτω)

Δίκτυα Αισθητήρων

38

5.4 Απόδειξη της ορθότητας

Ο αλγόριθμος του Boruvka υπολογίζει το ελάχιστο ζευγνύον δένδρο σεοποιοδήποτε συνδεδεμένο γράφο.

Υποθέτουμε ότι τα βάρη των ακμώ ν είναι διακριτά. Σε αυτή την περίπτωση , κάθεκόμβος έχει έναν μοναδικό κοντινότερο γείτονα, το ΕΖΔ είναι μοναδικό, καιγνωρίζουμε πως κάθε ακμή που προστίθεται είναι μία ακμή του ΕΖΔ, εφαρμόζονταςτην ιδιότητα της τομής. Αφού κάθε ακμή που επιλέχθηκε εί ναι από το μοναδικόΕΖΔ, δεν γίνεται να υπάρχουν κύκλοι, κάθε ακμή που προστίθεται ενώνει δύο δένδρααπό το δάσος σε ένα μεγαλύτερο , και η διαδικασία συνεχίζεται μέχρι ένα μοναδικόδένδρο ,το ΕΖΔ, να απομείνει.

Εάν τα βάρη των ακμών δεν είναι σαφή, μπορεί να υπάρχει παραπάνω από έναςπλησιέστερος γείτονας, και ένας κύκλος θα μπορούσε να δημιουργηθεί ότανπροστίθενται ακμές στους πλησιέστερους γείτονες (εικόνα). Για να το θέσουμεαλλιώς, μπορεί να εισάγουμε δύο ακμές από το σύνολο με τις ελάχιστες ακμέςδιασταύρωσης για κάποιον κόμβο, όταν η μία βρίσκεται στο ΕΖΔ. Για νααποφύγουμε το πρόβλημα αυτό , χρειαζόμαστε κάποιον κανόνα. Μία πιθανή λύση θαήταν να διαλέξουμε, ανάμεσα στους ελάχιστους γείτονες αυτόν με τον ελάχιστοαριθμό κόμβου. Τότε κάθε κύκλος θα παρουσιάσει μία αντίκρουση: Εάν ο v είναιαυτός με τον πιο μεγάλο αριθμό κόμβων στον κύκλο, τότε κανένας γείτονας του v δενθα τον είχε επιλέξει σαν τον πλησιέστερο, και ο v θα είχε οδηγηθεί στην επιλογή ενόςμόνου γείτονα με τον χαμηλότερο αριθμό κόμβων.

Εικόνα: Κύκλοι στον BoruvkaΣε γράφο με 4 κόμβους και 4 ακμές , οι ακμές έχουν το ίδιο μήκος. Όταν ενώνουμε κάθε κόμβο

με τον πλησιέστερο γείτονα, πρέπει να αποφασίσουμε ανάμεσα στις ελάχιστες ακμές. Στοπαράδειγμα στην κορυφή, επιλέγουμε 1 από 0, 2 από 1, 3 από 2, και 0 από 3, το οποίο οδηγεί

σε κύκλο στο ΕΖΔ. Κάθε μία από τις ακμές βρίσκονται σε κάποιο ΕΖΔ, αλλά δεν βρίσκονταιόλες σε κάθε ΕΖΔ. Για να αποφύγουμε το πρόβλημα αυτό, υιοθετούμε έναν κανόνα, όπως

φαίνεται κάτω: Επιλέγουμε την ελάχιστη ακμή στον κόμβο με τον μικρότερο δείκτη. Επομένως,διαλέγουμε 1 από 0, 0 από 1, 1 από 2, και 0 από 3, που αποδίδει ένα ΕΖΔ. Ο κύκλος έσπασε

επειδή ο κόμβος 3 με τον υψηλότερο δείκτη δεν επιλέχθηκε από τους γείτονές του 2 ή 1, καιμπορεί να επιλέξει μόνο έναν από αυτούς(0).

Δίκτυα Αισθητήρων

39

5.5 Απόδοση

Ο αλγόριθμος του Boruvka κατασκευάσει ΕΕΔ εντός χρόνου O(ElogV), όπου Εείναι το πλήθος των ακμών, και V το πλήθος των κόμβων.

Υπάρχουν δύο κύριοι παράγοντες που επηρεάζουν την αποδοτικότητα τουαλγορίθμου:

Το κόστος της λειτουργίας της αναζήτησης είναι σταθερό. Κάθε στάδιο μειώνει τον αριθμό των ελάχιστων ζευγνύων υποδένδρων στο

δάσος κατά ένα παράγοντα τουλάχιστον 2.

Αφού ο αριθμός των δένδρων στο δάσος μειώνεται στο μισό σε κάθε στάδιο, οαριθμός των σταδίων δεν είναι μεγαλύτερο από lg V. Ο χρόνος κάθε σταδίου είναιανάλογος με το κόστος των E αναζητήσεων. Επομένως ο αλγόριθμος εκτελείται σεχρόνο O(Elog V). Ο παραπάνω χρόνος εκτέλεσης είναι ένα συντηρητικό άνω όριο,αφού δεν λαμβάνει υπόψη την μείωση των ακμών σε κάθε στάδιο.

Στους επιπεδικούς γράφους (planar graphs), ο αλγόριθμος του Boruvka μπορεί νααποκτήσει γραμμική πολυπλοκότητα, αφαιρώντας όλες τις ακμές εκτός από τηνφτηνότερη μεταξύ κάθε ζευγαριού συνιστωσών, μετά από κάθε στάδιο τουαλγορίθμου.

Δίκτυα Αισθητήρων

40

6. Ο ΑΛΓΟΡΙΘΜΟΣ REVERSE - DELETE

6.1 Γενικά

Ο αλγόριθμος reverse-delete είναι ένας αλγόριθμος στη θεωρεία γράφων ο οποίοςχρησιμοποιείται για να βρεθεί το ΕΖΔ σε έναν συνδεδεμένο ζυγισμένο γράφο. Εάν ογράφος δεν είναι συνδεδεμένος, ο αλγόριθμος θα βρει ένα ελά χιστο ζευγνύον δάσοςγια κάθε συνιστώσα του γράφου .

6.2 Αλγόριθμος

Αυτός ο αλγόριθμος είναι άπληστος, επιλέγοντας την καλύτερη επιλογή μίαςκατάστασης. Είναι το αντίθετο του αλγορίθμου του Kruskal. Ο αλγόριθμος τουKruskal ξεκινάει με έναν άδειο γράφο και προσθέτει ακμές, ενώ ο αλγόριθμοςReverse-Delete ξεκινάει με τον αρχικό γράφο και διαγράφει ακμές από αυτόν. Οαλγόριθμος λειτουργεί ως εξής:

συνάρτηση ReverseDelete(edges[] E)1. //Ξεκίνα με τον γράφο G, ο οποίος περιέχει μία λίστα από ακμές E.2. ταξινόμησε τις ακμές E σε φθίνουσα σειρά3. i ← 04. Όσο i < size(E) // Διέσχισε το E σε φθίνουσα σειρά βαρών5. temp ← E[i]6. delete E[i]7. εάν temp.v1 δεν συνδέεται με το temp.v28. E[i] ← temp9. i ← i + 110. επέστρεψε edges[] E

Στο παραπάνω ο γράφος είναι ένα σύνολο από ακμές E με κάθε ακμή να περιέχει έναβάρος και συνδέει τις κορυφές v1 και v2.

Δίκτυα Αισθητήρων

41

Εικόνα: Παράδειγμα εκτέλεσης reverse delete αλγορίθμουΟι πράσινες ακμές είναι οι ακμές που μελετώντα ι την παρούσα στιγμή και οι κόκκινες ακμέςείναι αυτές που έχουν διαγραφεί. Στην αρχή υπάρχει ο αρχικός γράφος (πάνω αριστερά). Ο

αλγόριθμος ξεκινάει με την μεγαλύτερη ακμή ( DE) και εφόσον ο γράφος δεν αποσυνδέεται, ηακμή διαγράφεται (επάνω δεξιά). Η επόμ ενη μεγαλύτερη ακμή είναι η FG και αφού ούτε αυτήαποσυνδέει τον γράφο, διαγράφεται (δεύτερος από επάνω γράφος αριστερά). Ομοίως γίνεταιγια την ακμή BD(δεύτερος γράφος από επάνω δεξιά). Η επόμενη ακμή που ελέγχεται είναι ηEG, η οποία και δεν θα διαγραφή αφού κάτι τέτοιο θα χώριζε τον γράφο σε δύο συνιστώσες.

Επομένως η επομένη ακμή που διαγράφεται είναι η BC ( τρίτος γράφος από επάνω αριστερά).Η ακμή EF θα διαγραφεί (τρίτος γράφος από επάνω δεξιά). Ο αλγόριθμος έπειτα ελέγχει τις

υπόλοιπες ακμές, και αφού δεν υπάρχει άλλη ακμή για διαγραφή ο τελικός γράφοςπαράγεται(κάτω αριστερά). Οι ακμές με μαύρο χρώμα ανήκουν στο ΕΖΔ.

Δίκτυα Αισθητήρων

42

6.3 Απόδειξη της Ορθότητας

Ο αλγόριθμος Reverse-Delete επιβεβαιώνει την συνδεσιμότητα στο γράφο ήμερών του γράφου πριν διαγράψει την ακμή. Αφού ο αλγόριθμος μόνο διαγράφειόταν δεν αποσυνδέεται ο γράφος, κάθε ακμή που αφαιρείτε από τον αλγόριθμοβρισκόταν σε κύκλο. Αφού ο αλγόριθμος ξεκινά από την πιο ακριβή ακμή καισυνεχίζει κατά φθίνουσα σειρά, η ακμή που αφαιρείτε από κάποιον κύκλο είναι ημέγιστη ακμή του κύκλου. Επομένως, σύμφωνα με τον ορισμό του ελάχιστουζευγνύοντος δένδρου, οι ακμές που αφαιρούνται από τον αλγόριθμο δεν βρίσκονταισε κανένα ελάχιστο ζευγνύον δένδρο.

6.4 Απόδοση

Ο αλγόριθμος εκτελείται σε χρόνο O(E log E (log log E)3), όπου E είναι το πλήθοςτων ακμών και V το πλήθος των κορυφών. Αυτό το όριο επιτεύχθηκε ως εξής:

ταξινόμηση των ακμών κατά βάρος χρησιμοποιώντας ένα αλγόριθμοσύγκρισης σε O(E log E) χρόνο

E επαναλήψεις του βρόγχου Διαγραφή σε O(1) χρόνο Έλεγχος συνδεσιμότητας σε O(logV (log log V)3) χρόνο

Επιπλέον ο χρόνος εκτέλεσης μπορεί να θεωρηθεί O(E log V (log log V)3) επειδήτο μεγαλύτερο E μπορεί να είναι V2.

Δίκτυα Αισθητήρων

43

7. Ο ΑΛΓΟΡΙΘΜΟΣ ΤΟΥ CHAZELLE

Ο γρηγορότερος αλγόριθμος για την εύρεση του ελάχιστου επικαλύπτοντοςδένδρου σε έναν γράφο με βάρη αναπτύχθηκε από τον Bernard Chazelle, ο οποίος καιβασίζεται στο Soft Heap, μία προσεγγιστική ουρά προτεραιότητας στην οποίααποθηκεύεται το ελάχιστο ζευγνύον δένδρο. Ο αλγόριθμος βασίζεται στη σύγκριση,χρησιμοποιώντας δείκτες και όχι πίνακες. Επιπλέον δεν υπάρχουν υποθέσεις για ταβάρη των ακμών.

Η πολυπλοκότητα του αλγορίθμου είναι O(e α(e,v)), όπου e είναι ο αριθμός τωνακμών, και v ο αριθμός των κόμβων και α είναι η αντίστροφη συνάρτηση τηςσυνάρτησης Ackermann. Η συνάρτηση α μεγαλώνει πολύ αργά, έτσι ώστε γιαπρακτικούς λόγους θεωρείται σαν σταθερά όχι μεγαλύτερη από 4. Επομένως οαλγόριθμος του Chazelle εκτελείται σε σχεδόν γραμμικό χρόνο.

Δίκτυα Αισθητήρων

44

8. ΥΒΡΙΔΙΚΟΣ ΑΛΓΟΡΙΘΜΟΣ

Ο υβριδικός αλγόριθμος δεν είναι στην ουσία ένας ξεχωριστός αλγόριθμος, αλλάένας συνδυασμός δύο κλασσικών αλγορίθμων, του Boruvka και του Prim. Στο πρώτομέρος του αλγορίθμου εκτελούνται O(log log n) περάσματα του αλγορίθμου τουBoruvka, και στο δεύτερο μέρος εκτελείται ο αλγόριθμος του Prim. Ο αλγόριθμος τουPrim σχηματίζει ένα μεγάλο δένδρο καθώς ενώνει όλα τα μικρά δένδρα πουπαρήχθησαν από τον αλγόριθμο του Boruvka. Υπάρχει ένας σωρός ο οποίοςαποθηκεύει την καλύτερη ακμή για κάθε υποδένδ ρο, την οποία μπορεί ναχρησιμοποιήσει για να συνδέσει το υποδένδρο στο τελικό ΕΖΔ. Εναλλακτικά ταδένδρα τα οποία βρεθήκαν από τον αλγόριθμο του Boruvka μπορούν να θεωρηθούνσαν μεγάλοι κόμβοι. Έτσι μειώνεται ο αριθμός των λειτουργιών εύρεσης ελαχίστουστον σωρό, χρησιμοποιώντας τον αλγόριθμο του Prim.

Δίκτυα Αισθητήρων

45

9. ΕΥΚΛΕΙΔΙΟ ΕΛΑΧΙΣΤΟ ZΕΥΓΝΥΟΝ ΔΕΝΔΡΟ

9.1 Γενικά

Έστω ότι υπάρχουν Ν σημεία σε ένα επίπεδο, το πρόβλημα του Ευκλείδιου ΕΖΔσυνίσταται στην εύρεση του συνόλου με τις συντ ομότερες ακμές, οι οποίες ενώνουνόλα τα σημεία. Το πρόβλημα αυτό θεωρείται γεωμετρικό και υπάρχουν αρκετέςπροσεγγίσεις για την αντιμετώπισή του.

Εικόνα: Ευκλείδιο ΕΖΔΔεδομένου ενός συνόλου από Ν σημεία στο επίπεδο (κορυφή) , το Ευκλε ίδιο ΕΖΔ είναι το

συντομότερο σύνολο από ακμές που ενώνει όλες τις κορυφές(κάτω).

9.2 ΟΑλγόριθμος

Ένας τρόπος για να επιλυθεί το πρόβλημα του Ευκλείδιου ΕΖΔ είναι νακατασκευάσουμε ένα πλήρη γράφο με Ν κόμβους και Ν(Ν-1) ακμές- μία ακμή ενώνεικάθε ζευγάρι από κόμβους. Αυτές οι ακμές θα έχουν σαν βάρος την απόσταση μεταξύτων κόμβων που ενώνουν. Έπειτα μπορούμε να χρησιμοποιήσουμε τον αλγόριθμοτου Prim για να βρούμε το ΕΖΔ σε χρόνο που εξαρτάται από το N2.

Αυτή η λύση είναι γενικότερα αργή. Το Ευκλείδ ιο πρόβλημα είναι κάπωςδιαφορετικό από τα άλλα προβλήματα των γράφων. Το μέγεθος της εισόδου

Δίκτυα Αισθητήρων

46

εξαρτάται από το Ν, επομένως η παραπάνω λύση έχει τετραγωνική πολυπλοκότητα.Η έρευνα η οποία έχει γίνει , αποδεικνύει ότι υπάρχει αλγόριθμος με καλύτερηαπόδοση. Η γεωμετρική δομή κάνει τις περισσότερες από τις ακμές στον πλήρηγράφο να μην έχουν σχέση με το πρόβλημα, και δεν χρειάζεται να προσθέσουμε όλεςαυτές στον γράφο πριν κατασκευάσουμε το ΕΖΔ.

Άλλες προσεγγίσεις αποκομίζονται από τους γεωμετρικούς αλγορίθμο υς. Γιατυχαία διαμοιρασμένα σημεία, το επίπεδο διαιρείτε σε τετράγωνα, τέτοια ώστε κάθετετράγωνο να περιέχει περίπου Ν/2 σημεία. Έπειτα, εάν προσθέσουμε στο γράφομόνο τις ακμές οι οποίες ενώνουν κάθε σημείο στα σημεία των γειτονικώντετραγώνων, είναι πολύ πιθανόν να πάρουμε όλες τις ακμές στο ΕΖΔ. Σε αυτή τηνπερίπτωση θα μπορούσαμε να χρησιμοποιήσουμε τον αλγόριθμο του Kruskal για ναολοκληρωθεί αποδοτικά η εργασία. Ή θα μπορούσαμε να αναπτύξουμε μία εκδοχήτου αλγορίθμου του Prim χρησιμοποιώντας αλγορίθμους πλησιέστερου γείτονα γιανα αποφύγουμε την ενημέρωση μακρινών κορυφών.

Ένας τρόπος να υπολογίσουμε το Ευκλείδιο ΕΖΔ είναι να παράγουμε έναν γράφομε ακμές που ενώνουν κάθε ζευγάρι από κορυφές μέσα σε μία απόσταση d. Παρ’ όλααυτά, αυτή η μέθοδος μπορεί να αποφέρει πάρα πολλές ακμές , εάν το d είναι πολύμεγάλο (κορυφή) και δεν είναι βέβαιο αν υπάρχουν ακμές που να ενώνουν όλες τιςκορυφές εάν το d είναι μικρότερο από την μεγαλύτερη ακμή στο ΕΖΔ(κάτω).

Με όλες τις πιθανές επιλογές που υπάρχουν για να προσεγγίσουμε το πρόβλημακαι με την πιθανότητα γραμμικών αλγορίθμων για το γενικό ΕΖΔ πρόβλημα, είναισημαντικό να σημειώσουμε ότι υπάρχει ένα απλό κατώτατο όριο για το καλύτερο πουμπορούμε να κάνουμε.

Εικόνα: Euclidean near-neighbor graphs

Η εύρεση του Ευκλείδιου ΕΖΔ Ν σημείων δεν είναι πιο εύκολο από τηνταξινόμηση Ν αριθμών. Δεδομένου μίας λίστας αριθμών που πρέπει ναταξινομηθούν, μετατρέπουμε τη λίστα σε μία λίστα από σημεία όπου η συντεταγμένηχ είναι ο αντίστοιχος αριθμός της λ ίστας και το y είναι 0. Βρες το ΕΖΔ της λίστας των

Δίκτυα Αισθητήρων

47

σημείων. Έπειτα, βάζουμε τα σημεία σε έναν γράφο και εκτελούμε ένα DFS για ναπαράγουμε το ζευγνύον δένδρο, ξεκινώντας με το σημείο ε το μικρότερο χ. Αυτό τοζευγνύον δένδρο αναλογεί σε μία συνδεδεμένη λίσ τα με τους αριθμούςταξινομημένους.

Το πρόβλημα του Ευκλείδιου ΕΖΔ αντικατοπτρίζει τη σχέση μεταξύ των γράφωνκαι των γεωμετρικών αλγορίθμων. Πολλά από τα πρακτικά προβλήματα μπορούν ναδιατυπωθούν είτε ως γεωμετρικά προβλήματα είτε σαν προβλήματα γράφων. Εάν ηφυσική θέση των αντικειμένων αποτελεί το κυρίαρχο χαρακτηριστικό, τότε μπορούμενα αναφερθούμε στους γεωμετρικούς αλγορίθμους, αλλά αν οι διασυνδέσεις μεταξύτων αντικειμένων είναι θεμελιώδης σημασίας, τότε οι αλ γόριθμοι γράφων είναικαλύτεροι.

9.3 Απόδοση

Μπορούμε να βρούμε το Ευκλείδιο ΕΖΔ Ν σημείων σε χρόνο NlogN. Αυτό τογεγονός είναι άμεση συνέπεια των δύο βασικών θεμάτων για τα σημεία ενόςεπιπέδου. Πρώτον , ένας γράφος γνωστός σαν Delauney triangulation περιέχει τοΕΖΔ εξ’ ορισμού. Δεύτερον, το Delauney triangulation είναι ένας επιπεδικός γράφος,του οποίου ο αριθμός των ακμών εξαρτάται από το Ν. Το Delauney triangulationμπορεί να υπολογιστεί σε χρόνο N log N, και μετά τον υπολογισμό του εκτελείται οαλγόριθμος του Kruskal για να βρεθεί το Ευκλείδιο ΕΖΔ σε χρόνο N log N. Όμως ησυγγραφή προγράμματος για τον υπολογισμό του Delauney triangulation αποτελείμία πρόκληση ακόμα και για τους έμπειρους προγραμματιστές. Επομένως αυτή ηπροσέγγιση μπορεί να είναι μη πρακτική για αυτό το πρόβλημα.

Δίκτυα Αισθητήρων

48

10. ΣΥΓΚΡΙΣΗ ΑΛΓΟΡΙΘΜΩΝ

Οι αλγόριθμοι του Prim, του Kruskal και του Boruvka είναι οι πιο γνωστοίαλγόριθμοι για την εύρεση του ελάχιστου ζευγνύοντος δένδρου σε έναν γράφο, καιγια τον λόγο αυτό θα ακολουθήσει σύγκριση κυρίως για τους αλ γορίθμους αυτούς.

Ξεκινώντας από τις ομοιότητες τους, πρέπει να αναφερθεί ότι και οι τρειςαποτελούν παραδείγματα άπληστων αλγορίθμων και εκτελούνται σε πολυωνυμικόχρόνο. Επιπλέον και ο αλγόριθμος Reverse-Delete θεωρείται άπληστος.

Από την άλλοι οι αλγόριθμοι αν και έχουν τον ίδιο στόχο, δηλαδή την εύρεση τουΕΖΔ, εκτελούνται διαφορετικά. Στον αλγόριθμο του Kruskal αρχικά σβήνουμε όλεςτις ακμές και τις τοποθετούμε στη σειρά κατά αύξουσα τάξη βάρους. Έπειταπροσπαθούμε να τις προσθέσουμε στο γράφημα με β άση αυτή τη σειρά,παραλείποντας όμως τις ακμές που θα δημιουργούσαν κύκλο. Από την άλλη στοναλγόριθμο του Prim, ξεκινούμε από μια ακμή ελαχίστου βάρους και προσθέτουμε τιςακμές βάσει του κριτηρίου ότι έχουν μία κορυφή στο ήδη σχηματισμένο γράφημα.Δεν λαμβάνεται έτσι υπόψη το βάρος της ακμής. Επιπλέον ο αλγόριθμος του Kruskalδιατηρεί ένα δάσος από ελάχιστα ζευγνύοντα δένδρα, τα οποία και τα ενώνει, ενώ οαλγόριθμος του Prim, προσθέτει ακμές σε ένα δένδρο το οποίο μεγαλώνει σταδιακά.

Από τα παραπάνω μπορούμε να συμπεράνουμε πως ο αλγόριθμος του Kruskalκάνει εξαντλητικότερη μελέτη του προβλήματος επειδή ελέγχει με τη σειρά όλες τιςακμές μικρού βάρους και τις απορρίπτει , αν η προσθήκη τους οδηγεί σε δημιουργίακυκλώματος, δίνοντας την καλύτερη λύση. Ο αλγόριθμος του Prim αντιθέτως φτάνειγρηγορότερα σε λύση, αποφεύγοντας τις ατυχείς απόπειρες του έτερου αλγορίθμου,αλλά η λύση του έχει λιγότερες πιθανότητες να είναι η ιδανική.

Αλγόριθμος Χειρότερη Περίπτωση

Ο Αλγόριθμος του Boruvka Ο(ElogV)

Reverse Delete Αλγόριθμος (E log V (log log V)3)

Ο Αλγόριθμος του Chazelle O(E α(E,V)),

Ο Αλγόριθμος του Prim

πίνακας γειτνίασης O(V2)ουρά προτεραιότητας O(ElogV)

σωρός Fibonacci Ο(E+VlogV)d-σωρός O(ElogdV)

E/V σωρός, E<2V O(VlogV)

Ο Αλγόριθμος του Kruskalσυγκριτική ταξινόμηση O(ElogE)

ταξινόμηση βάσεως O(Elog*E)σωρός O(E+ElogV)

Δίκτυα Αισθητήρων

49

Θα πρέπει να σημειωθεί πως το E lg E δεν είναι αναγκαίως χειρότερο από το E lgV, διότι το E είναι το πολύ V2, επομένως lg E είναι το πολύ 2logV. ΟΙ διαφορές στηναπόδοση για συγκεκριμένους γράφους οφείλονται στις ιδιότητες των υλοποιήσεωνκαι στο εάν ο πραγματικός χρόνος εκτέλεσης πλησιάζει αυτά τα όρια χειρότερηςπερίπτωσης.

Ποιος είναι λοιπόν ο γρηγορότερος δυνατός αλγόριθμος για το πρόβλημα τουΕΖΔ; Αυτό αποτελεί και ένα από τα πιο παλιά ανοιχτά ερωτήματα στην επιστήμη τωνυπολογιστών. Υπάρχει ένα γραμμικό κατώτατο όριο στο πρόβλημα, αφού πρέπειοπωσδήποτε να ελέγξουμε όλα τα βάρη. Εάν τα βάρη των ακμών είναι ακέραιοι μεσυγκεκριμένα bit μάκρους, τότε οι ντετερμινιστικοί αλγόριθμοι είναι γνωστοί μεγραμμικό χρόνο εκτέλεσης. Για πιο γενικευμένα βάρη , υπάρχουν randomizedαλγόριθμοι των οποίων ο χρόνος είναι γραμμικός. Ενώ αυτοί οι αλγόριθμοι είναιαρκετά πολύπλοκοι, απλοποιημένες εκδοχές μερικών από αυτών μπορεί να είναιχρήσιμοι στην πράξη.

Πιο γρήγοροι αλγόριθμοι μπορούν να επιτευχθούν αν συνδυάσουμε τον αλγόριθμοτου Prim με αυτό του Borůvka. Ένας γρηγορότερος αλγόριθμος εξαιτίας του Karger,Klein and Tarjan τρέχει σε χρόνο O(m), όπου m είναι ο αριθμός των άκμων.

Για παράλληλους αλγορίθμους προτιμάται ο αλγόριθμος του Boruvka, ενώ για τοναλγόριθμο του Prim και ειδικά του Kruskal δεν μεγιστοποιείται η απόδοσή τους μεεπιπρόσθετους επεξεργαστές.

Δίκτυα Αισθητήρων

50

11. GABRIEL ΓΡΑΦΟΣ

11.1 Γενικά

Δύο σημεία Α και Β ονομάζονται Gabriel γείτονες,εάν η διαμετρική τους σφαίρα (δηλαδή η σφαίρα μεδιάμετρο την γραμμή ΑΒ) δεν περιέχει άλλα σημεία.

Ένας γράφος όπου όλα τα ζευγάρια Gabriel γειτόνωνσυνδέονται με μία ακμή ονομάζεται Gabriel γράφος. Ογράφος Gabriel περιέχει σαν υπογράφο το ευκλείδει oελάχιστο ζευγνύον δένδρο και τον γράφο τουπλησιέστερου γείτονα.

Οι Gabriel γράφοι ονομάστηκε από τον K. R. Gabriel, ο οποίος και τους εισήγαγεσε μία εργασία με τον R. R. Sokal το 1969.

10.2 Voronoi και Gabriel Γράφοι

Ο Gabriel γράφος είναι ένας υπογράφος του Delaunay triangulation. Άμεσησυνέπεια αυτού αποτελεί το γεγονός πως το σύνολο των σημείων του Gabriel είναιπάντα υποσύνολο του επεξεργασμένου Voronoi συνόλου. Επομένως, η Gabrielεπεξεργασία μειώνει το μέγεθος του συν όλου εκπαίδευσης πιο πολύ από την Voronoiεπεξεργασία.

Εάν θεωρήσουμε έναν 1-NN κανόνα απόφασης, ο Voronoi γράφος, αναπαριστάακριβώς το όριο απόφασης. Εάν σχεδιάσουμε μία γραμμή μεταξύ δύο σημείων -ογράφος αναπαριστά το όριο απόφασης. Η γραμμή αυτή μεταξ ύ των δύο σημείων είναικάθετη στην ευθεία που θα ένωνε τα σημεία αυτά, έτσι ώστε όλα τα στοιχεία από τημία μεριά να αποτελούν μία κλάση με το ένα σημείο, και από την άλλη πλευρά ταυπόλοιπα σημεία να αποτελούν μία άλλη κλάση με το άλλο σημείο. Εάν εκτελέ σουμετο παραπάνω για όλους τους συνδυασμούς των σημείων, το αποτέλεσμα θα είναι έναVoronoi διάγραμμα. Παρατηρήστε πως στο τέλος κάθε σημείο βρίσκεται στη δικήτου περιοχή.

Εικόνα: Voronoi Διάγραμμα

Δίκτυα Αισθητήρων

51

Το Delaunay triangulation αποτελείται από τονVoronoi γράφο και τις ακμές πουενώνουν τα γειτονικά σημεία.

Εικόνα: Delaunay Triangulation

Ο Gabriel αλγόριθμος επεξεργασίας είναι παρόμοιος στην κεντρική του ιδέα μετον Voronoi αλγόριθμο επεξεργασίας, εκτός από το γεγονός ότι ο Gabrielαλγόριθμος, όπως και το όνομά του προδίδει, χρησιμοποιεί τον Gabriel γράφο τουσυνόλου αναφοράς, αντί για το Voronoi διάγραμμα.

Αλγόριθμος

1. Υπολόγισε τον Gabriel γράφο από το σύνολο εκπαίδευσης/αναφοράς.2. Επισκέψου κάθε κόμβο, σημειώνοντας τον, εάν όλοι Gabriel γείτονες του

είναι της ίδιας τάξης με τον κόμβο που επισκεπτόμαστε.3. Διέγραψε όλους του σημειωμένους κόμβους, και αφήνοντας τους υπολοίπους

σαν το επεξεργασμένο σύνολο εκπαίδευσης/αναφοράς.

Το Gabriel σύνολο είναι πάντα υποσύνολο του Voronoi συνόλου, επειδή έναζευγάρι από σημεία αν είναι Gabriel γείτονες τότε είναι και Voronoi γείτονες.Επομένως μπορούμε να πούμε πως, ο Gabriel αλγόριθμος μειώνει το Voronoi σύνολοπερισσότερο. Παρ’ όλα αυτά είναι φανερό πως το Gabriel σύνολο δεν είναι απόφασηορίου.

Τέλος, ο Gabriel γράφος μπορεί να υπολογιστεί αγνοώντας τις ακμές από τοDelaunay Triangulation. Παρ’ όλα αυτά, η πολυπλοκότητα του υπολογισμού μπορείνα είναι O(n[d/2]), όπου d είναι ο αριθμός των διαστάσεων, η οποία θεωρείται πολύκακή πολυπλοκότητα. Επομένως αυτή η προσέγγισ η δεν είναι πολύ ελκυστική, ότανο αριθμός των διαστάσεων είναι μεγάλος.

Εικόνα: Gabriel Επεξεργασία

Δίκτυα Αισθητήρων

52

10.3 Αλγόριθμος Ωμής Βίας

Η κατασκευή ενός Gabriel γράφου σε ένα επίπεδο χώρο από σημεία περιγράφηκεπαραπάνω και η μέθοδος αυτή χρησιμοποιεί την κατα σκευή Voronoi διαγράμματοςσαν ένα βήμα προεπεξεργασίας. Αφού η πραγματική μας πρόθεση είναι νακατασκευάσουμε έναν Gabriel γράφο αποδοτικά σε περισσότερες διαστάσεις, ηχρήση της κατασκευής του Voronoi διαγράμματος δεν είναι πλέον επιθυμητή.Επομένως, παρουσιάζουμε έναν αλγόριθμο για να κατασκευάσουμε τον Gabrielγράφο στον d-διάστατο χώρο ο οποίος δεν χρειάζεται πλέον τον υπολογισμό τουVoronoi διαγράμματος.

Εξ’ ορισμού, δύο σημεία ενός συνόλου είναι Gabriel γείτονες εάν και μόνο εάν ησφαίρα επιρροής (διαμετρική σφαίρα) είναι άδεια. Μπορούμε πάντα νακατασκευάσουμε τον Gabriel γράφο μόλις όλοι οι Gabriel γείτονες είναι γνωστοί. ΟιGabriel γείτονες μπορούν να βρεθούν με εξαντλητικό τρόπο χρησιμοποιώντας έναναλγόριθμο ωμής βίας.

Αλγόριθμος

Έστω ένα σύνολο από σημεία {Χ}={Χ1,Χ2,…..,Χn}.1. Θεωρείστε όλα τα ζευγάρια σημείων (Χ i, Xj) όπουi,j=1,2,….,n και i<j.2. Για κάθε τέτοιο ζευγάρι (Xi, Xj) έλεγξε εάν υπάρχει σημείο Xk, όπου k≠i,j,

που να ανήκει στο {Χ} τέτοιο ώστε:

D2(Xi, Xj)>d2(Xi, Xk) + d2(Xj, Xk)

3. Εάν τέτοιο σύνολο δεν υπάρχει, τότε τα σημεία Xi, Xj είναι Gabriel γείτονες.

Το πρώτο βήμα του αλγορίθμου χρειάζεται Ο( n2) πράξεις, για να δημιουργήσειΟ(n2) ζευγάρια σημείων. Για κάθε τέτοιο ζευγάρι των σημείων ( Xi, Xj), το βήμα 2χρειάζεται Ο(dn) λειτουργίες. Επομένως η συνολική πολυπλοκότητα του αλγορίθμουείναι Ο(dn3).

Εύκολα μπορούμε να συμπεράνουμε πως η μέθοδος της ωμής βίας πρωταρχικάεξαρτάται από τον αριθμό των σημείων στο σύνολο. Αυτό δεν συμβαίνει, όταν τοVoronoi διάγραμμα χρησιμοποιείται για τον υπολογισμό του Gabriel γράφου, επειδήσε αυτή την περίπτωση η πολυπλοκότητα χειρότερης περίπτωσης είναι τουλάχιστονΟ(n[d/2]). Επομένως για μεγάλο d ο αλγόριθμος ωμής βίας, με πολυπλοκότητα Ο( dn3),είναι πολύ πιο γρήγορος από την μέθοδο που χρησιμοποιεί τ α Voronoi διαγράμματα.Από την άλλη , εάν το n είναι πολύ μεγάλο, τότε το Ο(dn3) είναι αποτρεπτικό.

10.4 Ευριστικός Αλγόριθμος

Ο αριθμός των ζευγαριών από Gabriel γείτονες σε ένα σύνολο από n σημεία, είναιγενικότερα , πολύ μικρότερος από τον συνολικό αριθμό ζευγαριών n(ν-1)/2, πουθεωρήσαμε στον αλγόριθμο ωμής βίας. Επομένως αν θα μπορούσαμε με κάποιοτρόπο να μειώσουμε τον αριθμό των ζευγαριών που ελέγχονται για Gabriel γείτονες,

Δίκτυα Αισθητήρων

53

τότε ο αλγόριθμος ωμής βίας θα ήταν πιο πρακτικός. Μία ευριστική προσέγγ ιση γιανα πετύχουμε τον στόχο αυτό περιγράφεται παρακάτω.

Για απλότητα, περιγράφουμε την μέθοδο στον δισδιάστατο χώρο, χωρίς όμως αυτόνα σημαίνει ότι δεν μπορεί να εφαρμοστεί σε περισσότερες διαστάσεις. Έστω ένασύνολο από σημεία, και Α ένα σημείο του ο ποίου τους Gabriel γείτονες ζητάμε ναυπολογίσουμε. Έστω ένα σημείο Β που ανήκει στο σύνολο των σημείων. Κατόπινσχεδιάζουμε μία γραμμή L(Α, Β) από το Β, η οποία είναι κατακόρυφη στην γραμμήπου ενώνει τα Α και Β. Έστω LH(L,Α) είναι ο μισός χώρος, ο οποίος ορίζεται από τοL(A, B) και περιέχει το σημείο A και RH(L,Α) είναι ο άλλος μισός χώρος που δενπεριέχει το σημείο B.

Προκύπτει το ακόλουθο:

Κανένα σημείο που περιέχεται στο σύνολο RH(L,Α) δεν μπορεί να είναι Gabrielγείτονας του Β.

Απόδειξη: Έστω το σημείο A και κάποιο σημείο C στο RΗ(L,Α). Έστω D(Α,C) ηδιαμετρική σφαίρα που ορίζεται από τα Α και C. Αφού το σημείο C περιέχεται στοRH(L,A), συνεπάγεται ότι η γωνία ABC είναι μεγαλύτερη από 90 μοίρες. Επομένωςτο σημείο B περιέχεται στο D(A,C) και το C δεν γίνεται να είναι Gabriel γείτονας τουA.

Εικόνα: Ευριστική μέθοδος για τον υπολογισμό των Gabriel γειτόνωνΠιθανοί Gabriel γείτονες του Α:Απορριφθέντα σημεία για Gabriel γείτονες του Α:

Δίκτυα Αισθητήρων

54

Χρησιμοποιώντας την παραπάνω ευριστική μ έθοδος ο αλγόριθμος ωμής βίαςγίνεται:

Αλγόριθμος

Για κάθε σημείο pi ,ενός δεδομένου συνόλου σημείων {Χ}, ξεχωριστά.1. Ξεκίνα με Ni={p1,p2,….pi-1,pi+1,….,pn) το σύνολο των πιθανών Gabriel

γειτόνων του σημείου pi.2. Για κάθε πιθανό Gabriel γείτονα pr, που ανήκει στο Ni κάνε τα ακόλουθα:

Για κάθε σημείο pk του {Χ}, pk pi≠pr:i) Έλεγξε εάν το pk βρίσκετε μέσα στη σφαίρα επιρροής, που ορίζεταιαπό το τα pi και pr. Εάν ισχύει, αφαίρεσε το pr από το σύνολο Ni καιπήγαινε στο βήμα 1,με έναν νέο πιθανό Gabriel γείτονα.ii) Εάν το pk περιέχεται στο Ni, τότε έλεγξε εάν το pr βρίσκεται μέσαστην σφαίρα επιρροής που ορίζεται από τα pi και pk. Εάν ισχύει,αφαίρεσε το pk από το Ni.

3. Αποδέξου τα εναπομείναντα σημεία του Ni σαν τους Gabriel γείτονες του pi.

Εικόνα: Αγνοούμε τα σημεία που δεν μπορούν να είναι Gabriel γείτονες

Όπως η παραπάνω εικόνα περιγράφει, όταν γίνεται έλεγχος εάν το σημείο C είναιμέσα στη διαμετρική σφαίρα, μπορούμε επίσης να ελέγξουμε εάν βρίσκεται στο δεξίμισό της σφαίρας σε σχέση μ ε την διάμετρο ΑΒ. Εάν βρίσκεται, το σημείο C δενμπορεί να είναι πιθανός Gabriel γείτονας του Α, αφού το σημείο Β θα περιέχεταιστην σφαίρα με διάμετρο AC. Επομένως, αγνοείται από τη λίστα των πιθανώνγειτόνων και αποφεύγεται ένας παρατεταμένος υπολογισμ ός, ο οποίος διαφορετικάθα ήταν απαραίτητος. Αυτός ο ευριστικός αλγόριθμος μειώνει τον χρόνο σε O(dn2).

10.5 Monte Carlo Εξομοίωση

Μία Monte Carlos εξομοίωση πραγματοποιήθηκε για να καθοριστεί η έκταση στηνοποία η ευριστική μέθοδος απορρίπτει ζευγάρια σημείων . Το πείραμα έγινεπαράγοντας σύνολα από σημεία με μέγεθος 100,300,500,700 και 1000 ομοιόμορφακατανεμημένα σε ένα d-κύβο με d=2,3 ή 4. Μετά από 20 φορές επανάληψη για κάθεπερίπτωση η μέση τιμή καταγράφηκε στον πίνακα. Έστω το Τ να δηλώνει τον

Δίκτυα Αισθητήρων

55

συνολικό αριθμό ζευγαριών που απορρίφτηκαν, τότε το ποσοστό των απορριφθέντωνζευγαριών , σε ένα σύνολο από n σημεία, ορισμένο σαν Pr(n) υπολογίζεται ως εξής:

Pr(n)=

Από τον πίνακα παρατηρείται ότι τα περισσότερα ζευγάρια απορρίφτηκαν πρινκαν ελεγχθούν. Για παράδειγμα , όταν n=500 και d=3, κατά μέσο όρο , 119,120ζευγάρια (από τα 124.750) δεν χρειάζεται ούτε να περάσουν από τον έλεγχο τουGabriel γείτονα. Για μία συγκεκριμένη διάσταση, το ποσοστό των απορριφθέντωνζευγαριών μεγαλώνει όσο το n μεγαλώνει, ενώ για συγκεκριμένο αριθμό σημείων , τοποσοστό των απορριφθέντων ζευγαριών μειώνεται όσο οι διαστάσεις των σημείωνμεγαλώνουν.

Πλήθος Σημείων Ποσοστό απορριφθέντων ζευγαριών

d=2 d=3 d=4100 91,37 86,01 80,51300 96,23 93,45 90,41500 97,46 95,49 93,30700 98,04 96,49 94,67

1000 98,43 97,31 95,92

Πίνακας: Η Monte Carlo εξομοίωση καθορίζει τα ποσοστά των σημείων που δεν θα ελεγχθούνγια Gabriel γείτονες.

Επομένως μπορούμε να συμπεράνουμε, ότι για πολλές διαστάσεις ο αλγόριθμοωμής βίας βελτιωμένος με την ευριστική μέθοδο, μπορεί να απαλλάξει από πολλούςυπολογισμούς, σε σχέση με τον απλό αλγόριθμο ωμής βίας και την μέθοδο τουVoronoi διαγράμματος.

Δίκτυα Αισθητήρων

56

12. ΚENTRIKOTHTA

12.1 Γενικά

Στη θεωρεία γράφων και την ανάλυση δικτύων , υπάρχουν διάφορα μέτρακεντρικότητας (centrality) ενός κόμβου σε έναν γράφο, τα οποία καθορίζουν τηνσχετική σημαντικότητα ενός κόμβου μέσα στον γράφο (για παράδειγμα , πόσοσημαντικό είναι ένα άτομο μέσα σε ένα κοινωνικό δίκτυο, ή πόσο σημαντικό είναιένα δωμάτιο σε ένα κτίριο ή πόσο καλά χρησιμοποιείται ένας δρόμος σε ένα αστικόδίκτυο). Η κεντρικότητα αποτελεί σημαντική πληροφορία σε ένα κοινωνικό δίκτυο(social network) όπως και σε ένα δίκτυο αισθητήρων , καθώς θα μας ενημερώσεικατά πόσο σημαντικός είναι ένας κόμβος-αισθητήρας μέσα στο δίκτυο.

Παρακάτω αναλύονται τρία μέτρα κεντρικότητας.

12.2 Ο Αλγόριθμος Betweenness Centrality

Ο αλγόριθμος Betweenness είναι ένα μέτρο κεντρικότητας ενός κόμβου σε ένανγράφο (υπάρχει επίσης και Betweenness για τις ακμές) ορίζοντας την θέση ενόςκόμβου στο δίκτυο ανάλογα με την ικανότητά του να συνδέεται με άλλα ζευγάριαστο δίκτυο. Οι κόμβοι που εμφανίζονται σε πολλά συντομότερα μονοπάτια μεταξύάλλων κόμβων έχουν μεγαλύτερη Betweenness Centrality από τους υπόλοιπους.

Ένας κόμβος με υψηλότερη Betweenness κεντρικότητα γενικά : Διατηρεί μία δυναμική και ευνοϊκή θέση στο δίκτυο. Αναπαριστά ένα σημείο αποτυχίας -εάν αφαιρέσουμε τον κόμβο με υψηλή

Betweenness κεντρικότητα από το δίκτυο, μπορεί το δίκτυο να μην ε ίναισυνδεδεμένο.

Έχει μεγαλύτερη επιρροή στο τι συμβαίνει στο δίκτυο.

Για έναν γράφο G = (V,E) με n κόμβους, η Betweenness CB(v) για έναν κόμβο vείναι:

όπου σst είναι ο αριθμός των συντομότερων μονοπατιών από το s στο t, και σst(v)είναι ο αριθμός των συντομότερων μονοπατιών από το s στο t που περνούν από τονκόμβο v. Αυτό μπορεί να κανονικοποιηθεί διαιρώντας το με τον αριθμό τωνζευγαριών κόμβων που δεν περιέχουν τον v, που είναι (n − 1)(n − 2).

Δίκτυα Αισθητήρων

57

Η Betweenness κεντρικότητα των κόμβων (κόκκινο =0 και μπλε =μεγαλύτερο)

Ο υπολογισμός της Betweenness κεντρικότητας σε έναν γράφο για όλους τουςκόμους περιέχει τον υπολογισμό των συντομότερων μονοπατιών μεταξύ όλων τωνζευγαριών κόμβων στον γράφο. Αυτό χρειάζεται Θ( V3) χρόνο με τον αλγόριθμοFloyd–Warshall, αφού έχει μετατραπεί έτσι ώστε να υπολογίσει ένα μόνο μονοπάτιαλλά όλα τα μονοπάτια μεταξύ δύο κόμβων. Σε έναν αραιό γράφο, ο αλγόριθμος τουJohnson's μπορεί να είναι πιο αποδοτικός, με χρόνο O(V2logV + VE). Σε μηβεβαρημένους γράφους, ο υπολογισμός της Betweenness κεντρικότητας χρειάζεταιO(VE) χρόνο χρησιμοποιώντας τον αλγόριθμο του Brandes.

Η Betweenness κεντρικότητα είναι κατά μία έννοια ένα μέτρο για την επιρροή πουέχει ο κόμβος στη διάδοση πληροφοριών στο δίκτυο. Όμως με τον υπολογισμό μόνοτων συντομότερων μονοπατιών, ο συμβατικός ορισμός υποθέτει ότι η πληροφορίαδιαδίδεται μόνο μέσα από τα συντομότερα μονοπάτια.

12.3 Ο Αλγόριθμος Random Walk Betweenness

Ο αλγόριθμος Random Walk Betweenness χαλαρώνει την παραπάνω υπόθεση,περιέχοντας όλα τα μονοπάτια μεταξύ των κόμβων του γράφου, και όχι μόνο τασυντομότερα. Ουσιαστικά ο αλγόριθμος βρίκε ι την Betweenness κεντρικότητα γιακάθε κόμβο στον γράφο, αλλά το συγκεκριμένο μέτρο βασίζεται σε τυχαίαμονοπάτια, υπολογίζοντας πόσο συχνά ένας κόμβος διασχ ίζεται από ένα τυχαίομονοπάτι μεταξύ δύο κόμβων.

12.4 Ο Αλγόριθμος HITS

Ο αλγόριθμος HITS (Hyperlink-Induced Topic Search, γνωστός επίσης και σανHubs και authorities) είναι ένας αλγόριθμος για την ανάλυση συνδέσμων και πρώτο -χρησιμοποιήθηκε στην βαθμολόγηση των ιστοσελίδων. Δημιουργήθηκε από τον JonKleinberg. Γενικά χρησιμοποιείται για την αξιολόγηση των κόμβων και σε άλλαδίκτυα. Ο αλγόριθμος μετράει την σημαντικότητα κάθε κόμβου στον γράφοχρησιμοποιώντας κάποια συγκεκριμένα μέτρα. Τα μέτρα αυτά ορί ζονται ως εξής:

Δίκτυα Αισθητήρων

58

Το «hubness» ενός κόμβου είναι ο βαθμός στον οποίο ο κόμβος «δείχνει» σεάλλα σημαντικά authorities

Το «authoritativeness» ενός κόμβου είναι ο βαθμός στον οποίο ο κόμβοςδείχνεται από σημαντικά hubs

Ο Αλγόριθμος

Ο αλγόριθμος εκτελεί μία σειρά από επαναλήψεις που αποτελούνται από δύοβήματα:

Ενημέρωση Authority: Ενημερώνεται το Authority σκορ κάθε κόμβου έτσιώστε να είναι ίσο με το άθροισμα όλων των Hub σκορ κάθε κόμβου πουδείχνει σε αυτόν τον κόμβο που ενημερώνουμε. Αυτό σημαίνει πω ς δίνεταιυψηλό authority βαθμό σε έναν κόμβο, που συνδέεται από κόμβους, οι οποίοιέχουν αναγνωριστεί σαν Hub.

Ενημέρωση Hub: Ενημερώνεται ο Hub βαθμός κάθε κόμβου έτσι ώστε ναείναι ίσος με το άθροισμα των Authority σκορ κάθε κόμβου, στους οποίουςδείχνει. Αυτό σημαίνει πως ένας κόμβος έχει υψηλό hub βαθμό, εάν ενώνεταιμε κόμβους που θεωρούνται authorities.

Ο Hub βαθμός και ο Authority βαθμός για έναν κόμβο υπολογίζονται από τονακόλουθο αλγόριθμο:

1. Ξεκίνα με κάθε κόμβο να έχει hub σκορ και authority σκορ ίσο με 1.2. Εκτέλεσε τον κανόνα Authority Ενημέρωση3. Εκτέλεσε τον κανόναHub Ενημέρωση4. Κανονικοποίησε τις τιμές διαιρώντας κάθε Hub σκορ με το άθροισμα όλων

των Hub σκορ, και διαιρώντας κάθε Authority σκορ με το άθροισμα όλωντων Authority σκορ.

5. Επανέλαβε το δεύτερο βήμα, εάν είναι αναγκαίο.

Ο αλγόριθμος HITS, όπως και ο αλγόριθμος PageRank, είναι ένας επαναληπτικόςαλγόριθμος βασισμένος στη συνδετική διάταξη του δικτύου.

Δίκτυα Αισθητήρων

59

Ψευδοκώδικας

1 G :=(V,E)2 για κάθε κόμβο v στο G κάνε3 v.auth = 1 // v.auth είναι το authority σκορ για τον κόμβο v4 v.hub = 1 // v.hub είναι το hub σκορ για τον κόμβο v5 function HubsAndAuthorities(G)6 για βήμα από 1 μέχρι k κάνε // τρέξε τον αλγόριθμο k βήματα7 για κάθε κόμβο v στο G κάνε //ενημέρωσε πρώτα όλες τις authority τιμές8 για κάθε κόμβο q στο v.incomingNeighbors κάνε // v.incomingNeighbors είναι

το σύνολο των κόμβων που δείχνουν στο v9 v.auth += q.hub

10 για κάθε κόμβο v στο G κάνε // μετά ενημέρωσε όλες τις hub τίμες11 για κάθε κόμβο r στο v.outgoingNeighbors κάνε // v.outgoingNeighbors είναι οαριθμός των σελίδων που ο v δείχνει12 v.hub += r.auth

Δίκτυα Αισθητήρων

60

13. ΔΙΚΤΥΑ ΑΙΣΘΗΤΗΡΩΝ

13.1 Γενικά

Τα δίκτυα μικροηλεκτρονικών αισθητήρων, ή απλά δίκτυα αισθ ητήρων,αποτελούν μια δημοφιλή ερευνητική περιοχή της πληροφορικής και όχι μόνο. Τατελευταία χρόνια, κατέκτησαν το ενδιαφέρον πολλών ερευνητών από διάφορουςκλάδους της πληροφορικής και της ηλεκτρονικής, λόγω των πολλών εφαρμογώντους. Ιδιαίτερης σημασίας θεωρούνται τα ασύρματα δίκτυα αισθητήρων ( WirelessSensor Networks), των οποίων η ανάπτυξη ξεκίνησε από εφαρμογές του στρατού,όπως η παρακολούθηση. Όμως , τα ασύρματα δίκτυα αισθητήρων χρησιμοποιούνταιπλέον σε πολλές εφαρμογές της καθημερινής ζωής, εφαρ μογές υγείας,αυτοματοποίηση του σπιτιού, παρακολούθηση της κίνησης. Στην επιστήμη τωνυπολογιστών και των τηλεπικοινωνιών, τα WSN είναι ένα ενεργό πεδίο έρευνας μεπολυάριθμες μελέτες και συνέδρια κάθε χρόνο.

Ένα δίκτυο αισθητήρων είναι ένα δίκτυο το οπο ίο αποτελείται από μερικώςαυτόνομες συσκευές ανίχνευσης που ονομάζονται αισθητήρες -κόμβοι. Αυτές οισυσκευές έχουν τη δυνατότητα να καταγράψουν φυσικές και περιβαλλοντικέςσυνθήκες, όπως θερμοκρασία, ήχο, πίεση και άλλα, σε διαφορετικές τοποθεσίες καισυνήθως είναι μικρές και ελαφριές.

Ενώ οι μικροηλεκτρονικοί αισθητήρες λειτουργούν σε πληροφορικά συστήματαεδώ και πολλά χρόνια, το έντονο ερευνητικό ενδιαφέρον των τελευταίων ετώνέγκειται κυρίως στους εξής λόγους:1. Η ταχεία ανάπτυξη της τεχνολογίας των μικροεπεξεργαστών που ενώ

παρουσιάζονται συνεχώς με μικρότερο μέγεθος, εφοδιάζονται με ισχυρότερουςεπεξεργαστές, μεγαλύτερη μνήμη καθώς και ενσωματωμένες επιπλέονδυνατότητες όπως ασύρματη επικοινωνία και δυνατότητα επαναπρογραμματισμού.Παρά το γεγονός αυτό, το κόστος παραγωγής πέφτει αισθητά. Η τελευταίαπαρατήρηση είναι η πλέον κρίσιμη καθώς επιτρέπει την δημιουργία προσωρινώνκαι αναλώσιμων δικτύων από τέτοιες συσκευές σε ad-hoc περιβάλλοντα.

2. Η ανάπτυξη και βελτίωση των μεταφερόμενων πηγών ενέργειας (μ παταρίες) πουεπιτρέπει την αυτόνομη λειτουργία των μικροσυσκευών για εκτεταμένο χρονικόδιάστημα, σε πολλές περιπτώσεις, χρόνια χωρίς ανθρώπινη επίβλεψη. Η ανάγκηγια εφαρμογές που απαιτούν την λειτουργία παρακολούθησης του περιβάλλοντος

Δίκτυα Αισθητήρων

61

με μεγάλη λεπτομέρεια και χρονική διάρκεια (όπως παρακολούθηση δύσβατωνδασικών περιοχών, θαλάσσιος βυθός, ζώα που μετακινούνται αλλά καικατασκόπευση σε πεδία μαχών) μπόρεσαν να εκμεταλλευτούν και να επιβάλουναυτή τη δυνατότητα.

13.2 Ο Αισθητήρας-Κόμβος

Ένας αισθητήρας-κόμβος , επίσης γνωστός και σαν ' mote' (κυρίως στην ΝότιαΑμερική), είναι ένας κόμβος, ο οποίος είναι ικανός να εκτελέσει κάποιες λειτουργίες,να μαζέψει πληροφορίες και να επικοινωνήσει με άλλους συνδεδεμένους κόμβουςστο δίκτυο. Μπορεί να παρομοιαστεί με μικρό υπολογιστή- υπερβολικά απλός στασυστατικά και στο interfaces του.

Το μέγεθος ενός αισθητήρα μπορεί να ποικίλει -από μέγεθος κουτιού παπουτσιού μέχρι το μέγεθοςενός κόκκου σκόνης, παρόλο που ' motes' με γνήσιεςμικροσκοπικές διαστάσεις , που να λειτουργούν δενέχουν δημιουργηθεί. Το κόστος των κόμβων -αισθητήρων διαφέρει, από εκατοντάδες δολάρια μέχριμερικά cents, ανάλογα με το μέγεθος του δικτύουαισθητήρων και την πολυπλοκότητα κάθε αισθητήρα.Το μέγεθος και το κόστος είναι δύο παράμετροι πο υπεριορίζουν τα αποτελέσματα των κόμβων,περιορίζοντας την ενέργεια, την μνήμη, τηνυπολογιστική δύναμη και το bandwidth. Η κύριαπρόκληση είναι να παρέχουμε αισθητήρες -κόμβουςχαμηλού κόστους και μικρού μεγέθους.

Η τυπική αρχιτεκτονική ενός αισθητήρα -κόμβου φαίνεται στην παρακάτω εικόνα.Συνήθως αποτελούνται από έναν μικροελεγκτή, έναν πομποδέκτη, μία πηγή ενέργειαςκαι έναν ή περισσότερους αισθητήρες.

Εικόνα:Αρχιτεκτονική ενός αισθητήρα -κομβου

Δίκτυα Αισθητήρων

62

Ο μικροελεγκτής είναι η μονάδα επεξεργασίας του κόμβου -αισθητήρα, δηλαδήεκτελεί λειτουργίες, επεξεργάζεται δεδομένα και ελέγχει τη λειτουργία τωνυπόλοιπων συστατικών του κόμβου. Ο πομποδέκτης, ο οποίος μπορεί να είναικαλωδιωμένος ή ασύρματος, δέχεται εντολές από τον κεντρικό υπολογιστή καιμεταδίδει δεδομένα σε αυτόν. Η εξωτερική μνήμη χρησιμοποιείται για τηναποθήκευση διαφόρων δεδομένων και συνήθως χρησιμοποιείτα ι on-chip memory καιFLASH μνήμη. Η κατανάλωση ενέργειας σε έναν αισθητήρα -κόμβο χρησιμοποιείταιγια την επικοινωνία και την αίσθηση/ανίχνευση. Έχ ει αποδειχθεί πως χρειάζεταιπερισσότερη ενέργεια για την επικοινωνία των δεδομένων μέσα σε ένα κόμβο -αισθητήρα, παρά για την επεξεργασία ή για να αισθανθεί. Η ενέργεια αποθηκεύεταιείτε σε μπαταρία είτε σε πυκνωτές. Οι μπαταρίες είναι η κύρια πηγή ενέργει ας γιατους αισθητήρες-κόμβους. Οι αισθητήρες είναι ηλεκτρονικές συσκευές που παράγουνμετρημένη απάντηση σε μία αλλαγή σε φυσική συνθήκη, όπως θερμοκρασία ή πίεση.Οι αισθητήρες αισθάνονται ή μετρούν φυσικά δεδομένα μίας περιοχής που χρειάζεταινα παρακολουθηθεί. Το συνεχόμενο αναλογικό σήμα που δέχεται ένας αισθητήραςψηφιοποιείται από έναν μετατροπέα Analog-to-digital (ADC) και αποστέλλεται στονμικροελεγκτή για περαιτέρω επεξεργασία.

13.3 Χαρακτηριστικά Δικτύων Αισθητήρων

Τα σημερινά δίκτυα μικροηλεκτρονικών αισθητήρων διαθέτουν κάποια θεμελιώδηχαρακτηριστικά:

Η ύπαρξή ολοκληρωμένου ενσωματωμένου μικροεπεξεργαστή και μνήμης. Η ύπαρξη ενός ή περισσότερων ενσωματωμένων αισθητήρων και μέθοδοί

πρόσβασης στις τιμές που μετρούνται. Η δυνατότητα ασύρματης επικοινωνίας και πρωτοκόλλου επικοινωνίας με

άλλους κόμβους. Η δυνατότητά προγραμματισμού και επαναπρογραμματισμού στο επίπεδο

βασικού συστήματος λειτουργίας. Αυτονομία με χρήση μπαταρίας για ανεξάρτητη λειτουργία Το μικρό μέγεθος και το εξαιρετικά μικ ρό κόστος αγοράς ανά συσκευή. Ικανότητα να αντέξουν βαριές περιβαλλοντικές συνθήκες Ικανότητα να τα αντιμετωπίζουν επιτυχώς την αποτυχία των κόμβων Κινητικότητα των κόμβων Δυναμική τοπολογία δικτύων Ετερογένεια στους κόμβους Περιορισμένη ενέργεια που μπορούν να αποθηκεύσουν Μεγάλη γκάμα από χρήσεις Ανεπιτήρητη λειτουργία

13.4 Εφαρμογές

Τα δίκτυα αισθητήρων έχουν πολλές εφαρμογές. Χρησιμοποιούνται για νακαταγράψουν παραμέτρους όπως: τη θερμοκρασία, την υγρασία, την πίεση, τηνκατεύθυνση και την ταχύτητα του αέρα, την ένταση του φωτός, την ένταση των

Δίκτυα Αισθητήρων

63

δονήσεων, την ένταση του ήχου, τα επίπεδα μόλυνσης, τις χημικές συγκεντρώσεις, τι ςζωτικές λειτουργίες του σώματος.

Πιθανές εφαρμογές των δικτύων αισθητήρων περιέχουν: Αυτοματοποίηση εργοστασίων Αυτοματοποιημένα και έξυπνα σπίτια Παρακολούθηση Video Παρακολούθηση κυκλοφοριακής κίνησης Παρακολούθηση ιατρικής συσκευή ς Παρακολούθηση καιρικών συνθηκών Έλεγχος εναέριας κυκλοφορίας Έλεγχος ρομπότ

Δίκτυα Αισθητήρων

64

13.5 Κατανάλωση Ενέργειας

Εκατοντάδες ή χιλιάδες ασύρματοι αισθητήρες-κόμβοι με περιορισμένη ενέργειαδιασκορπίζονται τυχαία στα πεδία παρατήρησης για να πάρουμε τα μηνύματα γιατους χρήστες. Επειδή η ενέργεια το υς δεν μπορεί να επαναφορτιστεί , η επάρκειαενέργειας είναι ένα από τα πιο σημαντικά προβλήμα τα. Για τον λόγο αυτό, ερευνούμεπως μπορούν οι κόμβοι αισθητήρες να διασυνδεθούν μεταξύ τους έτσι ώστε ναμειώνεται η κατανάλωση ενέργειας. Ένας τρόπος επίλυσης του προβλήματος αυτούείναι τα ελάχιστα ζευγνύοντα δένδρα, όπου κάθε κόμβος στο γράφο είναι έν αςαισθητήρας-κόμβος. Διαφορετικά μπορούμε να βρούμε τον Gabriel γράφο τουδικτύου.

13.6 Επίλογος

Τα δίκτυα αισθητήρων αναμένεται να χρησιμοποιούνται παντού στο μέλλον, κυρίωςσε στρατιωτικές και εμπορικές εφαρμογές . Οι ερευνητές οραματίζονται πως έναμεγάλο φάσμα μελλοντικών εφαρμογών θα υλοποιείται με τη βοήθεια τωνασύρματων δικτύων αισθητήρων. Πιο συγκεκριμένα υπόσχονται πως τα ασύρματαδίκτυα αισθητήρων θα φέρουν την επανάσταση στον τρόπο που οι άνθρωποιαλληλεπιδρούν με τον φυσικό περίγυρό τους. Μ ερικά παραδείγματα τέτοιωνεφαρμογών αποτελούν και τα εξής: στρατιωτικές εφαρμογές (π.χ. παρακολούθησηπεδίου μάχης, εντοπισμό φιλικών/εχθρικών δυνάμεων, έλεγχος εξοπλισμού),παρακολούθηση περιβάλλοντος (π.χ. εντοπισμός πλημμύρας/πυρκαγιάς σε δάσος,εξερεύνηση διαστήματος), εφαρμογές υγείας (π.χ. ολοκληρωμένη παρακολούθησηασθενή, διάγνωση, εντοπισμός και παρακολούθηση ιατρών και ασθενών μέσα στονοσοκομείο) και πολλές άλλες εμπορικές εφαρμογές ( e.g. σπίτι / γραφείο έξυπνουπεριβάλλοντος, περιβαλλοντικός έλ εγχος σε κτίρια).

Δίκτυα Αισθητήρων

65

Δίκτυα Αισθητήρων

66

Β’ ΜΕΡΟΣΑΝΑΠΤΥΞΗ

ΠΡΟΓΡΑΜΜΑΤΟΣ

Δίκτυα Αισθητήρων

67

14. ΣΧΕΔΙΑΣΗ ΠΡΟΓΡΑΜΜΑΤΟΣ

14.1 Γενικά

Ο κύριος στόχος μας είναι η δημιουργία ενός προγράμματος με γραφικόπεριβάλλον, έτσι ώστε ο χρήστης να μπορέσει να προσ ομοιώσει τη λειτουργία τωνδικτύων αισθητήρων. Δεδομένου ότι τα δίκτυα αισθητήρων μπορούν νααναπαρασταθούν σαν γράφοι, το πρόγραμμα δίνει τη δυνατότητα δημιουργίας καιεπεξεργασίας ενός γράφου, το οποίο σημαίνει πως ο χρήστης μπορεί να προσθέσεικόμβους ή ακμές, να επεξεργαστεί ακμές και κόμβους και να διαγράψει κόμβους καιακμές. Επιπλέον μέσω του προγράμματος ο χρήστης μπορεί να δημιουργήσει τοελάχιστο ζευγνύον δένδρο με τη χρήση του αλγορίθμου του Kruskal, καθώς και τονGabriel γράφο. Η έννοια της κεντρικότητας αποτελεί μία ακόμη δυνατότητα, όπου οχρήστης μπορεί να επιλέξει έναν, δύο ή και τρεις διαφορετικούς αλγορίθμουςκεντρικότητας και να συγκρίνει τα αποτελέσματά τους, εξάγοντας πληροφορίες γιατη σημαντικότητα των κόμβων του γράφου. Η ενέργεια απ οτελεί ένα σημαντικόζήτημα στη μελέτη των δικτύων αισθητήρων και για τον λόγο αυτό έχει ενσωματωθείστο πρόγραμμα. Τέλος, θα πρέπει ο χρήστης να μπορεί να διαχειριστεί τα αρχεία,δηλαδή να ανοίξει ένα νέο αρχείο, να αποθηκεύσει τον γράφο σε ένα αρχείο txt ή σανμία εικόνα και να τον εκτυπώσει.

14.2 Διάγραμμα Κλάσεων

Λόγω των πολλών πλεονεκτημάτων της , αποφασίστηκε να ακολουθηθεί ηαντικειμενοστραφή σχεδίαση και ανάπτυξη του προγράμματος. Παρακάτωπαρατίθεται ένα συνοπτικό διάγραμμα κλάσεων UML του συστήματος.

Δίκτυα Αισθητήρων

68

Δίκτυα Αισθητήρων

69

15. ΣΥΓΓΡΑΦΗ ΠΡΟΓΡΑΜΜΑΤΟΣ

Για την ανάπτυξη του προγράμματος χρησιμοποιήθηκε το πρόγραμμα IntelliJIDEA με JDK 1.5 σε λειτουργικό σύστημα Windows.

15.1 Επιλογή Γλώσσας Προγραμματισμού

Για την ανάπτυξη του προγράμματος χρησιμοποιήθηκε η αντικε ιμενοστραφήςγλώσσα Java για τους παρακάτω λόγους:

Είναι σχετικά απλή στη χρήση της, καθώς οι δημιουργοί της Java άφησαν έξωαπό τη γλώσσα «δύσκολα» χαρακτηριστικά που συναντάμε σε άλλεςγλώσσες, όπως λόγου χάρη τους δείκτες της C.Η Java δημιουργεί προγράμματα με ανεξαρτησία πλατφόρμας. Αυτό σημαίνειπως το ίδιο πρόγραμμα μπορεί να εκτελεσθεί σε έναν υπολογιστή με Windowsόπως και σε έναν υπολογιστή με Linux, χωρίς κανένα πρόβλημα.Είναι ασφαλής. Η Java έχει σχεδιαστεί από την αρχή με τέτοιον τρόπο, ώστενα παρέχει ασφάλεια εκτέλεσης του κώδικα σε δίκτυο και προστασία από τηδράση των ιών.Παρέχει βιβλιοθήκες κώδικα για διάφορες χρήσεις, όπως δημιουργίαγραφικών, χειρισμό αλφαριθμητικών, μαθηματικές πράξεις, προσπέλασηαρχείων κτλ.Υπάρχουν στο διαδίκτυο αναρίθμητες ανοιχτές βιβλιοθήκες για την Java οιοποίες εξυπηρετούν διάφορους σκοπούς.

15.2 Επιπρόσθετες Βιβλιοθήκες

JUNG

Επιπλέον, χρησιμοποιήθηκε η βιβλιοθήκη της Jung για την διαχείριση τωνγράφων, αφού η Java από μόνη της δεν αρκούσε για την αποτελεσ ματικήεπεξεργασία των γράφων. Η Jung –Java Universal Network/Graph Framework- είναιμία βιβλιοθήκη η οποία παρέχει μία κοινή και επεκτάσιμη γλώσσα για τηνμοντελοποίηση , ανάλυση και οπτικοποίηση των δεδομένων τα οποία μπορούν νααναπαρασταθούν σαν ένα γράφο ή δίκτυο. Για την δημιουργία της χρησιμοποιήθηκεη Java, η οποία επιτρέπει εφαρμογές βασισμένες στην Jung να χρησιμοποιήσουν τιςενσωματωμένες ικανότητες του Java API, όπως και αυτών των δυνατοτήτων πουυπάρχουν σε άλλες Java βιβλιοθήκες.

Η αρχιτεκτονική Jung σχεδιάστηκε για να υποστηρίξει μία ποικιλία απόαναπαραστάσεις οντοτήτων και των σχέσεών τους, όπως κατευθυνόμενους και μηκατευθυνόμενους γράφους, γράφους με παράλληλες ακμές, και υπέρ -γράφους.Παρέχει έναν μηχανισμό για τον σχολιασμό γράφων, οντ οτήτων και σχέσεων μεμετά-δεδομένα . Αυτό διευκολύνει την δημιουργία αναλυτικών εργαλείων γιαπολύπλοκα σύνολα δεδομένων τα οποία εξετάζουν τις σχέσεις μεταξύ των οντοτήτωνκαι των μετά-δεδομένων που σχετίζονται με κάθε οντότητα και σχέση.

Δίκτυα Αισθητήρων

70

Η τωρινή έκδοση της Jung περιέχει υλοποιήσεις των αλγορίθμων της θεωρίαςγράφων, της ανάλυσης των κοινωνικών δικτύων, όπως ρουτίνες για ομαδοποίηση,βελτιστοποίηση, δημιουργία τυχαίων γράφων , αποσύνθεση, στατιστική ανάλυση, καιυπολογισμό των αποστάσεων του δικτύου, τ ων ροών και μέτρων της σημαντικότητας(centrality, PageRank, HITS κτλ).

Η Jung επίσης παρέχει ένα πλαίσιο οπτικοποίησης το οποίο διευκολύνει τηνδημιουργία εργαλείων για την διαδραστική εξερεύνηση των δεδομένων του δικτύου.Οι χρήστες μπορούν να χρησιμοπο ιήσουν ένα από τους layout αλγορίθμους, οι οποίοιπαρέχονται, ή να χρησιμοποιήσουν ένα πλαίσιο για να δημιουργήσουν δικά τουςlayout. Επιπλέον, παρέχονται διάφορα φίλτρα τα οποία επιτρέπουν τους χρήστες ναεστιάσουν την προσοχή τους ή τους αλγορίθμους τους σε συγκεκριμένα τμήματα τουγράφου.

Σαν μία βιβλιοθήκη ανοιχτού λογισμικού, η Jung παρέχει ένα κοινό πλαίσιο γιατην ανάλυση και την οπτικοποίηση των γράφων και των δικτύων. Για περισσότερεςπληροφορίες μπορείτε να απευθυνθείτε στην σελίδα: jung.sourcefo rge.net.

15.3 Κλάσεις Προγράμματος

Η Κλάση MyGraph

Η κλάση MyGraph αναπαριστά τον γράφο, κληρονομώντας την κλάσηUndirectedSparseMultigraph της Jung. Οι γράφοι του προγράμματος είναι μηκατευθυνόμενοι γράφοι, όπου υποστηρίζονται οι παράλληλες ακμές, όπως και οιβρόγχοι. Οι παράλληλες ακμές είναι ακμές οι οποίες ενώνουν τους ίδιους κόμβους,ενώ βρόγχος (loop) είναι μία ακμή της οποίας ο αρχικός και ο τελικός κόμβος είναιακριβώς ο ίδιος. Μέσω της κλάσης MyGraph υπάρχει η δυνατότητα να

Δίκτυα Αισθητήρων

71

αναζητήσουμε έναν κόμβο χρησιμοποιώντας σαν κλειδί το όνομά του ή τιςσυντεταγμένες του ή να αναζητήσουμε μία ακμή. Επιπλέον μπορούμε να χειριστούμετην ενέργεια του γράφου –ανανέωση ενέργειας, μείωση ενέργειας, υπολογισμόςενέργειας, εύρεση κόμβου με την μεγαλύτερη/μικρό τερη ενέργεια. Η κλάσηMyGraph διαθέτει μεθόδους για την αντιγραφή του τρέχοντος αντικειμένου,δημιουργώντας ένα αντικείμενο MyGraph ίδιο και ανεξάρτητο με το αρχικό, για τονυπολογισμό του συνολικού βάρους του γράφου και για άλλες διεργασίες.

Η Κλάση MyEdge

Η κλάση MyEdge αναπαριστά την ακμή τουγράφου. Διαθέτει δύο χαρακτηριστικά : τοόνομα, μοναδικό για κάθε ακμή, και το βάρος,το οποίο είναι προαιρετικό.

Η Κλάση MyVertex

Η κλάση MyVertex αναπαριστά τον κόμβο τουγράφου. Κάθε κόμβος αποτελείτ αι από το όνομά του,μοναδικό για κάθε κόμβο του γράφου, την ενέργειάτου, και τις συντεταγμένες του ( x,y). Η αρχικήενέργεια κάθε κόμβου είναι 100%. Παρόλα αυτάυπάρχουν μέθοδοι οι οποίοι μειώνουν ή αυξάνουντην ενέργεια.

Η Κλάση InputOutput

Η κλάση InputOutput αναπαριστά την είσοδοκαι την έξοδο των αρχείων. Αυτό σημαίνει πωςδιαθέτει μεθόδους για την ανάγνωση γράφων απόαρχεία, αλλά και την αποθήκευση αυτών. Ηανάγνωση και η εγγραφή των αρχείωντοποθετήθηκε σε ξεχωριστή κλάση, διότι σεπερίπτωση όπου μελλοντικός προγραμματιστήςεπιθυμεί να αλλάξει την είσοδο και την έξοδοτων γράφων να μπορεί να το κάνει εύκολατοποθετώντας την δική του κλάση αντί για τηνκλάση InputOutput.

Δίκτυα Αισθητήρων

72

Η Κλάση KruskalAlgorithm

Η κλάση KruskalAlgorithm είναι υπεύθυνη για την εκτέλεση του αλγορίθμου τουKruskal. Τα edges είναι οι ακμές που αποτελούν την λύση του αλγορίθμου καθώς καιεκείνες που δεν αποτελούν λύση, τα endpoints είναι τα σημεία που ενώνουν οι ακμές,ενώ τα edgesState δηλώνουν εάν οι ακμές πρέπει να προστεθούν ή να αφαιρεθούναπό τον γράφου. Οι ακμές που προστίθενται στον γράφο είναι αυτές που αποτελούνλύση του αλγορίθμου. Η κλάση χρησιμοποιεί τον αλγόριθμο ταξινόμησης merge sortγια την ταξινόμηση των ακμών. Η μέθοδος insertEdge() ελέγχει εάν η συγκεκριμένηακμή αποτελεί λύση του αλγορίθμου ή όχι, εάν δηλαδή δημιουργεί κύκλο ή όχι.

Η Κλάση GabrielAlgorithm

Η συγκεκριμένη κλάση εκτελεί τον αλγόριθμο για να πάρουμε σαν αποτέλεσματον Gabriel Graph. Η ιδιότητα solution αναφέρεται στις ακμές του γράφου πουαποτελούν την λύση του αλγορίθμου και η ιδιότητα endpoints είναι τα σημεία τωνακμών.

Η Κλάση DeletEdgeMenuItem

Δίκτυα Αισθητήρων

73

Η κλάση αυτή είναι αναπαριστά ένα JMenuItem το οποίο εκτελεί την διαγραφήμίας ακμής και υλοποιεί το interface EdgeMenuListener.

Το Interface EdgeMenuListener

Πρόκειται για ένα interface, το οποίο χρησιμοποιείται στα διάφορα menu itemsτου popup menu , τα οποία πιθυμούν να γνωρίσουν την ακμή που έχει επιλεχθεί καιτο VisualizationViewer.

Η Κλάση EdgePropItem

Η κλάση αυτή κληρονομεί την κλάση JMenuItem και υλοποιεί τα interfacesEdgeMenuListener και MenuPointListener. Θα αποτελέσει στοιχείο του popup μενούτων ακμών και θα δημιουργήσει ένα EdgePropertyDialog για τις ιδιότητες της ακμήςπου επιλέχθηκε.

Το Interface MenuPointListener

Το interface αυτό χρησιμοποιείται για να θέσει ένα σημείοστο οποίο το ποντίκι έκανε κλικ, για εκείνα τα menu items ταοποία ενδιαφέρονται για αυτή την πληροφορία. Είναι χρήσιμοεάν θέλουμε να εμφανίσουμε ένα dialog box σε μία θέσησχετική με αυτό το σημείο.

Η Κλάση VertexPropItem

Η κλάση αυτή κληρονομεί την κλάση JMenuItem και υλοποιεί τα interfacesVertexMenuListener και MenuPointListener. Θα αποτελέσει στοιχείο του popupμενού των κόμβων και θα δημιουργήσει ένα VertexPropertyDialog για τις ιδιότητεςτου κόμβου που επιλέχθηκε.

Δίκτυα Αισθητήρων

74

Η Κλάση VertexMenu

Η κλάση αυτή κληρονομεί την κλάση JPopupMenu καιδημιουργεί ένα popup menu για τον κόμβο πουεπιλέχθηκε με επιλογές όπως η διαγραφή του κόμβου, οι

ιδιότητες του κόμβου, ενώ μπορούμε να δούμε και την ενέρ γεια του κόμβου.

Η Κλάση WeightDisplay

Η κλάση αυτή υλοποιεί τοinterface EdgeMenuListener καικληρονομεί την κλάση

JMenuItem. Αποτελεί ένα στοιχείο του popup menu της ακμής που επιλέγεται καιεμφανίζει το βάρος της ακμής.

Η Κλάση EnergyDisplay

Η κλάση αυτή υλοποιεί το interface VertexMenuListener και κληρονομεί τηνκλάση JMenuItem. Αποτελεί ένα στοιχείο του popup menu του κόμβου πουεπιλέγεται και εμφανίζει την ενέργεια του κόμβου.

Η Κλάση EdgeMenu

Η κλάση αυτή κληρονομεί την κλάση JPopupMenu καιδημιουργεί ένα popup menu για την ακμή που επιλέχθηκεμε επιλογές όπως η διαγραφή της ακμής, οι ιδιότητες της

ακμής, ενώ μπορούμε να δούμε και το βάρος της ακμής.

Η Κλάση DeleteVertexMenuItem

Η κλάση αυτή είναι αναπαριστά ένα JMenuItem το οποίο εκτελεί την διαγραφήενός κόμβου και υλοποιεί το interface VertexMenuListener.

Το Interface VertexMenuListener

Δίκτυα Αισθητήρων

75

Πρόκειται για ένα interface, το οποίο χρησιμοποιείται στα διάφορα menu itemsτου popup menu , τα οποία επιθυμούν να γνωρίσουν τον κόμβο που έχε ι επιλεχθεί καιτο VisualizationViewer.

Η Κλάση MyMouseMenus

Η κλάση αυτή αποτελείται από ένα σύνολο κλάσεων, οιοποίες αναφέρθηκαν παραπάνω. Οι κλάσεις αυτέςείναι:EdgeMenu, EdgePropItem, WeightDisplay, VertexMenu,VertexPropItem, EnergyDisplay.

Η Κλάση VertexPropertyDialog

Η συγκεκριμένη κλάση κληρονομεί την JDialog και αναπαριστά ένα παράθυρο μετις ιδιότητες του επιλεγμένου κόμβου – το όνομα και την ενέργειά του. Μέσω αυτούτου παραθύρου μπορούμε να αλλάξουμε τις ιδιότητες αυτές.

Η Κλάση SkipTimeDialog

Η κλάση SkipTimeDialog κληρονομέι την κλάση JDialog και αναπαριστά έναπαράθυρο το οποίο αναφέρεται στον χρόνο. Στο παράθυρο αυτό, ο χρήστης έχει τηνδυνατότητα να ορίσει πόσα λεπτά να προχωρήσει το πρόγραμμα, έτσι ώστε να δειπως θα μειωθεί η ενέργεια μετά από αυτά τα λεπτά. Για να μπορέσει ναχρησιμοποιήσει αυτό το παράθυρο θα πρέπει πρώτα να έχει ενεργοποιήσει τον χρόνο,ορίζοντας τον τρόπο με τον οποίο θα μειώνεται η ενέργεια.

Η Κλάση PopupVertexEdgeMenuMousePlugin

Πρόκειται για GraphMousePlugin το οποίο ασχολείται με τα popup menu , ότανμία ακμή ή ένας κόμβος επιλέγεται στον γράφο. Εάν αυτά τα μενού υλοποιούν είτε το

Δίκτυα Αισθητήρων

76

EdgeMenuListener interface είτε το VertexMenuListener interface, τότε οικατάλληλες μέθοδοι του interface καλούνται για την εμφάνιση του μενού (έτσι ώστενα δείξουν πληροφορίες για την ακμή ή τον κόμβο).

Η Κλάση EdgePropertyDialog

Η συγκεκριμένη κλάση κληρονομεί την JDialog και αναπαριστά ένα παράθυρο μετις ιδιότητες της επιλεγμένης ακμής – το όνομα και το βάρος της. Μέσω αυτού τουπαραθύρου μπορούμε να αλλάξουμε τις ιδιότητες αυτές.

Η Κλάση main

Η κλάση main είναι η πρώτη κλάση που υλοποιείται.Περιέχει μέσα τη μέθοδο main(String[] args).

Η Κλάση ChartFrame

Η κλάση ChartFrame κληρονομεί από τηνκλάση JFrame και αναπαριστά ένα παράθυροτο οποίο περιέχει ένα διάγραμμα. Τοδιάγραμμα αποτελείται από δύο μπάρεςενέργειας , μία για τον αλγόριθμο του Kruskal

και μία για τον Gabriel Graph για έναν γράφο, έτσι ώστε ο χρήστης να μπορέσει νασυγκρίνει τις ενέργειες των δύο αλγορίθμων για τον ίδιο γράφο. Η κλάση αυτήπεριέχει την κλάση MyCanvas.

Η Κλάση MyCanvas

Πρόκειται για την κλάση, η οποία σχεδιάζει το διάγραμμα καικληρονομεί από την κλάση Canvas.

Δίκτυα Αισθητήρων

77

Η Κλάση HelpListener

Η κλάση αυτή κληρονομεί την κλάσηActionListener και αναφέρεται στις ενέργειες πουθα γίνονται όταν επιλεχθεί κάποιο στοιχείοβοήθειας. Τα στοιχεία βοήθειας είναι η βοήθειακαι το Σχετικά. Στην περίπτωση πουαναφερόμαστε στο στοιχείο Βοήθεια ανοίγει τοαρχείο του Word που περιέχει την βοήθεια. Εάνεπιλεχθεί το στοιχείο Σχετικά τότε εμφανίζεται το παράθυρο με τις απαραίτητεςπληροφορίες.

Η Κλάση MyEditingGraphMousePlugin

Η κλάση MyEditingGraphMousePLugin κληρονομεί την κλάσηEditingGraphMousePluhgin και την επεκτείνει κατά πολύ λίγο, έτσι ώστε ναανατίθενται στο αντικείμενο του κόμβου και οι συντεταγμένες κατά τη δημιουργίατου. Ως επί τον πλείστον, ο κώδικας είναι του δημιουργού Tom Nelson.

Η Κλάση TimeDialog

Η κλάση αυτή κληρονομεί την κλάση JDialog καιεμφανίζει ένα παράθυρο για την ενεργο ποίηση καιπαραμετροποίηση του χρόνου. Τα χαρακτηριστικά τηςκλάσης είναι η ενέργεια, η οποία θα μειώνεται, και κάθεπόσα λεπτά θα μειώνεται η ενέργεια.

Η Κλάση MyEditingModalGraphMouse

Δίκτυα Αισθητήρων

78

Η κλάση αυτή κληρονομεί την κλάση EditingModalGraphMouse, αναπαριστώνταςτο ποντίκι για τον γράφο. Περιέχει τα popup μενού για τις ακμές και τους κόμβους.

Η Κλάση MyEdgeFactory

Πρόκειται για την κλάση η οποία παράγει αυτόματατις ακμές, όταν χρησιμοποιούμε το ποντίκι για ναδημιουργήσουμε μία ακμή.

Η Κλάση MyVertexFactory

Πρόκειται για την κλάση, η οποία παράγειαυτόματα τους κόμβους, όταν χρησιμοποιούμε τοποντίκι για την δημιουργία του κόμβου.

Η Κλάση AboutDialog

Η κλάση αυτή κληρονομεί από την κλάση JDialogκαι εμφανίζει ένα παράθυρο με πληροφο ρίες σχετικέςμε το πρόγραμμα.

Η Κλάση GraphInfoDialog

Η κλάση αυτή κληρονομεί την κλάση JDialog αναπαριστώντας πληροφορίες πουαφορούν τον τρέχοντα γράφο. Εάν δεν υπάρχει κάποιος γράφος εμφανίζεται μήνυμαλάθους, διαφορετικά εμφανίζονται σε ένα παράθυρο πληροφορίες όπως ο αριθμόςτων ακμών, ο αριθμός των κόμβων, το συνολικό βάρος του γράφου, η συνολικήενέργεια του γράφου, ο κόμβος με την μεγαλύτερη ενέργεια και ο κόμβος με τηνμικρότερη ενέργεια.

Η Κλάση RandomGraphDialog

Η κλάση RandomGraphDialog εμφανίζει το παράθυρο απ’ όπου ο χρήστης έχειτην δυνατότητα να δημιουργήσει έναν τυχαίο γράφο, ορίζοντας τον αριθμό τωνκόμβων , τον αριθμό των ακμών, εάν θα υπάρχουν βάρη στις ακμές και εάν θα

Δίκτυα Αισθητήρων

79

υπάρχουν βρόγχοι στο νέο γράφο. Ο αριθμός των κόμβων θα πρ έπει να είναιμεγαλύτερος από δύο. Τα βάρη που ανατίθενται στις ακμές είναι τυχαίοι αριθμοί απότο 0 μέχρι το 100. Στη συνέχεια ο τυχαίος γράφος εμφανίζεται. Σε περίπτωση λάθουςεμφανίζεται το κατάλληλο μήνυμα και η διαδικασία ακυρώνεται.

Η Κλάση ClockLabel

Πρόκειται για μία εξαιρετικά απλή κλάση, ηοποία αναπαριστά μία ετικέτα, κληρονομώντας τηνκλάση JLabel. Η ετικέτα αναπαριστά ταδευτερόλεπτα τα οποία περνούν όταν έχειενεργοποιηθεί ο χρόνος.

Η Κλάση vertexFillColor

Πρόκειται για την κλάση η οποία ορίζει πως θαχρωματίζονται οι κόμβοι ανάλογα με την ενεργείατους, κληρονομώντας την κλάση Transformer.

Η Κλάση MyPrintableImpl

Η κλάση αυτή καθορίζει τον τρόπο με τον οποίο θα εκτυπωθεί ο γράφος από ένανεκτυπωτή.

Η Κλάση CloseDialog

Η κλάση αυτή αναπαριστά το παράθυρο το οποίοεμφανίζεται όταν ο χρήστης επιθυμεί έξοδο από τοπρόγραμμα. Ο χρήστης έχει την επιλογή να αποθηκεύσειτον γράφο και να κλείσει το πρόγραμμα, να μηναποθηκεύσει τον γράφο και να κλείσει το πρόγραμμα,και να ακυρώσει την ενέργεια εξόδου. Η κλάση αυτήκληρονομεί την κλάση JDialog.

Δίκτυα Αισθητήρων

80

Η κλάση CentralityPanel

Η κλάση CentralityPanel αναπαριστάένα Panel, το οποίο αφορά τα μέτρα γιατην centrality του γράφου. Πιοσυγκεκριμένα κληρονομεί την κλάσηJPanel, διαθέτει μία περιοχή κειμένουόπου εμφανίζονται πληροφορίες για τηνcentrality, τρία check Boxes για τουςαλγόριθμους: HITS, BetweennessCentrality και randomWalkCentrality. Οχρήστης μπορεί να επιλέξει και ένα, δύο ήκαι τους τρεις αλγορίθμους και να δει τααποτελέσματά του.

Η Κλάση insertionPanel

Η κλάση αυτή αναπαριστά το πάνελτο οποίο αφορά την εισαγωγή ακμώνκαι κόμβων μέσω φόρμας. Επιπλέονεάν επιλεχθεί κάποιος κόμβος ή κάποιαακμή, οι σχετικές πληροφορίεςεμφανίζονται στο πάνελ αυτό και οχρήστης έχει τη δυνατότητα να τιςαλλάξει. Οι πληροφορίες αυτέςαφορούν το όνομα του κόμβου, τιςσυντεταγμένες του κόμβου, τηνενέργεια του κόμβου, το όνομα τηςακμής, οι κόμβοι που ενώνει η ακμή καιτο βάρος της ακμής. Κληρονομεί τηνκλάση JPanel.

Η Κλάση MyFrame

Η κλάση αυτή είναι η πιο σημαντική κλάση του προγράμματος και αναπαριστά τοκύριο παράθυρο της εφαρμογής. Κληρονομεί την κλάση JFrame και εκτελεί τιςπερισσότερες επιλογές του χρήστη σε συνεργασία με τις υπόλοιπες κλάσεις. Μέσωτης κλάσης αυτής εκτελούνται ενέργειες όπως: δημιουργία νέου γράφου, ανάγνωσηγράφου από αρχείο, αποθήκευση ως γράφου, αποθήκευση γράφου, αποθήκευσηγράφου σαν εικόνα, εκτύπωση γράφου, δημιουργία τυχαίου γράφου, επαναφορά στοναρχικό γράφο, εκτέλεση του αλγορίθμου του Kruskal, εκτέλεση του αλγορίθμου τουGabriel, έξοδος από το πρόγραμμα, ενεργοποίηση/απενεργοποίηση χρόνου, σύγκρισηαλγορίθμων. Οι ενέργειες αυτές δεν εκτελούνται εξ’ ολοκλήρου από την κλάσηMyFrame, απλώς αυτή είναι που θα καθορίσει τον τρόπο με τον οποίο θααλληλεπιδράσουν οι υπόλοιπες κλάσεις.

Δίκτυα Αισθητήρων

81

Δίκτυα Αισθητήρων

82

16. ΛΕΙΤΟΥΡΓΙΕΣ ΣΥΣΤΗΜΑΤΟΣ

Η εφαρμογή υποστηρίζει ένα πλήθος από λειτουργίες που αφορούν την οργάνωσητων γράφων, την δημιουργία ζευγνύοντος δένδρου και τη δημιορυγία Gabrielγράφου, την εξαγωγή πληροφοριών σχετικά με την τοπολογία και τ ην κεντρικότητα(centrality) του γράφου, την διαχείριση της ενέργειας του δικτύου και άλλα.Παρακάτω όλες οι λειτουργίες που υποστηρίζονται από την εφαρμογή αναλύονται μελεπτομέρεια.

Δημιουργία Νέου Γράφου

Ο χρήστης θα πρέπει να έχει τη δυνατότητα να δη μιουργήσει έναν νέο γράφο ανάπάσα στιγμή. Αυτό σημαίνει πως οποιοσδήποτε γράφ ος εμφανίζεται εκείνη τηστιγμή, «αφαιρείτε» και δημιουργείτε ένας κενός χώρος για τον νέο γράφο. Επιπλέον,εάν ο χρήστης εκτελεί κάποιον αλγόριθμο εκείνη τη στιγμή, σταματά αμέσ ως και όλατα δεδομένα που σχετίζονται με τον αλγόριθμο χάνονται.

Ο χρήστης μπορεί με τρεις τρόπους να δημιουργήσει έναν νέο κενό γράφο: Κάνοντας κλικ στο πρώτο εικονίδιο

της γραμμής εργαλείων.

Επιλέγοντας το μενού «File» μενού και στη συνέχεια «New Graph».

Πατώντας Ctrl και Ν

Άνοιγμα Γράφου

Μία ακόμα λειτουργία του συστήματος είναι το άνοιγμα γράφου, δηλαδή ηανάγνωση και η προβολή ενός γράφου, ο οποίος είναι αποθηκευμένος σε ένα txtαρχείο. Ο χρήστης μπορεί να γράψει σε ένα txt αρχείο το δικό του γράφο και να τοανοίξει με το πρόγραμμα ή διαφορετικά να ανοίξει κάποιο υπάρχον αρχείο, το οποίομπορεί να έχει αποθηκεύσει παλιότερα. Για να μπορέσει το πρόγραμμα να ανοίξει τααρχεία, θα πρέπει να έχουν συγκεκριμένη μορφή, η οποία φαίνεται παρακάτω.

Δίκτυα Αισθητήρων

83

Το αρχείο χωρίζεται σε δύο μέρη: ένα για τους κόμβους και ένα για τις ακμές. Όσοναφορά το πρώτο κομμάτι, κάθε κόμβος γράφεται σε νέα γραμμή. Για να μπορέσει ναγίνει αποδεκτός ο κόμβος, θα πρέπει να έχει τη μορφή: «ΌνομαΚόμβου(Χ,Υ), όπουτο όνομα του κόμβου θα πρέπει να είναι μοναδικό, οι συντεταγμένες (Χ,Υ) θα πρέπεινα είναι θετικές και να μην υπάρχει άλλος κόμβος σε αυτές τις συντεταγμένες. Εάνκάτι πάει στραβά, ο κόμβος δεν προστίθεται, εμφανίζοντας το κατάλληλο μήνυμα,και το σύστημα προχωράει στην προ σθήκη του επόμενου κόμβου. Μετά τηνανάγνωση των κόμβων, προχωράμε στην ανάγνωση του δεύτερου μέρους που είναι οιακμές. Κάθε ακμή γράφεται σε νέα γραμμή και έχει την μορφή:«ΌνομαΑκμής(ΌνομαΚόμβου1,ΌνομαΚόμβου2,Βάρος)». Το όνομα της ακμήςπρέπει να είναι μοναδικό, ενώ οι κόμβοι τους οποίους και ενώνει θα πρέπει νααναφέρονται στο πρώτο μέρος του αρχείου. Τέλος το βάρος της ακμής είναι έναςθετικός αριθμός μεταξύ του 0 και του 100, αλλά ο χρήστης μπορεί να δώσει σανβάρος το σύμβολο «-» και έτσι δεν θα ανατεθεί βάρος στην ακμή. Εάν δημιουργηθείκάποιο σφάλμα, η ακμή δεν θα προστεθεί, εμφανίζοντας το κατάλληλο μήνυμα.

Ο χρήστης μπορεί να εκτελέσει τη λειτουργία «Άνοιγμα Γράφου» με τρεις τρόπους: Κάνοντας κλικ στο δεύτερο εικονίδιο

της γραμμής εργαλείων .

Επιλέγοντας το «File» μενού και στη συνέχεια «Open Graph».

Πατώντας Ctrl και Ο.

Δίκτυα Αισθητήρων

84

Αποθήκευση Ως Γράφου

Η λειτουργία αυτή αποθηκεύει τον υπάρχον γράφο σε ένα νέο αρχείο txt το οποίοθα επιλέξει ο χρήστης. Ο γράφος αποθηκεύεται στο αρχείο με την ίδια μορφ ή όπωςπαραπάνω, έτσι ώστε να μπορεί το πρόγραμμα να το ανοίξει αργότερα, αν χρειαστεί.

Ο χρήστης μπορεί να επιλέξει τη λειτουργία αυτή με δύο τρόπους: Επιλέγοντας το μενού «File» μενού και στη συνέχεια «Save As».

Πατώντας Ctrl και S.

Αποθήκευση Γράφου

Ο χρήστης της εφαρμογής μπορεί να αποθηκεύσει τον γράφο σε ήδη υπάρχοναρχείο. Αυτό σημαίνει πως εάν ο χρήστης ανοίξει κάποιο αρχείο και διαχειρίζεται τονγράφο του με το πρόγραμμα, μπορεί να αποθηκεύσει τις αλλαγές σε αυτό το αρχείο.Ακριβώς το ίδιο ισχύει εάν κάνει «Αποθήκευση Ως» σε ένα αρχείο τον γράφο, καιτον αλλάξει στη συνέχεια, μπορεί να τον αποθηκεύσει σε αυτό το αρχείο με τοπάτημα ενός κουμπιού. Η λειτουργία αυτή είναι ανενεργή, όταν ο γράφος δεν ανήκεισε κανένα αρχείο.

Υπάρχουν δύο τρόποι εκτέλεσης της λειτουργίας: Κάνοντας κλικ στο τρίτο

εικονίδιο της γραμμήςεργαλείων .

Επιλέγοντας το μενού «File» μενού και στη συνέχεια «Save».

Δίκτυα Αισθητήρων

85

Αποθήκευση Γράφου Ως εικόνα

Μία από τις δυνατότητες του προγράμματος είναι η αποθήκευση του γράφου ωςεικόνα. Αυτό επιτρέπει στους χρήστες να χειριστούν πλέον τον γράφο ως εικόνα, νατον τοποθετήσουν σε κάποια παρουσίαση ή σε κάποιο έγγραφο. Εάν δεν υπάρχεικάποιος γράφος θα εμφανιστεί το κατάλληλο μήνυμα.

Υπάρχουν δύο τρόποι για την εκτέλεση της λειτουργίας αυ τής: Κάνοντας κλικ στο

τέταρτο εικονίδιο τηςγραμμής εργαλείων.

Επιλέγοντας το «File» μενού και στη συνέχεια «Save As Image».

Εκτύπωση Γράφου

Επιπλέον, ο χρήστης μπορεί να εκτυπώσει τον γράφο σε χαρτί.Υπάρχουν τρεις τρόποι για την εκτέλεση της λειτου ργίας: Κάνοντας κλικ στο

πέμπτο εικονίδιο τηςγραμμής εργαλείων.

Επιλέγοντας το «File» μενού και στη συνέχεια «Print».

Πατώντας Ctrl και P.

Έξοδος Από το Πρόγραμμα

Κατά την έξοδο από την εφαρμογή, εμφανίζεται ένα παράθυρο, το οποίο «ρωτάει»τον χρήστη εάν θέλει να αποθηκεύσει τον γράφο και να κλείσει την εφαρμογή, ναμην αποθηκεύσει τον γράφο και να κλείσει την εφαρμογή, και να ακυρώσει τηνλειτουργία της εξόδου.

Υπάρχουν τέσσερεις τρόποι για να κλείσει η εφαρμογή:

Δίκτυα Αισθητήρων

86

Κάνοντας κλικ στο έβδομοεικονίδιο της γραμμήςεργαλείων.

Επιλέγοντας το «File» μενού και στη συνέχεια «Quit».

Πατώντας Ctrl και Q. Πατώντας το x του κύριου παραθύρου της εφαρμογής.

Επαναφορά στον Αρχικό Γράφο

Όταν εκτελείται κάποιος αλγόριθμος, η εφαρμογή αποθηκεύει προσωρινά τοναρχικό γράφο, σε περίπτωση που ο χρήστης επιθυμεί να επιστρέψει σε αυτόν. Εάνδημιουργηθεί νέος γράφος ή ανοιχτεί κάποιο αρχείο, τότε ο αρχικός γράφοςδιαγράφεται.

Για να επιστρέψει ο χρήστης στον αρχικό γράφο επιλέγει « Graph» μενού και στησυνέχεια «Initial Graph».

Δημιουργία Τυχαίου Γράφου

Το πρόγραμμα έχει τη δυνατότητα να δημιουργήσει έναν τυχαίο γράφο. Ο χρήστηςμέσω μίας φόρμας μπορεί να συμπληρώσει διάφορες παραμέτρους για τον τυχαίογράφο, όπως τον αριθμό των κόμβων, τον αριθμό των ακμών, να επιλέξε ι αν θαανατεθούν τυχαία βάρη στις ακμές και εάν θα υπάρχουν βρόγχοι στον γράφο. Οαριθμός των κόμβων θα πρέπει να είναι ίσος ή μεγαλύτερος από το 2, διαφορετικά θαεμφανιστεί μήνυμα λάθους. Τα βάρη των ακμών επιλέγονται τυχαία και είναι μεταξύτου 0 και του 100. Ενώ οι συντεταγμένες των κόμβων επιλέγονται και αυτές τυχαίακαι είναι μεταξύ του 0 και 550.

Δίκτυα Αισθητήρων

87

Για να δημιουργηθεί ένας τυχαίος γράφος, ο χρήστης επιλέγει το « Graph» μενούκαι στη συνέχεια «Random Graph».

Πληροφορίες Γράφου

Με την λειτουργία αυτή, εμφανίζονται κάποιες πληροφορίες για τον τρέχονταγράφο, όπως ο αριθμός των κόμβων του γράφου, ο αριθμός των ακμών του γράφου,το συνολικό βάρος του γράφου, η συνολική ενέργεια του γράφου, ο κόμβος με τηνλιγότερη ενέργεια και ο κόμβος με την μεγαλύτερ η ενέργεια. Εάν στον γράφο δενέχουν ανατεθεί σε όλες τις ακμές βάρος, τότε το συνολικό βάρος του γράφου δενυπολογίζεται. Ενώ εάν δεν υπάρχει γράφος, τότε δεν υπάρχουν πληροφορίες καιεμφανίζεται μήνυμα λάθους.

Για να εμφανιστούν οι πληροφορίες του γράφου , ο χρήστης επιλέγει το «Graph»μενού και στη συνέχεια το «Graph’s Info».

Επαναφόρτιση Κόμβων

Ο χρήστης έχει τη δυνατότητα να επαναφέρει όλους τους κόμβους στο 100% τηςενέργειάς τους. Για να συμβεί αυτό επιλέγει το « Graph» μενού και στη συνέχεια το«Charge the Nodes».

Δίκτυα Αισθητήρων

88

Ανανέωση

Σε περίπτωση, που ο γράφος «κολλήσει» ή δεν φαίνεται σωστά ο γράφος, υπάρχειη δυνατότητα της ανανέωσης του γράφου για να επιλυθεί το πρόβλημα. Για νασυμβεί αυτό ο χρήστης επιλέγει το «Graph» και στη συνέχεια «Refresh».

Ενεργοποίηση/Απενεργοποίηση Χρόνου

Ο χρήστης έχει τη δυνατότητα να ενσωματώσει τον χρόνο στον γράφο του. Ηενεργοποίηση του χρόνου εμφανίζει ένα παράθυρο, το οποίο επιτρέπει στον χρήστηνα ορίσει κάποιες παραμέτρους όπως τα λεπτά και η ενέργεια. Αυτό σημαί νει πως οχρήστης θα πρέπει να καθορίσει κάθε πόσα λεπτά θα μειώνεται η ενέργεια στουςκόμβους και κατά πόσο θα μειώνεται η ενέργεια των κόμβων.

Με άλλα λόγια, όσο περνάει ο χρόνος η ενέργεια των κόμβων μειώνεται. Με αυτότον τρόπο προσπαθούμε να προσ ομοιώσουμε την πραγματική λειτουργία τωναισθητήρων – κόμβων , οι οποίοι διαθέτουν κάποια πηγή ενέργειας, όπως ημπαταρία, η οποία εξαντλείται καθώς ο χρόνος περνάει. Όταν έχει ενεργοποιηθεί οχρόνος, εμφανίζεται μία «ετικέτα» στο πρόγραμμα με τα δευτερόλε πτα τα οποίαπερνάνε, ενώ υπάρχει και η δυνατότητα να απενεργοποιήσουμε τον χρόνο.

Δίκτυα Αισθητήρων

89

Για την ενεργοποίηση/απενεργοποίηση του χρόνου υπάρχουν δύο τρόποι: Επιλέγοντας το «Graph» μενού, έπειτα το «Time» και τέλος «Enable Time» ή

«Disable Time».

Πατώντας Alt και C.

Επιτάχυνση Χρόνου

Υπάρχει η δυνατότητα, να προχωρήσει ο χρόνος μπροστά, αφού καθορίσει οχρήστης πρώτα πόσα λεπτά θα προχωρήσει μέσω ενός παραθύρου.

Αυτό σημαίνει πως εάν ο χρήστης δεν μπορεί να περιμένει τον χρόνο να περάσειμε τους φυσιολογικούς ρυθμούς για να δει την μείωση της ενέργειας στον γράφο,μπορεί να προχωρήσει τον χρόνο μπροστά όσα λεπτά θέλει. Για να συμβεί αυτό, οχρήστης πρέπει να έχει ήδη ενεργοποιήσει τον χρόνο.

Ο χρήστης μπορεί να προχωρήσει τον χρόνο μπροστά, επιλέγει το «Graph», έπειτα«Time» και τέλος «Move Forward Time».

Δίκτυα Αισθητήρων

90

Μετασχηματισμός Γράφου

Ο χρήστης μπορεί να μεταφέρει ολόκληρο τον γράφο προς οποιαδήποτεκατεύθυνση. Για να συμβεί αυτό, υπάρχουν δύο τρόποι:

Ο χρήστης επιλέγει από το μενού το στοιχείο « Mouse Mode» και στησυνέχεια «Transforming».

Διαφορετικά πατώντας Alt και Τ.

Μεγέθυνση Γράφου

Υπάρχει η δυνατότητα να μεγεθυνθεί ο γράφος εάν το επιθυμεί ο χρήστης. Αυτόμπορεί να γίνει με δύο τρόπους:

Επιλέγοντας το στοιχείο zoom in της γραμμήςεργαλείων.

Πατώντας Alt και Ι. Κουνώντας προς τα κάτω την κεντρική ροδέλα του ποντικιού.

Σμίκρυνση Γράφου

Επιπλέον , το πρόγραμμα δίνει τη δυνατότητα στον χρήστη να σμικρύνει τογράφο. Αυτό μπορεί να γίνει με τρεις τρόπους:

Επιλέγοντας το στοιχείο zoom out της γραμμήςεργαλείων.

Πατώντας Alt και Ο. Κουνώντας προς τα επάνω την κεντρική ροδέλα του ποντικιού.

Δίκτυα Αισθητήρων

91

Βοήθεια

Ανά πάσα στιγμή, εάν ο χρήστης έχει κάποια απορία ή δεν γνωρίζει πώς ναχρησιμοποιήσει το πρόγραμμα, υπάρχει ένα αρχείο βοήθειας το οποίο ανοίγει.

Για να ανοίξει το αρχείο της βοήθειας υπάρχουν τρεις τρόποι: Επιλέγοντας το στοιχείο της

βοήθειας της γραμμήςεργαλείων.

Επιλέγοντας το «Help» μενού και στη συνέχεια «Help».

Πατώντας Ctrl και Η.

Σχετικά

Η λειτουργία Σχετικά του συστήματος εμφανίζει ένα παράθυρο με πληροφορίεςσχετικές με το πρόγραμμα. Για να εμφανιστούν οι πληροφορίες αυτές, ο χρήστηςπρέπει να επιλέξει το στοιχείο «Help» και στη συνέχεια «About».

Προσθήκη Κόμβου στον Γράφο

Υπάρχει η δυνατότητα αλληλεπίδρασης του χρήστη με τον γράφ ο. Μία από τιςπιθανές λειτουργίες είναι η προσθήκη κόμβου στον γράφο. Υπάρχουν δύο τρόποιεισαγωγής νέου κόμβου.

Ένας τρόπος για να προσθέσει ο χρήστης κόμβο, είναι να επιλέξει αρχικά τοστοιχείο «Mouse Mode» του μενού και στη συνέχεια «Editing» (ή πατώνταςAlt και E).

Στη συνέχεια, ο χρήστης, στον χώρο σχεδίασης του γράφου, κάνει αριστερόκλικ και έτσι δημιουργείται ένας νέος κόμβος.

Διαφορετικά, ο χρήστης διαλέγει το « Insertion Panel» και συμπληρώνει τηνεπάνω φόρμα εισαγωγής κόμβου.

Δίκτυα Αισθητήρων

92

Διαγραφή κόμβου

Μία επιπλέον λειτουργία για την αλληλεπίδραση με τον γράφο, είναι η διαγραφήκόμβου. Για να διαγράψει ο χρήστης έναν κόμβο, κάνει δεξί κλικ με το ποντίκι επάνωστον κόμβο που θέλει να διαγράψει και εμφανίζεται ένα popup μενού. Τέλος επιλέγειστο μενού το στοιχείο «Delete Node ΌνομαΚόμβου». Όταν διαγράφεται έναςκόμβος, τότε όλες οι ακμές που ενώνουν αυτόν τον κόμβο με άλλους κόμβουςδιαγράφονται.

Δίκτυα Αισθητήρων

93

Επεξεργασία Κόμβου

Η επεξεργασία του κόμβου είναι μια σημαντική δυνατότητα, καθώς ο χρήστηςμπορεί να αλλάξει το όνομα του κόμβου, τις συντεταγμένες του κόμβου και τηνενέργειά του. Για να γίνει αυτό υπάρχουν δύο τρόποι:

Ο χρήστης κάνει δεξί κλικ πάνω στον κόμβο που θέλει να επεξεργαστεί, καιαυτομάτως εμφανίζεται ένα popup μενού και στη συνέχεια επιλέγει τοστοιχείο «Edit Node Properties».

Στη συνέχεια εμφανίζεται ένα παράθυρο, απ’ όπου ο χρήστης μπορεί νααλλάξει το όνομα του κόμβου και την ενέργειά του.

Διαφορετικά, ο χρήστης επιλέγει το στοιχείο « Mouse Mode» του μενού καιστη συνέχεια «Picking» (ή πατώντας Alt και P).

Ο χρήστης κάνει δεξί κλικ στον κόμβο, τον οποίο επιθυμεί να επεξεργαστεί.Μόλις γίνει αυτό, οι πληροφορίες του κόμβου εμφανίζονται στο insertionpanel ,απ’ όπου ο χρήστης μπορεί να αλλάξει ότι θέλει.

Δίκτυα Αισθητήρων

94

Προσθήκη Ακμής

Ο χρήστης μπορεί να προσθέσει μία ακμή στον υπάρχον γράφο και μπορεί ναγίνει με δύο τρόπους:

Ένας τρόπος για να προσθέσει ο χρήστης ακμή, είναι να επιλέξει αρχικά τοστοιχείο «Mouse Mode» του μενού και στη συνέχεια «Editing» (ή πατώνταςAlt και E).

Στη συνέχεια, ο χρήστης, στον χώρο σχεδίασης του γράφου, κάνει αριστερόκλικ πάνω στον ένα κόμβο που θα ενώνει η ακμή και κρατώντας πατημένο το

Δίκτυα Αισθητήρων

95

αριστερό κλικ σέρνει την ακμή μέχρι τον άλλο κόμβο που θα ενώνει η ακμήκαι εκεί αφήνει το αριστερό κλικ.

Διαφορετικά, ο χρήστης διαλέγει το «Insertion Panel» και συμπληρώνει τηνκάτω φόρμα εισαγωγής ακμής.

Διαγραφή Ακμής

Υπάρχει δυνατότητα διαγραφή μίας ακμής του γράφου. Για να συμβεί αυτό, οχρήστης κάνει δεξί κλικ επάνω στην ακμή, την οποία θέλει να διαγράψει, καιεμφανίζεται ένα popup μενού. Στη συνέχεια, επιλέγει το στοιχείο του μενού « DeleteNode ‘ΟνομαΚόμβου» και η ακμή διαγράφεται.

Δίκτυα Αισθητήρων

96

Επεξεργασία Ακμής

Μέσα από το πρόγραμμα, δίνεται η δυνατότητα στον χρήστη να επεξεργαστεί τηνακμή, αλλάζοντας τις ιδιότητες της, ό πως το όνομα της ακμή, τους κόμβους πουενώνει η ακμή και το βάρος της ακμής. Υπάρχουν δύο τρόποι για την επεξεργασίατης ακμής:

Ο χρήστης κάνει δεξί κλικ πάνω στην ακμή που θέλει να επεξεργαστεί, καιαυτομάτως εμφανίζεται ένα popup μενού και στη συνέχεια επιλέγει τοστοιχείο «Edit Edge Properties».

Στη συνέχεια εμφανίζεται ένα παράθυρο απ’ όπου ο χρήστης μπορεί να αλλάξει οόνομα και το βάρος της ακμής.

Δίκτυα Αισθητήρων

97

Διαφορετικά, ο χρήστης επιλέγει το στοιχείο « Mouse Mode» του μενού καιστη συνέχεια «Picking» (ή πατώντας Alt και P).

Ο χρήστης κάνει δεξί κλικ στην ακμή, την οποία επιθυμεί να επεξεργαστεί.Μόλις γίνει αυτό, οι πληροφορίες της ακμής εμφανίζονται στο insertion panel,απ’ όπου ο χρήστης μπορεί να αλλάξει ότι θέλει.

Δίκτυα Αισθητήρων

98

Επιλογή και Εκτέλεση Μέτρων Κεντρικότητας

Υπάρχει η δυνατότητα ο χρήστης να επιλέξει κάποιο(α) από τα τρία μέτρακεντρικότητας και στη συνέχεια να εκτελεσθεί για να εξαχθούν διάφορεςπληροφορίες για τον γράφο. Για τον λόγο αυτό, υπάρχει στο πρόγραμμα το CentralityPanel.

Στο πάνελ αυτό πάνω υπάρχουν τρείς αλγόριθμοι κεντρικότητας : ο αλγόριθμοςBetweenness Centrality, ο αλγόριθμος HITS και ο αλγόριθμος Random WalkBetweenness Centrality. Ο χρήστης μπορεί να επιλέξει ένα, δυο ή και τους τρειςαλγορίθμους και στη συνέχεια να πατ ήσει το κουμπί «Run». Κάθε ένας από τουςτρεις αλγορίθμους βαθμολογεί τους κόμβους του γράφου. Τα αποτελέσματα τωναλγορίθμων εμφανίζονται στην περιοχή κειμένου, που βρίσκεται στο πάνελ,τοποθετημένα σε έναν πίνακα. Για να εκτελεσθεί ο αλγόριθμος Random Walk

Δίκτυα Αισθητήρων

99

Betweenness Centrality, ο γράφος θα πρέπει να είναι συνδεδεμένος. Εάν δεν είναι καιο χρήστης επιθυμεί να εκτελεσθεί ο αλγόριθμος, τότε εμφανίζεται μήνυμα λάθους.

Εκτέλεση Αλγορίθμου του Kruskal

Μία από τις λειτουργίες του συστήματος είναι η εκτέλεση του αλγορίθμου τουKruskal. Ο αλγόριθμος αυτός έχει ως αποτέλεσμα το ελάχιστο ζευγνύον δένδρο τουγράφου.

Ο χρήστης επιλέγει από το πάνελ «Topology Control» τον αλγόριθμο του Kruskalκαι στη συνέχεια μπορεί να δει το αποτέλεσμα του αλγορίθμου με δύο τ ρόπους:

Απευθείας, πατώντας το κουμπί «See the Result». Στην περίπτωση αυτή, τοελάχιστο ζευγνύον δένδρο εμφανίζεται στο χώρο σχεδίασης του γράφου, όπουοι έντονες ακμές είναι οι ακμές της λύσης του αλγορίθμου και εμφανίζεται τοσυνολικό βάρος και η συνολική ενέργεια του γράφου στην περιοχή κειμένουτου πάνελ.

Δίκτυα Αισθητήρων

100

Διαφορετικά ο αλγόριθμος μπορεί να εκτελεσθεί βήμα -βήμα, πατώντας τα

κουμπιά (προηγούμενο βήμα) και (επόμενο βήμα) της γραμμήςεργαλείων. Σε αυτή την περίπτωση, ο χρήστης μπορεί να παρατηρήσει πω ςπροστίθενται και αφαιρούνται ακμές στον γράφο κατά την εκτέλεση τουαλγορίθμου. Οι ακμές με έντονο μαύρο χρώμα είναι και η λύση τουαλγορίθμου. Όταν ολοκληρωθεί η διαδικασία εμφανίζονται στην περιοχή τουκειμένου το συνολικό βάρος του γράφου και η συνολι κή ενέργεια του γράφου.Ανά πάσα στιγμή ο χρήστης μπορεί να πατήσει το κουμπί « See the Result»για να δει κατευθείαν το τελικό αποτέλεσμα. Εάν ο χρήστης πατήσει

επανειλημμένα το κουμπί και φτάσει στον αρχικό γράφο, εμφανίζεταιένα μήνυμα για να ενημερωθεί ο χρήστης.

Εάν δεν υπάρχει κάποιος γράφος και ο χρήστης θέλει να εκτελέσει τον αλγόριθμοτου Kruskal, τότε εμφανίζεται μήνυμα λάθους. Ενώ για να μπορέσει να εκτελεσθεί οαλγόριθμος του Kruskal, θα πρέπει να έχουν ανατεθεί βάρη σε όλες τις ακμές τουγράφου, σε διαφορετική περίπτωση εμφανίζεται μήνυμα λάθους. Κατά την εκτέλεσητου αλγορίθμου του Kruskal, αφαιρείται ενέργεια από τους κόμβους ως εξής: ότανεπιλέγεται μία ακμή σαν λύση του αλγορίθμου, αφαιρείται 5% ενέργεια από κάθεκόμβο που ενώνει η ακμή καθώς επίσης και 0,1% επί το βάρος της ακμής αυτής.

Εκτέλεση Αλγορίθμου του Gabriel

Μία άλλη λειτουργία του συστήματος είναι η εκτέλεση του αλγορίθμου τουGabriel για να δημιουργηθεί ο Gabriel γράφος. Ο χρήστης επιλέγει από το πάνελ«Topology Control» τον αλγόριθμο του Gabriel και στη συνέχεια μπορεί να δει τοαποτέλεσμα του αλγορίθμου με δύο τρόπους:

Απευθείας, πατώντας το κουμπί «See the Result». Στην περίπτωση αυτή, τοαποτέλεσμα του αλγορίθμου εμφανίζεται στο χώρο σχεδίασης, όπου οιέντονες ακμές είναι οι ακμές της λύσης του αλγορίθμου και εμφανίζεται ησυνολική ενέργεια του γράφου στην περιοχή κειμένου του πάνελ.

Διαφορετικά ο αλγόριθμος μπορεί να εκτελεσθεί βήμα -βήμα, πατώντας τα

κουμπιά (προηγούμενο βήμα) και (επόμενο βήμα) της γραμμήςεργαλείων. Σε αυτή την περίπτωση, ο χρήστης μπορεί να παρατηρήσει πωςπροστίθενται και αφαιρούνται ακμές στον γράφο κατά την εκτέλεση τουαλγορίθμου. Οι ακμές με έντονο μαύρο χρώμα είναι και η λύση του Gabrielγράφου. Όταν ολοκληρωθεί η διαδικασία εμφανίζονται στ ην περιοχή τουκειμένου η συνολική ενέργεια του γράφου. Ανά πάσα στιγμή ο χρήστηςμπορεί να πατήσει το κουμπί «See the Result» για να δει κατευθείαν το τελικό

αποτέλεσμα. Εάν ο χρήστης πατήσει επανειλημμένα το κουμπί καιφτάσει στον αρχικό γράφο, εμφανί ζεται ένα μήνυμα για να ενημερωθεί οχρήστης.

Εάν δεν υπάρχει κάποιος γράφος και ο χρήστης θέλει να εκτελέσει τον αλγόριθμοτου Gabriel, τότε εμφανίζεται μήνυμα λάθους. Κατά την εκτέλεση του αλγορίθμου,

Δίκτυα Αισθητήρων

101

αφαιρείται ενέργεια από τους κόμβους ως εξής: όταν ε πιλέγεται μία ακμή σαν λύσητου αλγορίθμου, αφαιρείται 5% ενέργεια από κάθε κόμβο που ενώνει η ακμή καθώςεπίσης και 1% για κάθε 35 pixels της ακμής. Ενώ όταν εκτελείται ο αλγόριθμος, πρινξεκινήσει η εκτέλεση αφαιρούνται όλες οι ήδη υπάρχουσες ακμές του γ ράφου.

Σύγκριση Αλγορίθμων

Το σύστημα επιτρέπει τη σύγκριση των αλγορίθμων του Kruskal και του Gabriel,συγκρίνοντας την ενέργεια που έχει ο γράφος μετά την εκτέλεση κάθε αλγορίθμουξεχωριστά. Στην αρχή εκτελείται εικονικά ο αλγόριθμος του Kruskal καιυπολογίζεται η συνολική ενέργεια του γράφου μετά την εκτέλεση του αλγορίθμου,στη συνέχεια γίνεται το ίδιο με τον αλγόριθμο του Gabriel και δημιουργείται ένασχεδιάγραμμα με δύο μπάρες. Οι δύο μπάρες αναπαριστούν την ενέργεια του γράφουμε τον αλγόριθμο του Kruskal και την ενέργεια του γράφου με τον αλγόριθμο τουGabriel, για να μπορέσει ο χρήστης να δει και σχηματικά την διαφορά των δύοαλγορίθμων. Τέλος επιλέγεται να εκτελεσθεί ο αλγόριθμος που χάνει την λιγότερηενέργεια και εμφανίζεται το αποτέλεσμά του. Ενώ στην περιοχή κειμένου του πάνελ,εμφανίζονται πληροφορίες για την ενέργεια, όπως η συνολική ενέργεια του γράφου,το ποσοστό ενέργειας το οποίο χάθηκε, ο κόμβος με την λιγότερη ενέργεια και οκόμβος με την περισσότερη ενέργεια. Εάν δεν υπάρχει κάποιος γ ράφος, τότεεμφανίζεται μήνυμα λάθους. Επιπλέον εάν δεν έχουν ανατεθεί βάρη σε όλες τις ακμέςτου γράφου, δεν μπορεί να εκτελεσθεί ο αλγόριθμος του Kruskal και εμφανίζεταιμήνυμα λάθους.

Για να μπορέσει ο χρήστης να συγκρίνει τους δύο αλγόριθμους πατάει το κουμπί«Compare Algorithms» που βρίσκεται στο πάνελ «Topology Control».

Δίκτυα Αισθητήρων

102

17. ΕΙΔΙΚΑ ΘΕΜΑΤΑ ΑΝΑΠΤΥΞΗΣ

17.1 Γραφικό Περιβάλλον Εφαρμογής

Οι σημερινές εμπορικές και μη εμπορικές εφαρμογές απευθύνονται σε χρήστες οιοποίοι δεν είναι απαραίτητο να έχουν άριστες γνώσεις πληροφορικής. Για τον λόγοαυτό, η κονσόλα για την αλληλεπίδραση συστήματος -χρήστη δεν είναι πλέοναποδεκτή. Επομένως το γραφικό περιβάλλον είναι απαραίτητο.

Μία αρχική σχεδίαση του GUI του συστήματος ήταν η παρακάτω:

Μέχρι το τέλος της ανάπτυξης του προγράμματος, το γραφικό περιβάλλον άλλαξεαρκετές φορές για να παρέχει ευκολία, λειτουργικότητα και ευχρηστία στουςχρήστες, μέχρι που έφτασε την τελική του εκδοχή:

1: Χώρος σχεδίασης του γράφου2: Περιοχή κειμένου με γενικές πληροφορίες κατά την εκτέλεση του προγράμματος3: Γραμμή Εργαλείων, για τη διαχείριση αρχείων και τη μεγέθυνση και σμίκρυνσητου γράφου.4: Επόμενο Βήμα και Προηγούμενο Βήμα, για την σταδιακή εκτέλεση τωναλγορίθμων του Kruskal και του Gabriel.5: Μενού, για την διαχείριση των αρχείων και του γράφου.

Δίκτυα Αισθητήρων

103

Το πρόγραμμα διαθέτει 4 πάνελ, ένα για τις γενικές πληροφορίες το οποίοφαίνεται παραπάνω, ένα για την εισαγωγή και διόρθωση στοιχείων, ένα για τουςαλγορίθμους του Kruskal και του Gabriel και ένα για τα μέτρα της κεντρικότητας.

Πάνελ Εισαγωγής και Διόρθωσης Στοιχείων

Το πάνω μέρος του πάνελ αφορά την εισαγωγή κόμβου δίνοντας τιςαπαραίτητες πληροφορίες. Η εισαγωγή ενέργειας είναι προαιρετική. Σεπερίπτωση που δεν θα συμπληρωθεί τότε η ενέργεια κό μβου γίνεται 100%.Εάν επιλεχθεί κάποιος κόμβος από τον σχεδιαστικό χώρο, τότε οιπληροφορίες του κόμβου εμφανίζονται στο επάνω μέρος και ο χρήστηςμπορεί να αλλάξει οποιοδήποτε από αυτά τα σημεία.Το κάτω μέρος του πάνελ χρησιμοποιείται για την εισαγωγή α κμής. Ησυμπλήρωση του πεδίου του βάρους είναι προαιρετική. Ενώ εάν επιλεχθείκάποια ακμή στον σχεδιαστικό χώρο, οι πληροφορίες της ακμής εμφανίζονταιεδώ, απ’ όπου μπορούν να αλλαχθούν.

Δίκτυα Αισθητήρων

104

Πάνελ για τον έλεγχο της τοπολογίας του γράφου

Το πάνελ για τον έλεγχο της τοπολογίας του γράφου χρησιμοποιείται γιατην εκτέλεση των αλγορίθμων του Kruskal και του Gabriel. Στο 1 ο χρήστηςμπορεί να επιλέξει έναν από τους δύο αλγορίθμους και στη συνέχεια μπορείνα πατήσει το κουμπί στο 2. Ενώ το κουμπί « Compare Algorithms» στο 3επιτρέπει τη σύγκριση των δύο αλγορίθμων. Τέλος υπάρχει μία περιοχήκειμένου(4), όπου εμφανίζονται διάφορες πληροφορίες γύρω από τουςαλγορίθμους.

Δίκτυα Αισθητήρων

105

Πάνελ Μέτρων Κεντρικότητας

Το πάνελ αυτό χρησιμοποιείται για να εκτελέσουμε κάποιους αλγόρι θμουςκεντρικότητας στον γράφο. Ο χρήστης πρέπει να επιλέξει έναν, δύο ή και τουςτρείς αλγορίθμους στο 1. Οι αλγόριθμοι είναι οι εξής: Betweenness centrality,HITS, random walk Betweenness centrality. Έπειτα ο χρήστης μπορεί ναπατήσει το κουμπί «Run» (2) για να εκτελεσθούν οι αλγόριθμοι πουεπιλέχθηκαν. Τέλος υπάρχει μία περιοχή κειμένου(3), όπου εμφανίζονται οιπληροφορίες για τους αλγορίθμους.

Δίκτυα Αισθητήρων

106

Δίκτυα Αισθητήρων

107

17.2 Οι Ενέργειες

Όπως αναφέρθηκε και στο θεωρητικό υπόβαθρο στην παρούσα τεκμηρίωση, ηενέργεια αποτελεί ένα σημαντικό και κρίσιμο ζήτημα στα δίκτυα αισθητήρων. Κάθεαισθητήρας κόμβος διαθέτει μία πηγή ενέργειας, και αυτή μειώνεται καθώς ο χρόνοςπερνάει. Επιπλέον, όσες περισσότερες ακμές συνδέουν έναν κόμβο, τόσηπερισσότερη ενέργεια χάνεται. Για αυτό τ ον λόγο, η έννοια της ενέργειας έχειενσωματωθεί στο πρόγραμμα.

Κάθε κόμβος στο δίκτυο διαθέτει ενέργεια. Όταν δημιουργείται ένας κόμβοςδιαθέτει 100% ενέργεια. Ανάλογα με την ενέργεια του κόμβου, χρωματίζεται και μεδιαφορετικό χρώμα.

Ενέργεια Χρώμα[100%,80%]

(80,60](60,40](40,20][0,20]

Πρώτον, μετά την εκτέλεση του αλγορίθμου του Kruskal ή του αλγορίθμου τουGabriel χάνεται συγκεκριμένο ποσοστ ό ενέργειας από κάθε κόμβο. Πιοσυγκεκριμένα, για τον αλγόριθμο του Kruskal σε κάθε κόμβο χάνεται 5% τηςενέργειάς του για κάθε ακμή που συνδέεται σε αυτόν. Επιπλέον επειδή έχει μεγάλησημασία το βάρος της ακμής στον αλγόριθμο του Kruskal, από κάθε κόμβο χάνεται0,1% επί το βάρος της ακμής, η οποία συνδέεται με τον κόμβο αυτό.

Για παράδειγμα έστω ο παρακάτω γράφος:

Ο κόμβος Node2 θα χάσει, εξαιτίας της ακμής Link0, 5% και 10*0,1%,δηλαδή σύνολο 6%.

Ο κόμβος Node1 θα χάσει, εξαιτίας της ακμής Link1, 5% και 6*0,1%, δηλαδή5,6%.

Ο κόμβος Node0 θα χάσει, εξαιτίας της ακμής Link0, 5% και 10*0,1%,δηλαδή σύνολο 6%. Ενώ, εξαιτίας της ακμής Link1, θα χάσει 5% και 6*0,1%,

Δίκτυα Αισθητήρων

108

δηλαδή σύνολο 5,6%. Επομένως ο κόμβος Node0 θα χάσει στο σύνολο6%+5,6%=11,6%

Για τον αλγόριθμο του Gabriel, σε κάθε κόμβο χάνεται 5% για κάθε ακμή πουσυνδέεται με τον κόμβο αυτό. Επιπλέον για κάθε 35 pixels της ακμής χάνεται 1% τηςενέργειας του κόμβου που συνδέεται με την ακμή αυτή.

Για παράδειγμα έστω ο παρακάτω γράφος:

Και οι συντεταγμένες των κόμβων είναι:Node0(100,100)Node1(100,200)Node3(209,209)

Ο κόμβος Node0 θα χάσει εξαιτίας της ακμής Link0 5% και 1% για κάθε 35pixels της ακμής Link0. Η ακμή Link0 είναι 100 pixels. Επομένως ο κόμβοςθα χάσει 5%+100/35%=7,85%.

Ο κόμβος Node3 θα χάσει εξαιτίας της ακμής Link1 5% και 1% για κάθε 35pixels της ακμής Link1. Η ακμή Link1 είναι 109,4 pixels. Επομένως ο κόμβοςθα χάσει 5%+109,4/35%=8,12%.

Ο κόμβος Node1 θα χάσει εξαιτίας της ακμής Link0 7,85% και εξαιτίας τηςακμής Link1 8,12%. Επομένως στο σύνολο θα χάσει 15,97%.

Με τον τρόπο με τον οποίο μειώνεται η ενέργεια στους δύο αλγορίθμους, ως επί τοπλείστον με τον αλγόριθμο του Kruskal μειώνεται λιγότερο η ενέργεια, σε σχέση μετον αλγόριθμο Gabriel. Αυτό ακούγεται λογικό, καθώς ο αλγόριθ μος του Kruskal έναελάχιστο ζευγνύον δάσος, οπότε στην χειρότερη περίπτωση θα δώσει το πολύ ν -1ακμές (ελάχιστο ζευγνύον δένδρο). Από την άλλη ο αλγόριθμος του Gabriel,δημιουργεί έναν γράφο με κύκλους, άρα περισσότερες ακμές από ν -1. Όσεςπερισσότερες ακμές υπάρχουν, τόσο μεγαλύτερη ενέργεια θα χάνεται από τουςκόμβους, αφού η ενέργεια εξαρτάται από τις ακμές που συνδέουν τους κόμβους. Σεπερίπτωση όμως που ο γράφος έχει κόμβους σε πολύ κοντινές αποστάσεις και ταβάρη των ακμών του είναι μεγάλα, τότε μάλλ ον ο αλγόριθμος του Gabriel θα μείωνελιγότερο την ενέργεια από τον αλγόριθμο του Kruskal.

Επιπλέον, στο πρόγραμμα υπάρχει η δυνατότητα να ενσωματωθεί η έννοια τουχρόνου. Αυτό σημαίνει πως ο χρήστης πρέπει να καθορίσει κάθε πόσα λεπτά θαμειώνεται η ενέργεια και κατά πόσο θα μειώνεται η ενέργεια των κόμβων. Τα

Δίκτυα Αισθητήρων

109

δευτερόλεπτα τα οποία περνάνε φαίνονται στην γραμμή εργαλείων. Έτσι αν γιαπαράδειγμα ο χρήστης ορίσει πως κάθε 2 λεπτά θα μειώνεται η ενέργεια των κόμβωνκατά 10%, αυτό σημαίνει πως μόλις περάσουν 2 λεπτά, η ενέργεια όλων των κόμβωνθα μειωθεί κατά 10%. Τέλος, εάν ο χρήστης δεν έχει την πολυτέλεια του χρόνου ναπεριμένει να μειωθεί η ενέργεια του δικτύου, μπορεί να προχωρήσει τον χρόνομπροστά. Ο χρήστης καθορίζει πόσα λεπτά θα προχωρήσει το σύστημα .

Δίκτυα Αισθητήρων

110

18. SCREENSHOTS ΕΦΑΡΜΟΓΗΣ

Αρχική Οθόνη Προγράμματος

Άνοιγμα Αρχείου

Αρχείο:

Δίκτυα Αισθητήρων

111

Αποτέλεσμα:

Δίκτυα Αισθητήρων

112

Αποθήκευση ως Αρχείου

Αρχείο:

Δίκτυα Αισθητήρων

113

Δημιουργία Τυχαίου Γράφου

Αποτέλεσμα:

Δίκτυα Αισθητήρων

114

Αποθήκευση Γράφου Ως Εικόνα

Εικόνα:

Δίκτυα Αισθητήρων

115

Έξοδος από το Πρόγραμμα

Πληροφορίες για τον Γράφο

Δίκτυα Αισθητήρων

116

Σχετικά

Εκτέλεση Αλγορίθμου του Kruskal

Αρχικός Γράφος:

Δίκτυα Αισθητήρων

117

Μετά από πέντε «Επόμενο Βήμα» :

Το αποτέλεσμα του αλγορίθμου :

Δίκτυα Αισθητήρων

118

Εκτέλεση Αλγορίθμου του Gabriel

Αρχικός Γράφος:

Μετά από πέντε «Επόμενο Βήμα» :

Δίκτυα Αισθητήρων

119

Αποτέλεσμα Αλγορίθμου:

Σύγκριση Αλγορίθμων

Αρχικός Γράφος:

Δίκτυα Αισθητήρων

120

Αποτέλεσμα:

Δίκτυα Αισθητήρων

121

Επιλογή και Εκτέλεση Μέτρων Κεντρικότητας

Δίκτυα Αισθητήρων

122

19. J – SIM

19.1 Γενικά

Το J-Sim αποτελεί ένα περιβάλλον διαχείρισης και προσομοίωσης δικτύων καιμπορεί να χρησιμοποιηθεί για την επεξεργασία και την μελέτη των δικτύωναισθητήρων . Έτσι τα δεδομένα του προγράμματος «Δίκτυα Αισθητήρων» πουαναπτύχθηκε στα πλαίσια της πτυχιακής εργασίας μπορούν να χρησιμοποιηθούν γιαπεραιτέρω επεξεργασία από το J-Sim.

Το J-Sim (γνωστό και σαν JavaSim) είναι ένα συνθετικό περιβάλλονπροσομοίωσης βασισμένο σε συστατικά. Δημιουργήθηκε βασισμένο στην έννοια τουπρογραμματιστικού μοντέλου με αυτόνομα συστατικά. Το J-Sim αναπτύχθηκεεξολοκλήρου σε Java TM. Αυτό, μαζί με την αρχιτεκτονική αυτόνομων συστατικών,κάνει το J-Sim ένα επεκτάσιμο και επαναχρησιμοποιήσιμο περιβάλλον ,πραγματικάανεξάρτητο από την πλατφόρμα.

19.2 Αρχιτεκτονική Αυτόνομων Συστατικών

Η βασική οντότητα στην αρχιτεκτονική λογισμικού είναι το συστατικό. Θεωρούμετην εφαρμογή σαν μία σύνθεση από συστατικά. Η έννοια των συστατικών δεν είναικαινούρια, και έχει χρησιμοποιηθεί σε μερικά εμπορικά λογισμικά όπως: JavaBeans,CORBA και COM/DCOM/COM+. Σε αντίθεση με το JavaBeans, το CORBA, και τοCOM/DCOM, τα συστατικά στο J-Sim είναι σχετικά αυτόνομα, επικοινωνούν το έναμε το άλλο ενώνοντας τα «λιμάνια» τους ( ports) και εξαρτώνται από συμβόλαια. Τασυμβόλαια προδιαγράφουν την ανεπισημότητα των δεδομένω ν που αποστέλλονταικαι γίνονται αποδεκτά μεταξύ των συστατικών, αλλά δεν προδιαγράφει τα συστατικάπου παίρνουν μέρος στην επικοινωνία. Τα συμβόλαια καθορίζονται στην σχεδίασηκαι τα συστατικά περιορίζονται στο χρόνο ενσωμάτωσης του συστήματος. Ένασημαντικό πλεονέκτημα αυτού του διαχωρισμού είναι πως διαφορετικά συστατικάμπορούν να αναπτυχθούν ανεξάρτητα (σε διαφορετικές πλατφόρμες και/ήδιαφορετικές γλώσσες προγραμματισμού) και ενσωματώνονται αργότερα.

Η αρχιτεκτονική βασισμένη σε αυτόνομα συστατικά

Port: Ένα συστατικό επικοινωνεί με τον υπόλοιπο κόσμο μέσω των λιμανιών του.Ένα συστατικό μπορεί να διαθέτει περισσότερα από ένα λιμάνι. Το

Δίκτυα Αισθητήρων

123

προγραμματιστικό interface μεταξύ ενός συστατικού και των λιμανιών του ορίζεταιπολύ καλά και ξεκάθαρα. Από τη στι γμή που το συστατικό επικοινωνεί στην ουσίαμόνο με τα λιμάνια του, ένα συστατικό μπορεί να αναπτυχθεί χωρίς την ύπαρξηάλλων συστατικών. Επίσης, ο πραγματικός μηχανισμός επικοινωνίας που ένασυστατικό χρησιμοποιεί για να επικοινωνήσει με τον υπόλοιπο κόσμ ο αποκρύπτεταιεξολοκλήρου από τα λιμάνια.

Συμβόλαιο: Η συμπεριφορά ενός συστατικού περιγράφεται από το συμβόλαιολιμανιού και το συμβόλαιο συστατικού. Ένα συμβόλαιο λιμανιού περιορίζεται γιαένα συγκεκριμένο λιμάνι ή ένα σύνολο από λιμάνια, και καθορίζε ι το υπόδειγμαεπικοινωνίας μεταξύ του συστατικού που κατέχει το(α) λιμάνι(α), και των άλλωνσυστατικών που ενώνονται με τα λιμάνι(α). Το συμβόλαιο συστατικού είναι το ίδιοόπως ένα παραδοσιακό blackbox specification και χαρακτηρίζει την σχέσηεισόδου/εξόδου ενός συστατικού. Ένα συστατικό οφείλει να λειτουργεί σωστά, εάνόλα τα υιοθετημένα συμβόλαια εκπληρώνονται.

Μέχρι τώρα είναι ξεκάθαρο πως όταν ο χρήστης γράφει ένα συστατικό, πρέπει ναυπακούσει στα υιοθετημένα από το συστατικό συμβόλαια, αλλά δεν χρε ιάζεται ναανησυχεί για τα υπόλοιπα συστατικά ή για τον μηχανισμό επικοινωνίας μεταξύαυτών.

Μια καλή αναλογία της αρχιτεκτονικής βασισμένης σε συστατικά είναι η τωρινήIC αρχιτεκτονική, όπου ένα hardware module (ένα σύστημα λογισμικού)δημιουργείται ενώνοντας ένα σύνολο από IC chips (συστατικά) μέσω των pins τους(ports). Όταν τα σήματα καταφθάνουν στα pins ενός IC chip, το chip εκτελείσυγκεκριμένες εργασίες που καθορίζονται από το cookbook (συμβόλαιο), και μπορείνα στείλει σήματα σε κάποια άλλα pins. Ένα συστατικό μπορεί ναεπαναχρησιμοποιηθεί σε άλλα συστήματα λογισμικού με το ίδιο περιεχόμενοσυμβολαίου, όπως και τα IC chips χρησιμοποιούνται στην σχεδίαση.

19.3 Προγραμματισμός

Ο προγραμματισμός χρησιμοποιείται συχνά σε περιβάλλοντα μεγάλων λογ ισμικών,για να μπορούν οι χρήστες να προσπελάσουν και να χειριστούν τα συστατικά σεόποιο επίπεδο λεπτομέρειας επιθυμούν. Ο προγραμματισμός είναι ένα σημαντικόκομμάτι του J-Sim, επειδή χρησιμοποιείται για να κολλήσει όλα τα συστατικά και ναορίσει πως λειτουργεί το σύστημα. Έχει αναπτυχθεί ένα interface για να συνδυαστούνοι διάφορες γλώσσες προγραμματισμού, όπως Perl, Tcl, ή Python ,με το J-Sim.

Δίκτυα Αισθητήρων

124

Δίκτυα Αισθητήρων

125

20. ΕΠΙΛΟΓΟΣ

Τα δίκτυα αισθητήρων σίγουρα αποτελούν ένα πεδίο έρευνας, το οποίο θααπασχολήσει τους ερευνητές τα επόμενα χρόνια, λόγω της ευρείας εφαρμογής του.Καθώς οι υπάρχουσες πηγές ενέργειας εξαντλούνται, η εξοικονόμηση ενέργειας σταδίκτυα αισθητήρων θα αποτελεί ένα σημαντικό ζήτημα. Εξαιτίας της μοντελοποίησηςτων δικτύων με γράφους, η επίλυση των προβλημάτων τους πραγματοποιείταιεύκολα με την δημιουργία νέων αλγορίθμων ή την χρήση ήδη υπαρχόντωναλγορίθμων της θεωρίας γράφων. Εξάλλου η επιστήμη της πληροφορικής δεναναπτύσσεται για έναν φανταστικό κόσμο, αλλά για την επίλυση προβλημ άτων τουπραγματικού κόσμου.

“The purpose of computing is insight, not numbers” (Richard Hamming)

Δίκτυα Αισθητήρων

126

ΒΙΒΛΙΟΓΡΑΦΙΑ “Algorithms”, Robert Sedgewick “Data Structures and Algorithms”, Alfred V. Aho “Encyclopedia of Algorithms”, Ming Yang Kao “Algorithms in Java, Third Edition, Part 5: Gra ph Algorithms”, Robert

Sedgewick “Data Structure and Algorithms in Java”, Mitchel Waite “Data Structures and Algorithms with Object Oriented Design Patterns in

Java”, Preiss, Bruno R. “Data Structures, Algorithms and Applications in C++”, McGraw – Hill “Data Structures, Algorithms and Applications in Java”, McGraw – Hill “Εισαγωγή στην Ανάλυση και Σχεδίαση Αλγορίθμων ”, Anany Levin “Αλγόριθμοι: Ανάλυση και Σύγκριση ”, Gregory J. E. Rawlins “Αλγόριθμοι: Σχεδιασμός και Ανάλυση ”, Παναγιώτης Δ. Μποζάνης “Μαθήματα Θεωρίας Γράφων”, Γιάννης Μανωλόπουλος “Application of the Gabriel Graph to Instance Based Algorithms” ,Kaustav

Mukherjee

www.wikipedia.com www.cs.sunysb.edu www.cs.sunysb.edu www.cs.usask.ca ieeexplore.ieee.org www.ics.uci.edu

Δίκτυα Αισθητήρων

127

Δίκτυα Αισθητήρων

128

ΠΑΡΑΡΤΗΜΑΤΑ

Δίκτυα Αισθητήρων

129

ΠΑΡΑΡΤΗΜΑ Α

Λίστα από εμπορικούς Αισθητήρες -Κόμβους/MotesΥπάρχουν δύο είδη αισθητήρων – κόμβων που χρησιμοποιούνται σε ένα δίκτυοαισθητήρων. Από την μία υπάρχει ο φυσιολογικός αισθητήρας - κόμβος, πουχρησιμοποιείται για να αισθανθεί τα φαινόμενα και από την άλλη υπάρχει ο gatewayαισθητήρας, ο οποίος χρησιμοποιείται για την επικοινωνία του δικτύου με τονεξωτερικό κόσμο.

ΌνομαΑισθητή

ρα -Κόμβου

Μικροελεγκτής Tranceiver

Πρόγραμμα +

ΜνήμηΔεδομένω

ν

Εξωτερική

Μνήμη

Προγραμματισμός

BEAN MSP430F169

CC1000 (300-1000 MHz)with 78.6kbit/s

4 Mbit

BTnode

AtmelATmega128L (8 MHz@ 8 MIPS)

ChipconCC1000 (433-915 MHz)and Bluetooth(2.4 GHz)

64+180 KRAM

128KFLASHROM, 4KEEPROM

C και nesCΠρογραμματισμός

COTSATMELMicrocontroller 916 MHz

Dot ATMEGA163 1K RAM 8-16K

Flash weC

EPICMote

TexasInstrumentsMSP430microcontroller

250 kbit/s 2.4GHz IEEE802.15.4ChipconWirelessTransceiver

10k RAM 48k Flash

Eyes MSP430F149 TR1001 8 Mbit

EyesIFXv1 MSP430F149

TDA5250(868 MHz)FSK

8 Mbit

EyesIFXv2

MSP430F1611

TDA5250(868 MHz)FSK

8 Mbit

FlatMesh 16MHz 802.15.4- 660 Over-air control

Δίκτυα Αισθητήρων

130

FM1 compliant sensorreadings

FlatMeshFM2 16MHz 802.15.4-

compliant

660sensorreadings

Over-air control

GWnode PIC18LF8722 BiM (173MHz) FSK 64k RAM 128k

flash C

IMote ARM core 12MHz

Bluetooth μεεύρος 30 m

64KSRAM

512KFlash

IMote 1.0 ARM 7TDMI12-48 MHz

Bluetooth μεεύρος 30 m

64KSRAM

512KFlash

IMote 2.0

MarvelPXA271ARM 11-400MHz

TI CC2420802.15.4/ZigBeecompliantradio

32MBSRAM

32MBFlash

Iris ATmega1281

AtmelAT86RF230802.15.4/ZigBeecompliantradio

8K RAM 128KFlash nesC

KMoteTI MSP430microcontroller

250 kbit/s 2.4GHz IEEE802.15.4ChipconWirelessTransceiver

10k RAM 48k Flash

Mica

AtmelATMEGA103 4 MHz 8-bitCPU

RFM TR1000radio 50 kbit/s

128+4KRAM

512KFlash

nesCΠρογραμματισμός

Mica2 ATMEGA128L

Chipcon868/916 MHz 4K RAM 128K

Flash

Mica2Dot

ATMEGA128 4K RAM 128K

Flash

MicaZ ATMEGA128

TI CC2420802.15.4/ZigBeecompliantradio

4K RAM 128KFlash nesC

Δίκτυα Αισθητήρων

131

Mulle RenesasM16C Bluetooth 2.0 31K RAM

384K+4KFlash, 2MBEEPROM

Cπρογραμματισμός

Nymph ATMEGA128L CC1000

64 kBEEPROM

Rene ATMEL8535

916 MHzradio μεεύρος 10kbit/s

512 bytesRAM 8K Flash

SenseNode

MSP430F1611

ChipconCC2420 10K RAM 48K

Flash

C και NesCπρογραμματισμός

SunSPOT ARM 920T 802.15.4 512K

RAM4 MBFlash Java

Telos MotorolaHCS08 4K RAM

TelosB

TexasInstrumentsMSP430microcontroller

250 kbit/s 2.4GHz IEEE802.15.4ChipconWirelessTransceiver

10k RAM 48k Flash

T-MoteSky

TexasInstrumentsMSP430microcontroller

250 kbit/s 2.4GHz IEEE802.15.4ChipconWirelessTransceiver

10k RAM 48k Flash

weC Atmel AVRAT90S2313

RFM TR1000RF

XYZ

ML67 seriesARM/THUMBmicrocontroller

CC2420Zigbeecompliantradio fromChipcon

32K RAM 256KFlash

Cπρογραμματισμός

Δίκτυα Αισθητήρων

132

Λίστα από τους αισθητήρες – κόμβους Gateway

Μικροελεγκτής

Tranceiver

Interface(USB/Serial/Wifi/Eth

ernet)

ΜνήμηΠρογράμμα

τος

Εξωτερική

Μνήμη

Stargate IntelPXA255 802.11 Σειριακή σύνδεση στο

WSN64 MBSDRAM

32 MBFlash

FlatMeshFMG-S

16 MHz

802.15.4-compliant

Σειριακή σύνδεση σεFlatMesh FM1, FM2

660sensorreadings

Δίκτυα Αισθητήρων

133

ΠΑΡΑΡΤΗΜΑ Β

Ο κώδικας του προγράμματος

import javax.swing.*;import java.awt.*;

/*H klasi AboutDialog einai ena JDialog me tis plirofories tou About*/

public class AboutDialog extends JDialog {

//Constructorpublic AboutDialog(JFrame parent){

super(parent,true);this.setPreferredSize(new Dimension(470,210));this.setResizable(false);initComponents();setTitle("About");

setLocation((int)parent.getLocation().getX()+(int)parent.getSize().getWidth()/3,(int)parent.getLocation().getY()+(int)parent.getSize().getHeight()/3);

}

private void initComponents(){JPanel panel=new JPanel();//panel.setLayout(new GridLayout(4,1));setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);JLabel l1=new JLabel("<html><font size=5 color= \'#800080\'>Sensor

Networks</font><br><font size=4 color= \'#FF0080\'>Built on 25 January 2009.<br>JDK :1.60_02</font></html>",new ImageIcon("icons/title/network.png"),JLabel.CENTER);

l1.setAlignmentX(Component.CENTER_ALIGNMENT);JLabel l2=new JLabel("<html><br><font size=3>Thanks for using this

program.<br>Sensor Networks is a free software that can manipulate undirectedgraphs<br>in addition to running basic algorithms in order to find the<br>minimum spanningtrees.</fomt></html>");

l2.setAlignmentX(Component.CENTER_ALIGNMENT);JLabel l3=new JLabel("Georgia Latsiou");panel.add(Box.createVerticalStrut(10));panel.add(l1);panel.add(Box.createVerticalStrut(20));panel.add(l2);panel.add(Box.createVerticalStrut(5));panel.add(l3);this.getContentPane().add(panel);pack();

}}

Δίκτυα Αισθητήρων

134

import edu.uci.ics.jung.algorithms.importance.*;

import edu.uci.ics.jung.visualization.Visualization Viewer;

import javax.swing.*;import javax.swing.border.Border;import javax.swing.border.TitledBorder;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.util.HashMap;

/*H klasi anaparista to panel g ia ta metra centrality toy grafou. Treis algorthmoi ipostirizontai:betweennessCentrality, RandomWalkBetweenness kai HITS. O xristis epilegei enan,dio i kaitous treis algorithmouskai blepei ta apotelesmata stin textaArea tou pael*/

public class CentralityPanel extends JPanel {

//Idiotitesprivate JTextArea textC;//H textArea opou emfanizontai oi diafores pliroforiesprivate JCheckBox betweenness;// to check box gia ton algorithmo tou betweenness

centralityprivate JCheckBox hits;//to check box gia ton algorithmo tou hitsprivate JCheckBox randomWalkBetweenness;//to check box gia ton algorithmo

randomWalkBetweenness centrality

//Constructorpublic CentralityPanel(){

super();setLayout(new BoxLayout(this, BoxL ayout.Y_AXIS));setPreferredSize(new Dimension(360,600));setBorder(BorderFactory.createLoweredBevelBorder());initComponents();

}

//////////////////////////////////////////////////////////////////////////////////// Alles Methodoi ///////////////////////////////////////////////////////////////////////////////////

//Arxikopoisi sistatikon toy panelprivate void initComponents(){

add(checkBoxes());//Dimiourgia JTextArea me tis pliroforiestextC=new JTextArea("\n\n\tCentrality Panel!!!",200,400);textC.setAlignmentX(Component.CENTER_ALIGNMENT);textC.setEditable(false);JScrollPane scrollPane = new JScrollPane(textC);Border etched = BorderFactory.createEtchedBorder();

Δίκτυα Αισθητήρων

135

scrollPane.setBorder(BorderFactory.createTitledBorder(etched, "Information",TitledBorder.LEADING,TitledBorder.TOP,newFont("serif",Font.BOLD,14),Color.BLACK));

add(Box.createVerticalStrut(10));add(scrollPane);

}

//Methodos gia tin dimiourgia tou panel me ta checkBoxesprivate JPanel checkBoxes(){

JButton button;JPanel panel1=new JPanel();panel1.setPreferredSize(new Dimension(360,260));panel1.setLayout(new BoxLayout(panel1,BoxLayout.Y_AXIS));

panel1.add(Box.createVerticalStrut(10));JLabel label1=new JLabel("Choose one or more Betweenness Algorithm :");label1.setAlignmentX(Component.LEFT_ALIGNMENT);panel1.add(label1);panel1.add(Box.createVerticalStrut(3));

betweenness=new JCheckBox("Betweenness Centrality");panel1.add(betweenness);hits=new JCheckBox("HITS");panel1.add(hits);randomWalkBetweenness=new JCheckBox("Random Walk Betweenness");panel1.add(randomWalkBetweenness);

panel1.add(Box.createVerticalStrut(10));button=new JButton("Run");button.setActionCommand("run");button.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent evt){centralityHandler();

}});panel1.add(button);panel1.add(Box.createVerticalStrut(10));return panel1;

}

//Methodos pou orizei ti tha ginetai otan o xristis pataei to koumpi gia//tin ektelesei ton algorithmonprivate void centralityHandler(){

if(!betweenness.isSelected()&&!hits.isSelected()&&!randomWalkBetweenness.isSelected() ){JOptionPane.showMessageDialog( this, "You must choose at least one

algorithm!","Error", JOptionPane.ERROR_MESSAGE );return;

}VisualizationViewer<MyVertex,MyEdge> vv=getVV();MyGraph graph=(MyGraph)vv.get GraphLayout().getGraph();

Δίκτυα Αισθητήρων

136

Object[] vertices=graph.getVertices().toArray();BetweennessCentrality<MyVertex,MyEdge> bc;HITS<MyVertex,MyEdge> h;RandomWalkBetweenness<MyVertex,MyEdge> rwb;long n;

HashMap<MyVertex,Double> bcMap=null;HashMap<MyVertex,Double> hitsMap=null;HashMap<MyVertex,Double> rwbMap=null;

int i;

if(vertices.length==0){JOptionPane.showMessageDialog( this, "There is no graph to run the

algorithm(s)!","Error", JOptionPane.ERROR_MESSAGE );return;

}

textC.append("\n\nBC:Betweenness Centrality \nRWBC:Random Walk BetweennessCentrality");

textC.append("\n\tRANKINGS");textC.append("\nVERTICES\t");

if(betweenness.isSelected()){textC.append("BC\t");bc=new BetweennessCentrality<MyVertex,MyEdge>(graph,true,false);bc.evaluate();bcMap=getRankings(bc.getRankings().toArray());

}

if(hits.isSelected()){textC.append("HITS\t");h=new HITS<MyVertex,MyEdge>(graph);h.evaluate();hitsMap=getRankings(h.getRankings().toArray());

}

if(randomWalkBetweenness.isSelected()){try{

rwb=new RandomWalkBetweenness<MyVertex,MyEdge>(graph);rwb.evaluate();rwbMap=getRankings(rwb.getRankings().toArray());textC.append("RWBC\t");

}catch(Exception e){JOptionPane.showMessageDialog( this, "In order to run the random walk

betweenness centrality algorithm, the graph should be connected!","Error",JOptionPane.ERROR_MESSAGE );

}}

MyVertex v;for(i=0;i<vertices.length;i++){

v=(MyVertex)vertices[i];

Δίκτυα Αισθητήρων

137

textC.append("\n"+v.getName()+"\t");if(bcMap!=null){

n=(int)Math.round(bcMap.get(v)*100);textC.append(Double.toString((double)n/100)+" \t");

}if(hitsMap!=null){

n=(int)Math.round(hitsMap.get(v)*100);textC.append(Double.toString((double)n/100)+" \t");

}if(rwbMap!=null){

n=(int)Math.round(rwbMap.get(v)*100);textC.append(Double.toString((double)n/100)+" \t");

}}

}

//H methodos ayti dexetai san orisma ta rankings tou grafoy poy edose enas algorithmos//kai ta topothetei se ena HashMap sto opoio to kleidi einai o komvo s kai antikeimeno to//ranking tou komvouprivate HashMap<MyVertex,Double> getRankings(Object[] rankings){

int i;HashMap<MyVertex,Double> ranks=new HashMap<MyVertex,Double>();Ranking<MyVertex> r;

for(i=0;i<rankings.length;i++){r=(Ranking<MyVertex>)rankings[i];ranks.put(r.getRanked(),r.rankScore);

}

return ranks;}

//H methodos ayti epistrefei to visualizationViewer poy yparxeiprivate VisualizationViewer<MyVer tex,MyEdge> getVV(){

VisualizationViewer<MyVertex,MyEdge> vv=null;Component frame=((((this.getParent()).getParent()).getParent()).getParent()).getParent();if(frame instanceof MyFrame){

MyFrame fr=(MyFrame)frame;Component[] comps=fr.getContentPane().getComponents();if(comps.length>0){

for (Component comp : comps) {if (comp instanceof VisualizationViewer) {

vv=(VisualizationViewer<MyVertex,MyEdge>)comp;return vv;

}//telos esoterikis if}//telos for

}//telos deyteris if}//telos eksoterikis ifreturn vv;

}

}

Δίκτυα Αισθητήρων

138

import javax.swing.*;import java.awt.*;

/*H klasi ayti anaparista ena parathiro me to diagramma energeion. To diagramma apoteleitaiapo dio mparesMia gia ton algorithmo tou Kruskal kai mia gia ton Gabriel Graph. Kai oi dio algorithmoiaforoun ton idiografo gia na mporesei o xristis na sygkrinei tiw eneregies.*/

public class ChartFrame extends JFrame {

//Idiotitesprivate double kruskal;//H energeia toy grafou gia ton algorithmo tou Kruskalprivate double gabriel;//H energei tou grafou gia ton Gabriel Graph

//Constructorpublic ChartFrame(double kruskal,double gabriel){

super();this.kruskal=kruskal;this.gabriel=gabriel;this.setSize(400,460);setTitle("Energy Charts");setBackground(Color.WHITE);getContentPane().add(new MyCanvas());

}

//H klasi anaparista to diaggrammapublic class MyCanvas extends Canvas{

//Constructorpublic MyCanvas(){

super();setPreferredSize(new Dimension(370,410));

}

//Edo ginetai i sxediasi ton diagrammatonpublic void paint(Graphics g){

g.fill3DRect(30,50,4,320,true);g.fill3DRect(30,370,320,4,true);g.drawString("Energy (%)",8,30);g.drawString("100",8,70);g.drawString("0",10,380);

g.setColor(Color.BLUE);g.fill3DRect(70,370-(int)kruskal*3,100,(int)kruskal*3,true);g.setColor(Color.BLACK);g.drawString(Double.toString(kruskal)+"%",110,370 -(int)kruskal*3-10);g.drawString("Kruskal",90,390);g.drawString("Algorithm",85,400);

Δίκτυα Αισθητήρων

139

g.setColor(Color.GREEN);g.fill3DRect(190,370-(int)gabriel*3,100,(int)gabriel*3,true);g.setColor(Color.BLACK);g.drawString(Double.toString(gabriel)+"%",230,370 -(int)gabriel*3-10);g.drawString("Gabriel",210,390);g.drawString("Graph",210,400);g.drawString("Algorithms",300,400);

}}

}

import javax.swing.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;

/*H klasi anaparista ena label deixnontas ton xrono pou pernaeioan exei energopoithei o xronos*/

public class ClockLabel extends JLabel implements ActionListener {

//Idiotitesprivate int i=1;//Ta deyterolepta

//Constructorpublic ClockLabel() {

super("Time : 1");Timer t = new Timer(1000, this);t.start();

}

public void actionPerformed(ActionEvent ae) {setText("Time : "+Integer.toString(i++));

}

}

import javax.swing.*;import java.awt.*;import java.awt.event.ActionListener;

Δίκτυα Αισθητήρων

140

import java.awt.event.ActionEvent;

/*H klasi closeDialog einia ena JDialog pou ilopoei to kleisimo tis efarmogis*/

public class CloseDialog extends JDialog {//Idiotites

//To status anaparista an tha prepei na apothikeysoume ton grafo kata tin eksodoprivate boolean status;

//Constructorpublic CloseDialog(JFrame parent){

super(parent,true);this.setPreferredSize(new Dimension(290,135));status=false;initComponents();setTitle("Sensor Networks");

setLocation((int)parent.getLocation().getX()+(int)parent.getSize().getWidth()/3,(int)parent.getLocation().getY()+(int)parent.getSize().getHeight()/3);

}

//Arxikopoisi sistatikon tou parathiroyprivate void initComponents(){

setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

JPanel panel=new JPanel();panel.add(Box.createVerticalStrut(20));panel.setLayout(new BoxLayout(panel,BoxLayout.Y_AXIS));JLabel l1=new JLabel("Do you want to save the changes?",new

ImageIcon("icons/other/close32.png"),JLabel.CENTER);l1.setAlignmentX(Component.CENTER_ALIGNMENT);

panel.add(l1);panel.add(Box.createVerticalStrut(10));

JPanel p1=new JPanel();p1.setLayout(new BoxLayout(p1,BoxLayout.X_AXIS));JButton jb=new JButton("Yes");jb.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent ev){status=true;setVisible(false);

}});

p1.add(jb);p1.add(Box.createHorizontalStrut(7));jb=new JButton("No");jb.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent ev){System.exit(0);

Δίκτυα Αισθητήρων

141

}});p1.add(jb);p1.add(Box.createHorizontalStrut(7));jb=new JButton("Cancel");jb.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent ev){setVisible(false);

}});p1.add(jb);p1.add(Box.createHorizontalStrut(7));panel.add(p1);getContentPane().add(panel);pack();

}

public boolean getStatus(){return status;

}}

import edu.uci.ics.jung.visualization.VisualizationViewer;

import javax.swing.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;

/*Mia klasi pou ilopoiei tin diagrafi akmis apo to PopupVertexEdgeMenuMousePlugin*/

public class DeleteEdgeMenuItem<E> extends JMenuItem implementsEdgeMenuListener<E>{

//Idiotitesprivate E edge;private VisualizationViewer visComp;

//Constructorpublic DeleteEdgeMenuItem(){

super("Delete Edge");this.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent e){visComp.getPickedEdgeState().p ick(edge,false);visComp.getGraphLayout().getGraph().removeEdge(edge);visComp.repaint();

}});

}

Δίκτυα Αισθητήρων

142

//H methodos pou ilopoeitai gia to interface EdgeMenuListenerpublic void setEdgeAndView(E ed ge,VisualizationViewer visComp){

this.edge=edge;this.visComp=visComp;this.setText("Delete Edge ");

}}

/*Klasi pou ilopoiei tin diagrafi komvou apo to PopupVertexEdgeMenuMousePlugin*/

import edu.uci.ics.jung.visualizati on.VisualizationViewer;

import javax.swing.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;

public class DeleteVertexMenuItem<V> extends JMenuItem implementsVertexMenuListener<V> {

//Idiotites

private V vertex;private VisualizationViewer visComp;

//Constructorpublic DeleteVertexMenuItem(){

super("DElete Node");this.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent e){visComp.getPickedVertexState().pick(vertex,false);visComp.getGraphLayout().getGraph().removeVertex(vertex);visComp.repaint();

}});

}

//Ylopoiisi tis methodou apo to interface VertexMenuListenerpublic void setVertexAndView(V v,VisualizationViewer visComp){

this.vertex=v;this.visComp=visComp;this.setText("Delete Node "+v.toString());

}}

import edu.uci.ics.jung.visualization.VisualizationViewer;

Δίκτυα Αισθητήρων

143

/*Ena interface gia ta menu items ta opoia epithimoun na mathounthn akmi pou exei epilexthei kai to VisualizationViewer*/

public interface EdgeMenuListener<E> {

void setEdgeAndView(E e, VisualizationViewer visView);

}

import edu.uci.ics.jung.visualization.Vi sualizationViewer;

import javax.swing.*;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;

/*H klasi ayti anaparista to parathiro me tis idiotites tiw akmis (onoma,baros)Meso tou parathirou mporoume na allaksou me tis idiotites aytes*/

public class EdgePropertyDialog extends JDialog {

//IdiotitesMyEdge edge;//H akmiprivate JTextField nmTextField;//Onomaprivate JTextField wtTextField;//Baros

//Constructorpublic EdgePropertyDialog(JFrame parent,MyEdge edge){

super(parent,true);this.setPreferredSize(new Dimension(200,150));initComponents();this.edge=edge;setTitle("Edge : "+edge.getName());

this.nmTextField.setText(edge.getName());if(edge.getWeight()!=null){

this.wtTextField.setText(Double.toString(edge.getWeight()));}else{

this.wtTextField.setText("-");}

}

////////////////////////////////////////////////////////////////////////// ///////// Alles Methodoi ///////////////////////////////////////////////////////////////////////////////////

Δίκτυα Αισθητήρων

144

//Arxikopoiisi ton systatikon tou parathirouprivate void initComponents(){

setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);setTitle("Edge Properties");

JPanel panel, panel1,panel2,panel3;

panel=new JPanel();panel.setLayout(new GridLayout(3,1));

panel1=new JPanel();panel1.setPreferredSize(new Dimension(150,30));JLabel jLabel1 = new JLabel("Name");jLabel1.setPreferredSize(new Dimension(70,30));nmTextField=new JTextField();nmTextField.setPreferredSize(new Dimension(70 ,30));panel1.add(Box.createHorizontalStrut(10));panel1.add(jLabel1);panel1.add(nmTextField);panel.add(panel1);panel1.add(Box.createHorizontalStrut(10));

panel2=new JPanel();panel2.setPreferredSize(new Dimension(150,30));JLabel jLabel2 = new JLabel("Weight");jLabel2.setPreferredSize(new Dimension(70,30));wtTextField=new JTextField();wtTextField.setPreferredSize(new Dimension(70,30));panel2.add(Box.createHorizontalStrut(10));panel2.add(jLabel2);panel2.add(wtTextField);panel.add(panel2);panel2.add(Box.createHorizontalStrut(10));

panel3=new JPanel();JButton jButton1 = new JButton("OK");jButton1.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent evt){okButtonHandler(evt);

}});jButton1.setAlignmentX(Component.CENTER_ALIGNMENT);panel3.add(jButton1);panel.add(panel3);

getContentPane().add(panel);pack();

}

//Methodos Pou orizei ti tha ginetai otan patame okprivate void okButtonHandler(ActionEvent evt){

String weight;checkName();

Δίκτυα Αισθητήρων

145

weight=this.wtTextField.getText();try{

if(Double.parseDouble(weight)<0||Double.parseDouble(weight)>100){JOptionPane.showMessageDialog( this, "The weight must be between 0 and

100!","Error", JOptionPane.ERROR_MESSAGE );}else{

edge.setWeight(Double.parseDouble(weight));}

}catch(NumberFormatException nfe){if(weight.equals("-")){

edge.setWeight(null);}else{

JOptionPane.showMessageDialog( this, "The weight must be number!","Error",JOptionPane.ERROR_MESSAGE );

}}dispose();

}

//Methodos pou elegxei ena yparxei idi alli akmi ston grafo me to idio onoma//kai allazei tion akmiprivate boolean checkName(){

String name=nmTextField.getText();MyGraph graph;VisualizationViewer<MyVertex,MyEdge> vv;JFrame frame=(JFrame)this.getParent();

Component[] comps=frame.getContentPane().getComponents();if(comps.length>0){

for (Component comp : comps) {if (comp instanceof VisualizationViewer) {

vv=(VisualizationViewer<MyVertex,MyEdge>)comp;graph=(MyGraph)vv.getGraphLayout().getGraph();

if(graph.findEdge(name)!=null&&!edge.getName().equalsIgnoreCase(this.nmTextField.getText())){

JOptionPane.showMessageDialog( this, "There is already an edge with thename "+name+"!","Error", JOptionPane.ERROR_MESSAG E );

return false;}else{

if(!this.nmTextField.getText().equals("")){edge.setName(this.nmTextField.getText());vv.repaint();

}else{JOptionPane.showMessageDialog( this, "You should give a name for the

edge","Error", JOptionPane.ERROR_MESSAGE );}

}//telos esoterikis if}//telos deyteris if

}//telos for}//telos protis ifreturn true;

}

Δίκτυα Αισθητήρων

146

}

import edu.uci.ics.jung.graph.util.Pair;import edu.uci.ics.jung.visualization.VisualizationViewer;

import java.util.Vector;

/*H klasi GabrielAlgorithm eketelei ton algorithm o o opoios paragei ton Gabriel graph*/

public class GabrielAlgorithm {

//Idiotitesprivate Vector<MyEdge> solution;//Oi akmes pou apoteloun ti lisiprivate Vector<Pair<MyVertex>> endPoints;//Ta simeia ton akmon tis lisis

//Constructorpublic GabrielAlgorithm(){

solution=new Vector<MyEdge>();endPoints=new Vector<Pair<MyVertex>>();

}

/////////////////////////////////////////////////////////////////////////////////// Ta gets kai ta sets ///////////////////////////////////////////////////////////////////////////////////public Vector<MyEdge> getSolution(){

return solution;}public Vector<Pair<MyVertex>> getEndPoints(){

return endPoints;}

/////////////////////////////////////////////////////////////////////////////////// Alles Methodoi //////////////////////////////////////////////////// ///////////////////////////////

//H methodos ayti ektelei ton algorithmopublic void runAlgorithm(VisualizationViewer<MyVertex,MyEdge> vv){

MyGraph graph=(MyGraph)vv.getGraphLayout().getGraph();int i,j,l;double xCentre,yCentre,aktina;Object[] nodes=graph.getVertices().toArray();MyEdge e;int name=1;MyVertex v1,v2,v3;

for(i=0;i<nodes.length;i++){

Δίκτυα Αισθητήρων

147

v1=(MyVertex)nodes[i];

for(j=i+1;j<nodes.length;j++){

v2=(MyVertex)nodes[j];xCentre=(v1.getX()+v2.getX())/2;yCentre=(v1.getY()+v2.getY())/2;

aktina=distance(xCentre,yCentre,v1.getX(),v1.getY());

//Tora tha eleksoume an yparxei k ombos pou na brisketai mesa ston kiklo//pou dhmiourgeitai me diametro tin akmi pou enonei tis akmes v1 v2.for(l=0;l<nodes.length;l++){

v3=(MyVertex)nodes[l];if(l!=i&&l!=j&&distance(xCentre,yCentre,v3.getX(),v3.getY())<aktina){

break;}//end if

}//telos tritou for

if(l==nodes.length){while(graph.findEdge("gabriel"+name)!=null){

name++;}e=new MyEdge("gabriel"+name);name++;endPoints.add(new Pair(v1,v2));solution.add(e);

}

}//telos deyterou for}//telos protou for

}

//H methodos ayti ipologizei tin apostash metaksi dio simeionprivate double distance(double x1,double y1,double x2,double y2){

return (Math.pow((x2-x1),2)+Math.pow((y2-y1),2));}

/*public double calculateLossEnergy(MyGraph graph){double energy=graph.calculateTotalEnergy();int nodes=graph.getVertices().toArray().length;long n;if(nodes==0){

return 0;}else{

n=(int)Math.round(((100*nodes-energy)/nodes)*100);return (double)n/100;

}}*/

}

Δίκτυα Αισθητήρων

148

import javax.swing.*;import java.awt.*;

public class GraphInfoDialog extends JDialog {

private MyGraph graph;

public GraphInfoDialog(Frame fr,MyGrap h graph){super(fr);this.graph=graph;setTitle("Graph's Information");setSize(350,250);initComponents();

}

private void initComponents(){setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE) ;JPanel panel=new JPanel();panel.setLayout(new GridLayout(7,1));JLabel label;

label=new JLabel("<html><em><font color=blue size=5>Graph'sInformation</font></em></html>");

label.setHorizontalAlignment(JLabel.CENT ER);panel.add(label);

if(graph==null||graph.getVertexCount()==0){label=new JLabel("<html><b>There is no graph!</b></html>");label.setHorizontalAlignment(JLabel.CENTER);panel.add(label);

}else{label=new JLabel("<html><b>Number of Vertices :

</b>"+graph.getVertexCount()+"</html>");label.setHorizontalAlignment(JLabel.CENTER);panel.add(label);label=new JLabel("<html><b>Number of Edge :

</b>"+graph.getEdgeCount()+"</html>");label.setHorizontalAlignment(JLabel.CENTER);panel.add(label);

if(graph.HasWeights()){label=new JLabel("<html><b>Total Weight :

</b>"+graph.calculateTotalWeight()+"</html>" );label.setHorizontalAlignment(JLabel.CENTER);panel.add(label);

}else{label=new JLabel("<html><b>Total Weight : </b>no weights assigned at all

edges</html>");

Δίκτυα Αισθητήρων

149

label.setHorizontalAlignment(JLabel.CENTER);panel.add(label);

}long n;n=(int)Math.round((graph.calculateTotalEnergy()/graph.getVertexCount())*100);label=new JLabel("<html><b>Total Energy :

</b>"+Double.toString((double)n/100)+"%</html>");label.setHorizontalAlignment(JLabel.CENTER);panel.add(label);n=(int)Math.round(graph.minEnergy().getCapacity()*100);

label=new JLabel("<html><b>Vertex with the less energy :</b>"+graph.minEnergy().getName()+" ("+(double)n/100+"%)</html>");

label.setHorizontalAlignment(JLabel.CENTER);panel.add(label);n=(int)Math.round(graph.maxEnergy().getCapacity()*100);label=new JLabel("<html><b>Vertex with the most energy :

</b>"+graph.maxEnergy()+" ("+(double)n/100+"%)</html>");label.setHorizontalAlignment(JLabel.CENTER);panel.add(label);

}getContentPane().add(panel);

}

}

import javax.swing.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.*;import java.io.File;

/*H klasi ayti anaparista tiw energeies pou tha ginontai ena epilexthei kapoio stoixeio boitheias*/

public class HelpListener implements ActionListener {

//Idiotitesprivate JFrame fr;//to parathiro thw efarmoghs

//Constructorpublic HelpListener(JFrame fr){

this.fr=fr;}

public void actionPerformed(ActionEvent e){String command=e.getActionCommand();

Δίκτυα Αισθητήρων

150

if(command.equals("Help")){help();

}else if(command.equals("About")){about();

}

}

//Methodos pou ilopoiei tin epilogi ths boitheiasprivate void help(){

try{Desktop.getDesktop().open( new File("docs/help.doc") );

}catch(Exception exc){JOptionPane.showMessageDialog(fr, "A problem has occured to the reading of the

file!","Error", JOptionPane.ERROR_MESSAGE );}

}

private void about(){AboutDialog ad=new AboutDialog(fr);ad.setVisible(true);

}}

import edu.uci.ics.jung.graph.util.Pair;

import java.io.*;import java.util.StringTokenizer;

/*H klasi InputOutput anaparista tin apothikeusi kai tin anagnosi ton arxeion apo ta arxeia.*/

public class InputOutput {

//Idiotites

//To onoma tou arxeiouprivate String filename;private MyGraph graph;private BufferedReader br;//Ta minimata pou paragontaiprivate String messages;private StringTokenizer st;private String line;

//Constructorpublic InputOutput(String filename){

this.filename=filename;this.graph=new MyGraph();this.messages="";

Δίκτυα Αισθητήρων

151

}

/////////////////////////////////////////////////////////////////////////////////// Ta gets kai ta sets ///////////////////////////////////////////////////////////////////////////////////

public String getFilename(){return filename;

}

public MyGraph getGraph(){return graph;

}

public String getMessages(){return messages;

}

//////////////////////////////////////////////////////////////////// /////////////// Alles Methodoi ///////////////////////////////////////////////////////////////////////////////////

//H methodos ayti diabazei ton grafo apo to arxeio kai epistrefe i true ean ola phgan kala//kai to diabase me epityxia kai false ean apetyxe na diabasei ton grafo.public boolean readGraph(){

messages="";try{

br=new BufferedReader(new FileReader(filename));if(readNodes()){

transformX();transformY();if(readEdges()){

br.close();return true;

}}else{

br.close();return false;

}}catch(IOException e){

messages += "Fatal Error \nAn input proble has occured. \nThe file reading failed. \n";return false;

}return false;

}

//H methodos ayti apothikeuei enan grafo se arxeio. Ean ola p;ane kala stin apothikeysi//tha epistrepsei true, allios an apotixei na ton apothikeusei tha epistrpsei false.public boolean saveGraph(MyGraph graph){

Δίκτυα Αισθητήρων

152

this.graph=graph;int i;Object[] vertices;Object[] edges;MyVertex v;MyEdge e;messages="";Pair<MyVertex> incidents;try{

if(!checkTxt(filename)){filename=filename+".txt";

}BufferedWriter bw = new BufferedWriter(new FileWriter(filename));

vertices=(graph.getVertices()).toArray();for(i=0;i<vertices.length;i++){

v=(MyVertex)vertices[i];bw.write(v.getName()+"("+v.getX()+","+v.getY()+" )");bw.newLine();

}

edges=(graph.getEdges()).toArray();for(i=0;i<edges.length;i++){

e=(MyEdge)edges[i];incidents=graph.getEndpoints(e);if(e.getWeight()==null){

bw.write(e.getName()+"("+incidents.getFirst().getName()+","+incidents.getSecond().getName()+",-)");

}else{

bw.write(e.getName()+"("+incidents.getFirst().getName()+","+incidents.getSecond(). getName()+","+e.getWeight()+")");

}bw.newLine();

}messages+="The graph has been written to the file \n"+filename+"\n with success.\n";bw.close();return true;

}catch(IOException o){messages+="An output problem has occured. \nThe graph cannot be written \n";return false;

}

}

//H methodos ayth diabazei to sinolo ton kombon kai mono tous kombous apo to arxeio kaiepistrefei

//true ean tous diabasei me epitixia, allios falseprivate boolean readNodes() throws IOException{

Δίκτυα Αισθητήρων

153

do{line=br.readLine();if(line==null){

messages=messages+"The file is empty. \n";return false;

}st=new StringTokenizer(line," ,()");

}while(st.countTokens()==0);

do{st=new StringTokenizer(line," ,()");if(st.countTokens()==3){

readNode();}else if(st.countTokens()==4){

return true;}else if(st.countTokens()!=0){

messages+="Wrong file form! \nYou should see the help file. \n";return false;

}line=br.readLine();

}while(line!=null);return true;

}

//H methodos auti diabazei enan kai mono enan kombo apo to arxeioprivate void readNode(){

MyVertex v;String name;double x,y;

name=st.nextToken();

if((graph.findVertex(name))!=null){messages+="The node "+name+" has not been added \nbecause there is already a node

with the name "+name+". \n";return;

}try{

x=Double.parseDouble(st.nextTo ken());y=Double.parseDouble(st.nextToken());

if(x<0||y<0){messages+="The node "+name+" has not been added \nbecause the coordinates are

not valid.\n";return;

}

if((graph.findVertex(x,y))!=null){messages+="The node "+name+" has not been added \nbecause there is already a

node ta the point ("+x+","+y+"). \n";

Δίκτυα Αισθητήρων

154

return;}v=new MyVertex(name,x,y);graph.addVertex(v);

}catch(Exception e){messages+="The node "+name+" has not been added \nbecause of wrong form.\n";

}}

//H methodos ayti diabazei to sinolo ton akmon apo to arxeio kai epistrefei true//ean tis diabase me epitixia, diaforetika falseprivate boolean readEdges() throws IOException{

if (line==null){return true;

}do{

st=new StringTokenizer(line," ,()");if(st.countTokens()==4){

readEdge();}else if(st.countTokens()!=0){

messages+="Wrong file form! \nYou should see the help file. \n";return false;

}}while((line=br.readLine())!=null);

return true;}

//H methodos ayti diabazei mia kai mono mia akmi apo toi arxeioprivate void readEdge(){

MyEdge e;String name,vertexA,vertexB;MyVertex A,B;double weight;String varos;

name=st.nextToken();vertexA=st.nextToken();vertexB=st.nextToken();

A=graph.findVertex(vertexA);B=graph.findVertex(vertexB);

if(A==null){messages+="The edge "+name+" has not been added \nbecause the node "+vertexA+"

does not exist.\n";return;

}else if(B==null){messages+="The edge "+name+" has not been added \nbecause the node "+vertexB+"

does not exist.\n";return;

}

Δίκτυα Αισθητήρων

155

if(graph.findEdge(name)!=null){messages+="The edge "+name+" has not been added \nbecause there is already an

edge with the name "+name+". \n";return;

}

try{varos=st.nextToken();if(varos.equalsIgnoreCase("-")){

e=new MyEdge(name);graph.addEdge(e,A,B);

}else{weight=Double.parseDouble(varos);if(weight<0||weight>100){

messages+="The edge "+name+" has not been added \nbecause the weight is notbetween 0 and 100.";

return;}e=new MyEdge(name,weight);graph.addEdge(e,A,B);

}

}catch(Exception d){messages+="The edge "+name+" has not been added \nbecause of wrong form.\n";

}

}

//H methodos ayti metatrepei ta x ton kombon etsi oste na anikoun ston periorismeno xorotoy

//programmatosprivate void transformX(){

if(graph.getVertexCount()==0){return;

}double max;Object[] vertices=graph.getVertices().toArray();max=((MyVertex)vertices[0]).getX();

for(int i=1;i<vertices.length;i++){if(max<((MyVertex)vertices[i]).getX()){

max=((MyVertex)vertices[i]).getX();}

}

for (Object vertice : vertices) {

((MyVertex) vertice).setX(500 * ((MyVertex) vertice).getX()/max);}

}

//H methodos ayti metatrepei ta y ton kombon etsi oste na anikoun ston periorism eno xoro

Δίκτυα Αισθητήρων

156

//toy programmatosprivate void transformY(){

if(graph.getVertexCount()==0){return;

}

double max;Object[] vertices=graph.getVertices().toArray();max=((MyVertex)vertices[0]).getY();

for(int i=1;i<vertices.length;i++){if(max<((MyVertex)vertices[i]).getY()){

max=((MyVertex)vertices[i]).getY();}

}

for (Object vertice : vertices) {

((MyVertex) vertice).setY(500 * ((MyVertex) vertice).getY() /max);}

}

//H methodos ayti elegxei ena to Strinn teleionei me .txtprivate boolean checkTxt(String name){

return name.endsWith(".txt");

}}

import edu.uci.ics.jung.graph.util.Pair;import edu.uci.ics.jung.visualization.VisualizationViewer;

import javax.swing.*;import javax.swing.border.CompoundBorder;import javax.swing.border.EmptyBorder;import javax.swing.border.EtchedBorder;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.geom.Point2D;

/*H klasi anaparista ena panel sto opoio mporoume na eisagoume enan kombo i mia akmi ston

yparxon grafoEan epilexthei kapoios komvos oi plirofories pou aforoun ayton emafnizontai sto panel kai o

xristis mporeina tis allaksei. To idio simvainei me tin akmi*/

public class insertionPanel extends JPanel {

//Idiotitesprivate Box insertionNode;//To box pou periexei tis plirofories tou komvouprivate Box insertionEdge;//To box po y perixei tis plirofories tis akmis

Δίκτυα Αισθητήρων

157

private JTextField nodeNameField;//To onoma tou komvouprivate JTextField nodeXField;//To X tou komvouprivate JTextField nodeYField;//To Y tou komvouprivate JTextField nodeCapacityField;//H energeia tou komvouprivate JTextField edgeNameField;//To onoma tiw akmisprivate JTextField edgeWeightField;//To baros tiw Akmisprivate JTextField edgeNodeAField;//O enas komvos poy envnei i akmiprivate JTextField edgeNodeBField;//O allos komvos pou enonei i akmiprivate JButton nodeButton;private JButton edgeButton;

private boolean enabled=true;private MyEdge edge=null;private MyVertex node=null;

//Constructorpublic insertionPanel(){

super();this.setPreferredSize(new Dimension(360,600));this.setBorder(BorderFactory.createLoweredBevelBorder());initComponents();

BorderLayout bl=new BorderLayout();bl.setVgap(15);this.setLayout(bl);

this.add(insertionNode,BorderLayout.NORTH);this.add(insertionEdge,BorderLayout.CENTER);

enabled=true;}

public void setEnabled(boolean enabled){this.enabled=enabled;

}

//Arxikopoisi Sistatikon tou panelprivate void initComponents(){

createInsertionNode();createInsertionEdge();

}

//H methodos dimiourgei to kommati tou panel pou afora ton komvoprivate void createInsertionNode(){

JPanel panel;JButton button;JLabel label;

insertionNode=Box.createVerticalBox();insertionNode.setBorder(new CompoundBorder(new EmptyBorder(10, 5,0,5),new

EtchedBorder()));insertionNode.add(Box.createVerticalStrut(30));

Δίκτυα Αισθητήρων

158

//O Titloslabel=new JLabel("Node");label.setAlignmentX(Component.CENTER_ALIGNMENT);Font font = new Font("Dialog",Font.BOLD,16);label.setFont(font);label.setForeground(Color.RED);insertionNode.add(label);insertionNode.add(Box.createVerticalStrut(16));

//To Onoma tou Komvoupanel=new JPanel();panel.add(new JLabel("Name :"));nodeNameField=new JTextField();nodeNameField.setPreferredSize(new Dimension(75,25));panel.add(nodeNameField) ;insertionNode.add(panel);insertionNode.add(Box.createVerticalStrut(9));

//H energeia tou Komvoupanel=new JPanel();panel.add(new JLabel("Energy %:"));nodeCapacityField=new JTextField();nodeCapacityField.setPreferredSize(new Dimension(75,25));panel.add(nodeCapacityField);insertionNode.add(panel);insertionNode.add(Box.createVerticalStrut(9));

//Oi Sintetagmenespanel=new JPanel();panel.setPreferredSize(new Dimension(150,30));panel.add(new JLabel("X :"));nodeXField=new JTextField();nodeXField.setPreferredSize(new Dimension(42,25));panel.add(nodeXField);panel.add(Box.createHorizontalStrut(10));panel.add(new JLabel("Y :"));nodeYField=new JTextField();nodeYField.setPreferredSize(new Dimension(42,25));panel.add(nodeYField);insertionNode.add(panel);insertionNode.add(Box.createVerticalStrut(17));

//To Koumpipanel=new JPanel();panel.setPreferredSize(new Dimension(150,35));nodeButton=new JButton("Add Node");nodeButton.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent evt){insertNode(evt);

}});panel.add(nodeButton);panel.add(Box.createHorizontalStrut(10));button=new JButton("Clear");

Δίκτυα Αισθητήρων

159

button.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent evt){

disposeNode();}

});panel.add(button);insertionNode.add(panel);insertionNode.add(Box.createVerticalStrut(20));

}

//H methodos dimioyrgei to kommati to u panel pou afora tin akmiprivate void createInsertionEdge(){

JPanel panel;JButton button;JLabel label;

insertionEdge=Box.createVerticalBox();insertionEdge.setBorder(new CompoundBorder(new EmptyBorder(0, 5,1 0,5),new

EtchedBorder()));insertionEdge.add(Box.createVerticalStrut(10));

//O Titloslabel=new JLabel("Edge");label.setAlignmentX(Component.CENTER_ALIGNMENT);Font font = new Font("Dialog",Font.BOLD,16);label.setFont(font);label.setForeground(Color.BLUE);insertionEdge.add(label);insertionEdge.add(Box.createVerticalStrut(18));

//To onoma tis akmispanel=new JPanel();panel.add(new JLabel("Name :"));edgeNameField=new JTextField();edgeNameField.setPreferredSize(new Dimension(75,25));panel.add(edgeNameField);insertionEdge.add(panel);insertionEdge.add(Box.createVerticalStrut(10));

//O komvos 1panel=new JPanel();panel.add(new JLabel("Node 1 :"));edgeNodeAField=new JTextField();edgeNodeAField.setPreferredSize(new Dimension(75,25));panel.add(edgeNodeAField);insertionEdge.add(panel);insertionEdge.add(Box.createVerticalStrut(10));

//O komvos 2panel=new JPanel();panel.add(new JLabel("Node 2 :"));edgeNodeBField=new JTextField();edgeNodeBField.setPreferredSize(new Dimension(75,25));

Δίκτυα Αισθητήρων

160

panel.add(edgeNodeBField);insertionEdge.add(panel);insertionEdge.add(Box.createVerticalStrut(10));

//To barospanel=new JPanel();panel.add(new JLabel("Weight :"));edgeWeightField=new JTextField();edgeWeightField.setPreferredSize(new Dimension(40,25));panel.add(edgeWeightField);insertionEdge.add(panel);insertionEdge.add(Box.createVerticalStrut(15));

//Ta Koumpiapanel=new JPanel();panel.setPreferredSize(new Dimensio n(150,35));edgeButton=new JButton("Add Edge");edgeButton.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent evt){insertEdge(evt);

}});panel.add(edgeButton);button=new JButton("Clear");button.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent evt){disposeEdge();

}});panel.add(Box.createHorizontalStru t(10));panel.add(button);insertionEdge.add(panel);insertionEdge.add(Box.createVerticalStrut(140));

}

//H methodos emfanizei sto kommati tou komvou tis plirofories sxetika me ton komvo touorismatos

public void showVertex(MyVertex v){long n;nodeButton.setText("Adjust Node");nodeNameField.setText(v.getName());if(v.getCapacity()>100){

nodeCapacityField.setText("100");}else if(v.getCapacity()<0){

nodeCapacityField.setText("0");}else{

n=(int)Math.round(v.getCapacity()*100);nodeCapacityField.setText(Double.toString((double)n/100));

}n=(int)Math.round(v.getX()*100);nodeXField.setText(Double.toString ((double)n/100));n=(int)Math.round(v.getY()*100);nodeYField.setText(Double.toString((double)n/100));this.node=v;

Δίκτυα Αισθητήρων

161

}

//H methodos emfanizei sto kommati tis akmis tis plirofories sxetika me tin akmi touorismatos

public void showEdge(MyEdge e, Pair<MyVertex> endPoints){edgeButton.setText("Adjust Edge");edgeNameField.setText(e.getName());if(e.getWeight()!=null){

long n=(int)Math.round(e.getWeight()*100);edgeWeightField.setText(Double.toString((double)n/100));

}else{edgeWeightField.setText("");

}if(endPoints.getFirst()!=null&&endPoints.getSecond()!=null){

edgeNodeAField.setText(endPoints.getFirst().getName());edgeNodeBField.setText(endPoints.getSecond().getName());

}this.edge=e;

}

//H methodos ayti eisagei ton komvo afou prota eleksei mipos yparxoun lathi stisplirofories

//pou edose o xristisprivate void insertNode(ActionEvent evt){

//Ean den einai ernegopoimeno to insertion panel tote den// yparxei logos na prosthesoume tin akmiif(!enabled){

return;}//Diaforetikadouble capacity;

//Prepei na grapsei ola ta pediaif(nodeNameField.getText().equals("")|| nodeXField.getText().equals("") ||

nodeYField.getText().equals("")){JOptionPane.showMessageDialog( this, "You must complete all the gaps.","Error",

JOptionPane.ERROR_MESSAGE );disposeNode();return;

}

String name=nodeNameField.getText();try{

double x=Double.parseDouble(nodeXField.getText());double y=Double.parseDouble(nodeYField.getText());//Oi sintetagmenes prepei na einai apo 0 mexri 550if(x<0||y<0||x>550||y>550){

JOptionPane.showMessageDialog( this, "The coordinates must be between 0 and550!","Error", JOptionPane.ERROR_MESSAGE );

disposeNode();return;

}VisualizationViewer<MyVertex,MyEdge> vv=getVV();

Δίκτυα Αισθητήρων

162

//Yparxei idi komvos me to onoma ayto?

if((((MyGraph)vv.getGraphLayout().getGraph()).findVertex(name)!=null)&&((node==null)||(node!=null&&!(name.equals(node.getName()))))){

JOptionPane.showMessageDialog( this, "There is already an node with the name"+name+"!","Error", JOptionPane.ERROR_MESSAGE );

}elseif((((MyGraph)vv.getGraphLayout().getGraph()).findVertex(x,y)!=n ull)&&((node==null)||(node!=null&&node.getX()!=x&&node.getY()!=y))){

JOptionPane.showMessageDialog( this, "There is already a node at the point("+x+","+y+") !","Error", JOptionPane.ERROR_MESSAGE );

}else{if(nodeCapacityField.getText().equals("")){

capacity=100;}else{

capacity=Double.parseDouble(nodeCapacityField.getText());if(capacity<0||capacity>100){

JOptionPane.showMessageDialog( this, "The Energy must be a numberbetween 0 and 100!","Error",JOptionPane.ERROR_MESSAGE );

disposeNode();return;

}}if(node==null){

MyVertex v=new MyVertex(name,x,y);v.setCapacity(capacity);Point2D p=new Point2D.Double();p.setLocation(x,y);vv.getGraphLayout().setLocation(v,p);vv.getGraphLayout().getGraph().addVertex(v);

}else{node.setName(name);node.setX(x);node.setY(y);node.setCapacity(capacity);Point2D p=new Point2D.Double();p.setLocation(x,y);vv.getGraphLayout().setLocation(node,p);

}vv.repaint();

}}catch(NumberFormatException nfe){

JOptionPane.showMessageDialog( this, "The coordinates and the energy must benumbers!","Error", JOptionPane.ERROR_MESSAGE );

}disposeNode();

}

//H methodos ayti eisagei tin akmi afou prota eleksei mipos yparxoun lathi stis plirofor iespou

//edose o xristisprivate void insertEdge(ActionEvent evt){

Δίκτυα Αισθητήρων

163

if(!enabled){return;

}

if(edgeNameField.getText().equals("")||edgeNodeAField.getText().equals("")||edgeNodeBField.getText().equals("")){

JOptionPane.showMessageDialog( this, "You must complete all the gaps. \nIt is notnecessary to complete the weight gap.","Error", JOptionPane.ERROR_MESSAGE );

disposeEdge();return;

}

String name=edgeNameField.getText();String nodeA=edgeNodeAField.getText();String nodeB=edgeNodeBField.getText();String weight=edgeWeightField.getText();VisualizationViewer<MyVertex,MyEdge> vv=getVV();

if((((MyGraph)vv.getGraphLayout().ge tGraph()).findEdge(name)!=null)&&((edge==null)||(edge!=null&&!(name.equals(edge.getName()))))){

JOptionPane.showMessageDialog( this, "There is already an edge with the name"+name+"!","Error", JOptionPane.ERROR_MESSAGE );

}else if(((MyGraph)vv.getGraphLayout().getGraph()).findVertex(nodeA)==null){JOptionPane.showMessageDialog( this, "The node "+nodeA+" does not

exist!","Error", JOptionPane.ERROR_MESSAGE );}else if(((MyGraph)vv.getGraphLayout().getGraph()).find Vertex(nodeB)==null){

JOptionPane.showMessageDialog( this, "The node "+nodeB+" does notexist!","Error", JOptionPane.ERROR_MESSAGE );

}else{try{

MyEdge e;if (weight.equals("")){

e=new MyEdge(name);}else{

Double varos=Double.parseDouble(weight);if(varos<0||varos>100){

JOptionPane.showMessageDialog( this, "The weight should be between 0 and100!","Error", JOptionPane.ERROR_MESSAGE );

disposeEdge();return;

}e=new MyEdge(name,varos);

}if(edge!=null){

vv.getGraphLayout().getGraph().removeEdge(edge);}

vv.getGraphLayout().getGraph().addEdge(e,((MyGraph)vv.getGraphLayout().getGraph()).findVertex(nodeA),((MyGraph)vv.getGraphLayout().getGraph()).findVertex(nodeB));

vv.repaint();

}catch(NumberFormatException nfe){

Δίκτυα Αισθητήρων

164

JOptionPane.showMessageDialog( this, "The edge weigth must be anumber!","Error", JOptionPane.ERROR_MESSAGE );

}}disposeEdge();

}

private void disposeEdge(){edgeNameField.setText("");edgeWeightField.setText("");edgeNodeAField.setText("");edgeNodeBField.setText("");edge=null;edgeButton.setText("Add Edge");

}private void disposeNode(){

nodeNameField.setText("");nodeXField.setText("");nodeYField.setText("");nodeCapacityField.setText("");node=null;nodeButton.setText("Add Node");

}

//H methodos ayti epistrefei to Visualiz ationViewerprivate VisualizationViewer<MyVertex,MyEdge> getVV(){

VisualizationViewer<MyVertex,MyEdge> vv=null;Component frame=((((this.getParent()).getParent()).getParent()).getParent()).getParent();if(frame instanceof MyFrame){

MyFrame fr=(MyFrame)frame;Component[] comps=fr.getContentPane().getComponents();if(comps.length>0){

for (Component comp : comps) {if (comp instanceof VisualizationViewer) {

vv=(VisualizationViewer<MyVertex,MyEdge>)comp;return vv;

}//telos esoterikis if}//telos for

}//telos deyteris if}//telos eksoterikis ifreturn vv;

}}

import edu.uci.ics.jung.graph.util.Pair;import edu.uci.ics.jung.visualization.VisualizationViewer;

import java.util.HashSet;import java.util.Vector;

Δίκτυα Αισθητήρων

165

/*H klasi ayti eketelei ton algorithmo tou Kruskal.*/

public class KruskalAlgorithm {

//Idiotitesprivate Vector<HashSet<MyVertex>> vertexSets;//To sinolo ton dendronprivate Vector<Pair<MyVertex>> endPoints;//Ta shmeia ton akmonprivate Vector<Boolean> edgesState; //Dilonei ean i ekastote akmi apot elei lisi tou

algorithmou i oxiprivate Vector<MyEdge> edges; //Oles oi akmes(kai aytes pou e;inai lisi kai aytes pou den

eina

//Constructorpublic KruskalAlgorithm(){

vertexSets=new Vector<HashSet<MyVertex>>();endPoints=new Vector<Pair<MyVertex>>();edgesState=new Vector<Boolean>();edges=new Vector<MyEdge>();

}

/////////////////////////////////////////////////////////////////////////////////// Ta gets kai ta sets ///////////////////////////////////////////////////////////////////////////////////

public Vector<MyEdge> getEdges(){return edges;

}

public Vector<Boolean> getEdgesState(){return edgesState;

}

public Vector<Pair<MyVertex>> getEndPoints(){return endPoints;

}

/////////////////////////////////////////////////////////////////////////////////// Taksinomisi Akmon ///////////////////////////////////////////////////////////////////////////////////

private void sortEdges(){mergesort(edges,0,edges.size());

}private void mergesort(Vector<MyEdge> edges,int first,int n){

int n1;int n2;if (n > 1){

n1 = n / 2;n2 = n - n1;

Δίκτυα Αισθητήρων

166

mergesort(edges, first, n1);mergesort(edges, first + n1, n2);merge(edges, first, n1, n2);

}}private void merge(Vector<MyEdge> edges, int first, int n1, int n2){

MyEdge[ ] temp = new MyEdge[n1+n2];int copied = 0;int copied1 = 0;int copied2 = 0;int i;

while ((copied1 < n1) && (copied2 < n2)){

if ((edges.elementAt(first + copied1)).getWeight( ) < (edges.elementAt(first + n1 +copied2)).getWeight())

temp[copied++] = edges.elementAt(first + (copied1++));else

temp[copied++] = edges.elementAt(first + n1 + (copied2++));}

// Copy any remaining entries i n the left and right subarrays.while (copied1 < n1)

temp[copied++] = edges.elementAt(first + (copied1++));while (copied2 < n2)

temp[copied++] = edges.elementAt(first + n1 + (copied2++));

// Copy from temp back to the data array.for (i = 0; i < n1+n2; i++)

edges.set(first + i,temp[i]);}

/////////////////////////////////////////////////////////////////////////////////// Alles Methodoi ///////////////////////////////////////////////////////////////////////////////////

//H methodos ayti epistrefei to dendro sto opoio anikei i sigkekrimeni korifiprivate HashSet<MyVertex> getSetVertex(MyVertex node){

for(HashSet<MyVertex> vertexSet:vertexSets){if(vertexSet.contains(node)){

return vertexSet;}

}return null;

}

//H methodos ayti ektelei ton algorithmopublic void runAlgorithm(VisualizationViewer<M yVertex,MyEdge> vv){

Object[] akmes;int i;

MyGraph graph=(MyGraph)vv.getGraphLayout().getGraph();

Δίκτυα Αισθητήρων

167

akmes=(graph.getEdges()).toArray();for( i=0;i<akmes.length;i++){

edges.add((MyEdge)akmes[i]);}sortEdges();

for(i=0;i<edges.size();i++){endPoints.add(graph.getEndpoints(edges.elementAt(i)));if(!insertEdge(edges.elementAt(i),graph)){

edgesState.add(false);}else{

edgesState.add(true);}

}}

//H methodos auti elegxei ean i sigkekrimeni korifi dimiourgei kiklo i oxiprivate boolean insertEdge(MyEdge e,MyGraph graph){

MyVertex nodeA=(graph.getEndpoints(e)).getFirst();MyVertex nodeB=(graph.getEndpoints(e)).getSecond();

if(nodeA==nodeB){return false;

}

HashSet<MyVertex> SetVertexA=getSetVertex(nodeA);HashSet<MyVertex> SetVertexB=getSetVertex(nodeB);

if(SetVertexA==null){

if(SetVertexB==null){HashSet<MyVertex> newSet=new HashSet<MyVertex>();newSet.add(nodeA);newSet.add(nodeB);vertexSets.add(newSet);

}else{SetVertexB.add(nodeA);

}return true;

}else{if(SetVertexB==null){

SetVertexA.add(nodeB);return true;

}else if(SetVertexA!=SetVertexB){SetVertexA.addAll(SetVertexB);vertexSets.remove(SetVertexB);return true;

}}

Δίκτυα Αισθητήρων

168

return false;}

}

public class main {public static void main(String []args){

MyFrame frame=new MyFrame() ;frame.setVisible(true);

}}

import java.awt.geom.Point2D;/*Xrisimopoeitai gia na thesei ena simeio sto opoio to pontikiklikare gia ekeina ta menu items pou endiaferontai gia ayti tinpliroforia. Einai xrisimo ean theloume na emfanisoume ena dialog boxdeksia apo to shmeio pou patithike to pontiki.*/

public interface MenuPointListener {

void setPoint(Point2D point);}

/*H klasi MyEdge anaparista tin akmh toy grafoy*/

public class MyEdge {

//Idiotitesprivate String name;//To onoma tou grafouprivate Double weight;//To baros tou grafou

//Constructorspublic MyEdge(){}

public MyEdge(String name){this.name=name;weight=null;

}

public MyEdge(String name,Double weight){this.name=name;this.weight=weight;

}

Δίκτυα Αισθητήρων

169

/////////////////////////////////////////////////////////////////////////////////// Ta gets kai ta sets /////////////////////////////// ////////////////////////////////////////////////////

public void setName(String name){this.name=name;

}

public String getName(){return this.name;

}

public void setWeight(Double weight){this.weight=weight;

}

public Double getWeight(){return this.weight;

}

/////////////////////////////////////////////////////////////////////////////////// Alles Methodoi ///////////////////////////////////////////////////////////////////////////////////

public String toString(){if(weight==null){

return this.name+" - ";}else{

return this.name+" - "+weight;}

}

//H methodos copy dimioyrgei ena antikeimeno tis klasis MyEdge idio kai aneksartito meayto

//pou tin kalese.public MyEdge copy(){

if(weight==null){return new MyEdge(name);

}else{return new MyEdge(name,weight);

}}

}

import org.apache.commons.collections15.Factory;

/*H klasi MyEdgeFactory ilopoiei tin Factory kai xrisimopoeitaiapo to pontiki otan dimiourgoume nees akmes.*/

Δίκτυα Αισθητήρων

170

public class MyEdgeFactory implements Factory<MyEdge> {

private int linkCount=0;private MyGraph graph;

//Constructorpublic MyEdgeFactory(MyGraph graph){

this.graph=graph;}

//Xrisimopoieitai apo to MyEditingGrphMousePlugin otan// dimiourgountai nees akmespublic MyEdge create(){

String name;//Tha dosei ena onoma stin akmi pou na min ksanaiparxeido{

name="Link"+linkCount++;}while(graph.findEdge(name)!=null);return new MyEdge(name);

}}

import edu.uci.ics.jung.algorithms.layout.GraphElementAccessor;import edu.uci.ics.jung.algorithms.layout.Layout;import edu.uci.ics.jung.graph.DirectedGraph;import edu.uci.ics.jung.graph.Graph;import edu.uci.ics.jung.graph.UndirectedGraph;import edu.uci.ics.jung.graph.ut il.EdgeType;import edu.uci.ics.jung.visualization.VisualizationViewer;import edu.uci.ics.jung.visualization.control.EditingGraphMousePlugin;import org.apache.commons.collections15.Factory;

import java.awt.event.MouseEvent;import java.awt.geom.AffineTransform;import java.awt.geom.Point2D;

/* H klasi MyEditingGraphMousePLugin epekteinei kata poli ligotin idi yparxousa klasi EditingGraphMousePlugin etsi oste na dinontaikai oi sintetagmenes toy komvou kata tin dimiourgia tou.O perissoteros kodikas einai toy dimiourgou Tom Nelson*/

public class MyEditingGraphMousePlugin<V,E> extendsEditingGraphMousePlugin<V,E> {

//Constructorpublic MyEditingGraphMousePlugin(Factory<V> vertexFactory,Factory<E>

edgeFactory){super(vertexFactory,edgeFactory);

Δίκτυα Αισθητήρων

171

}

/*Otan patithei to pontiki sto keno dimiourgeitai neos komvosallios etoimazomaste gia tin dimiourgia neas akmis.*/@SuppressWarnings("unchecked")public void mousePressed(MouseEvent e) {

if(checkModifiers(e)) {final VisualizationViewer<V,E> vv =(VisualizationViewer<V,E>)e.getSource();final Point2D p = e.getPoint();GraphElementAccessor<V,E> pickSupport = vv.getPickSupport();if(pickSupport != null) {

Graph<V,E> graph = vv.getModel().getGraphLayout().getGraph();

if(graph instanceof DirectedGraph) {edgeIsDirected = EdgeType.DIRECTED;

} else {edgeIsDirected = EdgeType.UNDIRECTED;

}

final V vertex = pickSupport.getVertex(vv.getModel().getGraphLayout(),p.getX(), p.getY());

if(vertex != null) {

//Exei epileksei komvo kai epomenos etoimazomaste na dimiourgisoume neaakmi

startVertex = vertex;down = e.getPoint();transformEdgeShape(down, down);vv.addPostRenderPaintable(edgePaintable);if((e.getModifiers() & MouseEvent.SHIFT_MASK) != 0 &&

!(vv.getModel().getGraphLayout().getGraph() instanceof UndirectedGraph)) {edgeIsDirected = EdgeType.DIRECTED;

}if(edgeIsDirected == EdgeType.DIRECTED) {

transformArrowShape(down, e.getPoint());vv.addPostRenderPaintable(arrowPaintable);

}} else {

//Dimiourgia Neou komvou//Tjetoume tis sintetagmenes pou tha xrisimopoiisoumeMyVertexFactory mvf=(MyVertexFactory)vertexFactory;mvf.setCoordinates(e.getX(),e.getY());//Kai dimiourgoume ton komvoV newVertex = vertexFactory.create();

Layout<V,E> layout = vv.getModel().getGraphLayout();//Prosthetoume ton komvo ston grafograph.addVertex(newVertex);layout.setLocation(newVertex,

vv.getRenderContext().getMultiLayerTransformer().inverseTransform(e.getPoint()));

}}

Δίκτυα Αισθητήρων

172

vv.repaint();}

}

private void transformEdgeShape(Point2D down, Point2D out) {float x1 = (float) down.getX();float y1 = (float) down.getY();float x2 = (float) out.getX();float y2 = (float) out.getY();

AffineTransform xform = AffineTransform.getTranslateInstance(x1, y1);

float dx = x2-x1;float dy = y2-y1;float thetaRadians = (float) Math.atan2(dy, dx);xform.rotate(thetaRadians);float dist = (float) Math.sqrt(dx*dx + dy*dy);xform.scale(dist / rawEdge.getBounds().getWidth(), 1.0);edgeShape = xform.createTransformedShape(rawEdge);

}

private void transformArrowShape(Point2D down, Point2D out) {float x1 = (float) down.getX();float y1 = (float) down.getY();float x2 = (float) out.getX();float y2 = (float) out.getY();

AffineTransform xform = AffineTransform.getTranslateIn stance(x2, y2);

float dx = x2-x1;float dy = y2-y1;float thetaRadians = (float) Math.atan2(dy, dx);xform.rotate(thetaRadians);arrowShape = xform.createTransformedShape(rawArrowShape);

}}

import edu.uci.ics.jung.visualization.RenderContext;import edu.uci.ics.jung.visualization.control.EditingModalGraphMouse;import org.apache.commons.collections15.Factory;

import javax.swing.*;

/*H klasi i opoia anaparista to pontiki gia ton grafo*/

public class MyEditingModalGraphMouse<V,E> extendsEditingModalGraphMouse<V,E> {

//Constructorpublic MyEditingModalGraphMouse(RenderContext rc, Factory<V> vertexFactory,

Factory<E> edgeFactory, JFrame fr) {

Δίκτυα Αισθητήρων

173

super(rc, vertexFactory, edgeFactory, 1.1f, 1/1.1f);

//To popupEditing plugin pou dimiourgisamePopupVertexEdgeMenuMousePlugin myPlugin=new

PopupVertexEdgeMenuMousePlugin();JPopupMenu edgeMenu=new MyMouseMenus.EdgeMenu(fr);JPopupMenu vertexMenu=new MyMouseMenus.VertexMenu(fr );myPlugin.setEdgePopup(edgeMenu);myPlugin.setVertexPopup(vertexMenu);this.remove(this.getPopupEditingPlugin());this.add(myPlugin);

//To Editing Plugin pou dimiourgisameMyEditingGraphMousePlugin plugin2 =new

MyEditingGraphMousePlugin(vertexFactory,edgeFactory);this.remove(this.getEditingPlugin());editingPlugin=plugin2;

}}

import edu.uci.ics.jung.algorithms.layout.GraphElementAccessor;import edu.uci.ics.jung.algorithms.layout.Stat icLayout;import edu.uci.ics.jung.graph.util.Pair;import edu.uci.ics.jung.visualization.VisualizationViewer;import edu.uci.ics.jung.visualization.control.CrossoverScalingControl;import edu.uci.ics.jung.visualization.control.ModalGraphMouse;import edu.uci.ics.jung.visualization.control.ScalingControl;import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;import org.apache.commons.collections15.Transformer;

import javax.imageio.ImageIO;import javax.swing.*;import javax.swing.border.Border;import javax.swing.border.TitledBorder;import javax.swing.filechooser.FileNameExtensionFilter;import java.awt.*;import java.awt.event.*;import java.awt.geom.Point2D;import java.awt.image.BufferedImage;import java.awt.print.PrinterJob;import java.io.File;import java.util.Vector;

public class MyFrame extends JFrame implements ActionListener, MouseListener {

//Idiotites gia to guiprivate JTextArea text;private JTextArea textInfo;private JToolBar jtb;private JRadioButton gabr ielButton;private JRadioButton kruskalButton;private insertionPanel iP;

Δίκτυα Αισθητήρων

174

private JMenu mouseMenu;private JTabbedPane tabbedPane;private JButton compare;

//Idiotita gia tin apothikeusi kai tin anagnosi ton arxeionprivate InputOutput store;

//Idiotites gia ton grafoprivate MyEditingModalGraphMouse<MyVertex,MyEdge> gm;private VisualizationViewer<MyVertex,MyEdge> vv;private MyGraph graph;//O Arxikos grafosprivate MyGraph initialGraph;

//Idiotites gia tous algorithmousprivate int counter;private Vector<MyEdge> AlgorithmEdges=new Vector<MyEdge>();private Vector<Pair<MyVertex>> endpoints=new Vector<Pair<MyVertex>>();private Vector<Boolean> edgesState=new Vector<Boolean>();private KruskalAlgorithm ka;private GabrielAlgorithm ga;private Vector<MyEdge> solution=new Vector<MyEdge>();

//Idiotites gia ton xronoprivate boolean time=false;private Timer timer;private int minutes;private int decrease;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//Constructorpublic MyFrame(){

initializeFrame();graph=new MyGraph();showGraph();addMouse();getContentPane().add(vv,BorderLayout.CENTER);initializeTabbedPane();createMenu();createToolBar();

gm.setMode(ModalGraphMouse.Mode.EDITING);counter=0;

}

//Arxikopoiisi Frameprivate void initializeFrame(){

setSize(960,700);setResizable(false);setTitle("Sensor Networks");setLocation(200,60);

Δίκτυα Αισθητήρων

175

setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent e){close();

}});setIconImage(Toolkit.getDefaultToolkit().getImage("ic ons/title/network.png"));this.getContentPane().setLayout(new BorderLayout());

}

//Arxikopoiisi TabbedPaneprivate void initializeTabbedPane(){

tabbedPane=new JTabbedPane();tabbedPane.setPreferredSize(new Dimension(360 ,600));

tabbedPane.add("Information",information());iP=new insertionPanel();tabbedPane.addTab("Insertion Panel",iP);tabbedPane.addTab("Topology Control",initializeBasicTab());tabbedPane.addTab("Centrality Panel",new CentralityPanel());//Prosthiki TabbedPanegetContentPane().add(tabbedPane,BorderLayout.EAST);

}//Arxikopoiisi panel me tis plirofories kai ta koumpiaprivate JPanel initializeBasicTab(){

JPanel panel;panel=new JPanel();panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));panel.setPreferredSize(new Dimension(360,600));panel.setBorder(BorderFactory.createLoweredBevelBorder());

panel.add(initializePanel());

//Dimiourgia JTextArea me tis pliroforiestext=new JTextArea("\n\nTOPOLOGY CONTROL!!!!",200,400);text.setAlignmentX(Component.CENTER_ALIGNMENT);text.setEditable(false);JScrollPane scrollPane = new JScrol lPane(text);Border etched = BorderFactory.createEtchedBorder();scrollPane.setBorder(BorderFactory.createTitledBorder(etched, "Information",

TitledBorder.LEADING,TitledBorder.TOP,newFont("serif",Font.BOLD,14),Color.BLACK));

panel.add(Box.createVerticalStrut(10));panel.add(scrollPane);return panel;

}private JPanel initializePanel(){

JButton jb;JPanel panel1=new JPanel();panel1.setPreferredSize(new Dimension(360,260));panel1.setLayout(new BoxLayout(panel1,BoxLayout.Y_AXIS));

panel1.add(Box.createVerticalStrut(10));JLabel label1=new JLabel("Choose An Algorithm :");

Δίκτυα Αισθητήρων

176

label1.setAlignmentX(Component.LEFT_ALIGNMENT);panel1.add(label1);

panel1.add(Box.createVerticalStrut(3));

ButtonGroup g = new ButtonGroup();kruskalButton=new JRadioButton("Kruskal");g.add(kruskalButton);gabrielButton=new JRadioButton("Gabriel");g.add(gabrielButton);panel1.add(kruskalButton);panel1.add(gabrielButton);

panel1.add(Box.createVerticalStrut(10));jb=new JButton("See the Result");jb.setActionCommand("result");jb.addActionListener(this);panel1.add(jb);panel1.add(Box.createVerticalStrut(10));compare=new JButton("Compare Algorithms");compare.setActionCommand("compare");compare.addActionListener(this);panel1.add(compare);

return panel1;}private JPanel information(){

JPanel panel;panel=new JPanel();panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));panel.setPreferredSize(new Dimension(360,600));panel.setBorder(BorderFactory.createLoweredBevelBorder());

textInfo=new JTextArea(" \n\nSENSOR NETWORKS\nWELCOME!!!!",200,400);textInfo.setAlignmentX(Component.CENTER_ALIGNMENT);textInfo.setEditable(false);JScrollPane scrollPane = new JScrollPane(textInfo);Border etched = BorderFactory.createEtchedBorder();scrollPane.setBorder(BorderFactory.createTitledBorder(etched, "Information",

TitledBorder.LEADING,TitledBorder.TOP,newFont("serif",Font.BOLD,14),Color.BLACK));

panel.add(Box.createVerticalStrut(10));panel.add(scrollPane);return panel;

}//Dimiourgia Menuprivate void createMenu(){

JMenuBar menuBar=new JMenuBar();menuBar.add(createFileMenu());menuBar.add(createGraphMenu());menuBar.add(createMouseMenu());menuBar.add(createHelpMenu());

Δίκτυα Αισθητήρων

177

setJMenuBar(menuBar);}private JMenu createFileMenu(){

JMenuItem item;JMenu fileMenu;fileMenu = new JMenu("File");

item=new JMenuItem("New",new Imag eIcon("icons/menu/file16.png"));item.addActionListener(this);

item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N,ActionEvent.CTRL_MASK));

fileMenu.add(item);fileMenu.addSeparator();

item=new JMenuItem("Open. ..",new ImageIcon("icons/menu/folder16.png"));item.addActionListener(this);

item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O,ActionEvent.CTRL_MASK));

fileMenu.add(item);

item=new JMenuItem("Save As...");item.addActionListener(this);

item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,ActionEvent.CTRL_MASK));fileMenu.add(item);

item=new JMenuItem("Save",new ImageIcon("icons/menu/saveas16.png"));if(store==null){

item.setForeground(Color.GRAY);}else{

item.addActionListener(this);}fileMenu.add(item);

item=new JMenuItem("Save As Image",new ImageIcon("icons/menu/pictures16.png"));item.addActionListener(this);fileMenu.add(item);item=new JMenuItem("Print",new ImageIcon("icons/menu/printer16.png"));item.addActionListener(this);

item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P,ActionEvent.CTRL_MASK));fileMenu.add(item);fileMenu.addSeparator();

item=new JMenuItem("Quit");item.addActionListener(this);

item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q,ActionEvent.CTRL_MASK));

fileMenu.add(item);

return fileMenu;

Δίκτυα Αισθητήρων

178

}private JMenu createGraphMenu(){

JMenu graphMenu;JMenuItem item;

graphMenu=new JMenu("Graph");

item=new JMenuItem("Initial Graph");item.addActionListener(this);graphMenu.add(item);

item=new JMenuItem("Random Graph");item.addActionListener(this);graphMenu.add(item);

item=new JMenuItem("Graph's Info");item.addActionListener(this);graphMenu.add(item);graphMenu.addSeparator();

item=new JMenuItem("Charge the Nodes");item.addActionListener(this);graphMenu.add(item);

item=new JMenuItem("Refresh",new ImageIcon("icons/menu/refresh16.png"));item.addActionListener(this);graphMenu.add(item);

graphMenu.addSeparator();JMenu sub=new JMenu("Time");if(time){

item=new JMenuItem("Disable Time",new ImageIcon("icons/menu/clock16.png"));}else{

item=new JMenuItem("Enable Time",new I mageIcon("icons/menu/clock16.png"));}item.addActionListener(this);

item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,ActionEvent.ALT_MASK));sub.add(item);item=new JMenuItem("Move Forward Time");item.addActionListener(this);sub.add(item);

graphMenu.add(sub);

return graphMenu;}private JMenu createMouseMenu(){

mouseMenu=gm.getModeMenu();mouseMenu.setIcon(null);mouseMenu.setText("Mouse Mode");mouseMenu.setPreferredSize(new Dimension(80,20));

Δίκτυα Αισθητήρων

179

mouseMenu.getItem(0).setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T,ActionEvent.ALT_MASK));

mouseMenu.getItem(1).setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P ,ActionEvent.ALT_MASK));

mouseMenu.getItem(2).setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E,ActionEvent.ALT_MASK));

return mouseMenu;}private JMenu createHelpMenu(){

JMenu helpMenu=new JMenu("Help");JMenuItem item;item=new JMenuItem("Help",new ImageIcon("icons/menu/help16.png"));item.addActionListener(new HelpListener(this));

item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_H,ActionEvent.CTRL_MASK));

helpMenu.add(item);//item=new JMenuItem("Tip of the day");//item.addActionListener(new HelpListener(this));//helpMenu.add(item);helpMenu.addSeparator();item=new JMenuItem("About",new ImageIcon("icons/menu/infoabout16.png"));item.addActionListener(new HelpListener(this));helpMenu.add(item);return helpMenu;

}

//Dimiourgia ToolBarprivate void createToolBar(){

jtb=new JToolBar(SwingConstants.HORIZONTAL);

JButton jb=new JButton(new ImageIcon("icons/toolbar/file24.png"));jb.setActionCommand("New");jb.setToolTipText("New Graph");jb.addActionListener(this);jtb.add(jb);jb=new JButton(new ImageIcon("icons/toolbar/folder24.png"));jb.setActionCommand("Open...");jb.setToolTipText("Open a Graph");jb.addActionListener(this);jtb.add(jb);if(store==null){

jb=new JButton(new ImageIcon("icons/toolbar/nosave24.png"));}else{

jb=new JButton(new ImageIcon("icons/toolbar/saveas24.png"));jb.setToolTipText("Save Graph");jb.setActionCommand("Save");jb.addActionListener(this);

}jtb.add(jb);jb=new JButton(new ImageIcon("ic ons/toolbar/pictures24.png"));

Δίκτυα Αισθητήρων

180

jb.setActionCommand("Save As Image");jb.setToolTipText("Save Graph As Image");jb.addActionListener(this);jtb.add(jb);jb=new JButton(new ImageIcon("icons/toolbar/printer24.png"));jb.setActionCommand("Print");jb.setToolTipText("Print Graph");jb.addActionListener(this);jtb.add(jb);jb=new JButton(new ImageIcon("icons/toolbar/help24.png"));jb.setActionCommand("Help");jb.setToolTipText("Help");jb.addActionListener(new HelpListener(this));jtb.add(jb);jb=new JButton(new ImageIcon("icons/toolbar/close24.png"));jb.setActionCommand("Quit");jb.setToolTipText("Quit");jb.addActionListener(this);jtb.add(jb);

if(time){jtb.add(Box.createHorizontalStrut(10));ClockLabel clock = new ClockLabel();jtb.add(clock);jtb.add(Box.createHorizontalStrut(68));

}else{jtb.add(Box.createHorizontalStrut(130));

}jb=new JButton(new ImageIcon("icons/toolbar/zoomout24.png"));jb.setActionCommand("zoomOut");jb.setToolTipText("Zoom Out");jb.setMnemonic(KeyEvent.VK_O);jb.addActionListener(this);jtb.add(jb);jtb.add(Box.createHorizontalStrut(5));jb=new JButton(new ImageIcon("icons/toolbar/zoomin24.png"));jb.setActionCommand("zoomIn");jb.setToolTipText("Zoom In");jb.setMnemonic(KeyEvent.VK_I);jb.addActionListener(this);jtb.add(jb);

jtb.add(Box.createHorizontalStrut(20));jb=new JButton(new ImageIcon("icons/toolbar/back24.png"));jb.setActionCommand("back");jb.setToolTipText("Back");jb.setMnemonic(KeyEvent.VK_B);jb.addActionListener(this);jtb.add(jb);jtb.add(Box.createHorizontalStrut(5));jb=new JButton(new ImageIcon("icons/toolbar/next24.png"));jb.setActionCommand("next");jb.setToolTipText("Next");jb.setMnemonic(KeyEvent.VK_N);

Δίκτυα Αισθητήρων

181

jb.addActionListener(this);jtb.add(jb);

jtb.setFloatable(false);jtb.setRollover(true);getContentPane().add(jtb,BorderLayout.NORTH);

}

//Methodos gia tin emfanisi tou grafouprivate void showGraph(){

int i;MyVertex v;Object[] vertices=graph.getVertices().toArray();Point2D p=new Point2D.Double();

StaticLayout<MyVertex, MyEdge> layout = new StaticLayout<MyVertex,MyEdge>(graph,new Dimension(550,550));

if(graph!=null){for(i=0;i<vertices.length;i++){

v=(MyVertex)vertices[i];p.setLocation(v.getX(),v.getY());layout.setLocation(v,p);

}}

vv=new VisualizationViewer<MyVertex,MyEdge>(layout);vv.setPreferredSize(new Dimension(600,600));

Transformer<MyEdge,Stroke> strokeEdge=new Transformer<MyEdge,Stroke>(){public Stroke transform(MyEdge e){

Stroke THIN=new BasicStroke(1);Stroke THICK=new BasicStroke(3);if(solution.contains(e)){

return THICK;}else{

return THIN;}

}};vv.getRenderContext().setEdgeStrokeTransformer(strokeEdge);vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller());vv.getRenderContext().setEdgeLabelTransformer(new ToString Labeller());vv.getRenderContext().setVertexFillPaintTransformer(new vertexFillColor());

vv.getRenderer().getVertexLabelRenderer().setPosition(edu.uci.ics.jung.visualization.renderers.Renderer.VertexLabel.Position.NE);

vv.addMouseListener(this);}

//Methodos gia tin prothiki pontikiouprivate void addMouse(){

Δίκτυα Αισθητήρων

182

//To pontikigm=new MyEditingModalGraphMouse<MyVertex,MyEdge>(vv.getRenderContext(),

new MyVertexFactory(graph),new MyEdgeFactory(graph),this);vv.setGraphMouse(gm);

}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//Ektelesi epilogon Menou

//Methodos pou ilopoiei th epilogi neos grafosprivate void newGraph(){

graph=new MyGraph();store=null;if(time){

time=false;timer.stop();

}remove(jtb);createToolBar();removeAndAddVV();setTitle("Sensor Networks");textInfo.append("\n\n------------------------------------------------------------------ ");textInfo.append("\nNew Graph");enableGraphReaction();gm.setMode(ModalGraphMouse.Mode.EDITING);solution=new Vector<MyEdge>();initialGraph=null;

}

//Methodos pou ilopoiei tin epilogi anoigma apothikeumenou grafouprivate void openGraph(){

String fileName;JFileChooser chooser=new JFileChooser();FileNameExtensionFilter filter = new FileNameExtensionFilter("TEXT file", "txt");chooser.setFileFilter(filter);int returnVal = chooser.showOpenDialog(this);if(returnVal == JFileChooser.APPROVE_OPTION) {

fileName=chooser.getSelectedFile().toString();textInfo.append("\n\n------------------------------------------------------------------ ");textInfo.append("\nFile Reading :\n"+fileName);store=new InputOutput(fileName);if(store.readGraph()){

graph=store.getGraph();removeAndAddVV();enableGraphReaction();gm.setMode(ModalGraphMouse.Mode.EDITING);if(time){

time=false;timer.stop();

}

Δίκτυα Αισθητήρων

183

remove(jtb);createToolBar();setTitle("Sensor Networks "+chooser.getSelectedFile());textInfo.append("\n"+store.getMessages());textInfo.append("\nThe file opened with success.");solution=new Vector<MyEdge>();pack();initialGraph=null;

}else{textInfo.append("\n"+store.getMessages());

}}

}

//Methodos pou ilopoei tin epilogi apothikeusi os...private void saveAs(){

JFileChooser chooser = new JFileChooser();FileNameExtensionFilter filter = new FileNameExtensionF ilter("TEXT file", "txt");chooser.setFileFilter(filter);int result = chooser.showSaveDialog(this);if (result == JFileChooser.APPROVE_OPTION){

store=new InputOutput((chooser.getSelectedFile()).toString());

if(store.saveGraph(graph)){setTitle("Sensor Networks "+store.getFilename());createMenu();remove(jtb);createToolBar();

}textInfo.append("\n\n------------------------------------------------------------------ ");textInfo.append("\nFile Saving :\n"+store.getMessages());

}pack();

}

//Methodos pou ilopoiei thn epilogi tis apothikeusisprivate void save(){

if(store!=null){store.saveGraph(graph);textInfo.append("\n\n------------------------------------------------------------------ ");textInfo.append("\nFile Saving :\n"+store.getMessages());

}}

//Methodos pou ilopoei thn epilogi thw apothikeysis tou grafou os eikonaprivate void saveAsImage(){

textInfo.append("\n\n------------------------------------------------------------------ ");textInfo.append("\nSave Graph As Image :");if(graph.getVertexCount()==0){

textInfo.append("\nThere is no graph to save.");return;

}

Δίκτυα Αισθητήρων

184

JFileChooser chooser = new JFileChooser();FileNameExtensionFilter filter = new FileNameExtensionFilter("JPEG file", "jp g",

"jpeg");chooser.setFileFilter(filter);int result = chooser.showSaveDialog(this);File file;int width=vv.getWidth();int height=vv.getHeight();vv.setDoubleBuffered(false);

if (result == JFileChooser.APPROVE_OPTION){file=new

File(chooser.getSelectedFile().getParent(),chooser.getSelectedFile().getName()+".jpeg");BufferedImage bi=new

BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);Graphics2D graphics=bi.createGraphics();vv.paint(graphics);graphics.dispose();try{

ImageIO.write(bi,"jpeg",file);textInfo.append("\nThe graph has been saved as an image \nsuccessfully!");

}catch(Exception o){textInfo.append("\nA problem has occurred during the \ngraph's transfomation to

image.");}vv.setDoubleBuffered(true);

}}

//Methodos pou kleinei tin efarmogiprivate void close(){

CloseDialog cd=new CloseDialog(this);cd.setVisible(true);if(cd.getStatus()){

if(store!=null){save();

}else{saveAs();

}System.exit(0);

}}

//Methodos pou dimiourgei enan tyxaio grafoprivate void createRandomGraph(){

RandomGraphDialog rgd=new RandomGraphDialog(this);rgd.setVisible(true);if(rgd.getGraph()!=null){

graph=rgd.getGraph();store=null;if(time){

time=false;timer.stop();

Δίκτυα Αισθητήρων

185

}remove(jtb);createToolBar();removeAndAddVV();setTitle("Sensor Networks");textInfo.append("\n\n------------------------------------------------------------------ ");textInfo.append("\nCreating Random Graph");enableGraphReaction();gm.setMode(ModalGraphMouse.Mode.EDITING);solution=new Vector<MyEdge>();initialGraph=null;

}}

//Methodos pou energopoiei kai apenergopoiei ton xronoprivate void time(){

if(time){time=false;timer.stop();textInfo.append("\n\n------------------------------------------------------------------ ");textInfo.append("\nThe time has been deactivated.");remove(jtb);createToolBar();

}else{TimeDialog td=new TimeDialog(this);td.setVisible(true);if(td.getCancel()){

return;}time=true;if(td.getOK()){

minutes=td.getMinutes();decrease=td.getCapacity();initializeTimer();remove(jtb);createToolBar();

}timer.start();textInfo.append("\n\n------------------------------------------------------------------ ");textInfo.append("\nThe time has been activated.");

}createMenu();pack();

}

//Methodos poy ilopoiei tin ektiposi grafouprivate void print(){

try{PrinterJob printJob=PrinterJob.getPrinterJob();printJob.setPrintable(new MyPrintableImpl(vv));if(printJob.printDialog()){

textInfo.append("\n\n------------------------------------------------------------------ ");textInfo.append("\nGraph Printing :");

Δίκτυα Αισθητήρων

186

printJob.print();textInfo.append("\nThe graph has been printed with success.");

}}catch(Exception exc){

textInfo.append("\nA problem has occurred while printing was running.");}

}

private void initialGraph(){if(initialGraph!=null){

graph=initialGraph.copy();removeAndAddVV();enableGraphReaction();gm.setMode(ModalGraphMouse.Mode.EDITING);solution=new Vector<MyEdge>();pack();textInfo.append("\n\n------------------------------------------------------------------ ");textInfo.append("\nInitial Graph");

}else{JOptionPane.showMessageDialog( this, "There is no initial graph!","Error" ,

JOptionPane.ERROR_MESSAGE );}

}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////

//Boithitikes Methodoi

//Methodos i opoia arxikopoiei ton xronoprivate void initializeTimer(){

timer=new Timer(minutes*60*1000,new ActionListener(){public void actionPerformed(ActionEvent evt){

graph.decreaseCapacity(decrease);vv.repaint();

}}

);timer.setInitialDelay(minutes*60*1000);

}

//Methodos i opoia afairei to yparxon vv kai prosthetei alloprivate void removeAndAddVV(){

Component[] comps=getContentPane().getComponents();showGraph();if(comps.length>0){

for (Component comp : comps) {if (comp instanceof VisualizationViewer) {

getContentPane().remove(comp);getContentPane().add(vv,BorderLayout.CENTER);

}//telos esoterikou if}//telos for

}//telos eksoterikou if

Δίκτυα Αισθητήρων

187

}

//Methodos i opoia energopoiei thn anadrasi sto grafoprivate void enableGraphReaction(){

counter=0;addMouse();createMenu();gabrielButton.setEnabled(true);kruskalButton.setEnabled(true);compare.setEnabled(true);iP.setEnabled(true);pack();

}

//Methodos i opoia apenergopoiei tin anadrasi sto grafoprivate void disableGraphReaction(){

//Afairese to pontiki gia na min peiraksei ton grafogm.remove(gm.getEditingPlugin());

//Apenergopoise kai sto menouto mode editingmouseMenu.getItem(2).setEnabled(false);mouseMenu.getItem(0).setSelected(true);//Apenergopoiise tin eisagogi stoixeioniP.setEnabled(false);

//Apenergopoise ta radioButtonsgabrielButton.setEnabled(false);kruskalButton.setEnabled(false);compare.setEnabled(false);

}

//Methodos i opoia epistrefei diafores plirofories gia ton grafoprivate String graphInfo(){

if(graph==null||graph.getVertexCount()==0){return null;

}String info="";long n;

info+="\nTotal Graph Energy: ";n=(int)Math.round((graph.calculateTotalEnergy()/graph.getVertexCount())*100);info+=Double.toString((double)n/100)+"%";

info+="\nTotal Loss Energy : ";n=(int)Math.round(((100*graph.getVertexCount() -

graph.calculateTotalEnergy())/graph.getVertexCount())*100);info+=Double.toString((double)n/100)+"%";

n=(int)Math.round(graph.minEnergy().getCapacit y()*100);info+="\nVertex with the less energy: \n"+graph.minEnergy()+" ("+(double)n/100+"%)";n=(int)Math.round(graph.maxEnergy().getCapacity()*100);info+="\nVertex with the most energy: \n"+graph.maxEnergy()+"

("+(double)n/100+"%)";

Δίκτυα Αισθητήρων

188

return info;}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//Oi Algorithmoi

private void showResult(){if(gabrielButton.isSelected()){

runGabriel();}else if(kruskalButton.isSelected()){

runKruskal();}else{

JOptionPane.showMessageDialog( this, "You must cho ose an algorithm!","Error", JOptionPane.ERROR_MESSAGE );

}}private void runKruskal(){

text.append("\n\n------------------------------------------------------------------ ");text.append("\nKruskal Algorithm - See Result :");//Elegxoume ean yparxei kapoios grafosif(graph.getVertexCount()==0){

JOptionPane.showMessageDialog( this, "There is no graph, in orderto run the\nKruskal algorithm!",

"Error", JOptionPane.ERROR_MESSAGE );text.append("\nThere is no graph, in order \nto run the Kruskal Algorithm!");return;

}else if (!graph.HasWeights()){JOptionPane.showMessageDialog( this, "You should give weight to all the edges,in

order to run\n the Kruskal algorithm!","Error", JOptionPane.ERROR_MESSAGE );

text.append("\nYou should give weight to all the edges \nbefore running the KruskalAlgorithm!");

return;}

if(counter==0){

initialGraph=graph.copy();graph.recharge();ka=new KruskalAlgorithm();ka.runAlgorithm(vv);AlgorithmEdges=ka.getEdges();endpoints=ka.getEndPoints();edgesState=ka.getEdgesState();solution=new Vector<MyEdge>();

}

for(int j=counter;j<AlgorithmEdges.size();j++){if(edgesState.elementAt(j)){

solution.add(AlgorithmEdges.elementAt(j));graph.KruskalEnergy(AlgorithmEdges.elementAt(j));

Δίκτυα Αισθητήρων

189

}else{vv.getGraphLayout().getGraph().removeEdge(AlgorithmEdges.elementAt(j));

}}vv.repaint();//Emfanisi MinimatosJOptionPane.showMessageDialog( this, "The Kruskal algorithm has b een completed

with success!","information",

JOptionPane.INFORMATION_MESSAGE );//Emfanisi Varoustext.append("\nThe Kruskal algorithm has been completed. \n\nGraph's Total Weight:

"+graph.calculateTotalWeight()+".");text.append(graphInfo());enableGraphReaction();

}//telos methodou runKruskalprivate void runGabriel(){

text.append("\n\n------------------------------------------------------------------ ");text.append("\nGabriel Algorithm - See Result :");//Elegxoume ean yparxei kapoios grafosif(graph.getVertexCount()==0){

JOptionPane.showMessageDialog( this, "There is no graph in orderto run\nthe Gabriel algorithm!",

"Error", JOptionPane.ERROR_MESSAGE );text.append("\nThere is no graph in order \nto run the Gabriel Algorithm!");return;

}

if(counter==0){initialGraph=graph.copy();graph.recharge();ga=new GabrielAlgorithm();ga.runAlgorithm(vv);AlgorithmEdges=ga.getSolution();endpoints=ga.getEndPoints();solution=new Vector<MyEdge>();graph.removeEdges();vv.repaint();

}for(int j=counter;j<AlgorithmEdges.size();j++){

vv.getGraphLayout().getGraph().addEdge(AlgorithmEdges.elementAt(j),endpoints.elementAt(j));

graph.GabrielEnergy(AlgorithmEdges.elementAt(j));solution.add(AlgorithmEdges.elementAt(j));vv.repaint();

}//Emfanisi MinimatosJOptionPane.showMessageDialog( this, "The Gabriel algorithm has been completed with

success!","information",

JOptionPane.INFORMATION_MESSAGE );

Δίκτυα Αισθητήρων

190

text.append("\nThe Gabriel algorithm has been completed\nwith success.\n");text.append(graphInfo());enableGraphReaction();

}//telos methodou runGabriel

private void next(){//Prota elegxoume poios algorithmos einai epilegmenos.if(gabrielButton.isSelected()){

runNextGabriel();}else if(kruskalButton.isSelected()){

runNextKruskal();}else{

JOptionPane.showMessageDialog( this, "You must choose an algorithm!","Error",JOptionPane.ERROR_MESSAGE );

}}private void runNextKruskal(){

if(counter==0){text.append("\n\n------------------------------------------------------------------ ");

}text.append("\nNext - Kruskal Algorithm");if(graph.getVertexCount()==0){

JOptionPane.showMessageDialog( this, "There is no graph in order to tun \ntheKruskal algorithm!",

"Error", JOptionPane.ERROR_MESSAGE );text.append("\nThere is no graph in order \nto run the Kruskal Algorithm!");return;

}else if(!graph.HasWeights()){JOptionPane.showMessageDialog( this, "You should give weight to all the edges, in

order to run\nthe Kruskal algorithhm!","Error", JOptionPane.ERROR_MESSAGE );

text.append("\nYou should give weight to all the edges \nbefore running the KruskalAlgorithm!");

return;}if(counter==0){

//Den exei treksei o algorithmos

//Antigrafoume ton grafo ean thelei na epistrepsei se ayton kap oia stigmiinitialGraph=graph.copy();//Trexoume ton algorithmoka=new KruskalAlgorithm();ka.runAlgorithm(vv);//Perno tis akmesAlgorithmEdges=ka.getEdges();endpoints=ka.getEndPoints();//To parakato mas leei ean einai gia prosthiki i afairesi i akmiedgesState=ka.getEdgesState();//H lysisolution=new Vector<MyEdge>();//Dinoyme energeia 100% stous kombousgraph.recharge();//Apenergopoiise tin allilepidrasi me ton grafodisableGraphReaction();

Δίκτυα Αισθητήρων

191

}

if(counter<AlgorithmEdges.size()){//O algorithmos exei idi treksei kai proxorame sto epomeno bimaif(edgesState.elementAt(counter)){

//H akmi anikei ston Kruskal//Epomenos tin prostethoume stin lisisolution.add(AlgorithmEdges.elementAt(counter));//kai allazoume thn energeia ton k ombongraph.KruskalEnergy(AlgorithmEdges.elementAt(counter));

}else{//Diaforetika h akmi den anikei ston Kruskal kai prepei na afairethei apo ton grafo

vv.getGraphLayout().getGraph().removeEdge(A lgorithmEdges.elementAt(counter));}//ksanazografizoumevv.repaint();//Auksanoume ton metriti na deixnei stin epomeni akmicounter++;

}else if(counter==AlgorithmEdges.size()){//O algorithmos exei oloklirothei

vv.repaint();//Emfanisi MinimatosJOptionPane.showMessageDialog( this, "The Kruskal algorithm has been completed

with success!","information",

JOptionPane.INFORMATION_MESSAGE );//Emfanisi Varoustext.append("\nThe Kruskal algorithm has been completed. \n\nGraph's Total Weight:

"+graph.calculateTotalWeight()+".");text.append(graphInfo());enableGraphReaction();

}}private void runNextGabriel(){

if(counter==0){text.append("\n\n------------------------------------------------------------------ ");

}text.append("\nNext - Gabriel Algorithm");if(graph.getVertexCount()==0){

JOptionPane.showMessageDialog( this, "There is no graph in order to run \ntheGabriel algorithm!",

"Error", JOptionPane.ERROR_MESSAGE );text.append("\nThere is no graph in order \nto run the Gabriel Algorithm!");return;

}if(counter==0){

//Den exei treksei o algorithmosinitialGraph=graph.copy();ga=new GabrielAlgorithm();ga.runAlgorithm(vv);//Perno tis akmes pou tha prosthesoAlgorithmEdges=ga.getSolution();

Δίκτυα Αισθητήρων

192

endpoints=ga.getEndPoints();solution=new Vector<MyEdge>();graph.recharge();disableGraphReaction();graph.removeEdges();vv.repaint();

}

if(counter<AlgorithmEdges.size()){//O algorithmos exei idi treksei kai proxorame sto epomeno bima

vv.getGraphLayout().getGraph().addEdge(AlgorithmEdges.elementAt(counter),endpoints.elementAt(counter));

graph.GabrielEnergy(AlgorithmEdges.elementAt(counter));solution.add(AlgorithmEdges.elementAt(counter));vv.repaint();counter++;

}else if(counter==AlgorithmEdges.size()){//O algorithmos exei oloklirothei

//Emfanisi MinimatosJOptionPane.showMessageDialog( this, "The Gabriel algorithm has been completed

with success!","information",

JOptionPane.INFORMATION_MESSAGE );//Emfanisi Varoustext.append("\nThe Gabriel algorithm has been completed \nwith success.\n");text.append(graphInfo());enableGraphReaction();

}}

private void back(){//Prota elegxoume poios algorithmos einai epilegmenos.if(gabrielButton.isSelected()){

runBackGabriel();}else if(kruskalButton.isSelected()){

runBackKruskal();}else{

JOptionPane.showMessageDialog( this, "You must choose an algorithm!","Error",JOptionPane.ERROR_MESSAGE );

}}private void runBackKruskal() {

text.append("\nBack - Kruskal Algorithm ");

if (counter <= AlgorithmEdges.size() && counter > 0) {counter--;if(edgesState.elementAt(counter)){

graph.reverseKruskalEnergy(AlgorithmEdges.elementAt(counter));solution.remove(AlgorithmEdges.elementAt(counter));

}else{

Δίκτυα Αισθητήρων

193

vv.getGraphLayout().getGraph().addEdge(AlgorithmEdges.elementAt(counter),endpoints.elementAt(counter));

}vv.repaint();

}if(counter==0){

text.append("\nInitial Graph");enableGraphReaction();

}}private void runBackGabriel(){

text.append("\nBack - Gabriel Algorith");if (counter <= AlgorithmEdges.size() && counter > 0) {

counter--;graph.reverseGabrielEnergy(AlgorithmEdges.elementAt(counter));solution.remove(AlgorithmEdges.elementAt(counter));vv.getGraphLayout().getGraph().removeEdge(AlgorithmEdges.elementAt(counter));vv.repaint();

}if(counter==0){

text.append("\nInitial Graph");enableGraphReaction();

}}

private void compare(){double kruskalEnergy,gabrielEnergy;long n;

//Sigkrisi ton duo algorithmontext.append("\n\n------------------------------------------------------------------ ");text.append("\nCompare the Algorithms");

//Elegxoiif(graph.getVertexCount()==0){

JOptionPane.showMessageDialog( this, "There is no graph, in orderto run the\n algorithms!",

"Error", JOptionPane.ERROR_MESSAGE );text.append("\nThere is no graph, in order \nto run the Algorithms!");return;

}else if (!graph.HasWeights()){JOptionPane.showMessageDialog( this, "You should give weight to all the edges,in

order to run\n the Kruskal algorithm!","Error", JOptionPane.ERROR_MESSAGE );

text.append("\nYou should give weight to all the edges \nbefore running the KruskalAlgorithm!");

return;}

text.append("\n\n TOTAL GRAPH ENERGY");text.append("\nKruskal Al.\tGabriel Gr.");//Ektelesi Kruskal Algorithmougraph.recharge();

Δίκτυα Αισθητήρων

194

ka=new KruskalAlgorithm();ka.runAlgorithm(vv);

n=(int)Math.round((graph.hypotheticalKruskalTotalEnergy(ka.getEdges(),ka.getEdgesState())/graph.getVertexCount())*100);

kruskalEnergy=(double)n/100;text.append("\n "+kruskalEnergy+"%.");

//Ektelesi Gabriel Algorithmgraph.recharge();ga=new GabrielAlgorithm();ga.runAlgorithm(vv);

n=(int)Math.round((graph.hypotheticalGabrielTotalEnergy(ga.g etEndPoints())/graph.getVertexCount())*100);

gabrielEnergy=(double)n/100;text.append(" \t"+gabrielEnergy+"%.");

//Emfanisi DiagrammatosChartFrame cd=new ChartFrame(kruskalEnergy,gabrielEnergy);cd.setVisible(true);

//Emfanisi Kaliterou algorithmouif(gabrielEnergy>kruskalEnergy){

runGabriel();}else{

runKruskal();}

}

////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

public void actionPerformed(ActionEvent event){String menuName;menuName=event.getActionCommand();final ScalingControl scaler=new CrossoverScalingControl();if(menuName.equals("Quit")){

close();}else if(menuName.equals("New")){

newGraph();}else if(menuName.equals("Open...")){

openGraph();}else if(menuName.equals("Save As...")){

saveAs();}else if(menuName.equals("Save As Image")){

saveAsImage();}else if(menuName.equals("Save")&&store!=null){

save();}else if(menuName.equals("zoomOut")){

scaler.scale(vv,1/1.1f,vv.getCenter());}else if(menuName.equals("zoomIn")){

Δίκτυα Αισθητήρων

195

scaler.scale(vv,1.1f,vv.getCenter());}else if(menuName.equals("next")){

next();}else if(menuName.equals("back")){

back();}else if(menuName.equals("result")){

showResult();}else if(menuName.equals("Random Graph")){

createRandomGraph();}else if(menuName.equals("Charge the Nodes")){

if(graph!=null){graph.recharge();vv.repaint();

}}else if(menuName.equals("Refresh")){

removeAndAddVV();}else if(menuName.equals("Enable Time")||menuName.equals("Disable Time")){

time();}else if(menuName.equals("Print")){

print();}else if(menuName.equals("Initial Graph")){

initialGraph();}else if(menuName.equals("compare")){

compare();}else if(menuName.equals("Graph's Info")){

GraphInfoDialog gid=new GraphInfoDialog(this,graph);gid.setVisible(true);

}else if(menuName.equals("Move Forward Time")){if(time){

SkipTimeDialog std=new SkipTimeDialo g(this,minutes,decrease,vv);std.setVisible(true);

}else{JOptionPane.showMessageDialog( this, "You must first edit the time settings and

enable the time before skipping it!","Error", JOptionPane.ERROR_MESS AGE );

}

}}

public void mousePressed (MouseEvent me) {

if(me.getButton()==MouseEvent.BUTTON1){

if(mouseMenu.getItem(1).isSelected()){

VisualizationViewer<MyVertex,MyEdge>visComp=(VisualizationViewer<MyVertex,MyEdge>)me.getSource();

Point2D p=me.getPoint();GraphElementAccessor<MyVertex,MyEdge>

pickSupport=visComp.getPickSupport();if(pickSupport!=null){

MyVertex v=pickSupport.getVertex(vv.getGraphLayout(),p.getX(),p.getY());if(v!=null){

Δίκτυα Αισθητήρων

196

iP.showVertex(v);tabbedPane.setSelectedIndex(1);

}else{MyEdge edge=pickSupport.getEdge(vv.getGraphLayout(),p.getX(),p.getY());if(edge!=null){

iP.showEdge(edge,graph.getEndpoints(edge));tabbedPane.setSelectedIndex(1);

}}

}}

}}public void mouseEntered (MouseEvent me) {}public void mouseClicked (MouseEvent me) {}public void mouseReleased (MouseEvent me) {}public void mouseExited (MouseEvent m e) {}

}import edu.uci.ics.jung.graph.UndirectedSparseMultigraph;import edu.uci.ics.jung.graph.util.Pair;

import java.util.Vector;

/*H klasi auti anaparista ton mi kateythinomeno grafo. Epitrepontai kai oi brogxoi.*/

public class MyGraph extends UndirectedSparseMultigraph<MyVertex,MyEdge> {

//Constructorspublic MyGraph(){

super();}public MyGraph(int nCount,int eCount, boolean w, boolean l){

super();int i;double x,y,weight;MyVertex v,u;MyEdge e;String name;int helpVariable=0;Object[] vertices;

//Dimiourgia Komvonfor(i=0;i<nCount;i++){

do{name="Node"+helpVariable++;

}while(this.findVertex(name)!=nu ll);do{

x=Math.random()*550;y=Math.random()*550;

}while(findVertex(x,y)!=null);

Δίκτυα Αισθητήρων

197

v=new MyVertex(name,x,y);this.addVertex(v);

}helpVariable=0;//Dimiourgia Akmonfor(i=0;i<eCount;i++){

do{name="Edge"+helpVariable++;

}while(this.findEdge(name)!=null);

vertices=this.getVertices().toArray();do{

v=(MyVertex)vertices[(int)(Math.random()*vertices.length)];u=(MyVertex)vertices[(int)(Math.random()*vertices.length)];

}while(u==v&&!l);if(w){

weight=(int)(Math.random()*100);e=new MyEdge(name,weight );

}else{e=new MyEdge(name);

}this.addEdge(e,v,u);

}}

/////////////////////////////////////////////////////////////////////////////////// Methodoi Anazitisis ///////////////////////////////////////////////////////////////////////////////////

//H methodos ayti psaxnei na brei ean yparxei kombos me to onoma toy orismatos kai ean//yparxei epistrefei ton kombo allios nullpublic MyVertex findVertex(String name){

Object[] komvoi;MyVertex v;int i;

komvoi=(this.getVertices()).toArray();for( i=0;i<komvoi.length;i++){

v=(MyVertex)komvoi[i];if((v.getName()).equals(name)){

return v;}

}return null;

}

//H methodos ayti psaxnei na brei ean yparxei kombos stis syntetagmenes x kai y poy einiasta orismata

//kai ean yparxei epistrefei ton kombo allios nullpublic MyVertex findVertex(double x,double y){

Object[] komvoi;

Δίκτυα Αισθητήρων

198

MyVertex v;int i;

komvoi=(this.getVertices()).toArray();for( i=0;i<komvoi.length;i++){

v=(MyVertex)komvoi[i];if((v.getX())==x&&(v.getY())==y){

return v;}

}return null;

}

//H methodos ayti psaxnei na brei thn akmi me to onoma toy orismatos//kai ean yparxei apistrefeitin akmi allios nullpublic MyEdge findEdge(String name){

Object[] akmes;MyEdge e;int i;

akmes=(this.getEdges()).toArray();for( i=0;i<akmes.length;i++){

e=(MyEdge)akmes[i];if((e.getName()).equals(name)){

return e;}

}return null;

}

//H methodos ayth psaxnei na brei tin akmi ston grafo kai ean//tin brei epistrefei tin akmi allios nullpublic MyEdge findEdge(MyEdge akmi){

Object[] akmes;MyEdge e;int i;

akmes=(this.getEdges()).toArray();for( i=0;i<akmes.length;i++){

e=(MyEdge)akmes[i];if(e==akmi){

return e;}

}return null;

}

//////////////////////////////////////////////////////////////////////////////////// Methodoi Gia Thn Energeia ///////////////////////////////////////////////////////////////////////////////////

Δίκτυα Αισθητήρων

199

//H methodos recharge() kanei tin energeia olon ton komvon se 100%public void recharge(){

Object[] nodes=(this.getVertices()).toArray();int i;for(i=0;i<nodes.length;i++){

((MyVertex)nodes[i]).setCapacity(100);}

}

//H methodos calculateTotalEnergy() ypologizei tin sinoliki energeia toy grafoy//athroizontas tis energeies olon ton kombonpublic double calculateTotalEnergy(){

double total=0;Object[] vertices=this.getVertices().toArray ();for (Object vertice : vertices) {

if(((MyVertex)vertice).getCapacity()<0){total+=0;

}else{total += ((MyVertex) vertice).getCapacity();

}}return total;

}

//H methodos decreaseCapacity(int d) meionei tin energeia olon ton kombon toy grafoy//kata mia posotita d.public void decreaseCapacity(int d){

Object[] vertices=this.getVertices().toArray();for (Object vertice : vertices) {

((MyVertex) vertice).decreaseCapacity(d);}

}

//H Methodos ayti ekteleitai kathe fora poy prostithetai mia akmi ston gabriel grafo// kai meionetai i energeia ston grafo logo tis akmis epublic void GabrielEnergy(MyEdge e){

double distance;Pair<MyVertex> endPoints=this.getEndpoints(e);distance=Math.sqrt((Math.pow((endPoints.getFirst().getX() -

endPoints.getSecond().getX()),2)+Math.pow((endPoints.getFirst().getY() -endPoints.getSecond().getY()),2)));

(endPoints.getFirst()).decreaseCapacity(5+distance/30);(endPoints.getSecond()).decreaseCapacity(5+distance/30);

}

//H methodos ayti kanei tin antitheti doyleia apo tin proigoumeni methodo kai auksanei//thn energeia ston Gabriel grafo ean afairesoyme thn akmi epublic void reverseGabrielEnergy(MyEdge e){

double distance;Pair<MyVertex> endPoints=this.getEndpoints(e);

Δίκτυα Αισθητήρων

200

distance=Math.sqrt((Math.pow((endPoints.getFirst().getX() -endPoints.getSecond().getX()),2)+Math.pow((endPoints.getFirst().getY() -endPoints.getSecond().getY()),2)));

(endPoints.getFirst()).increaseCapacity(5+distance/30);(endPoints.getSecond()).increaseCapacity(5+distance/30);

}

//H methodos ayti ekteleitai kathe fora pou prosthetoume mia akmi ston grafo//simfona me ton algorithmo toy kruskal kai meionetai i energeia toy grafoy//logo tis akmis epublic void KruskalEnergy(MyEdge e){

Pair<MyVertex> endpoints=this.getEndpoints( e);double d=5+e.getWeight()/10;endpoints.getFirst().decreaseCapacity(d);endpoints.getSecond().decreaseCapacity(d);

}

//H methodos ayti kanei thn antitheti doyleia apo tin proigoumeni methodo kai auksanei//thn energeia ston grafo ean afairesoume tin akmi e toy Kruskal algorithmoupublic void reverseKruskalEnergy(MyEdge e){

Pair<MyVertex> endpoints=this.getEndpoints(e);double d=5+e.getWeight()/10;endpoints.getFirst().increaseCapacity(d);endpoints.getSecond().increaseCapacity(d);

}

//H methodos ayth ypologizei thn posotita tis energeias poy tha xanotan ston grafo//ean trexame ton algorithmo kruskal me apotelesma tis akmes edgespublic double hypotheticalKruskalTo talEnergy(Vector<MyEdge> edges,Vector<Boolean>

state){double totalLoss=0;

for(int i=0;i<edges.size();i++){if(state.elementAt(i)){

totalLoss+=2*(5+edges.elementAt(i).getWeight()/10);}

}if(100*this.getVertexCount() -totalLoss<0){

return 0;}else{

return 100*this.getVertexCount() -totalLoss;}

}

//H methodos auti ypologizei tin posotita tis energeias pou tha xanotan apo ton grafo//ean trexame ton algorithmo tou Gabriel me apotelesma tis akmes me akra simeion//ta endpointspublic double hypotheticalGabrielTotalEnergy(Vector<Pair<MyVertex>> endpoints){

double totalLoss=0;double distance;

Δίκτυα Αισθητήρων

201

for(int i=0;i<endpoints.size();i++){distance=Math.sqrt((Math.pow((endpoints.elementAt(i).getFirst().getX() -

endpoints.elementAt(i).getSecond().getX()),2)+Math.pow((endpoints.elementAt(i).getFirst().getY()-endpoints.elementAt(i).getSecond().getY()),2)));

totalLoss+=2*(5+distance/35);}if(100*this.getVertexCount() -totalLoss<0){

return 0;}else{

return 100*this.getVertexCount() -totalLoss;}

}

//H methodos auti ypologizei ton komvo me t in mikroterh energeiapublic MyVertex minEnergy(){

MyVertex v=null;Object[] komvoi=this.getVertices().toArray();int i;if(komvoi.length>0){

v=(MyVertex)komvoi[0];for(i=1;i<komvoi.length;i++){

if(v.getCapacity()>((MyVertex)komvoi[i]).getCapacity()){v=(MyVertex)komvoi[i];

}}

}return v;

}

//H methodos ayti ipologizei ton kombo me tin megaliteri energeiapublic MyVertex maxEnergy(){

MyVertex v=null;Object[] komvoi=this.getVertices().toArray();int i;if(komvoi.length>0){

v=(MyVertex)komvoi[0];for(i=1;i<komvoi.length;i++){

if(v.getCapacity()<((MyVertex)komvoi[i]).getCapacity()){v=(MyVertex)komvoi[i];

}}

}return v;

}

//////////////////////////////////////////////////////////////////////////////////// Alles Methodoi ///////////////////////////////////////////////////////////////////////////////////

Δίκτυα Αισθητήρων

202

//H methodos auti afairei oles tis akmes toy grafoupublic void removeEdges(){

Object[] edges=this.getEdges().toArray();int i;for(i = 0; i<edges.length;i++){

this.removeEdge((MyEdge)edges[i]);}

}

//H methodos ayti antigrafei ton yparxon grafo kai epistrefei ena aneksartito antigarfo toupublic MyGraph copy(){

int i;MyGraph initial=new MyGraph();Object[] vertices=this.getVertices().toArray();Object[] edges=this.getEdges().toArray();MyEdge e;

for(i=0;i<vertices.length;i++){initial.addVertex(((MyVertex)vertices[i]).copy());

}

for(i=0;i<edges.length;i++){e=(MyEdge)edges[i];

initial.addEdge(e.copy(),initial.findVertex(this.getEndpoints(e).getFirst().getName()),initial. findVertex(this.getEndpoints(e).getSecond().getName()));

}return initial;

}

//H methodos ayti elegxei ean exoyn anatethei se oles tis akmes baripublic boolean HasWeights(){

Object[] edges=getEdges().toArray();int i;MyEdge e;

for(i=0;i<edges.length;i++){e=(MyEdge)edges[i];

if(e.getWeight()==null){return false;

}}return true;

}

//H methodos ayti ypologizei to sinoliko baros tou grafoypublic double calculateTotalWeight(){

double totalWeight=0;Object[] akmes=this.getEdges().toArray();

Δίκτυα Αισθητήρων

203

for (Object akme : akmes) {totalWeight += ((MyEdge) akme).getWeight();

}return totalWeight;

}}

import edu.uci.ics.jung.visualization.VisualizationViewer;

import javax.swing.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.geom.Point2D;

/*Mia sillogi apo klaseis pou xrisimopoiountai gia na dimiourghsoun ta popup mouse menusgia ti akmes typou MyEdge kai tous komvous tipou MyVertex.*/

public class MyMouseMenus {

public static class EdgeMenu extends JPopupMenu {public EdgeMenu(final JFrame frame){

super("Edge Menu");this.add(new WeightDisplay());this.addSeparator();this.add(new DeleteEdgeMenuItem<MyEdge>());this.add(new EdgePropItem(frame));

}}

public static class EdgePropI tem extends JMenuItem implementsEdgeMenuListener<MyEdge>,MenuPointListener{

//IdiotitesMyEdge edge;VisualizationViewer visComp;Point2D point;

public void setEdgeAndView(MyEdge edge,VisualizationViewer visComp){this.visComp = visComp;this.edge=edge;

}

public void setPoint(Point2D point){this.point=point;

}

public EdgePropItem(final JFrame frame){

Δίκτυα Αισθητήρων

204

super("Edit Edge Properties...");this.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent e){EdgePropertyDialog dialog=new EdgePropertyDialog(frame,edge);

dialog.setLocation((int)point.getX() +frame.getX(),(int)point.getY()+frame.getY());dialog.setVisible(true);

}});

}}

public static class WeightDisplay extends JMenuItem implementsEdgeMenuListener<MyEdge>{

public void setEdgeAndView(MyEdge edge,VisualizationViewer vv){this.setText("Weight "+edge.getName()+" = "+edge.getWeight());

}}

public static class VertexMenu extends JPopupMenu{public VertexMenu(final JFrame fr ame){

super("Node Menu");this.add(new EnergyDisplay());this.addSeparator();this.add(new DeleteVertexMenuItem<MyVertex>());this.add(new VertexPropItem(frame));

}}

public static class VertexPropItem extends JMenuItem implementsVertexMenuListener<MyVertex>,MenuPointListener{

//IdiotitesMyVertex vertex;VisualizationViewer visComp;Point2D point;

public void setVertexAndView(MyVertex ver tex,VisualizationViewer visComp){this.visComp = visComp;this.vertex=vertex;

}

public void setPoint(Point2D point){this.point=point;

}

public VertexPropItem(final JFrame frame){super("Edit Node Properties...");this.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent e){VertexPropertyDialog dialog=new VertexPropertyDialog(frame,vertex);

dialog.setLocation((int)point.getX()+frame.getX(),(int)point.getY()+frame.getY());dialog.setVisible(true);

Δίκτυα Αισθητήρων

205

}});

}}public static class EnergyDisplay extends JMenuItem implements

VertexMenuListener<MyVertex>{public void setVertexAndView(MyVertex node,VisualizationViewer vv){

long n;if(node.getCapacity()>100){

this.setText("Energy "+node.getName()+" = 100%");}else if(node.getCapacity()<0){

this.setText("Energy "+node.getName()+" = 0%");}else{

n=(int)Math.round(node.getCapacity()*100);this.setText("Energy "+node.getName()+" =

"+Double.toString((double)n/100)+"%");}

}}

}

import edu.uci.ics.jung.visualization.VisualizationViewer;

import java.awt.*;import java.awt.print.PageFormat;import java.awt.print.Printable;import java.awt.print.PrinterException;

/*H klasi ayti orizei pos tha ektipothei o grafos*/

public class MyPrintableImpl implements Printable {

//Idiotitaprivate VisualizationViewer<MyVertex,MyEdge> visComp;

//Constructorpublic MyPrintableImpl(VisualizationViewer<MyVertex,MyEdge> visComp){

this.visComp=visComp;}

public int print(Graphics graphics, PageFormat pageFormat,int pageIndex) throwsPrinterException{

if(pageIndex>0){return (Printable.NO_SUCH_PAGE);

}else{Graphics2D g2d=(Graphics2D)graphi cs;visComp.setDoubleBuffered(false);g2d.translate(pageFormat.getImageableX(),pageFormat.getImageableY());

Δίκτυα Αισθητήρων

206

visComp.paint(g2d);visComp.setDoubleBuffered(true);return (Printable.PAGE_EXISTS);

}}

}

/*H klasi MyVertex anaparista tous komvous.Kathe komvos apoteleitai apo to ena kai monadiko onoma tou,tis syntetagmenes (x,y) kai tin energeia tou.*/

public class MyVertex{

//Idiotitesprivate String name; //To onoma tou ko mvouprivate double x; //Oi sintetagmenes touprivate double y;private double capacity; //H energeia tou kombou

//Constructorspublic MyVertex(){}

public MyVertex(String name,double x,double y){this.name=name;this.x = x;this.y=y;this.capacity=100;

}

/////////////////////////////////////////////////////////////////////////////////// Ta gets kai ta sets ///////////////////////////////////////////////////////////////////////////////////

public void setName(String name){this.name=name;

}public String getName(){

return this.name;}

public void setX(double x){this.x=x;

}public double getX(){

return this.x;}

public void setY(double y){this.y=y;

Δίκτυα Αισθητήρων

207

}public double getY(){

return y;}

public void setCapacity(double capacity){this.capacity=capacity;

}public double getCapacity(){

return capacity;}

/////////////////////////////////////////////////////////////////////////////////// Alles Methodoi ///////////////////////////////////////////////////////////////////////////////////

//H methodos toStringpublic String toString(){

return this.name;}

//H methodos meionei tin capacity kata dpublic void decreaseCapacity(double d){

capacity -= d;}

//H methodos auksanei tin capacity kata dpublic void increaseCapacity(double d){

capacity += d;}

//H methodos copy dimioyrgei ena aneksartito antigrafo toy antikeimenou pou tin kalesepublic MyVertex copy(){

MyVertex v=new MyVertex(name,x,y);v.setCapacity(capacity);return v;

}

}

import org.apache.commons.collections15.Factory;

/*H klash MyVertexFactory ilopoiei to interface Factory gia na dimiourgountai komvoime to pontiki.Einai aparaititi gia tin klasi MyEditingModalGraphMOuse*/

public class MyVertexFactory implements Factory<MyVertex> {

private int nodeCount=0;

Δίκτυα Αισθητήρων

208

private MyGraph graph;private int x;private int y;

//Constructorpublic MyVertexFactory(MyGraph graph){

this.graph=graph;this.x=0;this.y=0;

}

//Xrisimopoeitai apo to MyEditingGraphMousePlugin otan// dimiourgeitai neos komvospublic MyVertex create(){

String name;//Tha vrei ena onoma to opoio den yparxei idido{

name="Node"+nodeCount++;}while(graph.findVertex(name)!=null);return new MyVertex(name,x,y);

}

//Xrisimopoieitai apo to MyEditingPlufin prin kalesei tin create//gia na orisei tis sintetagmenes tou neou komvou.public void setCoordinates(int x,int y){

this.x=x;this.y=y;

}}

import edu.uci.ics.jung.algorithms.layout.GraphElementAccessor;import edu.uci.ics.jung.visualization.Visualizati onViewer;import edu.uci.ics.jung.visualization.control.AbstractPopupGraphMousePlugin;

import javax.swing.*;import java.awt.*;import java.awt.event.MouseEvent;import java.awt.geom.Point2D;

/*Einai ena GraphMousePlugin to opoio asxoleitai me to popup menu , otan mia akmi i enaskomvos patietaisto grafo. Ean auta ta menou periexoun components pou ilopoioun eite to EdgeMenuListenerinterface eite to VertexMenuListener interface tote oi kataliles methodoi tou interfacekalountai gia tin emfanisi ton menou(etsi oste na deiksoun plirofories gia tin akmi i ton

komvo.*/

public class PopupVertexEdgeMenuMousePlugin<V,E> extendsAbstractPopupGraphMousePlugin {

Δίκτυα Αισθητήρων

209

//Idiotitesprivate JPopupMenu edgePopup,vertexPopup;

//Constructors

public PopupVertexEdgeMenuMousePlugin(){this(MouseEvent.BUTTON3_MASK);

}

public PopupVertexEdgeMenuMousePlugin(int modifiers){super(modifiers);

}

/////////////////////////////////////////////////////////////////////////////////// Ta gets kai ta sets ///////////////////////////////////////////////////////////////////////////////////

public JPopupMenu getEdgePopup(){return edgePopup;

}

public void setEdgePopup(JPopupMenu edgePopup){this.edgePopup=edgePopup;

}

public JPopupMenu getVertexPopup(){return vertexPopup;

}

public void setVertexPopup(JPopupMenu vertexPopup){this.vertexPopup=vertexPopup;

}

/////////////////////////////////////////////////////////////////////////////////// Alles Methodoi /////////////////////////////////////////////////////////////////////////////// ////

//Methodos tis abstract klasis AbstractPopupGraphMousePlugin//Edo kathorizetai ti tha ginetai.protected void handlePopup(MouseEvent e){

final VisualizationViewer<V,E> vv=(VisualizationViewer<V,E>)e.getSource();Point2D p=e.getPoint();

GraphElementAccessor<V,E> pickSupport=vv.getPickSupport();

if(pickSupport!=null){

//Ean exei peiraxthei kati sto VisualizationViewerfinal V v=pickSupport.getVertex(vv.getGraphLayout(),p.ge tX(),p.getY());if(v!=null){

Δίκτυα Αισθητήρων

210

//Ean exei peiraxthei vertex enimerose to vertexMenu kai emfanise toupdateVertexMenu(v,vv,p);vertexPopup.show(vv,e.getX(),e.getY());

}else{final E edge=pickSupport.getEdge(vv.getGraphLayout(),p.getX(),p.getY());

if(edge!=null){

//Ean exei peiraxthei akmi enimerose to edegMenu kai emfanise toupdateEdgeMenu(edge,vv,p);edgePopup.show(vv,e.getX(),e.getY());

}}

}}

//Methodos pou enimeronei to vertexMenu gia tin vertex pou patithikeprivate void updateVertexMenu(V v,VisualizationV iewer vv,Point2D point){

if (vertexPopup==null) return;

Component[] menuComps=vertexPopup.getComponents();for(Component comp:menuComps){

if(comp instanceof VertexMenuListener){((VertexMenuListener)comp).setVertexAndView(v,vv);

}

if(comp instanceof MenuPointListener){((MenuPointListener)comp).setPoint(point);

}}

}

//Methodos pou enimeronei to EdgeMenu gia tin akmi pou patithikeprivate void updateEdgeMenu(E edge,VisualizationViewer vv,Point2D point){

if(edgePopup==null) return;

Component[] menuComps=edgePopup.getComponents();for(Component comp:menuComps){

if(comp instanceof EdgeMenuListener){((EdgeMenuListener)comp).setEdgeAndView(edge,vv);

}if(comp instanceof MenuPointListener){

((MenuPointListener)comp).setPoint(point);}

}}

}

Δίκτυα Αισθητήρων

211

import javax.swing.*;import java.awt.*;import java.awt.event.ActionListener;import java.awt.event.ActionEvent;

/*H klasi RandomGraphDialog einai ena JDialog.O xristis eisagei tis parametrous gia ton tyxaiografo*/

public class RandomGraphDialog extends JDialog {

//Idiotites

//O arithmos ton akmonprivate JTextField edgeCount;//O arithmos ton komvonprivate JTextField nodeCount;//Epilogi ena tha mpoun bari i oxiprivate JCheckBox weight;//Epilogi an tha mpoun loops i oxiprivate JCheckBox loop;//O tyxaios grafos pou dimiourgeitaiprivate MyGraph graph;

//Constructorpublic RandomGraphDialog(JFrame parent){

super(parent,true);this.setPreferredSize(new Dimension(280,200));initComponents();setTitle("Create Random Graph");

setLocation((int)parent.getLocation().getX()+(int)parent.getSize().getWidth()/3,(int)parent.getLocation().getY()+(int)parent.getSize().getHeight()/3);

}

///////////////////////////////////////////// /////////////////////////////////////// Alles Methodoi ///////////////////////////////////////////////////////////////////////////////////

//Arxikopoiisi sistatikon parathirouprivate void initComponents(){

setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);JPanel panel, panel1,panel2,panel3,panel4,panel5;panel=new JPanel();panel.setLayout(new GridLayout(5,1));

panel1=new JPanel();

Δίκτυα Αισθητήρων

212

panel1.setPreferredSize(new Dimension(170,30));JLabel jLabel1 = new JLabel("Number of Nodes:");jLabel1.setPreferredSize(new Dimension(110,30));nodeCount=new JTextField();nodeCount.setPreferredSize(new Dimen sion(50,25));panel1.add(jLabel1);panel1.add(Box.createHorizontalStrut(10));panel1.add(nodeCount);panel1.add(Box.createHorizontalStrut(10));panel.add(panel1);

panel2=new JPanel();panel2.setPreferredSize(new Dimension(170,30));JLabel jLabel2=new JLabel("Number of Edges:");jLabel2.setPreferredSize(new Dimension(110,30));edgeCount=new JTextField();edgeCount.setPreferredSize(new Dimension(50,25));panel2.add(jLabel2);panel2.add(Box.createHorizontalStrut(10));panel2.add(edgeCount);panel2.add(Box.createHorizontalStrut(10));panel.add(panel2);

panel3=new JPanel();panel3.setPreferredSize(new Dimension(170,30)) ;JLabel jLabel3=new JLabel("Weight Edge:");jLabel3.setPreferredSize(new Dimension(100,30));weight=new JCheckBox();weight.setForeground(Color.WHITE);panel3.add(jLabel3);panel3.add(Box.createHorizontalStr ut(10));panel3.add(weight);panel3.add(Box.createHorizontalStrut(5));panel.add(panel3);

panel4=new JPanel();panel4.setPreferredSize(new Dimension(170,30));JLabel jLabel4=new JLabel(" Loop :");jLabel4.setPreferredSize(new Dimension(100,30));loop=new JCheckBox();loop.setForeground(Color.WHITE);panel4.add(jLabel4);panel4.add(Box.createHorizontalStrut(10));panel4.add(loop);panel4.add(Box.createHorizontalStrut(15));panel.add(panel4);

panel5=new JPanel();JButton jButton1 = new JButton("Create");jButton1.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent evt){createButtonHandler();

}});

Δίκτυα Αισθητήρων

213

JButton jButton2=new JButton("Cancel");jButton2.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent evt){cancelButtonHandler();

}});panel5.add(jButton1);panel5.add(jButton2);panel.add(panel5);getContentPane().add(panel);pack();

}

//Methodos pou ilopoiei tin epilogi createprivate void createButtonHandler() {

int edgeC,nodeC;graph=null;

try{if(nodeCount.getText().equals("")){

nodeC=0;}else{

nodeC=Integer.parseInt(nodeCount.getText());}if(nodeC<2){

JOptionPane.showMessageDialog( this, "The number of nodes should be greater orequal to 2!",

"Error", JOptionPane.ERROR_MESSAGE );return;

}}catch(NumberFormatException e){

JOptionPane.showMessageDialog( this, "The number of nodes should be integer!","Error", JOptionPane.ERROR_MESSAGE );

return;}try{

if(edgeCount.getText().equals("")){edgeC=0;

}else{edgeC=Integer.parseInt(edgeCount.getText());

}if(edgeC<0){

JOptionPane.showMessageDialog( this, "The number of edges should be positive orzero!",

"Error", JOptionPane.ERROR_MESSAGE ) ;return;

}}catch(NumberFormatException e){

JOptionPane.showMessageDialog( this, "The number of edges should be integer!","Error", JOptionPane.ERROR_MESSAGE );

return;}

graph=new MyGraph(nodeC,edgeC,weight.isSelected(),loop.isSelected());

Δίκτυα Αισθητήρων

214

dispose();}

//Methodos pou ilopoei tin epilogi cancelprivate void cancelButtonHandler(){

dispose();}

//Epistrefei ton tyxaio grafopublic MyGraph getGraph(){

return graph;}

}

import edu.uci.ics.jung.visualization.VisualizationViewer;

import javax.swing.*;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.WindowAdapte r;import java.awt.event.WindowEvent;

/*H klasi ayti anaparista to parathira gia na proxorisoume ton xrono mprosta.O xristios mporei na kathorsiei posa lepta mprosta tha proxorisoume. Gia na simbei aytoomostha prepei prota na energopoiisei ton xrono.*/

public class SkipTimeDialog extends JDialog {

//Idiotitesprivate JTextField minutes;//Ta lepta pou tha perasounprivate int min;//Kathe posa lepta meionetai i energeiaprivate int decrease;//Kata poso tha meivnetai h energeiaprivate VisualizationViewer<MyVertex,MyEdge> vv;private boolean ok=false;

//Constructorpublic SkipTimeDialog(Frame parent,int min,int decrease,

VisualizationViewer<MyVertex,MyEdge> vv){super(parent);this.min=min;this.decrease=decrease;this.vv=vv;setSize(new Dimension(200,130));this.addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent we){dispose();

}});

Δίκτυα Αισθητήρων

215

setLocation((int)parent.getLocation().getX()+(int)parent.getSize().getWidth()/3,(int)parent.getLocation().getY()+(int)parent.getSize().getHeight()/3);

setTitle("Move Forard Time");initComponents();

}

////////////////////////////////////// ///////////////////////////////////////////// Alles Methodoi ///////////////////////////////////////////////////////////////////////////////////

//Arxikopoiisi ton sistatikonprivate void initComponents(){

JPanel panel=new JPanel();panel.setLayout(new GridLayout(2,1));

JPanel jp=new JPanel();JLabel label=new JLabel("How many minutes?");jp.add(label);minutes=new JTextField();minutes.setPreferredSize(new Dimension(50,25));jp.add(minutes);panel.add(jp);

jp=new JPanel();JButton ok=new JButton("OK");ok.setPreferredSize(new Dimension(60,30));ok.addActionListener(new Acti onListener(){

public void actionPerformed(ActionEvent evt){okButtonHandler();

}});

jp.add(ok);panel.add(jp);

getContentPane().add(panel);

}

//Methodos pou kathorizei ti tha ginetai an o xristis patisei to koumpi okprivate void okButtonHandler(){

int portion;try{

portion=Integer.parseInt(minutes.getText());if(portion<0){

JOptionPane.showMessageDialog( t his, "The minutes must be a positive number!","Error", JOptionPane.ERROR_MESSAGE );

return;}

}catch(NumberFormatException e){

Δίκτυα Αισθητήρων

216

JOptionPane.showMessageDialog( this, "The minutes must be a number!","Error", JOptionPane.ERROR_MESSAGE );

return;}ok=true;

((MyGraph)vv.getGraphLayout().getGraph()).decreaseCapacity((int)portion*decrease/min);vv.repaint();dispose();

}

}

import javax.swing.*;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;

/*H klasi TimeDialog einai ena JDialog. O xristis mporei na dosei tis parametrous tou xronoumesa apo ayto.*/

public class TimeDialog extends JDialog {

//Idiotes

//kathe posa lepta tha meionetai i energeia ton komvonprivate JTextField minutes;private int min;//Poso tha meionetai i energeiaprivate JTextField capaci ty;private int cap;//Metabliti pou anaparista an pigan ola kala stin eisagogi stoixeionprivate boolean ok;//Metabliti pou anaparista an ean exei patisei to cancel i to xprivate boolean cancel=false;

//Constructorpublic TimeDialog(JFrame parent){

super(parent,true);this.setPreferredSize(new Dimension(240,160));initComponents();setTitle("Set Time");this.addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent we){cancel=true;dispose();

}});

Δίκτυα Αισθητήρων

217

setLocation((int)parent.getLocation().getX()+(int)parent.getSize().getWidth()/3,(int)parent.getLocation().getY()+(int)parent.getSize().getHeight()/3);

}

//////////////////////////////////////////////////////////////////////////////////// Ta gets ///////////////////////////////////////////////////////////////////// //////////////

public boolean getOK(){return ok;

}public int getCapacity(){

return cap;}public int getMinutes(){

return min;}public boolean getCancel(){

return cancel;}

//////////////////////////////////////////////////////////////////////////////////// Alles Methodoi ///////////////////////////////////////////////////////////////////////////////////

//Methodos pou ilopoiei tin epilogi timeprivate void okButtonHandler(){

try{min=(int)Double.parseDouble(minutes.getText());if(min<0){

JOptionPane.showMessageDialog( this, "The minutes must be a positive num ber orzero!",

"Error", JOptionPane.ERROR_MESSAGE );ok=false;return;

}}catch(NumberFormatException e){

JOptionPane.showMessageDialog( this, "The minutes should be a number!","Error", JOptionPane.ERROR_MESSAGE );

ok=false;return;

}try{

cap=(int)Double.parseDouble(capacity.getText());if(cap<0||cap>100){

JOptionPane.showMessageDialog( this, "The energy must be between 0 and 100!","Error", JOptionPane.ERROR_MESSAGE );

ok=false;return;

}}catch(NumberFormatException e){

Δίκτυα Αισθητήρων

218

JOptionPane.showMessageDialog( this, "The energy should be a numbe r!","Error", JOptionPane.ERROR_MESSAGE );

ok=false;return;

}ok=true;dispose();

}

//Methodos pou ilopoiei tin epiogi cancelprivate void cancelButtonHandler(){

cancel=true;dispose();

}//Arxikopoiisi ton sistatikon toy parathirouprivate void initComponents(){

setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);JPanel panel, panel1,panel2,panel3;panel=new JPanel();panel.setLayout(new GridLayout(3,1));panel1=new JPanel();panel1.setPreferredSize(new Dimension(170,30));JLabel jLabel1 = new JLabel("Minutes :");jLabel1.setPreferredSize(new Dimension(70,30));minutes=new JTextField() ;minutes.setToolTipText("The minutes per which the node energy is decreased.");minutes.setPreferredSize(new Dimension(50,25));panel1.add(jLabel1);panel1.add(Box.createHorizontalStrut(10));panel1.add(minutes);panel1.add(Box.createHorizontalStrut(10));panel.add(panel1);panel2=new JPanel();panel2.setPreferredSize(new Dimension(170,30));JLabel jLabel2=new JLabel("Energy (%):");jLabel2.setPreferredSize(new Dimensio n(70,30));capacity=new JTextField();capacity.setToolTipText("The portion that will be abstracted from the node energy.");capacity.setPreferredSize(new Dimension(50,25));panel2.add(jLabel2);panel2.add(Box.createHorizontalStrut(10));panel2.add(capacity);panel2.add(Box.createHorizontalStrut(10));panel.add(panel2);panel3=new JPanel();JButton jButton1 = new JButton("Ok");jButton1.addActionListener(new ActionListene r(){

public void actionPerformed(ActionEvent evt){okButtonHandler();

}});JButton jButton2=new JButton("Cancel");jButton2.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent evt){

Δίκτυα Αισθητήρων

219

cancelButtonHandler();}

});panel3.add(jButton1);panel3.add(jButton2);panel.add(panel3);getContentPane().add(panel);pack();

}}

import org.apache.commons.collections15.Transformer;

import java.awt.*;

/*H klasi ayti enimeronei ton grafo gia to pos ua xromatizontai oi komvoianaloga me tin energeia tous*/

public class vertexFillColor implements Transformer<MyVertex, Paint> {

//Constructorpublic vertexFillColor(){}

//Pos tha xromatizontai oi komvoipublic Paint transform(MyVertex node){

double capacity= node.getCapacity();

if(capacity>=80){return Color.BLUE;

}else if(capacity<80&&capacity>=60){return new Color(0,130,0);

}else if(capacity<60&&capacity>=40){return Color.YELLOW;

}else if(capacity<40&&capacity>=20){return Color.ORANGE;

}else if(capacity<20){return Color.RED;

}

return Color.PINK;

}}

/*Xrisimopoietai gia na deiksei oti ayti i klasi epithimei na mathei giaton epilegmeno komvo kai to visualiztionViewer.*/

import edu.uci.ics.jung.visualization.VisualizationViewer;

Δίκτυα Αισθητήρων

220

public interface VertexMenuListener<V> {void setVertexAndView(V v, VisualizationViewer visView);

}

import edu.uci.ics.jung.visualization.VisualizationViewer;

import javax.swing.*;import java.awt.*;import java.awt.event.ActionListener;import java.awt.event.ActionEvent;

/*H klasi ayti anaparista to parathiro me tis idiotites tou kombou(onoma kai energeia)Meso tou parathirou mporoume na allaksoume tis idiotites aytes*/

public class VertexPropertyDialog extends JDialog {

//IdiotitesMyVertex node;//O komvowprivate JTextField nmTextField;//To onomaprivate JTextField energy;//H energeia

//Constructorpublic VertexPropertyDialog(JFrame parent,MyVertex node){

super(parent,true);this.setPreferredSize(new Dimens ion(200,150));initComponents();this.node=node;setTitle("Node : "+this.node.toString());this.nmTextField.setText(node.getName());long n;if(node.getCapacity()>100){

this.energy.setText("100");}else if(node.getCapacity()<0){

this.energy.setText("0");}else{

n=(int)Math.round(node.getCapacity()*100);this.energy.setText(Double.toString((double)n/100));

}}

/////////////////////////////////////////////////////////////////////////////////// Alles Methodoi ///////////////////////////////////////////////////////////////////////////////////

//arxikopoiisi ton sistatikon tou parathirouprivate void initComponents(){

setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);setTitle("Node Properties");

JPanel panel, panel1,panel2,panel3;

Δίκτυα Αισθητήρων

221

panel=new JPanel();panel.setLayout(new GridLayout(3,1));

panel1=new JPanel();panel1.setPreferredSize(new Dimension(150,30));JLabel jLabel1 = new JLabel("Name");jLabel1.setPreferredSize(new Dimension(70,30));nmTextField=new JTextField();nmTextField.setPreferredSize(new Dimension(70,30));panel1.add(Box.createHorizontalStrut(10));panel1.add(jLabel1);panel1.add(nmTextField);panel.add(panel1);panel1.add(Box.createHorizontalStrut(10));panel2=new JPanel();panel2.setPreferredSize(new Dimension(150,30));JLabel jlabel2=new JLabel("Energy % :");jlabel2.setPreferredSize(new Dimension(70,30));energy=new JTextField();energy.setPreferredSize(new Di mension(40,30));panel2.add(Box.createHorizontalStrut(10));panel2.add(jlabel2);panel2.add(energy);panel.add(panel2);panel2.add(Box.createHorizontalStrut(10));

panel3=new JPanel();JButton jButton1 = new JButton("OK");jButton1.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent evt){okButtonHandler();

}});jButton1.setAlignmentX(Component.CENTER_ALIGNMENT );panel3.add(jButton1);panel.add(panel3);

getContentPane().add(panel);pack();

}

//Methodos Pou orizei ti tha ginetai otan patame okprivate void okButtonHandler(){

check();dispose();

}//Methodos pou elegxei ena yparxei idi allos komvos ston grafo me to idio onoma//Kai ena den yparxei allazei tis idiotites tou komvouprivate void check(){

String name=nmTextField.getText();MyGraph graph;double en;VisualizationViewer<MyVertex,MyEdge> vv;

Δίκτυα Αισθητήρων

222

JFrame frame=(JFrame)this.getParent();

Component[] comps=frame.getContentPane().getComponents();if(comps.length>0){

for (Component comp : comps) {if (comp instanceof VisualizationViewer) {

vv=(VisualizationViewer<MyVertex,MyEdge>)comp;graph=(MyGraph)vv.getGraphLayout().getGraph();

if(graph.findVertex(name)!=null&&!node.getName().equalsIgnoreCase(this.nmText Field.getText())){

JOptionPane.showMessageDialog( this, "There is already node with the name"+name+"!","Error", JOptionPane.ERROR_MESSAGE );

return;}else{

if(!this.nmTextField.getText().equals("")){node.setName(this.nmTextField.getText());vv.repaint();

}else{JOptionPane.showMessageDialog( this, "You must give a name for the

node!","Error", JOptionPane.ERROR_MESSAGE );}

}//telos esoterikis if

try{en=Double.parseDouble(energy.getText());if(en<0||en>100){

JOptionPane.showMessageDialog( this, "The energy must be between 0 and100!","Error", JOptionPane.ERROR_MESSAGE );

}else{node.setCapacity(en);vv.repaint();

}}catch(NumberFormatException nfe){

JOptionPane.showMessageDialog( this, "The energy must be anumber!","Error", JOptionPane.ERROR_MESSAGE );

}}//telos deyteris if

}//telos for}//telos protis if

}

}

Δίκτυα Αισθητήρων

223