source: tags/arb-6.0/MULTI_PROBE/MP_Generation.cxx

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