source: branches/stable/MULTI_PROBE/MP_probe_combi_statistic.cxx

Last change on this file was 16766, checked in by westram, 6 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.9 KB
Line 
1// ============================================================= //
2//                                                               //
3//   File      : MP_probe_combi_statistic.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 "MultiProbe.hxx"
13
14probe_combi_statistic::probe_combi_statistic(probe **pc, probe_tabs *ps, double exp, double fit, int life_cnt) {
15    memset((void*)this, 0, sizeof(probe_combi_statistic)); // @@@ potentially dangerous (overwrites vtable pointer!)
16
17    if (ps) probe_tab = ps;
18    else    probe_tab = NULp; // new probe_tabs
19
20    probe_combi = new probe*[mp_gl_awars.no_of_probes];
21    if (pc) {
22        for (int i=0; i < mp_gl_awars.no_of_probes; i++) {
23            probe_combi[i] = pc[i];
24        }
25    }
26    else {
27        memset(probe_combi, 0, mp_gl_awars.no_of_probes * sizeof(probe*));
28    }
29
30    expected_children = exp;
31    fitness = fit;
32    life_counter = life_cnt;
33}
34
35probe_combi_statistic::~probe_combi_statistic() {
36    delete [] probe_combi;
37    delete probe_tab;
38}
39
40bool probe_combi_statistic::ok_for_next_gen(int &len_roul_wheel) {
41    double exp_child = get_expected_children();
42
43    if (exp_child >= 1.0 || get_random(1, 100) <= 100 * exp_child) { // Behandlung nach Goldberg S.115 bzw. S.121
44        if (!is_dead()) {
45            return true;
46        }
47        else {
48            len_roul_wheel -= (int) (MULTROULETTEFACTOR * get_expected_children());
49            expected_children = 0.0;
50        }
51    }
52    return false;
53}
54
55void probe_combi_statistic::init_life_counter() {
56    life_counter = MAXLIFEFORCOMBI;
57}
58
59void probe_combi_statistic::sort(long feld_laenge) {
60    if (!feld_laenge)
61        return;
62
63    quicksort(0, feld_laenge-1);
64}
65
66inline void probe_combi_statistic::swap(probe **a, probe **b) {
67    probe *help;
68
69    help = *a;
70    *a = *b;
71    *b = help;
72}
73
74void probe_combi_statistic::quicksort(long left, long right) {
75    // Randomized Quicksort!!! wegen effizienz fuer den Fall, dass Feld sortiert
76    long   i = left,
77        j = right;
78    int         x,
79        help,
80        help2;
81
82    if (j>i) {
83        help = (left + right) / 2;
84
85        // Randomisierung des Quicksort Anfang
86        // Falls keine Randomisierung erwuenscht, einfach diesen Teil auskommentieren !!!
87        help2 = get_random(left, right);
88        swap(& probe_combi[help2], & probe_combi[help]);
89        // Randomisierung des Quicksort Ende
90
91        x = probe_combi[help]->probe_index;         // Normale Auswahl des Pivotelements
92
93        do {
94            while (probe_combi[i]->probe_index < x) i++;
95            while (probe_combi[j]->probe_index > x) j--;
96
97            if (i<=j) {
98                swap (& probe_combi[i], & probe_combi[j]);
99
100                i++;
101                j--;
102            }
103        } while (i<=j) ;
104
105        quicksort(left, j);
106        quicksort(i, right);
107    }
108}
109
110probe_combi_statistic *probe_combi_statistic::check_duplicates(GenerationDuplicates *dup_tree) {
111    bool result = true;
112
113    sort(mp_gl_awars.no_of_probes);
114
115    if (get_dupl_pos() == -1)
116        return this;
117
118    if (dup_tree)           // d.h. dass feld this nur einmal in der Generation vorkommen darf
119        if (dup_tree->insert(this, result, mp_gl_awars.no_of_probes))
120            return this;
121
122    return NULp;
123}
124
125
126void probe_combi_statistic::print(probe *p) {
127    printf("Idx:%d alMis:%d  ", p->probe_index, p->allowed_mismatches);
128}
129
130void probe_combi_statistic::print() {
131    for (int i=0; i<mp_gl_awars.no_of_probes; i++)
132        print(probe_combi[i]);
133
134    printf("Fit:%f Expchil: %f\n", fitness, expected_children);
135    probe_tab->print();
136}
137
138void probe_combi_statistic::print(probe **arr, int length) {
139    for (int i=0; i<length; i++)
140        print(arr[i]);
141}
142
143int probe_combi_statistic::sub_expected_children(double val) {
144    double result;
145
146    if (expected_children - val > 0)
147        result = (double)MULTROULETTEFACTOR * val;
148    else
149        result = (double)MULTROULETTEFACTOR * expected_children;
150
151    expected_children -= val;
152
153    if (expected_children < 0)
154        expected_children = 0;
155
156    return (int)result;
157}
158
159probe_combi_statistic *probe_combi_statistic::duplicate() {
160    probe_tabs *new_obje = NULp;
161
162    if (probe_tab)
163        new_obje = probe_tab->duplicate();
164
165    return new probe_combi_statistic(probe_combi, new_obje, expected_children, fitness, life_counter);
166}
167
168void probe_combi_statistic::mutate_Probe() {
169    int             rand_pool_pos;              // Stelle, an der die Sonde im Pool liegt ( von 0 bis laenge-)
170
171
172    for (int i=0; i<mp_gl_awars.no_of_probes; i++) {
173        // Jede Posititon der Sondenkombination wird mit einer Wahrscheinlichkeit von 1/MUTATION_WS mutiert.
174        if (get_random(1, MUTATION_WS) == 1) {
175            init_stats(); // Statistik hat sich geaendert.
176            rand_pool_pos   = get_random(0, mp_main->get_p_eval()->get_pool_length() - 1);
177            probe_combi[i]  = (mp_main->get_p_eval()->get_probe_pool())[rand_pool_pos];
178        }
179    }
180
181    while (!check_duplicates()) {
182        // Solange wie in der Sondenkombination noch Duplikate vorhanden sind muessen diese entfernt werden.
183        rand_pool_pos   = get_random(0, mp_main->get_p_eval()->get_pool_length() - 1);
184        probe_combi[get_dupl_pos()] = (mp_main->get_p_eval()->get_probe_pool())[rand_pool_pos];
185    }
186
187
188}
189
190int probe_combi_statistic::get_dupl_pos() {
191    int length = mp_gl_awars.no_of_probes;
192
193    for (int i=0; i<length-1; i++)      // auf duplikate in der Sondenkombi. pruefen
194        if (probe_combi[i]->probe_index == probe_combi[i+1]->probe_index)
195            return i;
196
197    return -1;
198}
199
200
201void probe_combi_statistic::sigma_truncation(double average_fit, double deviation) {
202    // vor allem dafuer gedacht, dass wenn wenige schlecht und sehr viele gute
203    // vorhanden sind, dann werden die schlechten 'herausskaliert'
204    fitness = (fitness - average_fit) + ((double)SIGMATRUNCATION_CONST * deviation);
205    if (fitness < 0)
206        fitness = 0;
207}
208
209void probe_combi_statistic::crossover_Probes(probe_combi_statistic *pcombi2) {
210    // An bis zu no_of_probes werden Gene zwischen pcombi1 und pcombi2 ausgetauscht.
211
212    int rand_cross_pos1,                        // Position an der der Crossover aufgefuehrt wird.
213        rand_cross_pos2,
214        rand_no_of_cross,                       // Anzahl der Austauschaktionen. (mind. 1)
215        random_interval = mp_gl_awars.no_of_probes - 1;
216    probe_combi_statistic *f1, *f2;
217
218    rand_no_of_cross = random_interval ? get_random(1, random_interval) : 0;
219
220    for (int i = 0; i < rand_no_of_cross; i++) { // eigentliche Crossover Schleife
221        rand_cross_pos1 = get_random(0, random_interval);
222        rand_cross_pos2 = get_random(0, random_interval);
223
224        swap(& probe_combi[rand_cross_pos1],          & pcombi2->probe_combi[rand_cross_pos2]);
225        swap(& probe_combi[rand_cross_pos1],          & probe_combi[random_interval]);       // um keine Listen zu verwenden
226        swap(& pcombi2->probe_combi[rand_cross_pos2], & pcombi2->probe_combi[random_interval]);         // wird im Array getauscht
227
228        random_interval--;
229    }
230
231    while (true) { // Crossovernachbehandlung, um duplikate in Kombinationen zu vermeiden
232        int change1, change2;
233
234        f1 = check_duplicates();
235        f2 = pcombi2->check_duplicates();
236
237        if (f1 && f2) break;
238
239        if (f1) change1 = get_random(0, mp_gl_awars.no_of_probes - 1); // in f1 kein Duplikat
240        else    change1 = get_dupl_pos();
241
242        if (f2) change2 = get_random(0, mp_gl_awars.no_of_probes - 1); // in f2 kein Duplikat
243        else    change2 = pcombi2->get_dupl_pos();
244
245        swap(&probe_combi[change1], &pcombi2->probe_combi[change2]); // worst case = die Felder sehen genauso aus, wie vor dem Crossover
246    }
247
248    init_stats();
249    pcombi2->init_stats();
250}
251
252void probe_combi_statistic::init_stats() {
253    memset(&probe_tab, 0, sizeof(probe_tabs));                      // bisherige Statistiken fuer diese Sondenkombination zuruecksetzten
254    life_counter = MAXLIFEFORCOMBI;
255    fitness = 0;
256    expected_children = 0;
257}
258
259int probe_combi_statistic::calc_index_system3(int *field) {
260    int i, result = 0;
261
262    for (i=0; i<mp_gl_awars.no_of_probes; i++)
263        result += system3_tab[field[i]][i];     // Ergebnis von : (3^i) * field[i];
264
265    return result;
266}
267
268
269inline int probe_combi_statistic::modificated_hamming_dist(int one, int two) { // pseudo hamming distanz einer Sondenkombi
270    return hamming_tab[one][two];
271}
272
273double  probe_combi_statistic::calc_fitness(int len_of_field) { // fitness-bewertung einer Sondenkombi
274    int     i, j, k, mod_ham_dist;
275    long        *hammingarray;
276    double  tolerated_non_group_hits, ham_dist;
277
278
279    Sondentopf  *sondentopf = new Sondentopf(mp_main->get_stc()->Bakterienliste,
280                                             mp_main->get_stc()->Auswahlliste);
281
282    for (i=0; i<len_of_field; i++)
283        sondentopf->put_Sonde((mp_main->get_p_eval()->get_sondenarray())[probe_combi[i]->probe_index],
284                              probe_combi[i]->allowed_mismatches,
285                              probe_combi[i]->allowed_mismatches + mp_gl_awars.outside_mismatches_difference);
286
287    probe_tab = sondentopf->fill_Stat_Arrays();
288    delete sondentopf;
289
290    fitness = 0.0;
291    hammingarray = new long[mp_gl_awars.no_of_probes+1];
292
293    for (i=0; i< probe_tab->get_len_group_tabs()-1; i++) {
294        memset(hammingarray, 0,  sizeof(long) * (mp_gl_awars.no_of_probes + 1));
295        for (j=0; j<probe_tab->get_len_group_tabs(); j++) {
296            mod_ham_dist = modificated_hamming_dist(i, j);
297            hammingarray[mod_ham_dist] +=  probe_tab->get_non_group_tab(j);
298        }
299
300        tolerated_non_group_hits = (double) mp_gl_awars.qualityborder_best;
301
302        for (k=0; k < mp_gl_awars.no_of_probes + 1 && tolerated_non_group_hits >= 0.0; k++) {
303            for (j=0; j<FITNESSSCALEFACTOR && tolerated_non_group_hits >= 0.0; j++) {
304                tolerated_non_group_hits -= (double) ((double)hammingarray[k] / (double)FITNESSSCALEFACTOR);
305            }
306
307        }
308
309        if (tolerated_non_group_hits<0.0) {
310            if (j)                               ham_dist = (double)k - 1.0 + ((double)(((double)j - 1.0)/(double)FITNESSSCALEFACTOR));
311            else                                 ham_dist = (double)k - 1.0;
312        }
313        else if (tolerated_non_group_hits > 0.0) ham_dist = (double) mp_gl_awars.no_of_probes;
314        else                                     ham_dist = 0.0;
315
316        fitness += ham_dist * ((double) probe_tab->get_group_tab(i));
317    }
318
319    delete [] hammingarray;
320    return fitness;
321}
322
323double probe_combi_statistic::calc_expected_children(double average_fitness) {
324    expected_children = fitness / average_fitness;
325    return expected_children;
326}
327
328
Note: See TracBrowser for help on using the repository browser.