Beispiel #1
0
int main(int argc, char *argv[])
{
    ///
    /// This is the main() routine that demonstrates how to import solutions and 
    /// plot them.
    ///

    VRPH_version();

    char in[VRPH_STRING_SIZE], plotfile[VRPH_STRING_SIZE],pdffile[VRPH_STRING_SIZE],
     solfile[VRPH_STRING_SIZE];
    
    int i,n;
    int orientation=1;
    bool do_pdf=false;

    // Usage: vrp_plotter -f <vrp_file> -s <sol_file> -p <plot_file>
    if(argc<7 )
    {        
        fprintf(stderr,"Usage: %s -f <vrp_file> -s <sol_file> -p <plot_file> [-e -w -r]\n",argv[0]);
        fprintf(stderr,"\t <plot_file> must be .ps format\n");
        fprintf(stderr,"\t .pdf format requires the epstopdf executable\n");
        fprintf(stderr,"\t -pdf <pdf_file> will also create a .pdf image of the solution\n");
        fprintf(stderr,"\t -e will not show the depot edges\n");
        fprintf(stderr,"\t -w will weight the size of the non-depot nodes by their demand\n");
        fprintf(stderr,"\t -o will rotate 90 degrees\n");
        exit(-1);
    }


    int options=VRPH_DEFAULT_PLOT;

    bool has_filename=false;
    for(i=1;i<argc;i++)
    {
        if(strcmp(argv[i],"-f")==0)
        {
            // Get the input file name
            has_filename=true;
            strcpy(in,argv[i+1]);            
        }

        if(strcmp(argv[i],"-s")==0)
        {
            // Get the solution file name
            strcpy(solfile,argv[i+1]);            
        }
        
        if(strcmp(argv[i],"-p")==0)
        {
            // Get the plot file name
            strcpy(plotfile,argv[i+1]);
            
        }

        if(strcmp(argv[i],"-pdf")==0)
        {
            do_pdf=true;
            strncpy(pdffile,argv[i+1],strlen(argv[i+1]));
            pdffile[strlen(argv[i+1])]='\0';
        }

        if(strcmp(argv[i],"-e")==0)
            options+=VRPH_NO_DEPOT_EDGES;

        if(strcmp(argv[i],"-w")==0)
            options+=VRPH_WEIGHTED;     

        if(strcmp(argv[i],"-r")==0)
        {
            // Get the plot file name
            orientation=0;
            
        }
        
    }

    if(!has_filename)
        report_error("No file name given!\n");

    n=VRPGetDimension(in);
    VRP V(n);

    // Load the problem data
    V.read_TSPLIB_file(in);    

    printf("Imported instance\n");

    V.read_solution_file(solfile);
    int *sol;
    sol=new int[V.get_num_nodes()+2];
    V.export_canonical_solution_buff(sol);
    V.import_solution_buff(sol);
    printf("Imported solution\n");

    // Show the solution to stdout
    V.summary();

    printf("Plotfile is %s\n",plotfile);
    V.plot(plotfile,options,orientation);

    if(do_pdf)
    {
        // Create a .pdf file
        char command[VRPH_STRING_SIZE];
        sprintf(command,"%s %s --outfile=%s\n",VRPH_EPS_EXE,plotfile,pdffile);
        system(command);
    }

    delete [] sol;

    return 0;

}
Beispiel #2
0
int main(int argc, char **argv)
{
#if USE_VRPH
   // A few things required by VRPH
   int i;
   double best_sol=VRP_INFINITY;
   int best_sol_buff[500];
#endif

   vrp_problem *vrp;

   sym_environment *env = sym_open_environment();

   version();

   sym_parse_command_line(env, argc, argv);

   sym_get_user_data(env, (void**)&vrp);
   
#if USE_VRPH
   // Get the size of the problem in the input file
   int n=VRPGetDimension(vrp->par.infile);
   // Declare a VRP object of size n
   VRP V(n);
   // Declare a ClarkeWright object of size n
   ClarkeWright CW(n);
 
   // Populate the VRP object with the input file
   V.read_TSPLIB_file(vrp->par.infile);

   // Now create NUM_VRPH_SOLUTIONS solutions using VRPH and set the
   // upper bound to the best solution discovered
   for(i=0;i<NUM_VRPH_SOLUTIONS;i++)
   {
       // Create default routes - each customer on its own route
       V.create_default_routes();
       // Create a new random feasible solution with Clarke Wright
       CW.Construct(&V, .5+ lcgrand(1),false);
       // Improve it with the RTR heuristic
       V.RTR_solve(ONE_POINT_MOVE+TWO_POINT_MOVE+TWO_OPT+THREE_OPT,
           30,5,1,.01,25,VRPH_LI_PERTURB,VRPH_BEST_ACCEPT,false);
       if(V.get_total_route_length()-V.get_total_service_time()<best_sol)
       {
           best_sol=V.get_total_route_length()-V.get_total_service_time();
           V.export_canonical_solution_buff(best_sol_buff);
       }                     
       // Reset VRPH's internal data structures
       V.reset();
   }
   
   // Import the best solution and display it - if SYMPHONY claims an infeasibility
   // because the VRPH solution is optimal, we wouldn't see it otherwise!
   printf("VRPH set SYMPHONY upper bound to %f based on solution:\n",best_sol);
   V.import_solution_buff(best_sol_buff);
   V.summary();

   // Set the upper bound using VRPH solution by accessing SYMPHONY's
   // internal data structures
   env->has_ub=1;
   env->ub=best_sol ;
#if 0
   // Note that this might be incorrect if the VRPH solution is not optimal
   // So the # of trucks still needs to be passed in on the command line!
   vrp->numroutes=V.get_total_number_of_routes();
#endif
#endif

   // Now just let SYMPHONY do its thing.  If an infeasibility is encountered,
   // then this certifies that the solution found by VRPH is indeed optimal
   // Note that the par.test will not work as we have processed only a single
   // file.  Thus, we changed the following line
   // if (vrp->par.test){
   if (0 && vrp->par.test){
 
     vrp_test(env, argc, argv);

   } else {

     sym_load_problem(env);
     
     sym_find_initial_bounds(env);
     
     sym_set_str_param(env, "lp_executable_name", "vrp_lp_cg");
     sym_set_str_param(env, "cp_executable_name", "vrp_cp");
     sym_set_int_param(env, "generate_cgl_cuts", FALSE);

     sym_solve(env);

   }

   sym_close_environment(env);
     
   return(0);
}
Beispiel #3
0
int main(int argc, char **argv)
{
    VRPH_version();

    int i, j, k, n, status, num_attempts, *sol_buff, *IP_sol_buff;
    char in_file[200];
    double lambda, best_heur_sol=VRP_INFINITY;
    bool first_sol=false, bootstrap=false;;
    VRPSolution *fresh_solution;
    OsiSolverInterface *si;
    const double *x;
    int last_num_cols=0, route_id=0;
    time_t start, stop;
    int *orderings[MAX_ROUTES];
    for(i=0;i<MAX_ROUTES;i++)
        orderings[i]=NULL;
    

    // Set timing counters to 0
    heur_time=mip_time=0;

    // Check arguments
    if(argc<5)
    {
        fprintf(stderr,"Usage: %s -f input_file -n num_runs [-v,-b,-c max_columns -d cols_to_delete]\n",
            argv[0]);
        fprintf(stderr,"\t Will solve the problem num_solutions times and add the routes\n");
        fprintf(stderr,"\t to a set partitioning problem.\n");
        fprintf(stderr,"\t Other options:\n");
        fprintf(stderr,"\t -v runs in verbose mode\n");
        fprintf(stderr,"\t -b will use bootstrapping where we send the set partitioning\n"
                       "\t    solution back to the metaheuristic solver\n");
        fprintf(stderr,"\t -c max_columns will allow this many active columns/variables in the IP.\n");
        fprintf(stderr,"\t    Default value is max_columns=500\n");
        fprintf(stderr,"\t -d num_cols_to_delete will delete this many columns once we have too many\n");
        fprintf(stderr,"\t    in the IP. Default value is num_cols_to_delete=100\n");
        exit(-1);
    }

    // Set defaults
    verbose=false;
    max_columns=500;
    num_cols_to_delete=100;

    // Parse command line
    for(i=0;i<argc;i++)
    {
        if(strcmp(argv[i],"-f")==0)
            strcpy(in_file,argv[i+1]);
        if(strcmp(argv[i],"-n")==0)
            num_attempts=atoi(argv[i+1]);
        if(strcmp(argv[i],"-v")==0)
            verbose=true;
         if(strcmp(argv[i],"-b")==0)
            bootstrap=true;
         if(strcmp(argv[i],"-c")==0)
             max_columns=atoi(argv[i+1]);
         if(strcmp(argv[i],"-d")==0)
             num_cols_to_delete=atoi(argv[i+1]);
    }

    // This is the # of non-VRPH_DEPOT nodes
    n=VRPGetDimension(in_file);
    // This will be used to import/export solutions
    fresh_solution = new VRPSolution(n);
    // Create buffers for importing solutions
    sol_buff= new int[n+2];
    IP_sol_buff = new int[n+2];

    // Declare an OSI interface
    si=new OsiGlpkSolverInterface;
    si->setIntParam(OsiNameDiscipline,2);

    for(i=0;i<n;i++)
    {
        si->addRow(0,NULL,NULL,1,1);
    }

    // Declare a VRP of the right size and import the file
    VRP V(n);
    ClarkeWright CW(n);
    VRPRoute route(n);
    V.read_TSPLIB_file(in_file);
    // Set up a "route warehouse" to store the routes to be added to the IP
    V.route_wh=new VRPRouteWarehouse(HASH_TABLE_SIZE);
  
    // Set up a minimization problem
    si->setObjSense(1);
    // Set to error only output
    si->setHintParam(OsiDoReducePrint,true, OsiHintDo);
    // Unfortunately GLPK still prints out something regarding the conflict graph

    for(i=0;i<num_attempts;i++)
    {
        if(i==0 || !bootstrap) 
        {
            lambda=.5+1.5*lcgrand(0);
            // Start with a clean VRP object
            V.reset();
            CW.Construct(&V, lambda, false);
            if(verbose)
                printf("CW solution %d[%5.3f]: %f\n",i,lambda,V.get_total_route_length()-V.get_total_service_time());
        }
        else
            // Use the solution from the IP
            V.import_solution_buff(IP_sol_buff);
        
        // Run VRPH's RTR algorithm to improve the solution
        start=clock();
        V.RTR_solve(ONE_POINT_MOVE | TWO_POINT_MOVE | TWO_OPT | VRPH_USE_NEIGHBOR_LIST,
            30, 5, 2, .01, 30, VRPH_LI_PERTURB, VRPH_FIRST_ACCEPT,false);
        stop=clock();
        heur_time += (stop-start);

        if(verbose)
            printf("RTR Metaheuristic found solution %5.3f\n",V.get_total_route_length()-V.get_total_service_time());
        
        // The RTR algorithm keeps a "warehouse" of the best solutions discovered during
        // the algorithm's search
        // Now go through the solutions in the solution warehouse and add the new routes
        // discovered to the IP
        for(j=0;j<V.solution_wh->num_sols;j++)
        {
            // Import solution j from the warehouse 
            V.import_solution_buff(V.solution_wh->sols[j].sol);
                
            if(V.get_total_route_length()-V.get_total_service_time() < best_heur_sol)
                best_heur_sol = V.get_total_route_length()-V.get_total_service_time() ;

            // Now add the routes from this solution to the IP
            for(k=1;k<=V.get_total_number_of_routes();k++)
            {
                // Clean up the route by running INTRA_ROUTE optimizations only
                // using the route_search method of the different local search
                // heuristics, accepting improving moves only (VRPH_DOWNHILL)
                OnePointMove OPM;
                TwoOpt TO;
                ThreeOpt ThO;
                while(OPM.route_search(&V,k,k,VRPH_DOWNHILL|VRPH_INTRA_ROUTE_ONLY )){}
                while(TO.route_search(&V,k,k,VRPH_DOWNHILL|VRPH_INTRA_ROUTE_ONLY  )){};
                while(ThO.route_search(&V,k,VRPH_DOWNHILL|VRPH_INTRA_ROUTE_ONLY )){};

                // Copy route k from the solution to the VRPRoute R
                V.update_route(k,&route);
                route.create_name();
                // Add it to the "route warehouse" - this uses a hash table to keep track
                // of duplicate columns
                status=V.route_wh->add_route(&route);

                if(status!=DUPLICATE_ROUTE)
                {
                    // This route is not currently in the WH and so it cannot be in the
                    // set partitioning problem
                    //OSI_add_route(si,&V,&route);
                    OSI_add_route(si,&V,&route,route_id,orderings);
                    route_id++;
                }
            }
            
            // Set the row RHS's if we need to
            if(first_sol)
            {
                first_sol=false;
                for(int rownum=0;rownum<n;rownum++)
                    si->setRowBounds(rownum,1,1);
                // Note that changing this to >= would be a set covering problem
                // where each customer can be visited by more than one route
            }
        }

        // Now erase all the solutions from the WH
        V.solution_wh->liquidate();

        if(verbose)
        {
            printf("Attempt %02d:  Solving IP with %d columns\n",i,si->getNumCols());
            printf("%d routes in the WH\n",V.route_wh->num_unique_routes);
        }

        // Solve the current set partitioning problem using the MIP solver
        start=clock();
        si->branchAndBound();
        stop=clock();
        mip_time += (stop-start);

        double opt=si->getObjValue();
        x=si->getColSolution();
        last_num_cols=si->getNumCols();
        if(verbose)
            printf("Optimal solution (%d columns) is %f\n",last_num_cols,opt);

        
        // Now recover the solution from the IP solution
        OSI_recover_solution(si, orderings, IP_sol_buff);
       
        if(verbose)
            printf("IP solution has obj. function value: %5.2f\n"
            "Best heuristic  obj. function value: %5.2f\n",
            si->getObjValue(),best_heur_sol);     
    }

    if(verbose)
        printf(
        "\nResults\n"
        "--------\n"
        "After %d runs\n"
        "IP solution has obj. function value: %5.2f\n"
        "Best heuristic  obj. function value: %5.2f\n",
        num_attempts,si->getObjValue(),best_heur_sol);

    // print to stderr since GLPK prints "conflict graph" to stdout (a known bug...)
    // best_heur_sol best_mip_sol heur_time mip_time
    fprintf(stderr,"%5.3f %5.3f %5.3f %5.3f\n", best_heur_sol, si->getObjValue(),
        (double)(heur_time)/CLOCKS_PER_SEC, (double)(mip_time)/CLOCKS_PER_SEC);

    delete V.route_wh;
    delete fresh_solution;
    delete [] sol_buff;
    delete [] IP_sol_buff;
    delete si;

    for(i=0;i<MAX_ROUTES;i++)
        if(orderings[i])
            delete [] orderings[i];

     
    return 0;
}