source: proiecte/GAIIA/TaskGraf.cpp @ 122

Last change on this file since 122 was 122, checked in by (none), 14 years ago
File size: 5.5 KB
Line 
1#include "Graf.h"
2#include <vector>
3
4#define DEBUG 0
5
6using namespace std;
7
8typedef struct
9{
10        Task * nod;
11        int stare;
12        int nr_parinti;
13} Candidat;
14
15/**
16* method initializing a graph of tasks to the structure specified in the file
17*
18* @param filename the input filename containing the configuration
19*/
20void TaskGraf::init(char * filename)
21{
22        FILE *file = fopen(filename, "r");
23        int s, d;
24        double cost;
25
26     
27
28        if (file == NULL)
29        { 
30                perror("Error reading file");
31                exit(1);
32        }
33        else
34        {
35                fscanf(file, "%i %i", &nr_noduri, &nr_muchii);
36                noduri = (Task*)calloc(nr_noduri, sizeof(Task));
37                muchii = (Muchie*) calloc(nr_muchii, sizeof(Muchie));
38                for(int i = 0 ; i < nr_noduri ; i ++)
39                {
40                        fscanf(file, "%lf", &cost);
41                        noduri[i] = Task(i, cost);     
42                }
43                for(int i = 0 ; i < nr_muchii ; i ++)
44                {
45                        fscanf(file, "%i %i %lf", &s, &d, &cost);
46                        int gasit = 0, sursa = -1, destin = -1;
47                        for(int j = 0 ; j < nr_noduri ; j ++)
48                        {       
49                                if(gasit == 2) break;
50                                if(noduri[j].id == s) { sursa = j; gasit ++;} 
51                                if(noduri[j].id == d) { destin = j; gasit ++;}
52                        }
53                        muchii[i] = Muchie(&noduri[sursa], &noduri[destin], cost);
54                        noduri[destin].addPredecesor(&muchii[i]);       
55                        noduri[sursa].addSuccesor(&muchii[i]);
56                }
57        }
58        fclose (file);
59        max_level = sortare_topologica();
60        sortare_topologica_inversa();
61        computeFreeFloatingNodes();
62}
63
64/**
65* the constructor
66*
67* @param n the number of tasks
68* @param m the number of communication links
69*/
70TaskGraf::TaskGraf(int n, int m)
71{
72        nr_noduri = n;
73        nr_muchii = m;
74        noduri = (Task *)calloc (n, sizeof(Task));
75        muchii = (Muchie *)calloc (m, sizeof (Muchie));
76}
77
78/**
79* method that computes the list of free floating nodes
80*/
81void TaskGraf::computeFreeFloatingNodes(){
82        int i,j;
83        int id_succ; 
84        int free_node;
85       
86        for (i = 0 ; i < nr_noduri ; i++){
87                if ( noduri[i].niv_topo_min < noduri[i].niv_topo_max){
88                        free_node = 1;                 
89                        for (j = 0 ; j < noduri[i].nr_succ ; j++){
90                                id_succ = ((Muchie *)(noduri[i].succesori[j]))->succesor->id;
91                                if (noduri[id_succ].niv_topo_min <= noduri[i].niv_topo_min + 1)
92                                        free_node = 0;
93                        } 
94                        if (free_node == 1){
95                                f_nodes.push_back(i);
96                        }
97
98                }
99        }
100        if (DEBUG == 1) {
101                for (i = 0 ; i < (int)f_nodes.size() ; i++)
102                        printf("%d ",f_nodes[i]);
103                printf("\n");
104        }
105
106}
107
108/**
109* method that prints the information about the graph of tasks
110*/
111void TaskGraf::print()
112{
113        printf("### task graf\n");
114        printf("nr_noduri = %i, nr_muchii = %i\n", nr_noduri, nr_muchii);
115        for(int i = 0 ; i < nr_noduri ; i ++)
116                noduri[i].print();
117        for(int i = 0 ; i < nr_muchii ; i ++)   
118                muchii[i].print();
119        printf("###\n");
120}
121
122/**
123* method that computes the topological sort
124*
125* @return the maximum topological level
126*/
127int TaskGraf::sortare_topologica()
128{
129        int nivel = 1;
130        Candidat * cand= (Candidat * )calloc(nr_noduri, sizeof(Candidat));
131        for(int i = 0 ; i < nr_noduri ; i ++)
132        {
133                cand[i].nod = &noduri[i];
134                cand[i].stare = -1;
135                cand[i].nr_parinti = noduri[i].nr_pred;
136        }       
137        for(int gasit = 0 ; gasit < nr_noduri ;)
138        {
139                for(int i = 0 ; i < nr_noduri ; i ++)
140                        if(cand[i].nr_parinti == 0 && cand[i].stare == -1 )
141                        {
142                                cand[i].nod->niv_topo_min = nivel;
143                                cand[i].nod->niv_topo = nivel;
144                                cand[i].stare = 0;
145                                gasit++;
146                        }       
147                for(int i = 0 ; i < nr_noduri ; i ++)
148                        if(cand[i].stare == 0 )
149                        {
150                                cand[i].stare = 1;
151                                for(int j = 0 ; j < nr_noduri ; j ++)
152                                        for(int k = 0 ; k < cand[j].nod->nr_pred ; k ++ )
153                                                if(((Muchie *)cand[j].nod->predecesori[k])->predecesor->id == cand[i].nod->id)
154                                                        cand[j].nr_parinti --;
155                        }
156                nivel++;
157        }
158        return nivel;
159}
160
161/**
162* method that computes the reverse topological sort
163*/
164void TaskGraf::sortare_topologica_inversa()
165{
166        int nivel = 1;
167        Candidat * cand= (Candidat * )calloc(nr_noduri, sizeof(Candidat));
168        for(int i = 0 ; i < nr_noduri ; i ++)
169        {
170                cand[i].nod = &noduri[i];
171                cand[i].stare = -1;
172                cand[i].nr_parinti = noduri[i].nr_succ;
173        }       
174        for(int gasit = 0 ; gasit < nr_noduri ;)
175        {
176                for(int i = 0 ; i < nr_noduri ; i ++)
177                        if(cand[i].nr_parinti == 0 && cand[i].stare == -1 )
178                        {
179                                cand[i].nod->niv_topo_max = max_level - nivel;
180                                cand[i].stare = 0;
181                                gasit++;
182                        }       
183                for(int i = 0 ; i < nr_noduri ; i ++)
184                        if(cand[i].stare == 0 )
185                        {
186                                cand[i].stare = 1;
187                                for(int j = 0 ; j < nr_noduri ; j ++)
188                                        for(int k = 0 ; k < cand[j].nod->nr_succ ; k ++ )
189                                                if(((Muchie *)cand[j].nod->succesori[k])->succesor->id == cand[i].nod->id)
190                                                        cand[j].nr_parinti --;
191                        }
192                nivel++;
193        }
194}
195
196/**
197* method that initializes the structure with the default configuration
198*/
199void TaskGraf::init(){
200        int i;
201        for (i = 0 ; i < nr_noduri ; i++)
202                noduri[i].init();
203}
204
205/**
206* the copy operator
207*/
208TaskGraf& TaskGraf::operator=(const TaskGraf& clone)
209{
210        //printf("!!!\n");
211        nr_noduri = clone.nr_noduri;
212        nr_muchii = clone.nr_muchii;
213        max_level = clone.max_level;
214        f_nodes = clone.f_nodes;
215        noduri = (Task *)calloc(nr_noduri, sizeof(Task));
216        muchii = (Muchie *)calloc(nr_muchii, sizeof(Muchie));
217        for(int i = 0 ; i < nr_noduri ; i ++){
218                noduri[i] = Task(clone.noduri[i].id, clone.noduri[i].cost);
219                noduri[i].niv_topo_min = clone.noduri[i].niv_topo_min;
220                noduri[i].niv_topo_max = clone.noduri[i].niv_topo_max; 
221        }
222        for(int i = 0 ; i < nr_muchii ; i ++)
223        {
224                int gasit = 0, sursa = -1, destin = -1;
225                for(int j = 0 ; j < nr_noduri ; j ++)
226                {       
227                        if(gasit == 2) break;
228                        if(noduri[j].id == clone.muchii[i].predecesor->id) { sursa = j; gasit ++;} 
229                        if(noduri[j].id == clone.muchii[i].succesor->id) { destin = j; gasit ++;}
230                }
231                muchii[i] = Muchie(&noduri[sursa], &noduri[destin], clone.muchii[i].cost);
232                noduri[destin].addPredecesor(&muchii[i]);       
233                noduri[sursa].addSuccesor(&muchii[i]);
234        }
235       
236        return *this;
237}
238
Note: See TracBrowser for help on using the repository browser.