source: tags/arb_5.2/MULTI_PROBE/MP_Generation.cxx

Last change on this file was 3549, checked in by westram, 19 years ago
  • includes fixed
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.9 KB
Line 
1#include <MultiProbe.hxx>
2
3#include <string.h>
4#include <math.h>
5
6extern BOOL check_status(int gen_cnt, double avg_fit, double min_fit, double max_fit);
7BOOL    Stop_evaluation = FALSE;
8
9probe_combi_statistic *Generation::single_in_generation(probe_combi_statistic *field)
10{
11    BOOL result = TRUE;
12
13    if (!dup_tree)
14        return NULL;
15
16    dup_tree->insert(field, result);        //dup_tree muss fuer jede Generation neu erstellt werden !!!!
17    //dieser Aufruf wird nur zur Vermeidung von doppelten
18    //Sondenkombis benoetigt
19    if (result)                 //wenn result, dann in generation einmalig
20        return field;
21
22    return NULL;                //field ist ein Duplikat
23}
24
25void Generation::print()
26{
27    for (int i=0; i<probe_combi_array_length; i++)
28        probe_combi_stat_array[i]->print();
29}
30
31void Generation::check_for_results()
32{
33    for (int i=0; i<probe_combi_array_length; i++)
34    {
35        if (probe_combi_stat_array[i])
36            mp_main->get_p_eval()->insert_in_result_list(probe_combi_stat_array[i]);
37    }
38}
39
40void Generation::calc_fitness(int flag, double old_avg_fit)     //reoulette_wheel wird DANACH initialisiert
41{
42    double  fitness = 0;
43    double  dummy = 0;
44
45    int     i;
46
47    for (i=0; i<probe_combi_array_length; i++)
48    {
49
50        dummy = probe_combi_stat_array[i]->calc_fitness(mp_gl_awars.no_of_probes);
51        fitness += dummy;
52
53        if (i==0)
54            min_fit = max_fit = dummy;
55
56        if (dummy < min_fit)
57            min_fit = dummy;
58        else if (dummy > max_fit)
59            max_fit = dummy;
60
61        if (!check_status(generation_counter, old_avg_fit, min_fit, max_fit))       //Berechnungen abbrechen
62        {
63            Stop_evaluation = TRUE;
64            probe_combi_array_length = i-1;
65            return;
66        }
67    }
68
69    if (flag == NO_GENETIC_ALG)             //wenn kein gen. ALgorithmus verwendet wird, dann
70        return;                     //muss der Rest nicht berechnet werden.
71
72    average_fitness = fitness / (double)probe_combi_array_length;
73
74    //    printf("--------------------------------------------------------------------------------------------------------------------\n");
75    //    printf("BEWERTUNG FUER DIE GENERATION:\n");
76    //    printf("Generation: %d   max: %f   min: %f   avg: %f\n", generation_counter, max_fit, min_fit, average_fitness);
77    //    printf("probe_combi_array_lentgh : %d\n",probe_combi_array_length);
78    //    printf("--------------------------------------------------------------------------------------------------------------------\n");
79
80
81    deviation = 0;
82
83
84#ifdef USE_LINEARSCALING
85    double  dev = 0;
86    double  a = 0,
87        b = 0;
88#ifdef USE_SIGMATRUNCATION
89    for (i=0; i<probe_combi_array_length; i++)          // Berechnung der Abweichung nach Goldberg S.124
90    {
91        dev = probe_combi_stat_array[i]->get_fitness() - average_fitness;
92        dev = dev * dev;
93        deviation += dev;
94    }
95    deviation = (1.0 / (double)((double)i - 1.0)) * deviation;
96    deviation = sqrt(deviation);
97
98    for (i=0; i<probe_combi_array_length; i++)          //sigma_truncation nur auf schlechte Kombis anwenden ???
99        probe_combi_stat_array[i]->sigma_truncation(average_fitness, deviation);
100#endif
101    //lineare Skalierung auf fitness anwenden !!!
102    //Skalierung erfolgt nach der Formel     fitness'= a*fitness + b
103
104    prescale(&a, &b);       //Koeffizienten a und b berechnen
105#endif
106
107    for (i=0; i<probe_combi_array_length; i++)
108    {
109#ifdef USE_LINEARSCALING
110        probe_combi_stat_array[i]->scale(a,b);
111#endif
112        probe_combi_stat_array[i]->calc_expected_children(average_fitness);
113    }
114
115    init_roulette_wheel();
116}
117
118void Generation::prescale(double *a, double *b) //berechnet Koeffizienten fuer lineare Skalierung
119{
120    double delta = 0;
121
122    if ((min_fit > C_MULT * average_fitness - max_fit) / (C_MULT - 1.0))    //nach Goldberg S.79
123    {
124        delta = max_fit - average_fitness;              // Normale Skalierung
125        *a = (C_MULT - 1.0) * average_fitness / delta;
126        *b = average_fitness * (max_fit - C_MULT * average_fitness) / delta;
127    }
128    else                                //Skalieren soweit moeglich
129    {
130        delta = average_fitness - min_fit;
131        *a = average_fitness / delta;
132        *b = -min_fit * average_fitness / delta;
133    }
134}
135
136void Generation::init_roulette_wheel()
137{
138    int     i=0;
139
140    len_roulette_wheel = 0;
141    while (i<probe_combi_array_length)
142        len_roulette_wheel += (int)(MULTROULETTEFACTOR * (probe_combi_stat_array[i++]->get_expected_children()));   //um aus z.B. 4,2 42 zu machen
143}
144
145probe_combi_statistic *Generation::choose_combi_for_next_generation()
146{
147    int random_help = get_random(0,len_roulette_wheel-1),
148        i;
149
150    for (i=0; i<probe_combi_array_length; i++)              //in einer Schleife bis zu den betreffenden Elementen
151    {                                   // vordringen (Rouletterad !!!)
152        random_help -= (int) (MULTROULETTEFACTOR * probe_combi_stat_array[i]->get_expected_children());
153
154        if (random_help <= 0)
155        {
156            if (probe_combi_stat_array[i]->ok_for_next_gen(len_roulette_wheel))
157                return probe_combi_stat_array[i];
158            else
159            {
160                random_help = get_random(0,len_roulette_wheel-1);
161                i = -1;
162            }
163        }
164    }
165
166    return NULL;
167}
168
169Generation *Generation::create_next_generation()
170{
171    Generation      *child_generation = new Generation(MAXPOPULATION, generation_counter+1);
172    probe_combi_statistic   *first_child_pcs = NULL,
173        *second_child_pcs = NULL,
174        *orig1 = NULL,
175        *orig2 = NULL;
176    int cnt = 0;
177#ifdef USE_DUP_TREE
178    BOOL res;
179#endif
180
181    while (len_roulette_wheel > 1)                  // kann kleiner sein, wenn Population kleiner als MAXPOPULATION
182    {
183        cnt++;
184        orig1 = choose_combi_for_next_generation();
185        orig2 = choose_combi_for_next_generation();
186
187        if (! orig1 && ! orig2)
188            break;
189        else if (!orig1 && orig2)
190        {
191            orig1 = orig2;
192            orig2 = NULL;
193        }
194
195        delete first_child_pcs;
196        delete second_child_pcs;
197        first_child_pcs = second_child_pcs = NULL;
198
199        first_child_pcs = orig1->duplicate();
200        if (orig2)
201            second_child_pcs = orig2->duplicate();
202
203        if (orig2 && get_random(1,100) <= CROSSOVER_WS)     //Crossover durchfueheren
204        {
205            first_child_pcs->crossover_Probes(second_child_pcs);
206            first_child_pcs->init_life_counter();       //wenn  Crossover durchgefuehrt wird, dann Lebensdauer wieder initialisieren, da
207            second_child_pcs->init_life_counter();      //sich die Gene veraendert haben
208            len_roulette_wheel -= orig1->sub_expected_children(0.5);    //Verfahren nach Goldberg S.115
209            len_roulette_wheel -= orig2->sub_expected_children(0.5);
210        }
211        else
212        {
213            first_child_pcs->sub_life_counter();                //Gene gleich geblieben => Lebensdauer verkuerzen
214            len_roulette_wheel -= orig1->sub_expected_children(1.0);    //nur tatsaechlich subtrahierte Zahl abziehen !!!
215
216            if (orig2)
217            {
218                second_child_pcs->sub_life_counter();
219                len_roulette_wheel -= orig2->sub_expected_children(1.0);
220            }
221        }
222
223        first_child_pcs->mutate_Probe();    //fuer jede Position wird mit 1/MUTATION_WS eine Mutation durchgefuehrt.
224        if (orig2)                  //Mutationen durchfuehren
225            second_child_pcs->mutate_Probe();
226
227#ifdef USE_DUP_TREE
228
229        res = TRUE;
230        if (child_generation->get_dup_tree()->insert(first_child_pcs, res, 0))
231        {
232            if (!child_generation->insert(first_child_pcs))     //Population schon auf MAXPOPULATION
233                break;
234        }
235
236        res = TRUE;
237        if (child_generation->get_dup_tree()->insert(second_child_pcs, res, 0))
238        {
239            if (orig2)
240                if (!child_generation->insert(second_child_pcs))
241                    break;
242        }
243
244#else
245        if (!child_generation->insert(first_child_pcs))     //Population schon auf MAXPOPULATION
246            break;
247
248        if (orig2)
249            if (!child_generation->insert(second_child_pcs))
250                break;
251
252#endif
253    }
254
255    delete first_child_pcs;
256    delete second_child_pcs;
257
258    if (len_roulette_wheel <= 1)
259        child_generation->set_length();             //probe_combi_array_length muss andere laenge bekommen
260
261    //  printf("Generationenschleife : %d\n",cnt);
262    return child_generation;
263}
264
265void Generation::gen_determ_combis(int beg,
266                                   int len,
267                                   int &pos_counter,
268                                   probe_combi_statistic *p)
269{
270    int     i, j;
271    probe_combi_statistic   *bastel_probe_combi;
272
273    if (len == 0)
274    {
275        probe_combi_stat_array[pos_counter++] = p;
276        return;
277    }
278
279    for (i=beg; i <= mp_main->get_p_eval()->get_pool_length() - len; i++)
280    {
281        bastel_probe_combi = new probe_combi_statistic();
282
283        for (j=0; j < mp_gl_awars.no_of_probes - len; j++)
284            bastel_probe_combi->set_probe_combi(j, p->get_probe_combi(j));
285
286        if (len == mp_gl_awars.no_of_probes ||
287            (mp_main->
288             get_p_eval()->
289             get_probe_pool())[i]->
290            probe_index !=
291            bastel_probe_combi->
292            get_probe_combi(mp_gl_awars.no_of_probes - len - 1)->probe_index)
293        {
294            bastel_probe_combi->set_probe_combi(    mp_gl_awars.no_of_probes - len,
295                                                    (mp_main->get_p_eval()->get_probe_pool())[i]);
296            gen_determ_combis(i+1, len-1, pos_counter, bastel_probe_combi);
297        }
298
299        if (len !=1)
300            delete bastel_probe_combi;
301    }
302}
303
304BOOL Generation::insert(probe_combi_statistic *pcs)
305{
306    if (last_elem == MAXPOPULATION)
307        return FALSE;
308
309    probe_combi_stat_array[last_elem++] = pcs->duplicate();
310    probe_combi_array_length = last_elem;
311
312    return TRUE;
313}
314
315void Generation::init_valuation()
316{
317    int         i, counter=0;
318    probe           *random_probe;
319    int         zw_erg;
320    probe_combi_statistic *pcs;
321    int         pos = 0;
322
323
324    if (probe_combi_array_length < MAXINITPOPULATION)
325    {
326        gen_determ_combis(0,mp_gl_awars.no_of_probes, pos, NULL);   //probe_combi_stat_array ist danach gefuellt !!!
327
328        probe_combi_array_length = pos;
329
330        return;         //aufruf der funktion fuer die letzte Generation
331    }
332
333    counter = 0;
334    pcs = new probe_combi_statistic();
335
336    while (counter < probe_combi_array_length)      //Hier erfolgt die Generierung des probe_combi_stat_array
337    {
338        for (i=0; i<mp_gl_awars.no_of_probes; i++)
339        {
340            zw_erg = get_random(0, mp_main->get_p_eval()->get_pool_length()-1);
341            random_probe = (mp_main->get_p_eval()->get_probe_pool())[zw_erg];
342            pcs->set_probe_combi(i, random_probe);
343        }
344
345        if (pcs->check_duplicates(dup_tree))            //2 gleiche Sonden in der Kombination => nicht verwendbar
346        {
347            probe_combi_stat_array[counter++] = pcs;
348            if (counter < probe_combi_array_length)
349                pcs = new probe_combi_statistic();
350        }
351    }
352}
353
354Generation::Generation(int len, int gen_nr)
355{
356    memset( (char *)this, 0, sizeof(Generation) );
357
358    probe_combi_array_length  = len;
359    probe_combi_stat_array = new probe_combi_statistic*[probe_combi_array_length];  //probe_combi_array_length entspricht
360    // der Groesse der Ausgangspopulation
361    memset(probe_combi_stat_array, 0, probe_combi_array_length * sizeof(probe_combi_statistic*));   // Struktur mit 0 initialisieren.
362    generation_counter = gen_nr;
363
364#ifdef USE_DUP_TREE
365    dup_tree = new GenerationDuplicates(mp_main->get_p_eval()->get_size_sondenarray());     //nur wenn sondenkombis nur einmal
366    // in der Generation vorkommen duerfen
367#endif
368
369}
370
371Generation::~Generation()
372{
373    int i;
374
375    for (i=0; i<probe_combi_array_length; i++)
376        delete probe_combi_stat_array[i];
377
378    delete [] probe_combi_stat_array;
379    delete dup_tree;
380}
Note: See TracBrowser for help on using the repository browser.