/**********************************************************************/ /* */ /* (c) Copyright, 1997 by Professor Gabriel Robins */ /* */ /* Department of Computer Science, University of Virginia */ /* Charlottesville, VA 22903-2442 (804) 982-2207 */ /* robins@cs.virginia.edu http://www.cs.virginia.edu/~robins/ */ /* */ /* This code may be freely used for all non-commercial purposes. */ /* All copies/portions of this code must contain this header. */ /* */ /**********************************************************************/ /**********************************************************************/ /* Calculations.c */ /**********************************************************************/ #include "geometry.h" /**********************************************************************/ /*char *errorstrings[] = { "***** Error: Storage allocation for %s\n", "***** Error: Cannot open file %s\n", };*/ extern void generate_steiner5(void); extern void error(enum errors, char *); void generate_random_points(); void print_separator(); void do_randomize(); void multi_loop_stats(void) { int i, j, old_gridsize, old_nop; old_gridsize = grid_size; old_nop = number_of_points; for(i=3;i<=50;i++) { for(j=0;j<9;j++) { number_of_points = i; grid_size = grid_sizes[j]; loop_stats(); } print_separator(); } grid_size = old_gridsize; number_of_points = old_nop; } /**********************************************************************/ void loop_stats(void) { int i, span_cost, stei_cost, mst_total, steiner_total; float total_perf; /*printf("Seed = %u\n", (int) next); fflush(stdout);*/ mst_total = steiner_total = 0; total_perf = 0.0; for(i=0; i< number_of_iterations;i++) { erase_window(); if(choice !=2) do_randomize(); generate_MST3(number_of_points); /* getchar();*/ span_cost = mst_cost; mst_total = mst_total + span_cost; generate_steiner5(); getchar(); stei_cost = mst_cost; /*steiner_cost[4];*/ steiner_total = steiner_total + stei_cost; total_perf = total_perf + (float)(span_cost-stei_cost)/(float)span_cost; } } /**********************************************************************/ int max(int i, int j) { if (i > j) return(i); else return(j); } int min(int i, int j) { if (i < j) return(i); else return(j); } double fmax(double i, double j) { if (i > j) return(i); else return(j); } double fmin(double i, double j) { if (i < j) return(i); else return(j); } int sig(int i){ if (i>0) return(1); else if (i<0) return(-1); else return(0); } /*********************************************************************/ int generate_unique_identifier(void) { return(unique_identifier++); } /**********************************************************************/ void draw_left_half_L(struct point p1, struct point p2, int thickness) { struct point p3, p4; p3.X = min(p1.X, p2.X); p3.Y = min(p1.Y, p2.Y); p4.X = min(p1.X, p2.X); p4.Y = max(p1.Y, p2.Y); draw_line(p3, p4, thickness); } void draw_right_half_L(struct point p1, struct point p2, int thickness) { struct point p3, p4; p3.X = max(p1.X, p2.X); p3.Y = min(p1.Y, p2.Y); p4.X = max(p1.X, p2.X); p4.Y = max(p1.Y, p2.Y); draw_line(p3, p4, thickness); } void draw_top_half_L(struct point p1, struct point p2, int thickness) { struct point p3, p4; p3.X = min(p1.X, p2.X); p3.Y = max(p1.Y, p2.Y); p4.X = max(p1.X, p2.X); p4.Y = max(p1.Y, p2.Y); draw_line(p3, p4, thickness); } void draw_bottom_half_L(struct point p1, struct point p2, int thickness) { struct point p3, p4; p3.X = min(p1.X, p2.X); p3.Y = min(p1.Y, p2.Y); p4.X = max(p1.X, p2.X); p4.Y = min(p1.Y, p2.Y); draw_line(p3, p4, thickness); } /**********************************************************************/ void draw_rectilinear_edge(struct point p1, struct point p2, int thickness, int L_orientation) { /*#ifdef MAC*/ int rnd_orientation[4] = { high_L, low_L, left_L, right_L }; switch (L_orientation) { case left_L: draw_left_half_L(p1, p2, thickness); if( sig(p1.X - p2.X) == sig(p1.Y - p2.Y) ) draw_top_half_L(p1, p2, thickness); else draw_bottom_half_L(p1, p2, thickness); break; case right_L: draw_right_half_L(p1, p2, thickness); if( sig(p1.X - p2.X) == sig(p1.Y - p2.Y) ) draw_bottom_half_L(p1, p2, thickness); else draw_top_half_L(p1, p2, thickness); break; case low_L: draw_bottom_half_L(p1, p2, thickness); if( sig(p1.X - p2.X) == sig(p1.Y - p2.Y) ) draw_right_half_L(p1, p2, thickness); else draw_left_half_L(p1, p2, thickness); break; case high_L: draw_top_half_L(p1, p2, thickness); if( sig(p1.X - p2.X) == sig(p1.Y - p2.Y) ) draw_left_half_L(p1, p2, thickness); else draw_right_half_L(p1, p2, thickness); break; case random_L: draw_rectilinear_edge(p1, p2, thickness, rnd_orientation[random(0,3)]); break; } /*#endif*/ } /**********************************************************************/ void draw_edge(struct point p1, struct point p2, int thickness) { /*#ifdef MAC*/ switch (metric_type) { case Euclidean : draw_line(p1,p2,thickness); break; case Manhattan: draw_rectilinear_edge(p1, p2, thickness, L_edge_orientation); break; case Linfinity: draw_rectilinear_edge(p1, p2, thickness, L_edge_orientation); break; } /*#endif*/ } /**********************************************************************/ void draw_points(void) { /*#ifdef MAC*/ int i; for(i=0;i= right) return; if(left>= (right-5)) { for(i=left; i < right; i++) { smallest_dist = edges[i].weight; smallest_edge = i; for(j=i + 1; j <= right; j++) { if(edges[j].weight < smallest_dist) { smallest_dist = edges[j].weight; smallest_edge = j; } } tmp = edges[i]; edges[i] = edges[smallest_edge]; edges[smallest_edge] = tmp; } return; } mid = (left + right) / 2; tmp = edges[left]; edges[left] = edges[mid]; edges[mid] = tmp; last = left; for(i=left+1; i <= right; i++) if (edges[i].weight < edges[left].weight) { last++; tmp = edges[last]; edges[last] = edges[i]; edges[i] = tmp; } tmp = edges[last]; edges[last] = edges[left]; edges[left] = tmp; qsort_edges(left, last - 1); qsort_edges(last + 1, right); } /**********************************************************************/ void draw_edges(void) { /*#ifdef MAC*/ int j; for(j=0;j