source: proiecte/GAIIA/GeneticOperators.cpp @ 122

Last change on this file since 122 was 122, checked in by (none), 14 years ago
File size: 7.9 KB
Line 
1#include "GeneticOperators.h"
2#include "Genetic.h"
3#include <time.h>
4#include <stdio.h>
5#include <stdlib.h>
6#include <vector>
7
8#define DEBUG 0
9
10using namespace std;
11
12/**
13* the default constructor
14*/
15HyperMutation::HyperMutation(){
16
17}
18
19/**
20* constructor
21*
22* @param t the graph of tasks
23* @param prob the hyper-mutation probability
24*/
25HyperMutation::HyperMutation(TaskGraf &tgraf, double prob){
26        tasks = tgraf;
27        mutation_pb = prob; 
28}
29
30/**
31* Method that increases the topological level of the current task, then analyzes its predecessors
32in order to find if there is another free floating node to be moved in the floating nodes list;
33finally deletes the current node.
34*
35* @param ch the current chromosome
36* @param task_id the current task id
37*/
38void HyperMutation::increaseTopoLvl(Chromosome &ch, int task_id){
39        int i, j, free_fnode,level,nod, succ;
40        tasks.noduri[task_id].niv_topo++;
41
42        if (DEBUG == 1) ch.print();
43
44        //each predecessor should be checked in order to decied if it becomes a free floating node
45        for (i = 0 ; i < tasks.noduri[task_id].nr_pred ; i++){
46                nod  = ((Muchie *)(tasks.noduri[task_id].predecesori[i]))->predecesor->id;             
47                level = tasks.noduri[nod].niv_topo;
48                free_fnode = 1; 
49                //the current node is a free node if all its successors have a current topological level grater with at least 2 units   
50                for (j = 0 ; j < tasks.noduri[nod].nr_succ ; j++){
51                        succ  = ((Muchie *)(tasks.noduri[nod].succesori[j]))->succesor->id;             
52                        if ( tasks.noduri[succ].niv_topo <= level + 1){
53                                free_fnode = 0;
54                                break;
55                        }
56                }
57                if (free_fnode == 1){
58                        ch.f_nodes.push_back(nod);
59                }
60
61        }
62
63        //check if the promoted node is still a free floating node
64        nod = task_id;
65        level = tasks.noduri[nod].niv_topo;
66        free_fnode = 1;         
67        for (j = 0 ; j < tasks.noduri[nod].nr_succ ; j++){
68                succ  = ((Muchie *)(tasks.noduri[nod].succesori[j]))->succesor->id;             
69                if ( tasks.noduri[succ].niv_topo <= level + 1){
70                        free_fnode = 0;
71                        break;
72                }
73        }
74        if (free_fnode == 1){
75                ch.f_nodes.push_back(nod);
76        }
77
78        int gasit = 0, poz;
79        for (i = 0 ; i < (int)ch.size() ; i++){
80                if (gasit == 0) {
81                        if (ch[i].task_index == task_id){
82                                gasit = 1;
83                                poz =  i ;
84                                continue;                       
85                        }               
86                }else if (ch[i].level == ch[poz].level + 1 && ch[i-1].level == ch[poz].level){
87                        ch[poz].level++;
88                        Gene g = ch[poz];
89                        ch[poz] = ch[i-1];
90                        ch[i-1] = g;
91                        break; 
92                }
93        }
94
95        ch.init();
96               
97        if (DEBUG == 1){
98                ch.print();
99                for (i = 0 ; i < (int)ch.f_nodes.size() ; i++)
100                        printf("%d ",ch.f_nodes[i]);
101                printf("\n");
102        }
103}
104
105/**
106* method applying the hyper-mutation on a chromosome
107*
108* @param ch the chromosome we want to mutate
109*/
110void HyperMutation::mutateIndividual(Chromosome &ch){
111        int i, poz, index ; 
112        Gene g; 
113
114        double rnd = (double)(rand() % 10000) / 10000;
115        if (DEBUG == 1) printf("Pb = %lf < %lf \n",rnd,mutation_pb);
116        if (rnd > mutation_pb){
117                return ; 
118        }
119               
120        ch.init();
121
122        //mapping current chromosome on the task graph
123        for (i = 0 ; i < ch.size() ; i++){
124                g = ch[i];             
125                tasks.noduri[g.task_index].niv_topo = g.level; 
126                tasks.noduri[g.task_index].procesor_id = g.proc_index; 
127        }
128
129        //choose which free floating node to process
130       
131        if (DEBUG == 1)printf("FN_size = %d \n", ch.f_nodes.size());
132       
133        if (ch.f_nodes.size() == 0)
134                return; 
135        poz = rand() % ch.f_nodes.size();
136               
137        index = ch.f_nodes[poz];
138
139        if (DEBUG == 1) printf("Poz = %d \n",index);
140
141        ch.f_nodes.erase(ch.f_nodes.begin()+poz);
142
143        increaseTopoLvl(ch, index);
144       
145
146}
147
148/**
149* method applying the hyper-mutation on a list of chromosomes
150*
151* @param pop the chromosomes list we want to mutate
152*/
153void HyperMutation::mutate(vector<Chromosome> &pop){
154        //int i;
155}
156
157/**
158* Method that applies the crossover on 2 parents obtaining 2 children
159*
160* @param p1 the parent #1
161* @param p2 the parent #2
162* @param c1 the child #1
163* @param c2 the child #2
164*/
165void Crossover::crossover(Chromosome &p1, Chromosome &p2, Chromosome& c1, Chromosome& c2)
166{
167        //printf("Cross\n");
168        c1.operator=(p1);
169        c2.operator=(p2);
170        int poz = rand() % (p1.genes.size() -1) + 1;
171        if (DEBUG == 1) printf("poz = %i\n", poz);
172        for(unsigned int i = poz ; i < p1.genes.size() ; i ++)
173                c1[i].proc_index = p2[i].proc_index;
174        for(unsigned int i = poz ; i < p1.genes.size() ; i ++)
175                c2[i].proc_index = p1[i].proc_index;
176        c1.init();
177        c2.init();
178
179        //c1.print();
180        //c2.print();
181        //printf("\n\n");
182}
183
184/**
185* Method that applies the crossover on a list of chromosomes
186*
187* @param chs the list of chromosomes
188*/
189void Crossover::applyCrossover(vector<Chromosome> &chs)
190{
191        int nr = chs.size();
192        if(nr % 2 != 0)
193                nr--;
194        Chromosome child1, child2;
195        //for each chromosomes pair
196        for(int i = 0 ; i < nr ; i +=2)
197        {
198                crossover(chs[i], chs[i+1], child1, child2);
199                chs.push_back(child1);
200                chs.push_back(child2);
201                if (DEBUG == 1){
202                        printf("parents:\n\t");
203                        chs[i].print(); 
204                        printf("\t");
205                        chs[i+1].print();
206                        printf("children:\n\t");
207                        child1.print(); 
208                        printf("\t");
209                        child2.print();
210                }
211        }
212}
213
214/**
215* constructor
216*
217* @param p the number of processors
218* @param l the maximum topological level
219* @param prob the simple mutation probability
220*/
221SimpleMutation::SimpleMutation(int p, int l, double pr)
222{
223        nr_procs = p;
224        max_level = l;
225        mutation_pb = pr;
226       
227}
228
229/**
230* method applying the simple mutation on a chromosome
231*
232* @param ch the chromosome we want to mutate
233*/
234void SimpleMutation::mutateIndividual(Chromosome & ch)
235{
236       
237        //mutation probability
238        int r = rand() % 100 ;
239        if(r > mutation_pb * 100)
240        {
241             
242                return;
243        }
244        ch.init();
245
246        r = rand() % ch.genes.size();
247        if (DEBUG == 1) printf("SM : poz = %i\n", r);
248        int old = ch[r].proc_index;
249        int nou;
250        for(;;)
251        {
252                nou = rand() % nr_procs;
253                if (DEBUG == 1) printf("SM : old = %i, nou = %i\n", old, nou);
254                if(nou != old)
255                        break;
256        }
257        ch[r].proc_index = nou;
258}
259
260typedef struct
261{
262        int level;
263        int proc;
264        int nr_genes;
265} Assocs;
266
267/**
268* constructor
269*
270* @param p the number of processors
271* @param l the maximum topological level
272* @param prob the swap gene mutation probability
273*/
274SwapMutation::SwapMutation(int p, int l, double pr)
275{
276        nr_procs = p;
277        max_level = l;
278        mutation_pb = pr;
279}
280
281/**
282* method applying the swap gene mutation on a chromosome
283*
284* @param ch the chromosome we want to mutate
285*/
286void SwapMutation::mutateIndividual(Chromosome & ch)
287{       
288        int crt=0, lev_crt = 1;
289        Assocs * asoc = (Assocs*)calloc(nr_procs*(max_level-1),sizeof(Assocs));
290        int * level_cnt = (int *)calloc(max_level, sizeof(int));
291        int * procs_crt = (int*)calloc(nr_procs, sizeof(int));
292
293        int r = rand() % 100 ;
294        if(r > mutation_pb* 100)
295                return;
296
297        ch.init();
298       
299        for(int i = 0 ; i < (signed int)ch.genes.size() ; )
300        {
301                if(lev_crt == ch[i].level)
302                {
303                        level_cnt[lev_crt]++;
304                        procs_crt[ch[i].proc_index]++;
305                        i++;
306                }
307                else
308                {
309                        for(int j = 0 ; j < nr_procs ; j ++)
310                        {
311                                if(procs_crt[j] > 0)
312                                {
313                                        asoc[crt].level = lev_crt;
314                                        asoc[crt].proc = j;
315                                        asoc[crt].nr_genes = procs_crt[j];
316                                        crt++;
317                                }
318                        }
319                        procs_crt = (int*)calloc(nr_procs, sizeof(int));                                       
320                        lev_crt ++;
321                }
322        }
323        for(int j = 0 ; j < nr_procs ; j ++)
324        {
325                if(procs_crt[j] > 0)
326                {
327                        asoc[crt].level = lev_crt;
328                        asoc[crt].proc = j;
329                        asoc[crt].nr_genes = procs_crt[j];
330                        crt++;
331                }
332        }
333        for(int i = 0 ; i < crt ; )
334        {
335                if(asoc[i].nr_genes < 2)
336                {               
337                        asoc[i].level = asoc[crt-1].level;
338                        asoc[i].proc = asoc[crt-1].proc;
339                        asoc[i].nr_genes = asoc[crt-1].nr_genes;
340                        crt--;
341                }                       
342                else    i++;
343        }
344        if(crt == 0)
345        {
346                if (DEBUG == 1) printf("no swap mutation\n");
347                return;
348        }
349        int random = rand() % crt, count = asoc[random].nr_genes, c1 = rand() % count, c2;
350        int start_poz = 0, good = 0, rc1, rc2;
351        for(;;)
352        {       
353                c2 = rand() % count;
354                if(c2 != c1) break;
355        }
356        for(int i = 0 ; i < asoc[random].level ; i ++)
357                start_poz += level_cnt[i];
358        for(int i = start_poz ; i < (int)ch.genes.size() ; i ++)
359        {
360                if(good == c1 && ch[i].proc_index == asoc[random].proc) rc1 = i;
361                if(good == c2 && ch[i].proc_index == asoc[random].proc) rc2 = i;
362                if(ch[i].proc_index == asoc[random].proc) 
363                      good++;
364        }
365        int aux = ch[rc1].task_index;
366        ch[rc1].task_index = ch[rc2].task_index;
367        ch[rc2].task_index = aux;
368        if (DEBUG == 1) printf("level = %i\n", ch[rc2].level);
369       
370}
Note: See TracBrowser for help on using the repository browser.