Next                  Up                    Back                 Contents

Επόμενο:ΠΟΛΛΑΠΛΑΣΙΑΣΜΟΣ ΠΙΝΑΚΑ ΜΕ ΔΙΑΝΥΣΜΑ Πάνω:Διάφορα Προβλήματα Παράλληλου Προγραμματισμού Πίσω: ΣΥΣΤΗΜΑ ΚΕΝΤΡΙΚΗΣ ΘΕΡΜΑΝΣΗΣ


 

ΠΑΡΑΛΛΗΛΗ ΤΑΞΙΝΟΜΗΣΗ ΔΕΝΤΡΟΥ

 

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

 

Το πρόγραμμα αποτελείται από έναν αριθμό απλών διεργασιών συνδεδεμένων μεταξύ τους σε μία δυαδική δενδρική δομή. 'Οπως και στη περίπτωση του πολλαπλασιασμού των πινάκων, καμμιά διεργασία δεν χρειάζεται να ξέρει που ακριβώς βρίσκεται μέσα στο δένδρο. Υπάρχουν μόνο δύο τύποι διεργασιών: τα φύλλα και οι κόμβοι. Και πάλι, η κάθε διεργασία είναι ανεξάρτητη του μεγέθους του προβλήματος, και αποθηκεύει μόνο δύο το πολύ τιμές και μερικές σημαίες (flags), ανεξάρτητα από τον αριθμό των ταξινομούμενων στοιχείων. 'Ενα μεγαλύτερο πρόβλημα χρειάζεται μεγαλύτερο δένδρο, αλλά τα συστατικά του δένδρου παραμένουν τα ίδια. Η στρατηγική έγκειται στην διανομή των στοιχείων πρός ταξινόμηση (π.χ. αριθμών) μέσα στο δένδρο, διά μέσου της ρίζας του, μέχρι τα στοιχεία να απλωθούν, ένα σε κάθε φύλλο. Στη συνέχεια κάθε διεργασία στέλνει στην πατρική της διεργασία την ακολουθία των αριθμών που έλαβε, αλλά ταξινομημένη σε αύξουσα σειρά. Γιά ένα φύλλο αυτή η διαδικασία είναι απλή, καθώς ο ένας μόνον αριθμός που έχει αποτελεί μιά απλούστατη ακολουθία αριθμών σε αύξουσα σειρά. Κάθε κόμβος στηρίζεται στις ταξινομημένες ακολουθίες που θα λάβει από τα παιδιά του, και τις οποίες συγχωνεύει σε μία ταξινομημένη σειρά, την οποία και στέλνει με τη σειρά του σαν ακολουθία εξόδου.

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

Για κάθε κόμβο i, τα παιδιά του δεικτοδοτούνται σαν 2i+1 το αριστερό και 2i+2 το δεξιό. Τα κανάλια με δείκτη i ενώνουν τη διεργασία i με την πατρική της, ενώ για τη σύνδεση με τα παιδιά ακολουθείται η ίδια δεικτοδότηση όπως και στους κόμβους.

 

 

image

 

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

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

 

Αναλυτικότερα το πρόγραμμα είναι το ακόλουθο:

 

Program Parallhlh_ta3inomhsh;

 

    Const

        depth_tree=3;

        number_leaves=8; (*number_leaves=2^depth_tree*)

        number_forks=number_leaves-1;

        number_processes=number_forks+number_leaves;

        number_channels=number_processes;

        root=0;

        first_fork=root;

        first_leaf=first_fork+number_forks;

        true=-1;false=-99;

       

    type

        chan=channel of integer;

        pin=array[0..number_channels+1] of chan;

       

    var

        up,down:pin;

        i:integer;

   

Όπως είπαμε και παραπάνω η διεργασία αυτή εισάγει την εικονική ρίζα.

Procedure driver_in(var up,down:chan);

    var

        i,number:integer;

    begin

        for i:=0 to number_leaves-1 do

        begin

            writeln('dwse ton arithmo');

            readln(number);

            up:=true;

            up:=number;

        end;

        up:=false;

    end;

Η διεργασία εμφάνισης των αποτελεσμάτων.

Procedure driver_out(var down:chan);

    var

        number,temp:integer;

    begin

        for i:=0 to number_leaves-1 do

        begin

            if down? then

                temp:=down;

            if down? then

                number:=down;

            writeln(number:3,' ');

        end;

    end;

Η διεργασία διανομής των αριθμών μέσα στο δέντρο.

 

Procedure a_fork_distribute(var up,left_up,right_up:chan);

    const

        leftward=0;rightward=1;

    var

        more,inclination,number:integer;

 

    begin

        inclination:=leftward;

        more:=up;

        while more=true do

        begin

            number:=up;

            if inclination=leftward then

            begin

                left_up:=true;

                left_up:=number;

                inclination:=rightward;

            end

            else if inclination=rightward then

            begin

                    right_up:=true;

                    right_up:=number;

                    inclination:=leftward;

            end;

            more:=up;

        end;

        left_up:=false;

        right_up:=false;

    end;

Η διεργασία του φύλλου επιστρέφει τον αριθμό πίσω στον πατέρα.

Procedure leaf(var up,down:chan);

    var

        number,i:integer;

  begin

        for i:=0 to number_channels do

        begin

            if up? then

            begin

                number:=up;

                down:=number;

            end;

        end;

    end;

Η διεργασία συγχώνευσης των αριθμών.

Procedure a_fork_gather(var down,left_down,right_down:chan);

    var

        left_more,left_min,right_more,right_min:integer;

    begin

        left_more:=left_down;

        left_min:=left_down;

        right_more:=right_down;

        right_min:=right_down;

        while (left_more=true) or (right_more=true) do

        begin

            if ( left_more=true) and ((right_more=false) or (left_min<=right_min)) then

            begin

                down:=true;

                down:=left_min;

                left_more :=left_down;

                if left_more=true then left_min:=left_down;

            end

            else if (right_more=true) and ((left_more=false) or (left_min>=right_min)) then

            begin

                down:=true;

                down:=right_min;

                right_more:=right_down;

                if right_more=true then right_min:=right_down;

            end;

        end;

        down:=false;

    end;

Το κυρίως πρόγραμμα.

 

Begin

    driver_in(up[root],down[root]);

   forall i:=first_fork to number_forks-1 do

    var temp1,temp2:integer;

    begin

        temp1:=(2*i)+1;

        temp2:=(2*i)+2;

        a_fork_distribute(up[i],up[temp1],up[temp2]);

    end;

    forall i:=first_leaf to (number_channels-1) do

        leaf(up[i],down[i]);

    forall i:=first_fork to number_forks-1 do

    var temp1,temp2:integer;

    begin

        temp1:=(2*i)+1;

        temp2:=(2*i)+2;

        a_fork_gather(down[i],down[temp1],down[temp2]);

    end;

    writeln;

    writeln(' oi arithmoi ta3inomhmenoi einai:');

    writeln;

    driver_out(down[root]);

End.

 

 

 

Tα αποτελέσματα για μια εκτέλεση του προγράμματος με τα παρακάτω δεδομένα είναι:

dwse ton arithmo

236

dwse ton arithmo

-5

dwse ton arithmo

12

dwse ton arithmo

49

dwse ton arithmo

-100

dwse ton arithmo

753

dwse ton arithmo

0

dwse ton arithmo

122

 

 

oi arithmoi ta3inomhmenoi einai:

-100

-5

0

12

49

122

236

753

     Next                  Up                    Back                 Contents

Επόμενο:ΠΟΛΛΑΠΛΑΣΙΑΣΜΟΣ ΠΙΝΑΚΑ ΜΕ ΔΙΑΝΥΣΜΑ Πάνω:Διάφορα Προβλήματα Παράλληλου Προγραμματισμού Πίσω: ΣΥΣΤΗΜΑ ΚΕΝΤΡΙΚΗΣ ΘΕΡΜΑΝΣΗΣ