ΗΥ-100: Εισαγωγή στην Επιστήμη Υπολογιστών η σειρά ασκήσεων Οδηγίες Για τη μεταγλώττιση των προγραμμάτων που ζητούνται θα πρέπει να χρησιμοποιήσετε το gcc με τις παρακάτω παραμέτρους: gcc -ansi -pedantic -Werror Για ευκολία, στα μηχανήματα του εργαστηρίου έχει δημιουργηθεί το alias gcc100 που καλεί τον gcc με αυτές τις παραμέτρους. ΠΡΟΣΟΧΗ: Οι ασκήσεις θα βαθμολογηθούν με αυτόματο τρόπο, οπότε θα πρέπει να υπακούν πιστά την εκφώνηση (ακόμη και τα ονόματα των αρχείων). Για να δοκιμάσετε την άσκηση σας αντιγράψτε το αρχείο hw-tests.tgz στον φάκελο με την άσκηση σας με την εντολή: cp ~hy100/public_html/hw-tests.tgz./ ή κατεβάστε το από το http://www.csd.uoc.gr/~hy100/hw-tests.tgz. Αποσυμπιέσετε το στον φάκελο με την άσκηση σας, μέσω της εντολής: tar xzf hw-tests.tgz και εκτελέστε την εντολή: sh test.sh./hw tests όπου./hw είναι το όνομα του προγράμματος σας και tests ο φάκελος με τα test. Κάθε test αποτελείται από ένα αρχείο με κατάληξη.in, που περιέχει την είσοδο για το πρόγραμμα σας, και το αντίστοιχο.out αρχείο που περιέχει την αναμενόμενη έξοδο του προγράμματος. Για κάθε test που περνάει το πρόγραμμα σας θα πρέπει να τυπώνεται PASS, αλλιώς FAIL. 1 Πινακες Markov Πίνακας Markov είναι ένα N N τετράγωνο το οποίο έχει τα εξής χαρακτηριστικά: Περιέχει πραγματικούς αριθμούς από 0 μέχρι 1. Κάθε αριθμός είναι θετικός. 1
Το άθροισμα κάθε γραμμής και κάθε στήλης είναι ίσο με 1. Ένα παράδειγμα πινακα Markov είναι: Σκοπός της άσκησης είναι να γράψετε ένα πρόγραμμα το οποίο θα μπορεί να ελέγχει αν ένας N N πίνακας είναι πίνακας Markov, και επίσης να μπορεί να παίρνει σαν όρισμα έναν ακέραιο αριθμό Ν και να παράγει ένα N N Markov πινακα. Μπορείτε να υποθέσετε ότι N < 10, το οποίο σημαίνει ότι στην αρχή του προγράμματός σας θα πρέπει να ορίσετε ότι: #define MAXN 10 Το πρόγραμμα θα εκτελεί δύο διαφορετικές λειτουργίες: τον έλεγχο και τη δημιουργία ενός πινακα Markov. Για να ξεχωρίσει ποιά απο τις λειτουργίες θα εκτελέσει, το πρόγραμμα θα δέχεται ένα επιπλέον command line argument το οποίο θα είναι είτε -create είτε -check. 1.1 Λειτουργία 1: Έλεγχος Για να ελέγξουμε εάν ένας πίνακας είναι πινακας Markov θα πρέπει να εκτελούμε το πρόγραμμα hw με την παράμετρο γραμμής εντολών -check, ως εξής:./hw -check
Το πρόγραμμα θα πρέπει να διαβάζει ένα πίνακα από το πληκτρολόγιο (χρησιμοποιώντας τη scanf). Ο πρώτος ακέραιος που διαβάζει είναι το N (η διάσταση του πίνακα). Στη συνέχεια, το πρόγραμμα πρέπει να διαβάζει κάθε ένα απο τα στοιχεία του πίνακα (συνολικά N 2 ). Ενδεικτικό παράδειγμα εισόδου: 1.1.1 Output 0.1 0. 0.6 0.5 0. 0.2 0.4 0.4 0.2 Το πρόγραμμά σας, αφού διαβάσει τον πίνακα, θα πρέπει να εξετάζει όλες τις γραμμές και στήλες. Για κάθε ένα απο τα παραπάνω θα πρέπει να τυπώνει το είδος του ελέγχου (ROW, COLUMN) και να τυπώνει YES ή NO αναλόγως αν ο έλεγχος πέτυχε ή απέτυχε. Στο τέλος, θα αναφέρει αν το τετράγωνο είναι όντως μαγικό ή οχι, τυπώνοντας MARKOV YES ή MARKOV NO αντίστοιχα. Για παράδειγμα αν δώσουμε την παραπάνω είσοδο, η έξοδος θα πρέπει να είναι: ROW 1 YES ROW 2 YES ROW YES COLUMN 1 YES COLUMN 2 YES COLUMN YES MARKOV YES Αντίθετα, αν δώσουμε σαν είσοδο: η έξοδος θα πρέπει να είναι: 0.2 0.8 0.1 0. 0.1 0.6 0.5 0.1 0.4 ROW 1 NO ROW 2 YES ROW YES COLUMN 1 YES COLUMN 2 YES COLUMN NO MARKOV NO Μπορείτε να υποθέσετε ότι οι αριθμοί που δίνονται στο πρόγραμμά σας θα είναι πάντα από 0 έως και 1. 1.2 Λειτουργία 2: Δημιουργία Για να δημιουργήσουμε ένα πινακα Markov θα πρέπει να εκτελούμε το πρόγραμμα hw με την παράμετρο γραμμής εντολών -create και στη συνέχεια έναν αριθμό N που είναι η διάσταση του πίνακα. Για παράδειγμα, για τη δημιουργία ενός πινακα Markov διαστάσεων 9 9, θα πρέπει το πρόγραμμα να εκτελεστεί ως εξής:
./hw -create 9 1.2.1 Αλγόριθμος Μπορείτε να χρησιμοποιήσετε τον αλγόριθμο που περιγράφει ο παρακάτω ψευδοκώδικας για να υλοποιήσετε τη λειτουργία -create: create Matrix dim of N x N create Row Sum vector create Column Sum vector for k = 1.. N for j = 1.. N save biggest number from Row Sum[k] and Column Sum[j] in Max if Max is zero create random float number from 0 to 1 as E else if k is equal to N E is equal (1 - Column Sum[j]) else if j is equal to N E is equal (1 - Row Sum[k]) else create random number from 0.0 to ( 1 - M ) and place it in E place E in M[k][j] add E to Row Sum[k] add E to Colum Sum[j] Check Matrix, if it is not corrent, then repeat the procedure. Ο παραπάνω αλγόριθμος δουλεύει μόνο εάν το N είναι περιττός. Δε θα σας ζητηθεί να κάνετε create με Ν άρτιο. 1. Output Σαν έξοδο το πρόγραμμα θα πρέπει να τυπώνει αρχικά τη διάσταση του πίνακα Ν, και στη συνέχεια όλα τα στοιχεία του πίνακα που θα δημιουργήσει, στοιχισμένα. π.χ.:./hw -create 0.7 0. 0.0 0.1 0.5 0.4 0.2 0.2 0.6 1.4 Παρατήρηση Προφανείς λύσεις με πίνακα που έχει 1.0 στη διαγώνιο και 0.0 στις αλλες θεσεις, δεν είναι δεκτές. Το ίδιο ισχύει για πίνακες που έχουν τον ίδιο αριθμό σε όλες τις θέσεις.
./hw -create 5 5 1.5 Υποδείξεις Μπορείτε να χρησιμοποιήσετε ανακατεύθυνση για να τρέξετε το πρόγραμμα σας με μια συγκεκριμένη είσοδο:./hw -check < tests/testx.in Μπορείτε να δημιουργήσετε ένα πινακα και να το αποθηκεύσετε σε ένα αρχείο test.out, για να το χρησιμοποιήσετε ως είσοδο αργότερα, καλώντας:./hw -create 5 > test.out Για να καλέσετε το hw με το test.out σαν είσοδο:./hw -check < test.out 1.6 Test Για αυτή την άσκηση δίνεται test μόνο το για το πρώτο μέρος (δηλαδή check). Μετά την ολοκλήρωση του check part μπορείτε να χρησιμοποιήσετε τη λύση σας για έλεγχο του create, για παραδειγμα:./hw -create 5./ hw -check Χρήσιμες συναρτήσεις: scanf, atoi, strcmp, rand, srand.