VRPH  1.0
src/VRPGraphics.cpp
Go to the documentation of this file.
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