source: trunk/MULTI_PROBE/MP_Generation.cxx @ 6347

Last change on this file since 6347 was 6347, checked in by westram, 15 years ago

Moved a lot of dead code to where it belongs: into the depths of SVN.
I didn't care much: If there was no obvious reason (e.g. some coment explaining why it's still there), it has been deleted

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.4 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    deviation = 0;
75
76
77#ifdef USE_LINEARSCALING
78    double  dev = 0;
79    double  a = 0,
80        b = 0;
81#ifdef USE_SIGMATRUNCATION
82    for (i=0; i<probe_combi_array_length; i++)          // Berechnung der Abweichung nach Goldberg S.124
83    {
84        dev = probe_combi_stat_array[i]->get_fitness() - average_fitness;
85        dev = dev * dev;
86        deviation += dev;
87    }
88    deviation = (1.0 / (double)((double)i - 1.0)) * deviation;
89    deviation = sqrt(deviation);
90
91    for (i=0; i<probe_combi_array_length; i++)          //sigma_truncation nur auf schlechte Kombis anwenden ???
92        probe_combi_stat_array[i]->sigma_truncation(average_fitness, deviation);
93#endif
94    //lineare Skalierung auf fitness anwenden !!!
95    //Skalierung erfolgt nach der Formel     fitness'= a*fitness + b
96
97    prescale(&a, &b);       //Koeffizienten a und b berechnen
98#endif
99
100    for (i=0; i<probe_combi_array_length; i++)
101    {
102#ifdef USE_LINEARSCALING
103        probe_combi_stat_array[i]->scale(a,b);
104#endif
105        probe_combi_stat_array[i]->calc_expected_children(average_fitness);
106    }
107
108    init_roulette_wheel();
109}
110
111void Generation::prescale(double *a, double *b) //berechnet Koeffizienten fuer lineare Skalierung
112{
113    double delta = 0;
114
115    if ((min_fit > C_MULT * average_fitness - max_fit) / (C_MULT - 1.0))    //nach Goldberg S.79
116    {
117        delta = max_fit - average_fitness;              // Normale Skalierung
118        *a = (C_MULT - 1.0) * average_fitness / delta;
119        *b = average_fitness * (max_fit - C_MULT * average_fitness) / delta;
120    }
121    else                                //Skalieren soweit moeglich
122    {
123        delta = average_fitness - min_fit;
124        *a = average_fitness / delta;
125        *b = -min_fit * average_fitness / delta;
126    }
127}
128
129void Generation::init_roulette_wheel()
130{
131    int     i=0;
132
133    len_roulette_wheel = 0;
134    while (i<probe_combi_array_length)
135        len_roulette_wheel += (int)(MULTROULETTEFACTOR * (probe_combi_stat_array[i++]->get_expected_children()));   //um aus z.B. 4,2 42 zu machen
136}
137
138probe_combi_statistic *Generation::choose_combi_for_next_generation()
139{
140    int random_help = get_random(0,len_roulette_wheel-1),
141        i;
142
143    for (i=0; i<probe_combi_array_length; i++)              //in einer Schleife bis zu den betreffenden Elementen
144    {                                   // vordringen (Rouletterad !!!)
145        random_help -= (int) (MULTROULETTEFACTOR * probe_combi_stat_array[i]->get_expected_children());
146
147        if (random_help <= 0)
148        {
149            if (probe_combi_stat_array[i]->ok_for_next_gen(len_roulette_wheel))
150                return probe_combi_stat_array[i];
151            else
152            {
153                random_help = get_random(0,len_roulette_wheel-1);
154                i = -1;
155            }
156        }
157    }
158
159    return NULL;
160}
161
162Generation *Generation::create_next_generation()
163{
164    Generation      *child_generation = new Generation(MAXPOPULATION, generation_counter+1);
165    probe_combi_statistic   *first_child_pcs = NULL,
166        *second_child_pcs = NULL,
167        *orig1 = NULL,
168        *orig2 = NULL;
169    int cnt = 0;
170#ifdef USE_DUP_TREE
171    BOOL res;
172#endif
173
174    while (len_roulette_wheel > 1)                  // kann kleiner sein, wenn Population kleiner als MAXPOPULATION
175    {
176        cnt++;
177        orig1 = choose_combi_for_next_generation();
178        orig2 = choose_combi_for_next_generation();
179
180        if (! orig1 && ! orig2)
181            break;
182        else if (!orig1 && orig2)
183        {
184            orig1 = orig2;
185            orig2 = NULL;
186        }
187
188        delete first_child_pcs;
189        delete second_child_pcs;
190        first_child_pcs = second_child_pcs = NULL;
191
192        first_child_pcs = orig1->duplicate();
193        if (orig2)
194            second_child_pcs = orig2->duplicate();
195
196        if (orig2 && get_random(1,100) <= CROSSOVER_WS)     //Crossover durchfueheren
197        {
198            first_child_pcs->crossover_Probes(second_child_pcs);
199            first_child_pcs->init_life_counter();       //wenn  Crossover durchgefuehrt wird, dann Lebensdauer wieder initialisieren, da
200            second_child_pcs->init_life_counter();      //sich die Gene veraendert haben
201            len_roulette_wheel -= orig1->sub_expected_children(0.5);    //Verfahren nach Goldberg S.115
202            len_roulette_wheel -= orig2->sub_expected_children(0.5);
203        }
204        else
205        {
206            first_child_pcs->sub_life_counter();                //Gene gleich geblieben => Lebensdauer verkuerzen
207            len_roulette_wheel -= orig1->sub_expected_children(1.0);    //nur tatsaechlich subtrahierte Zahl abziehen !!!
208
209            if (orig2)
210            {
211                second_child_pcs->sub_life_counter();
212                len_roulette_wheel -= orig2->sub_expected_children(1.0);
213            }
214        }
215
216        first_child_pcs->mutate_Probe();    //fuer jede Position wird mit 1/MUTATION_WS eine Mutation durchgefuehrt.
217        if (orig2)                  //Mutationen durchfuehren
218            second_child_pcs->mutate_Probe();
219
220#ifdef USE_DUP_TREE
221
222        res = TRUE;
223        if (child_generation->get_dup_tree()->insert(first_child_pcs, res, 0))
224        {
225            if (!child_generation->insert(first_child_pcs))     //Population schon auf MAXPOPULATION
226                break;
227        }
228
229        res = TRUE;
230        if (child_generation->get_dup_tree()->insert(second_child_pcs, res, 0))
231        {
232            if (orig2)
233                if (!child_generation->insert(second_child_pcs))
234                    break;
235        }
236
237#else
238        if (!child_generation->insert(first_child_pcs))     //Population schon auf MAXPOPULATION
239            break;
240
241        if (orig2)
242            if (!child_generation->insert(second_child_pcs))
243                break;
244
245#endif
246    }
247
248    delete first_child_pcs;
249    delete second_child_pcs;
250
251    if (len_roulette_wheel <= 1)
252        child_generation->set_length();             //probe_combi_array_length muss andere laenge bekommen
253
254    return child_generation;
255}
256
257void Generation::gen_determ_combis(int beg,
258                                   int len,
259                                   int &pos_counter,
260                                   probe_combi_statistic *p)
261{
262    int     i, j;
263    probe_combi_statistic   *bastel_probe_combi;
264
265    if (len == 0)
266    {
267        probe_combi_stat_array[pos_counter++] = p;
268        return;
269    }
270
271    for (i=beg; i <= mp_main->get_p_eval()->get_pool_length() - len; i++)
272    {
273        bastel_probe_combi = new probe_combi_statistic();
274
275        for (j=0; j < mp_gl_awars.no_of_probes - len; j++)
276            bastel_probe_combi->set_probe_combi(j, p->get_probe_combi(j));
277
278        if (len == mp_gl_awars.no_of_probes ||
279            (mp_main->
280             get_p_eval()->
281             get_probe_pool())[i]->
282            probe_index !=
283            bastel_probe_combi->
284            get_probe_combi(mp_gl_awars.no_of_probes - len - 1)->probe_index)
285        {
286            bastel_probe_combi->set_probe_combi(    mp_gl_awars.no_of_probes - len,
287                                                    (mp_main->get_p_eval()->get_probe_pool())[i]);
288            gen_determ_combis(i+1, len-1, pos_counter, bastel_probe_combi);
289        }
290
291        if (len !=1)
292            delete bastel_probe_combi;
293    }
294}
295
296BOOL Generation::insert(probe_combi_statistic *pcs)
297{
298    if (last_elem == MAXPOPULATION)
299        return FALSE;
300
301    probe_combi_stat_array[last_elem++] = pcs->duplicate();
302    probe_combi_array_length = last_elem;
303
304    return TRUE;
305}
306
307void Generation::init_valuation()
308{
309    int         i, counter=0;
310    probe           *random_probe;
311    int         zw_erg;
312    probe_combi_statistic *pcs;
313    int         pos = 0;
314
315
316    if (probe_combi_array_length < MAXINITPOPULATION)
317    {
318        gen_determ_combis(0,mp_gl_awars.no_of_probes, pos, NULL);   //probe_combi_stat_array ist danach gefuellt !!!
319
320        probe_combi_array_length = pos;
321
322        return;         //aufruf der funktion fuer die letzte Generation
323    }
324
325    counter = 0;
326    pcs = new probe_combi_statistic();
327
328    while (counter < probe_combi_array_length)      //Hier erfolgt die Generierung des probe_combi_stat_array
329    {
330        for (i=0; i<mp_gl_awars.no_of_probes; i++)
331        {
332            zw_erg = get_random(0, mp_main->get_p_eval()->get_pool_length()-1);
333            random_probe = (mp_main->get_p_eval()->get_probe_pool())[zw_erg];
334            pcs->set_probe_combi(i, random_probe);
335        }
336
337        if (pcs->check_duplicates(dup_tree))            //2 gleiche Sonden in der Kombination => nicht verwendbar
338        {
339            probe_combi_stat_array[counter++] = pcs;
340            if (counter < probe_combi_array_length)
341                pcs = new probe_combi_statistic();
342        }
343    }
344}
345
346Generation::Generation(int len, int gen_nr)
347{
348    memset( (char *)this, 0, sizeof(Generation) );
349
350    probe_combi_array_length  = len;
351    probe_combi_stat_array = new probe_combi_statistic*[probe_combi_array_length];  //probe_combi_array_length entspricht
352    // der Groesse der Ausgangspopulation
353    memset(probe_combi_stat_array, 0, probe_combi_array_length * sizeof(probe_combi_statistic*));   // Struktur mit 0 initialisieren.
354    generation_counter = gen_nr;
355
356#ifdef USE_DUP_TREE
357    dup_tree = new GenerationDuplicates(mp_main->get_p_eval()->get_size_sondenarray());     //nur wenn sondenkombis nur einmal
358    // in der Generation vorkommen duerfen
359#endif
360
361}
362
363Generation::~Generation()
364{
365    int i;
366
367    for (i=0; i<probe_combi_array_length; i++)
368        delete probe_combi_stat_array[i];
369
370    delete [] probe_combi_stat_array;
371    delete dup_tree;
372}
Note: See TracBrowser for help on using the repository browser.