9 #include <ucw/eltpool.h>
14 #include "lab-utils.h"
15 #include "lab-bitmaps.h"
16 #include "lab-evolution.h"
26 static void evolution_compute_sizes(void);
28 static void make_population(void);
29 static void rank_population(void);
31 static bool shall_terminate(void);
32 static void breed(void);
33 static void mutate(void);
34 static void elite(void);
36 static void hide_segment_labels(struct individual *individual);
38 static void init_placement(struct placement *p, struct individual *individual, struct request *r);
40 static void init_individual(struct individual *i);
41 static int cmp_individual(const void *a, const void *b);
42 static void plan_individual(struct individual *individual);
43 static void clear_individual(struct individual *individual);
45 static struct individual **perform_crossover(struct individual *parent1, struct individual *parent2);
46 static void perform_mutation(struct individual *individual);
47 static void copy_individual(struct individual *src, struct individual *dest);
49 static double gen_movement(void);
50 static double gen_movement_uniform(void);
51 static void move_symbol(struct placement *p);
52 static void move_symbol_point(struct placement *p);
53 static void move_symbol_segment(struct placement *p);
55 static void gen_coords(struct placement *p);
56 static void gen_coords_point(struct placement *p);
57 static void gen_coords_segment(struct placement *p);
58 static void gen_coords_area(struct placement *p);
60 static void copy_symbols(struct placement **closure, struct individual *parent, struct individual *child, bool **processed_ptr);
62 static int individual_overlap(struct individual *individual);
64 static double get_distance(struct placement *p);
65 static double individual_distances(struct individual *individual);
67 static double get_omittment(struct placement *p);
68 static double individual_omittment(struct individual *individual);
70 static void clear_population(struct individual **pop);
72 static void dump_penalties(struct individual **population);
74 static struct eltpool *ep_individuals;
76 static int conf_pop_size = 200, conf_fit_size = 1, conf_term_cond = TERM_COND_ITERATIONS;
78 static double conf_penalty_bound = 100, conf_stagnation_bound = 10;
79 static int conf_iteration_limit = 200;
81 static double conf_rank_distance_w = 1, conf_rank_overlap_w = 1, conf_rank_omittment_w = 1;
83 static int breed_pop_size;
84 static int breed_rbest_size;
86 static int mutate_pop_size;
87 static int mutate_rbest_size;
89 static int elite_pop_size;
92 static int move_min = 0;
93 static int move_max = 5;
95 static double conf_breed_pop_size = 0.45, conf_breed_rbest = 1,
96 conf_mutate_children, conf_mutate_children_prob = 0.6,
97 conf_mutate_pop_size = 0.45, conf_mutate_rbest = 1,
98 conf_mutate_move_bound = 0.1, conf_mutate_regen_bound = 0.05, conf_mutate_chvar_bound = 0.1,
99 conf_elite_pop_size = 0.1;
101 static struct cf_section evolution_cf = {
103 CF_INT("PopSize", &conf_pop_size),
104 CF_INT("FitSize", &conf_fit_size),
105 CF_INT("TermCond", &conf_term_cond),
106 CF_DOUBLE("PenaltyBound", &conf_penalty_bound),
107 CF_DOUBLE("StagnationBound", &conf_stagnation_bound),
108 CF_INT("IterationLimit", &conf_iteration_limit),
109 CF_DOUBLE("BreedPopSize", &conf_breed_pop_size),
110 CF_DOUBLE("BreedNumBest", &conf_breed_rbest),
111 CF_DOUBLE("MutateChild", &conf_mutate_children_prob),
112 CF_DOUBLE("MutatePopSize", &conf_mutate_pop_size),
113 CF_DOUBLE("MutateNumBest", &conf_mutate_rbest),
114 CF_DOUBLE("MutateMoveBound", &conf_mutate_move_bound),
115 CF_DOUBLE("MutateRegenBound", &conf_mutate_regen_bound),
116 CF_DOUBLE("MutateChvarBound", &conf_mutate_chvar_bound),
117 CF_DOUBLE("ElitePopSize", &conf_elite_pop_size),
118 CF_DOUBLE("DistanceWeight", &conf_rank_distance_w),
119 CF_DOUBLE("OverlapWeight", &conf_rank_overlap_w),
120 CF_DOUBLE("OmittmentWeight", &conf_rank_omittment_w),
125 static struct placement dummy_placement;
127 static struct individual **population1;
128 static struct individual **population2;
130 static int old_best = INT_MAX;
131 static int iteration = 0;
136 void evolution_conf(void)
138 cf_declare_section("Evolution", &evolution_cf, 0);
141 void evolution_init(void)
143 evolution_compute_sizes();
148 ep_individuals = ep_new(sizeof(struct individual), 1);
150 GARY_INIT(population1, conf_pop_size);
151 GARY_INIT(population2, conf_pop_size);
155 qsort(population1, conf_pop_size, sizeof(struct individual *), cmp_individual);
157 if (dbg_evolution >= VERBOSITY_GENERAL)
159 printf("Penalties after initialization\n");
160 dump_penalties(population1);
163 while (! shall_terminate())
167 printf("\n*** Iteration %d ***\n", iteration);
173 struct individual **swp = population1;
174 population1 = population2;
177 clear_population(population2);
181 if (dbg_evolution >= VERBOSITY_INDIVIDUAL)
183 printf("Penalties before sort\n");
184 dump_penalties(population1);
187 DEBUG(dbg_evolution, VERBOSITY_GENERAL, "Sorting population\n");
188 qsort(population1, conf_pop_size, sizeof(struct individual *), cmp_individual);
190 if (dbg_evolution >= VERBOSITY_GENERAL)
192 printf("Penalties after sort\n");
193 dump_penalties(population1);
196 old_best = population1[0]->penalty;
199 if (dbg_overlaps >= VERBOSITY_GENERAL)
200 dump_bitmaps(population1[0]);
202 plan_individual(population1[0]);
206 static void evolution_compute_sizes(void)
208 breed_pop_size = conf_breed_pop_size * conf_pop_size;
209 breed_rbest_size = conf_breed_rbest * conf_pop_size;
210 if (dbg_evolution >= VERBOSITY_GENERAL)
212 printf("Breeding parameters:\n");
213 printf(" %d individuals are created\n", breed_pop_size);
214 printf(" %d best individuals in old population are considered\n", breed_rbest_size);
217 mutate_pop_size = conf_mutate_pop_size * conf_pop_size;
218 mutate_rbest_size = conf_mutate_rbest * conf_pop_size;
219 if (dbg_evolution >= VERBOSITY_GENERAL)
221 printf("Mutation parameters:\n");
222 printf(" %d individuals are created\n", mutate_pop_size);
223 printf(" %d best individuals in old population are considered\n", mutate_rbest_size);
226 elite_pop_size = conf_elite_pop_size * conf_pop_size;
227 if (dbg_evolution >= VERBOSITY_GENERAL)
229 printf("Elitism parameters:\n");
230 printf(" %d best individuals are copied\n", elite_pop_size);
233 if (breed_pop_size + mutate_pop_size + elite_pop_size != conf_pop_size)
237 elite_pop_size += conf_pop_size - (breed_pop_size + mutate_pop_size + elite_pop_size);
241 fprintf(stderr, "Breeding + mutation + elitism won't create correct number of individuals\n");
242 fprintf(stderr, "Please fix conf_breed_pop_size, conf_mutate_pop_size and conf_elite_pop_size parameters\n");
249 void dump_individual(struct individual *individual)
251 printf("*** Individual dump\n");
252 printf("(There are %d requests)\n", num_requests);
254 for (uns i=0; i<GARY_SIZE(individual->placements); i++)
256 struct placement *p = &(individual->placements[i]);
258 switch (p->request->type)
261 printf("Point at [%.2f; %.2f] on %u\n", p->x, p->y, ((struct request_point *) p->request)->zindex);
264 struct request_line *rl = (struct request_line *) p->request;
266 dump_label(rl->sections[0].segments[0].label);
268 case REQUEST_SECTION: ;
271 case REQUEST_SEGMENT: ;
272 if (p->variant_used >= 0)
273 printf("Segment placed at [%.2f; %.2f] on %u\n", p->x, p->y, ((struct request_segment *) p->request)->zindex);
275 printf("Segment not placed\n");
278 struct request_area *ra = (struct request_area *) p->request;
279 printf("Area label ");
280 dump_label(ra->label);
281 printf(" at [%.2f; %.2f] on %u\n", p->x, p->y, ((struct request_area *) p->request)->zindex);
284 ASSERT(p->request->type != 0);
287 printf("\nTotal penalty: %d\n", individual->penalty);
290 static void plan_individual(struct individual *individual)
292 for (uns i=0; i<GARY_SIZE(individual->placements); i++)
294 struct symbol *s = NULL;
295 z_index_t zindex = 0;
297 if (individual->placements[i].variant_used < 0)
299 printf("Skipping placement of request %d\n", individual->placements[i].request->ind);
302 if (individual->placements[i].variant_used < 0) continue;
303 switch (individual->placements[i].request->type)
305 case REQUEST_POINT: ;
306 struct request_point *rp = (struct request_point *) individual->placements[i].request;
310 case REQUEST_SEGMENT: ;
311 struct request_segment *rs = (struct request_segment *) individual->placements[i].request;
318 struct request_area *ra = (struct request_area *) individual->placements[i].request;
323 ASSERT(individual->placements[i].request != REQUEST_INVALID);
327 DEBUG(dbg_plan, VERBOSITY_PLACEMENT, "Will plan symbol of request %d at [%.2f; %.2f] on %u\n", individual->placements[i].request->ind, individual->placements[i].x, individual->placements[i].y, zindex);
329 if (s) switch (s->type)
331 case SYMBOLIZER_POINT: ;
332 struct sym_point *sp = (struct sym_point *) s;
333 sp->x = individual->placements[i].x;
334 sp->y = individual->placements[i].y;
335 sym_plan((struct symbol *) sp, zindex);
337 case SYMBOLIZER_ICON: ;
338 struct sym_icon *si = (struct sym_icon *) s;
339 si->sir.x = individual->placements[i].x;
340 si->sir.y = individual->placements[i].y;
341 sym_plan((struct symbol *) si, zindex);
343 case SYMBOLIZER_TEXT: ;
344 struct sym_text *st = (struct sym_text *) s;
345 st->x = individual->placements[i].x;
346 st->y = individual->placements[i].y;
347 st->next_duplicate = NULL;
348 DEBUG(dbg_plan, VERBOSITY_PLACEMENT, "Planning text %s at [%.2f; %.2f] on %u, with rotation %.2f\n", osm_val_decode(st->text), st->x, st->y, zindex, st->rotate);
349 sym_plan((struct symbol *) st, zindex);
352 ASSERT(s->type != SYMBOLIZER_INVALID);
357 static void dump_penalties(struct individual **population)
359 for (int i=0; i<conf_pop_size; i++)
361 printf("Individual %d has penalty %d\n", i, population[i]->penalty);
365 static void make_population(void)
367 for (int i=0; i<conf_pop_size; i++)
369 num_placements = 0; // FIXME: This IS a terrible HACK
370 struct individual *i2 = ep_alloc(ep_individuals);
374 DEBUG(dbg_init, VERBOSITY_INDIVIDUAL, "Making individual %d\n", i);
375 struct individual *individual = ep_alloc(ep_individuals); init_individual(individual);
376 population1[i] = individual;
379 for (uns j=0; j<GARY_SIZE(requests_point); j++)
381 init_placement(&(individual->placements[p++]), individual, (struct request *) &requests_point[j]);
384 for (uns j=0; j<GARY_SIZE(requests_line); j++)
386 init_placement(&(individual->placements[p++]), individual, (struct request *) &requests_line[j]);
388 for (uns k=0; k<GARY_SIZE(requests_line[j].sections); k++)
390 init_placement(&(individual->placements[p++]), individual, (struct request *) &requests_line[j].sections[k]);
392 for (uns l=0; l<GARY_SIZE(requests_line[j].sections[k].segments); l++)
394 init_placement(&(individual->placements[p++]), individual, (struct request *) &requests_line[j].sections[k].segments[l]);
399 for (uns j=0; j<GARY_SIZE(requests_area); j++)
401 init_placement(&(individual->placements[p++]), individual, (struct request *) &requests_area[j]);
404 hide_segment_labels(individual);
406 ASSERT(p == num_requests);
410 static bool shall_terminate(void)
412 switch (conf_term_cond)
414 case TERM_COND_PENALTY:
415 return (population1[0]->penalty < conf_penalty_bound);
416 case TERM_COND_STAGNATION:
417 return (abs(old_best - population1[0]->penalty) < conf_stagnation_bound);
418 case TERM_COND_ITERATIONS:
419 return (iteration >= conf_iteration_limit);
421 fprintf(stderr, "Warning: No termination condition is set, terminating\n");
426 static void breed(void)
430 struct individual **breed_buffer;
431 while (i < breed_pop_size)
433 int parent1 = randint(0, breed_rbest_size);
434 int parent2 = randint(0, breed_rbest_size);
435 DEBUG(dbg_breeding, VERBOSITY_INDIVIDUAL, "Will breed %d and %d\n", parent1, parent2);
437 breed_buffer = perform_crossover(population1[parent1], population1[parent2]);
438 population2[pop2_ind++] = breed_buffer[0];
439 population2[pop2_ind++] = breed_buffer[1];
445 static struct individual **perform_crossover(struct individual *parent1, struct individual *parent2)
447 struct individual **buffer = xmalloc(2*sizeof(struct individual));
448 struct individual *child1 = ep_alloc(ep_individuals); init_individual(child1);
449 struct individual *child2 = ep_alloc(ep_individuals); init_individual(child2);
452 GARY_INIT_ZERO(processed, GARY_SIZE(parent1->placements));
454 for (uns i=0; i<GARY_SIZE(parent1->placements); i++)
456 if (! processed[parent1->placements[i].ind])
458 DEBUG(dbg_breeding, VERBOSITY_PLACEMENT, "Creating symbol closure for placement %u\n", i);
460 struct placement **clos_symbols = get_closure(&(parent1->placements[i]), parent2);
461 int x = randint(0, 2);
465 DEBUG(dbg_breeding, VERBOSITY_PLACEMENT, "Copying parent->child 1->1 and 2->2\n");
466 copy_symbols(clos_symbols, parent1, child1, &processed);
467 copy_symbols(clos_symbols, parent2, child2, &processed);
471 DEBUG(dbg_breeding, VERBOSITY_PLACEMENT, "Copying parent->child 2->1 and 1->2\n");
472 copy_symbols(clos_symbols, parent2, child1, &processed);
473 copy_symbols(clos_symbols, parent1, child2, &processed);
476 GARY_FREE(clos_symbols);
480 GARY_FREE(processed);
482 if (conf_mutate_children)
484 if (randdouble() < conf_mutate_children_prob) perform_mutation(child1);
485 else hide_segment_labels(child1);
487 if (randdouble() < conf_mutate_children_prob) perform_mutation(child2);
488 else hide_segment_labels(child2);
496 static void mutate(void)
498 for (int i=0; i < mutate_pop_size; i++)
500 DEBUG(dbg_mutation, VERBOSITY_INDIVIDUAL, "Creating %d-th individual by mutation\n", i);
501 int ind = randint(0, mutate_rbest_size);
502 DEBUG(dbg_mutation, VERBOSITY_INDIVIDUAL, "Mutating %d-th individual of original population\n", ind);
503 population2[pop2_ind] = ep_alloc(ep_individuals);
504 copy_individual(population1[ind], population2[pop2_ind]);
505 DEBUG(dbg_mutation, VERBOSITY_INDIVIDUAL, "Individual %d in pop2 inited from individual %d in pop1\n", pop2_ind, ind);
506 perform_mutation(population2[pop2_ind]);
511 static void perform_mutation(struct individual *individual)
513 for (uns i=0; i<GARY_SIZE(individual->placements); i++)
515 double x = randdouble();
518 if (x <= acc + conf_mutate_move_bound)
520 DEBUG(dbg_mutation, VERBOSITY_PLACEMENT, "Mutation: Moving symbol in placement %u\n", i);
521 move_symbol(&(individual->placements[i]));
524 acc += conf_mutate_move_bound;
526 if (x <= acc + conf_mutate_regen_bound)
528 gen_coords(&(individual->placements[i]));
531 acc += conf_mutate_regen_bound;
533 if (x <= acc + conf_mutate_chvar_bound)
535 struct placement *p = &(individual->placements[i]);
536 switch (p->request->type)
540 // Does nothing when there are 0 variants... does it mind?
541 p->variant_used = randint(-1, GARY_SIZE(p->request->variants));
543 case REQUEST_SEGMENT:
544 p->variant_used = randint(0, GARY_SIZE(p->request->variants));
546 case REQUEST_SECTION:
547 p->variant_used = randint(0, GARY_SIZE(((struct request_section *) p->request)->segments));
555 hide_segment_labels(individual);
558 static void elite(void)
560 for (int i=0; i<elite_pop_size; i++)
562 DEBUG(dbg_evolution, VERBOSITY_INDIVIDUAL, "Iteration %d: Copying individual #%d from pop 1 to #%d in pop 2\n", iteration, i, pop2_ind);
563 population2[pop2_ind] = ep_alloc(ep_individuals);
564 copy_individual(population1[i], population2[pop2_ind++]);
568 static int cmp_individual(const void *a, const void *b)
570 struct individual **ia = (struct individual **) a;
571 struct individual **ib = (struct individual **) b;
573 return (*ia)->penalty - (*ib)->penalty;
576 static void rank_population(void)
580 for (int i=0; i<conf_pop_size; i++)
582 DEBUG(dbg_rank, VERBOSITY_INDIVIDUAL, "Individual %d\n", i);
583 population1[i]->penalty = 0;
585 penalty = conf_rank_omittment_w * individual_omittment(population1[i]);
586 DEBUG(dbg_rank, VERBOSITY_INDIVIDUAL, "Increasing penalty by %d for omittment\n", penalty);
587 population1[i]->penalty += penalty;
589 penalty = conf_rank_overlap_w * individual_overlap(population1[i]);
590 DEBUG(dbg_rank, VERBOSITY_INDIVIDUAL, "Increasing penalty by %d for overlap\n", penalty);
591 population1[i]->penalty += penalty;
593 penalty = conf_rank_distance_w * individual_distances(population1[i]);
594 DEBUG(dbg_rank, VERBOSITY_INDIVIDUAL, "Increasing penalty by %d for distances\n", penalty);
595 population1[i]->penalty += penalty;
599 static void gen_coords(struct placement *p)
601 switch(p->request->type)
609 case REQUEST_SEGMENT:
610 gen_coords_segment(p);
614 printf("Not yet implemented\n");
617 DEBUG(dbg_movement, VERBOSITY_ALL, "Testing request type\n");
618 ASSERT(p->request->type != REQUEST_INVALID);
624 static double gen_movement(void)
626 double m = (random() % 100000) / 10000;
627 m = pow(m, 1.0/3) * flip(1, -1);
628 DEBUG(dbg_movement, VERBOSITY_ALL, "Movement %.2f\n", m);
632 static double gen_movement_uniform(void)
634 return (move_max - move_min) * randdouble() * flip(1, -1);
637 static void gen_coords_point(struct placement *p)
639 p->x = p->x + gen_movement();
642 static void gen_coords_segment(struct placement *p)
644 struct request_segment *rs = (struct request_segment *) p->request;
645 p->x = (rs->x1 + rs->x2) / 2;
646 p->y = (rs->y1 + rs->y2) / 2;
649 static void gen_coords_area(struct placement *p)
651 struct request_area *ra = (struct request_area *) p->request;
653 p->x = p->x + gen_movement();
654 p->y = p->y + gen_movement();
656 DEBUG(dbg_movement, VERBOSITY_PLACEMENT, "Moved label to [%.2f; %.2f] from [%.2f; %.2f]\n", p->x, p->y, ra->cx, ra->cy);
659 static void copy_symbols(struct placement **closure, struct individual *parent, struct individual *child, bool **processed_ptr)
661 bool *processed = *processed_ptr;
662 DEBUG(dbg_breeding, VERBOSITY_ALL, "Will copy %zu symbols\n", GARY_SIZE(closure));
664 for (uns i=0; i<GARY_SIZE(closure); i++)
666 processed[closure[i]->ind] = 1;
667 int ind = closure[i]->ind;
668 child->placements[ind] = parent->placements[ind];
669 child->placements[ind].individual = child;
670 child->placements[ind].processed = 0;
671 child->placements[ind].map_links = NULL;
672 update_map_parts(&child->placements[ind]);
676 static void move_symbol(struct placement *p)
678 switch (p->request->type)
682 move_symbol_point(p);
684 case REQUEST_SEGMENT:
685 move_symbol_segment(p);
688 ASSERT(p->request->type != REQUEST_INVALID);
692 static void move_symbol_point(struct placement *p)
694 p->x += gen_movement_uniform();
695 p->y += gen_movement_uniform();
698 static void move_symbol_segment(struct placement *p)
700 struct request_segment *rs = (struct request_segment *) p->request;
701 double m = gen_movement_uniform();
702 if (fabs(rs->x2 - rs->x1) > 0.01)
705 p->y += m * rs->slope;
713 static void hide_segment_labels(struct individual *individual)
715 // BEWARE: This fully depends on current genetic encoding
717 int used = -1, num = -1;
718 for (uns i=0; i<GARY_SIZE(individual->placements); i++)
720 switch (individual->placements[i].request->type)
722 case REQUEST_SECTION:
723 used = individual->placements[i].variant_used;
726 case REQUEST_SEGMENT:
728 individual->placements[i].variant_used = 0;
730 individual->placements[i].variant_used = -1;
739 static void init_placement(struct placement *p, struct individual *individual, struct request *r)
741 p->ind = num_placements++;
744 p->x = p->y = 0; // To prevent valgrind from complaining
747 p->individual = individual;
750 case REQUEST_POINT: ;
751 struct request_point *rp = (struct request_point *) r;
757 case REQUEST_SECTION: ;
758 struct request_section *rls = (struct request_section *) r;
759 p->variant_used = randint(0, GARY_SIZE(rls->segments));
761 case REQUEST_SEGMENT: ;
762 struct request_segment *rs = (struct request_segment *) r;
767 struct request_area *ra = (struct request_area *) r;
773 ASSERT(p->request->type != REQUEST_INVALID);
777 DEBUG(dbg_init, VERBOSITY_PLACEMENT, "Inited placement to [%.2f; %.2f]\n", p->x, p->y);
780 static void clear_individual(struct individual *individual)
782 for (uns j=0; j<num_map_parts; j++)
784 struct map_placement *mp = individual->map[j]->placement;
787 struct map_placement *tmp = mp;
788 mp = mp->next_in_map;
792 free(individual->map[j]);
795 GARY_FREE(individual->map);
796 GARY_FREE(individual->placements);
797 ep_free(ep_individuals, individual);
800 static void clear_population(struct individual **pop)
802 for (uns i=0; i<GARY_SIZE(pop); i++)
804 clear_individual(pop[i]);
808 static void init_individual(struct individual *individual)
810 GARY_INIT(individual->placements, num_requests);
811 GARY_INIT(individual->map, 0);
812 for (uns j=0; j<num_map_parts; j++)
814 GARY_PUSH(individual->map);
815 struct map_part *part = xmalloc(sizeof(struct map_part));
816 struct map_placement *mp = xmalloc(sizeof(struct map_placement));
817 part->placement = mp;
819 mp->placement = &dummy_placement;
820 mp->next_in_map = mp->prev_in_map = NULL;
821 mp->next_in_placement = mp->prev_in_placement = NULL;
822 individual->map[j] = part;
824 individual->penalty = 0;
827 static void copy_individual(struct individual *src, struct individual *dest)
829 init_individual(dest);
830 dest->penalty = src->penalty;
832 for (uns i=0; i<GARY_SIZE(src->placements); i++)
834 dest->placements[i] = src->placements[i];
835 dest->placements[i].map_links = NULL;
836 dest->placements[i].individual = dest;
838 update_map_parts_create(&dest->placements[i]);
842 static int individual_overlap(struct individual *individual)
847 GARY_INIT_ZERO(planned, GARY_SIZE(individual->placements));
849 for (uns i=0; i<GARY_SIZE(individual->placements); i++)
851 overlap += get_overlap(&individual->placements[i], &planned, i+1);
856 // printf("Total overlap is %d\n", overlap);
861 static double get_distance(struct placement *p)
863 if (p->variant_used < 0) return 0;
864 struct variant *v = &p->request->variants[p->variant_used];
866 double dx, dy, distance;
867 switch (p->request->type)
869 case REQUEST_POINT: ;
870 struct request_point *rp = (struct request_point *) p->request;
871 dx = rp->x + v->offset_x - p->x;
872 dy = rp->y + v->offset_y - p->y;
873 distance = hypot(dx, dy);
874 DEBUG(dbg_rank, VERBOSITY_PLACEMENT, "Point placed at [%.2f; %.2f], expected at [%.2f; %.2f]\n", p->x, p->y, rp->x, rp->y);
876 case REQUEST_SEGMENT: ;
877 struct request_segment *rs = (struct request_segment *) p->request;
878 struct sym_text *st = (struct sym_text *) rs->label;
880 double width = p->request->variants[p->variant_used].width;
881 double rotated_x = p->x + width * sin(convert_to_rad(st->rotate));
882 double rotated_y = p->y + width * cos(convert_to_rad(st->rotate));
891 else if (rotated_x > rs->x2)
893 dx = rotated_x - rs->x2;
894 dy = rotated_y - rs->y2;
908 else if (rotated_x > rs->x1)
910 dx = rotated_x - rs->x1;
911 dy = rotated_y - rs->y1;
919 distance = hypot(dx, dy);
922 struct request_area *ra = (struct request_area *) p->request;
923 dx = ra->cx + v->offset_x - p->x;
924 dy = ra->cy + v->offset_y - p->y;
925 distance = hypot(dx, dy);
926 DEBUG(dbg_rank, VERBOSITY_PLACEMENT, "Area placed at [%.2f; %.2f], expected at [%.2f; %.2f]\n", p->x, p->y, ra->cx, ra->cy);
932 DEBUG(dbg_rank, VERBOSITY_PLACEMENT, "Placement %d has distance %.2f\n", p->ind, distance);
936 static double individual_distances(struct individual *individual)
940 for (uns i=0; i<GARY_SIZE(individual->placements); i++)
942 distances += get_distance(&individual->placements[i]);
948 static double get_omittment(struct placement *p)
950 if (p->variant_used >= 0) return 0;
953 switch (p->request->type)
964 static double individual_omittment(struct individual *individual)
968 for (uns i=0; i<GARY_SIZE(individual->placements); i++)
970 omittment += get_omittment(&individual->placements[i]);