VRPH
1.0
|
00001 00002 // // 00003 // This file is part of the VRPH software package for // 00004 // generating solutions to vehicle routing problems. // 00005 // VRPH was developed by Chris Groer (cgroer@gmail.com). // 00006 // // 00007 // (c) Copyright 2010 Chris Groer. // 00008 // All Rights Reserved. VRPH is licensed under the // 00009 // Common Public License. See LICENSE file for details. // 00010 // // 00012 00013 #include "VRPH.h" 00014 00015 bool VRP::plot(const char *filename, int options, int orientation) 00016 { 00017 00035 00036 if(!this->can_display) 00037 { 00038 fprintf(stderr,"Unable to display. No coordinates known!\n"); 00039 return false; 00040 } 00041 00042 #ifdef HAS_PLPLOT 00043 00044 PLFLT *x, *y; 00045 int current, i, ctr, rnum; 00046 PLFLT xmin, xmax, ymin, ymax; 00047 int colors[]={VRPH_BLUE,VRPH_RED,VRPH_GREEN,VRPH_CYAN,VRPH_BROWN,VRPH_MAGENTA,VRPH_TURQUOISE,VRPH_VIOLET}; 00048 int num_colors = 8; 00049 00050 rnum = 0; 00051 00052 // Allocate storage 00053 x=new PLFLT [3*num_original_nodes+1]; 00054 y=new PLFLT [3*num_original_nodes+1]; 00055 // Max size would be default CW routes--this should be plenty! 00056 00057 // Rotate 00058 plsori(orientation); 00059 00060 // Set filename 00061 plsfnam(filename); 00062 00063 if(options & VRPH_BLACK_AND_WHITE) 00064 plsdev("ps"); 00065 else 00066 // default 00067 plsdev("psc"); 00068 00069 // Background color-set to white 00070 plscolbg (255,255,255); 00071 00072 // Initialize 00073 plinit(); 00074 00075 // Set to blue for axes and numbers 00076 if(!(options & VRPH_BLACK_AND_WHITE)) 00077 plcol0(VRPH_BLUE); 00078 00079 // Now find the min and max coords 00080 xmin=VRP_INFINITY; 00081 ymin=VRP_INFINITY; 00082 xmax=-VRP_INFINITY; 00083 ymax=-VRP_INFINITY; 00084 00085 for(i=0; i <= this->num_original_nodes; i++) 00086 { 00087 if((PLFLT)nodes[i].x<xmin) 00088 xmin=(PLFLT)nodes[i].x; 00089 if((PLFLT)nodes[i].x>xmax) 00090 xmax=(PLFLT)nodes[i].x; 00091 00092 if((PLFLT)nodes[i].y<ymin) 00093 ymin=(PLFLT)nodes[i].y; 00094 if((PLFLT)nodes[i].y>ymax) 00095 ymax=(PLFLT)nodes[i].y; 00096 } 00097 00098 // Stretch the window by a factor of .05 00099 xmin=xmin-.05*VRPH_ABS(xmax-xmin); 00100 xmax=xmax+.05*VRPH_ABS(xmax-xmin); 00101 00102 ymin=ymin-.05*VRPH_ABS(ymax-ymin); 00103 ymax=ymax+.05*VRPH_ABS(ymax-ymin); 00104 00105 // Create environment 00106 if(options & VRPH_BOXED) 00107 plenv(xmin,xmax,ymin,ymax,2,-1); 00108 else 00109 if(options & VRPH_BARE_BONES) 00110 plenv(xmin,xmax,ymin,ymax,2,-2); 00111 else 00112 // Default 00113 plenv(xmin,xmax,ymin,ymax,2,0); 00114 00115 char dest[VRPH_STRING_SIZE]; 00116 if(has_service_times==false) 00117 sprintf(dest,"%d nodes %7.2f %d routes", num_nodes,total_route_length, 00118 count_num_routes()); 00119 else 00120 sprintf(dest,"%d nodes %7.2f %d routes",num_nodes,total_route_length-total_service_time, 00121 count_num_routes()); 00122 00123 00124 // Add a label 00125 if(!(options & VRPH_NO_TITLE)) 00126 pllab("", "", dest); 00127 00128 // These may need to be modified for some problems... 00129 // Defaults 00130 // Set the symbol size 00131 plssym(0,.5); 00132 // Set the line width 00133 plwid (10); 00134 00135 double symbol_size=0; 00136 // Can roughly base this on num_nodes 00137 if(this->num_nodes<200) 00138 { 00139 // Set the symbol size 00140 plssym(0,.6); 00141 symbol_size=.6; 00142 // Set the line width 00143 plwid (9); 00144 } 00145 00146 if(this->num_nodes>=200 && this->num_nodes<500) 00147 { 00148 // Set the symbol size 00149 plssym(0,.4); 00150 symbol_size=.4; 00151 // Set the line width 00152 plwid (8); 00153 } 00154 00155 if(this->num_nodes>=500) 00156 { 00157 // Set the symbol size 00158 plssym(0,.2); 00159 symbol_size=.2; 00160 // Set the line width 00161 plwid (8); 00162 } 00163 00164 int R; 00165 00166 normalize_route_numbers(); 00167 R= count_num_routes(); 00168 00169 for(i=1;i<=R;i++) 00170 { 00171 // Plot route i 00172 ctr=0; 00173 00174 if(!(options&VRPH_NO_DEPOT_EDGES)) 00175 { 00176 x[ctr]= nodes[VRPH_DEPOT].x; 00177 y[ctr]= nodes[VRPH_DEPOT].y; 00178 ctr++; 00179 } 00180 00181 current= route[i].start; 00182 while(current!=VRPH_DEPOT) 00183 { 00184 x[ctr]= nodes[current].x; 00185 y[ctr]= nodes[current].y; 00186 ctr++; 00187 current= VRPH_MAX(VRPH_DEPOT,next_array[current]); 00188 } 00189 00190 // Close the route at the VRPH_DEPOT 00191 if(!(options&VRPH_NO_DEPOT_EDGES)) 00192 { 00193 x[ctr]= nodes[VRPH_DEPOT].x; 00194 y[ctr]= nodes[VRPH_DEPOT].y; 00195 ctr++; 00196 } 00197 00198 // Set the color 00199 if(!(options & VRPH_BLACK_AND_WHITE)) 00200 plcol0(colors[i % num_colors]); 00201 00202 // Draw the lines 00203 plline(ctr,x,y); 00204 00205 00206 } 00207 00208 // Now draw the points 00209 if(!(options & VRPH_BLACK_AND_WHITE) || options==VRPH_DEFAULT_PLOT) 00210 plcol0(VRPH_BLUE); 00211 int j=0; 00212 double max_ratio=-VRP_INFINITY; 00213 for(i=1;i<=this->num_original_nodes;i++) 00214 { 00215 if(routed[i]) 00216 { 00217 x[j]=this->nodes[i].x; 00218 y[j]=this->nodes[i].y; 00219 // Plot the point 00220 if(!(options & VRPH_NO_POINTS)) 00221 { 00222 if(options & VRPH_WEIGHTED) 00223 plssym( 0, 2*sqrt((double)(this->nodes[i].demand)/(double)(this->max_veh_capacity)) ); 00224 else 00225 plssym( 0, symbol_size ); 00226 00227 if((double)(this->nodes[i].demand)/(double)(this->max_veh_capacity) >max_ratio) 00228 max_ratio=(double)(this->nodes[i].demand)/(double)(this->max_veh_capacity) ; 00229 plpoin(1,x+j,y+j,4); 00230 } 00231 j++; 00232 } 00233 } 00234 00235 j=0; 00236 for(i=1;i<=this->num_original_nodes;i++) 00237 { 00238 if(!(routed[i])) 00239 { 00240 x[j]=this->nodes[i].x; 00241 y[j]=this->nodes[i].y; 00242 plcol0(VRPH_RED); 00243 if(!(options & VRPH_NO_POINTS)) 00244 plpoin(1,x+j,y+j,4); 00245 j++; 00246 } 00247 } 00248 00249 //plcol0(VRPH_RED); 00250 //if(!(options & VRPH_NO_POINTS)) 00251 // plpoin(j,x,y,4); 00252 00253 // Plot the VRPH_DEPOT 00254 plcol0(VRPH_RED); 00255 if(options & VRPH_WEIGHTED) 00256 plssym(0,2); 00257 else 00258 plssym(0,1); 00259 00260 x[0]=nodes[0].x; 00261 y[0]=nodes[0].y; 00262 if(!(options & VRPH_NO_POINTS)) 00263 plpoin(1,x,y,4); 00264 00265 00266 plend(); 00267 00268 delete [] x; 00269 delete [] y; 00270 return true; 00271 00272 #else 00273 00274 report_error("%s: PLPlot not installed\n",__FUNCTION__); 00275 exit(-1); 00276 00277 #endif 00278 00279 } 00280 bool VRP::plot(const char *filename) 00281 { 00285 00286 if(!this->can_display) 00287 { 00288 fprintf(stderr,"Unable to display. No coordinates known!\n"); 00289 return false; 00290 } 00291 #ifdef HAS_PLPLOT 00292 00293 this->plot(filename,VRPH_DEFAULT_PLOT,1); 00294 return true; 00295 #endif 00296 report_error("Must have PLPLOT installed to plot solutions!\n"); 00297 return false; 00298 } 00299 00300 bool VRP::plot_route(int r, const char *filename) 00301 { 00302 00306 00307 if(!this->can_display) 00308 { 00309 fprintf(stderr,"Unable to display. No coordinates known!\n"); 00310 return false; 00311 } 00312 00313 #ifdef HAS_PLPLOT 00314 00315 PLFLT *x, *y; 00316 int current, i, ctr, rnum; 00317 PLFLT xmin, xmax, ymin, ymax; 00318 00319 rnum = 0; 00320 00321 // Allocate storage 00322 x=new PLFLT [3*num_nodes+1]; 00323 y=new PLFLT [3*num_nodes+1]; 00324 // Max size would be default CW routes 00325 00326 // Invert-seems necessary?? 00327 plsori(1); 00328 00329 // Set filename 00330 plsfnam(filename); 00331 00332 // Set format-colored postscript only right now 00333 plsdev("psc"); 00334 //For black and white 00335 //plsdev("ps"); 00336 00337 // Background color-set to white 00338 plscolbg (255,255,255); 00339 00340 // Initialize 00341 plinit(); 00342 00343 // Set to blue for axes and numbers 00344 plcol0(VRPH_BLUE); 00345 00346 00347 // Now find the min and max coords so we can get similar plots 00348 // for different routes 00349 xmin=VRP_INFINITY; 00350 ymin=VRP_INFINITY; 00351 xmax=-VRP_INFINITY; 00352 ymax=-VRP_INFINITY; 00353 00354 for(i=0;i<= num_nodes;i++) 00355 { 00356 if((PLFLT)nodes[i].x<xmin) 00357 xmin=(PLFLT)nodes[i].x; 00358 if((PLFLT)nodes[i].x>xmax) 00359 xmax=(PLFLT)nodes[i].x; 00360 00361 if((PLFLT)nodes[i].y<ymin) 00362 ymin=(PLFLT)nodes[i].y; 00363 if((PLFLT)nodes[i].y>ymax) 00364 ymax=(PLFLT)nodes[i].y; 00365 } 00366 00367 xmin=xmin-.05*VRPH_ABS(xmax-xmin); 00368 xmax=xmax+.05*VRPH_ABS(xmax-xmin); 00369 00370 ymin=ymin-.05*VRPH_ABS(ymax-ymin); 00371 ymax=ymax+.05*VRPH_ABS(ymax-ymin); 00372 00373 00374 // Create environment 00375 // Use this for axes 00376 plenv(xmin,xmax,ymin,ymax,2,0); 00377 00378 // Use this for bare bones 00379 //plenv(xmin,xmax,ymin,ymax,2,-2); 00380 00381 // Use this for bare bones with box 00382 //plenv(xmin,xmax,ymin,ymax,2,-1); 00383 00384 char dest[VRPH_STRING_SIZE]; 00385 sprintf(dest,"Route %d (%7.2f, %d, %d)", r, route[r].length, 00386 route[r].load, route[r].num_customers); 00387 00388 // Add a label 00389 pllab("", "", dest); 00390 00391 00392 // Set the line width 00393 plwid (0); 00394 00395 // Draw the route in red 00396 plcol0(VRPH_RED); 00397 00398 ctr=0; 00399 x[ctr]= nodes[0].x; 00400 y[ctr]= nodes[0].y; 00401 00402 ctr++; 00403 current= route[r].start; 00404 while(current!=VRPH_DEPOT) 00405 { 00406 x[ctr]= nodes[current].x; 00407 y[ctr]= nodes[current].y; 00408 ctr++; 00409 current= VRPH_MAX(VRPH_DEPOT,next_array[current]); 00410 } 00411 00412 // Close the route at the VRPH_DEPOT 00413 x[ctr]= nodes[VRPH_DEPOT].x; 00414 y[ctr]= nodes[VRPH_DEPOT].y; 00415 ctr++; 00416 00417 // Draw the lines 00418 plline(ctr,x,y); 00419 00420 // Plot the VRPH_DEPOT 00421 plcol0(VRPH_BLUE); 00422 plssym(1,5); 00423 x[0]=nodes[0].x; 00424 y[0]=nodes[0].y; 00425 plpoin(1,x,y,0); 00426 00427 // Plot all the other points 00428 plssym(2,1); 00429 for(i=1;i<=this->num_nodes;i++) 00430 { 00431 x[i-1]=this->nodes[i].x; 00432 y[i-1]=this->nodes[i].y; 00433 00434 } 00435 plpoin(this->num_nodes,x,y,4); 00436 00437 plend(); 00438 00439 delete [] x; 00440 delete [] y; 00441 00442 return true; 00443 00444 #else 00445 00446 report_error("%s: PLPlot not installed\n"); 00447 exit(-1); 00448 00449 #endif 00450 00451 } 00452