1. Εισαγωγή ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΥΠΡΟΥ - ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ ΕΡΓΑΣΙΑ 4 Εκλογικό Σύστημα με Μεταφορά και Συσσώρευση Ψήφων Ημερομηνία Ανάρτησης: 16/04/2018 Ημερομηνία Παράδοσης: 04/05/2018, 09:00 Για την τελευταία εργασία χρειάζεται να κατασκευάσετε το πρόγραμμα Elections.java το οποίο υλοποιεί ένα σύστημα εκλογών με μεταφορά και συσσώρευση ψήφων. Από την προγραμματιστική σκοπιά στόχος είναι να αποκτήσετε μια πρώτη εμπειρία με αντικείμενα. Οι κλάσεις που εμπλέκονται είναι ο υποψήφιος (ECandidate) και η ψήφος (Vote), για τις οποίες σας δίνονται περιγράμματα (αρχεία.java) που θα πρέπει να συμπληρώσετε. Στη συνέχεια να κατασκευάσετε το πρόγραμμα Elections.java το οποίο αξιοποιεί, είναι δηλαδή είναι πελάτης (client class) των 2 άλλων κλάσεων. Σε ένα σύστημα εκλογών το οποίο εφαρμόζει μεταφορά ψήφων, ο κάθε ψηφοφόρος κατατάσσει τους υποψηφίους σε σειρά προτίμησης. Στο σύστημα που θα κατασκευάσετε είναι υποχρεωτικό να κατατάσσονται όλοι οι υποψήφιοι σε σειρά προτίμησης. Για να εκλεγεί κάποιος υποψήφιος χρειάζεται να συσσωρεύσει το 50% + 1 των έγκυρων ψήφων. Οι λεπτομέρειες του αλγόριθμου μεταφοράς και συσσώρευσης ψήφων, και ανάδειξης του νικητή θα σας εξηγηθούν στη συνέχεια, αφού προηγουμένως παρουσιαστεί ένα παράδειγμα χρήσης του προγράμματος Elections.java και δοθούν τα περιγράμματα των κλάσεων ECandidate.java και Vote.java. 2. Περιγραφή Καταρχάς το πρόγραμμα Elections.java λαμβάνει τα δεδομένα εισόδου του από ένα αρχείο κειμένου μέσω file redirection. Ένα τέτοιο αρχείο κειμένου είναι το ακόλουθο election.txt, όπου πρώτα δίνεται το πλήθος των υποψηφίων (4 στο παράδειγμα) και το σύνολο των ψήφων (20 στο παράδειγμα). Στη συνέχεια δίνεται σε κάθε γραμμή ξεχωριστά το ονοματεπώνυμο του κάθε υποψηφίου. Βάσει αυτής της σειράς καταχωρούνται αύξοντες αριθμοί για τους υποψηφίους. Ο πρώτος υποψήφιος λαμβάνει τον αύξοντα αριθμό 1. Ακολούθως παρουσιάζονται οι ψήφοι. Η κάθε ψήφος προσδιορίζεται μέσα στο αρχείο ως έγκυρη (valid), λευκή (blank) ή άκυρη (akyro). Μια έγκυρη ψήφος θεωρείται αυτή στην οποία υπάρχουν οι αύξοντες αριθμοί όλων των υποψηφίων σε φθίνουσα σειρά προτίμησης. Αρχείο election.txt 4 20 John Smith Helen Slater ΕΠΛ131 Εργασία 4. Υπεύθυνος Εργασίας: Παύλος Αντωνίου 1
Marion Jones Peter Elliott valid 1 4 3 2 blank akyro valid 4 2 1 3 valid 3 2 4 1 blank blank akyro akyro valid 2 1 3 4 valid 1 2 3 4 valid 1 2 3 4 valid 2 1 4 3 valid 4 1 2 3 valid 1 2 3 4 valid 3 2 1 4 valid 2 4 3 1 valid 4 1 3 2 valid 2 1 3 4 valid 3 4 2 1 3. Παράδειγμα εκτέλεσης Το output του προγράμματος για το πιο πάνω αρχείο election.txt είναι το ακόλουθο: $ java Elections < election.txt VOTES This is a valid vote with initial preferences: 1 4 3 2 Its current top preference is candidate 1 This is a blank vote This is an akyro vote This is a valid vote with initial preferences: 4 2 1 3 Its current top preference is candidate 4 This is a valid vote with initial preferences: 3 2 4 1 Its current top preference is candidate 3 This is a blank vote This is a blank vote This is an akyro vote This is an akyro vote This is a valid vote with initial preferences: 2 1 3 4 ΕΠΛ131 Εργασία 4. Υπεύθυνος Εργασίας: Παύλος Αντωνίου 2
Its current top preference is candidate 2 This is a valid vote with initial preferences: 1 2 3 4 Its current top preference is candidate 1 This is a valid vote with initial preferences: 1 2 3 4 Its current top preference is candidate 1 This is a valid vote with initial preferences: 2 1 4 3 Its current top preference is candidate 2 This is a valid vote with initial preferences: 4 1 2 3 Its current top preference is candidate 4 This is a valid vote with initial preferences: 1 2 3 4 Its current top preference is candidate 1 This is a valid vote with initial preferences: 3 2 1 4 Its current top preference is candidate 3 This is a valid vote with initial preferences: 2 4 3 1 Its current top preference is candidate 2 This is a valid vote with initial preferences: 4 1 3 2 Its current top preference is candidate 4 This is a valid vote with initial preferences: 2 1 3 4 Its current top preference is candidate 2 This is a valid vote with initial preferences: 3 4 2 1 Its current top preference is candidate 3 There are 14 valid votes Thus the winner needs to get at least 8 votes CANDIDATES Candidate John Smith is still competing in round 1-4 in round 1 Candidate Helen Slater is still competing in round 1-4 in round 1 Candidate Marion Jones is still competing in round 1 Candidate Peter Elliott is still competing in round 1 ΕΠΛ131 Εργασία 4. Υπεύθυνος Εργασίας: Παύλος Αντωνίου 3
ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΥΠΡΟΥ - ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ The following candidate is being eliminated: Candidate Marion Jones lost in round 1 The following candidate is being eliminated: Candidate Peter Elliott lost in round 1 CANDIDATES Candidate John Smith is still competing in round 2-4 in round 1-2 in round 2 Candidate Helen Slater is still competing in round 2-4 in round 1-4 in round 2 Candidate Marion Jones lost in round 1 Candidate Peter Elliott lost in round 1 There is a winner on round 2 who is Helen Slater S/he received 8 votes in total from all rounds 4. Περίγραμμα για το αντικείμενο ECandidate Το αντικείμενο ECandidate αντιπροσωπεύει τον εκλογικό υποψήφιο. Για την εργασία χρειάζεται να συμπληρώσετε το ακόλουθο περίγραμμα για το εν λόγω αντικείμενο: ΕΠΛ131 Εργασία 4. Υπεύθυνος Εργασίας: Παύλος Αντωνίου 4
public class ECandidate{ ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΥΠΡΟΥ - ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ private int id; // ο αύξον αριθμός του υποψηφίου private String name; // το ονοματεπώνυμό του private int[] votes; // οι ψήφοι που πήρε σε κάθε γύρο private int round; // το πλήθος των γύρων private boolean active; // κατά πόσον παραμένει «ενεργός» // Ο κατασκευαστής, ο οποίος είναι ΠΛΗΡΩΣ ορισμένος πιο κάτω // λαμβάνει τον αύξοντα αριθμό του υποψηφίου (Id), το ονοματεπώνυμο // (n) και το πλήθος των υποψηφίων (num) και αρχικοποιεί ανάλογα τα // πεδία του αντικειμένου public ECandidate(int Id, String n, int num){ id = Id; name = n; votes = new int[num]; for (int i = 0; i < num; i++) votes[i] = 0; round = 0; active = true; // αρχικά κάθε υποψήφιος είναι «ενεργός» // Επιστρέφει το συσσωρευμένο σύνολο των ψήφων του υποψηφίου που // είναι το άθροισμα των ψήφων για τον κάθε γύρο ΝΑ ΟΡΙΣΘΕΙ public int totalvotes(){....... // Καταχωρεί μια νέα ψήφο για τον υποψήφιο στο γύρο r ΝΑ ΟΡΙΣΘΕΙ public void putvote (int r){....... // Ο υποψήφιος παύει να είναι στην κούρσα των εκλογών, δεν είναι // πλέον δηλαδή «ενεργός» υποψήφιος. Το γεγονός αυτό επισημαίνεται // και με σχετικό μήνυμα (βλ. πιο πάνω παράδειγμα χρήσης του // προγράμματος) ΝΑ ΟΡΙΣΘΕΙ public void Eliminate(){....... // Επιστρέφει τον αύξοντα αριθμό του υποψηφίου Είναι ήδη ορισμένη public int getid(){ return id; // Επιστρέφει το ονοματεπώνυμο του υποψηφίου Είναι ήδη ορισμένη public String getname(){ return name; ΕΠΛ131 Εργασία 4. Υπεύθυνος Εργασίας: Παύλος Αντωνίου 5
// Επιστρέφει κατά πόσον ο υποψήφιος είναι «ενεργός» Είναι ήδη // ορισμένη public boolean isactive(){ return active; // Δημιουργεί την παρουσίαση του υποψηφίου σε εκτυπώσιμη μορφή (βλ. // πιο πάνω παράδειγμα χρήσης του προγράμματος) ΝΑ ΟΡΙΣΘΕΙ public String tostring(){....... // Στην main να διατυπωθεί ο κώδικας για τη δοκιμή των πιο πάνω // μεθόδων (για δική σας χρήση δεν ζητείται για βαθμολόγηση) public static void main(string[] args){..... 5. Περίγραμμα για το αντικείμενο Vote Το αντικείμενο Vote αντιπροσωπεύει μία ψήφο. Για την εργασία χρειάζεται να συμπληρώσετε το ακόλουθο περίγραμμα για το εν λόγω αντικείμενο: public class Vote{ private boolean valid; // κατά πόσον η ψήφος είναι έγκυρη private boolean blank; // κατά πόσον η ψήφος είναι λευκή private boolean akyro; // κατά πόσον η ψήφος είναι άκυρη private ECandidate[] preferences; // το πεδίο αφορά μόνο τις // έγκυρες ψήφους και δίνει την κατάταξη υποψηφίων, σε φθίνουσα // σειρά προτίμησης private int currenttoppref; // ο αύξον αριθμός του υποψηφίου που // αποτελεί την τρέχουσα υψηλότερη προτίμηση ανάμεσα // στους «ενεργούς» υποψηφίους // Ο κατασκευαστής για έγκυρες ψήφους λαμβάνει ως παράμετρο // ένα πίνακα με τους υποψηφίους σε φθίνουσα σειρά προτίμησης. // Ο κατασκευαστής είναι ήδη ορισμένος και μέσω αυτού καταμετρούνται // οι ψήφοι πρώτης προτίμησης, αφού ο υποψήφιος που είναι η πρώτη // προτίμηση της έγκυρης αυτής ψήφου θα λάβει τη ψήφο στον πρώτο // αυτό γύρο της καταμέτρησης public Vote(ECandidate[] prefs){ valid = true; blank = false; akyro = false; preferences = prefs; currenttoppref = preferences[0].getid(); preferences[0].putvote(1); // ο υποψήφιος πρώτης προτίμησης // λαμβάνει την εν λόγω ψήφο στον πρώτο αυτό γύρο // καταμέτρησης ΕΠΛ131 Εργασία 4. Υπεύθυνος Εργασίας: Παύλος Αντωνίου 6
// Υπάρχει και δεύτερος κατασκευαστής που αφορά τις μη έγκυρες // ψήφους και η δική του παράμετρος προσδιορίζει τον τύπο της // ψήφου. Και αυτός ο κατασκευαστής είναι πλήρως ορισμένος. public Vote(String type){ if (type.equals("blank")) { blank = true; valid = false; akyro = false; else {akyro = true; blank = false; valid = false; // Είναι η ψήφος έγκυρη; - Η μέθοδος είναι ήδη ορισμένη public boolean isvalid(){ return valid; // Είναι η ψήφος λευκή; - Η μέθοδος είναι ήδη ορισμένη public boolean isblank(){ return blank; // Είναι η ψήφος άκυρη; Η μέθοδος είναι ήδη ορισμένη public boolean isakyro(){ return akyro; // Επιστρέφει την κατάταξη των υποψηφίων, βάσει των αυξόντων αριθμών // τους, σε φθίνουσα σειρά προτίμησης ΝΑ ΟΡΙΣΘΕΙ public int[] getprefs(){........ // Επιστρέφει τον αύξοντα αριθμό του υποψηφίου που αποτελεί την // τρέχουσα καλύτερη προτίμηση της ψήφου Η μέθοδος είναι ήδη // ορισμένη public int gettoppref(){ return currenttoppref; // Η μέθοδος λαμβάνει ως παράμετρο τον αριθμό του γύρου // καταμέτρησης ψήφων. Αν η ψήφος δεν είναι έγκυρη, ή είναι έγκυρη // και ο τρέχον υποψήφιος πρώτης προτίμησής της παραμένει «ενεργός» // τότε δεν χρειάζεται να κάνει οτιδήποτε. Διαφορετικά, δηλαδή στην // περίπτωση μιας έγκυρης ψήφου της οποίας η πρώτη προτίμηση δεν // είναι πλέον ενεργός υποψήφιος, τότε εντοπίζεται η πιο υψηλή, // επόμενη ενεργή προτίμηση, και καταχωρείται σε αυτόν τον υποψήφιο // η ψήφος κάτω από το συγκεκριμένο γύρο καταμέτρησης ψήφων // ΝΑ ΟΡΙΣΘΕΙ public void changeprefnext(int round){....... ΕΠΛ131 Εργασία 4. Υπεύθυνος Εργασίας: Παύλος Αντωνίου 7
ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΥΠΡΟΥ - ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ // Δημιουργεί την παρουσίαση της ψήφου σε εκτυπώσιμη μορφή (βλ. // πιο πάνω παράδειγμα χρήσης του προγράμματος) ΝΑ ΟΡΙΣΘΕΙ public String tostring(){........ // Στην main να διατυπωθεί ο κώδικας για τη δοκιμή των πιο πάνω // μεθόδων (για δική σας χρήση δεν ζητείται για βαθμολόγηση) public static void main(string[] args){..... 6. Αλγόριθμος μεταφοράς και συσσώρευσης ψήφων Αρχικά μετρούνται οι ψήφοι πρώτης προτίμησης για κάθε υποψήφιο. Αν κάποιος από τους υποψηφίους έχει εξασφαλίσει το 50% + 1 των έγκυρων ψήφων, τότε είναι ο νικητής της εκλογικής διαδικασίας. Διαφορετικά ο κάθε υποψήφιος που έχει εξασφαλίσει το χαμηλότερο αριθμό ψήφων πρώτης προτίμησης, αποκλείεται από την εκλογική διαδικασία, δηλαδή καθίσταται μη ενεργός πλέον, και η κάθε μια από τις ψήφους που έχει λάβει (σε όλους τους γύρους καταμέτρησης) μεταφέρεται στον υποψήφιο που αποτελεί την αμέσως πιο υψηλή, ενεργή προτίμηση της ψήφου. Η μεταφορά αυτή υλοποιείται από τη μέθοδο changeprefnext() μέσα στη κλάση Vote. Η διαδικασία αυτή συνεχίζεται μέχρις ότου είτε ένας από τους ενεργούς υποψηφίους να έχει εξασφαλίσει, συσσωρευτικά πλέον, το 50% + 1 των έγκυρων ψήφων, οπόταν αυτός αναδεικνύεται ως ο νικητής της εκλογικής διαδικασίας, είτε όλοι οι ενεργοί υποψήφιοι να έχουν συσσωρεύσει ακριβώς τον ίδιο αριθμό ψήφων, οπόταν ο νικητής θα αναδειχθεί μέσω κλήρου. Η κλήρωση γίνεται εκτός του συστήματος που θα αναπτύξετε. Το σύστημα απλά επισημαίνει την ισοψηφία και τερματίζει. Με βάση τα πιο πάνω, κατασκευάστε το πρόγραμμα Elections.java, το οποίο διαβάζει τα δεδομένα του από ένα αρχείο κειμένου (με file redirection) το οποίο είναι δομημένο όπως επιδεικνύεται στο παράδειγμα του αρχείου election.txt, κατασκευάζει το σύνολο των περιπτώσεων (instances) των αντικειμένων ECandidate και Vote, και εφαρμόζει τον πιο πάνω αλγόριθμο καταμέτρησης, μεταφοράς και συσσώρευσης ψήφων, αναδεικνύοντας τον νικητή της εκλογικής διαδικασίας ή επισημαίνοντας αν θα πρέπει να διεξαχθεί κλήρωση ανάμεσα στους ισοψηφούντες, ενεργούς υποψηφίους. Σε σχέση με την κατασκευή (των περιπτώσεων) των αντικειμένων επισημαίνεται ότι θα κατασκευαστεί ένα αντικείμενο για τον κάθε υποψήφιο (συνεπώς σύνολο τέσσερα αντικείμενα για το πιο πάνω παράδειγμα) και ένα αντικείμενο για την κάθε ψήφο (συνεπώς σύνολο είκοσι αντικείμενα για το πιο πάνω παράδειγμα). Δεν θα κατασκευαστούν άλλα αντικείμενα πέραν αυτών. Η κάθε ψήφος μέσω των προτιμήσεων της, διασυνδέεται με τον κάθε υποψήφιο (βλ. πιο κάτω σχήμα). ΕΠΛ131 Εργασία 4. Υπεύθυνος Εργασίας: Παύλος Αντωνίου 8
Παράδοση Όταν έχετε τελειώσει με τον πηγαίο κώδικα, μεταγλωττίστε το και βεβαιωθείτε ότι τρέχει σωστά. Δημιουργήστε μια λίστα δοκιμής με όνομα userid_erg4.txt όπου userid βάλτε το username που σας δόθηκε από το τμήμα, κάνοντας ένα τρέξιμο του προγράμματός σας. Ακολουθείστε τα πιο κάτω βήματα όταν υποβάλετε την άσκηση σας: 1. Δημιουργείστε ένα κατάλογο με το όνομά σας π.χ., PavlosAntoniou/ χωρίς να αφήνετε κενά στο όνομα του καταλόγου. 2. Βάλτε μέσα στον κατάλογο αυτό όλα τα java αρχεία της εργασίας (Vote.java, ECandidate.java και Elections.java) και τη λίστα δοκιμής (userid_erg4.txt) που πρέπει να υποβάλετε. 3. Συμπιέστε (zip) τον κατάλογο (και όχι τα αρχεία ξεχωριστά) χρησιμοποιώντας την εντολή στο terminal: zip -c PavlosAntoniou.zip PavlosAntoniou/* 4. Βεβαιωθείτε ότι κάνατε σωστά τα τρία προηγούμενα βήματα 5. Ανεβάστε ΜΟΝΟ το συμπιεσμένο αρχείο π.χ., PavlosAntoniou.zip Παραδώστε το αρχείο zip ηλεκτρονικά μέσω του submit assignment κάτω από το Ασκήσεις Εργασία 4 στην ιστοσελίδα του μαθήματος μέχρι τις 04/05/2018 και ώρα 09:00. ΕΠΛ131 Εργασία 4. Υπεύθυνος Εργασίας: Παύλος Αντωνίου 9
Προσοχή: Το σύστημα ελέγχει το χρόνο παράδοσης εργασιών γι αυτό μην περιμένετε την τελευταία στιγμή να κάνετε submit την εργασία σας. Βαθμολογία Ένα πρόγραμμα για να πάρει όλες τις μονάδες είναι απαραίτητο να: χρησιμοποιεί σχόλια έχει ευθυγραμμισμένο κώδικας χρησιμοποιεί αυτό-επεξηγηματικά ονόματα για τις μεταβλητές δουλεύει σωστά κάνει όλους τους απαραίτητους ελέγχους χρησιμοποιεί μεθόδους (αρθρωτή σχεδίαση) και τις ζητούμενες κλασεις Για όλα τα παραπάνω ακολουθήστε τις οδηγίες που περιγράφονται εδώ: http://introcs.cs.princeton.edu/java/11style/. Όλα τα αρχεία με τον πηγαίο κώδικα πρέπει οπωσδήποτε να περιέχουν μια συμπληρωμένη κατάλληλα επικεφαλίδα από σχόλια στην αρχή του αρχείου όπως: /** * Author: Γράψτε εδώ το όνομα σας * Written:../../2018 * Last updated:../../2018 * * Γράψτε εδώ πληροφορίες σχετικά με το τι κάνει * το πρόγραμμα * */ Κριτήρια αξιολόγησης Κλάση Vote 5+10+5=20 Κλάση NCandidate 5+5+5=15 Κλάση Elections 50 Ανάγνωση αρχείου, αρχικοποίηση αντικειμένων, διαδικασία καταμέτρησης ψήφων, ανακήρυξη νικητή Σχόλια Ονόματα μεταβλητών 15 αρθρωτή σχεδίαση (χρήση μεθόδων) χρήση δοθέντων κλάσεων ΣΥΝΟΛΟ 100 ΕΠΛ131 Εργασία 4. Υπεύθυνος Εργασίας: Παύλος Αντωνίου 10
Η εργασία είναι ατομική. Μπορείτε να συζητήσετε για αυτήν με τους συμφοιτητές σας, ωστόσο ποτέ δεν είναι αποδεκτό για σας να δείτε τον κώδικα κάποιου άλλου ή να κάνετε από κοινού τον κώδικα. Φυσικά, αν έχετε οποιεσδήποτε ερωτήσεις σχετικά με την εργασία, είμαστε πάντα στη διάθεσή σας για βοήθεια. Ανίχνευση αντιγραφής θα τιμωρείται με μηδενισμό. Κώδικας που δε μεταγλωττίζει ή δεν τρέχει (crashes) παίρνει αυτόματα βαθμολογία 0. ΕΠΛ131 Εργασία 4. Υπεύθυνος Εργασίας: Παύλος Αντωνίου 11