/home/coin/SVN-release/OS-2.1.1/OS/examples/branchCutPriceTSP/LP/OS_lp.cpp

Go to the documentation of this file.
00001 // Last edit: 6/23/06
00002 //
00003 // Name:     OS_lp.cpp
00004 // Author:   Francois Margot
00005 //           Tepper School of Business
00006 //           Carnegie Mellon University, Pittsburgh, PA 15213
00007 //           email: fmargot@andrew.cmu.edu
00008 // Date:     12/28/03
00009 //-----------------------------------------------------------------------------
00010 // Copyright (C) 2003, Francois Margot, International Business Machines
00011 // Corporation and others.  All Rights Reserved.
00012 
00013 #undef HEUR_SOL
00014 
00015 #include <vector>
00016 
00017 #include "OS_lp.hpp"
00018 #include "OS_cut.hpp"
00019 #include "OS_var.hpp"
00020 #include "OsiClpSolverInterface.hpp"
00021 #include "CglSimpleRounding.hpp"
00022 #include "CglKnapsackCover.hpp"
00023 #include "CglGomory.hpp"
00024 
00025 #include "BCP_math.hpp"
00026 #include "BCP_lp.hpp"
00027 #include "BCP_problem_core.hpp"
00028 #include "BCP_lp_param.hpp"
00029 
00030 #include <map>
00031 #include "OSConfig.h" 
00032 #include "OSInstance.h"
00033 #include "OSiLWriter.h"
00034 #include "OSParameters.h"
00035 #include "OSnLNode.h"
00036 #include "OSErrorClass.h"
00037 #include "OSCoinSolver.h"
00038 #include "OSrLReader.h" 
00039 #include <iostream>
00040 #include <fstream>
00041 #include <string>
00042 
00043 
00044 
00045 int locs;
00046 int routes;
00047 int hubloc; 
00048 //int rootnde = 0;
00049 
00050 
00051 
00052 using namespace std;
00053 /************************************************************************/ 
00054 
00055 void OS_lp::unpack_module_data(BCP_buffer& buf) {
00056   buf.unpack( os_prob);
00057   EPS = os_prob->EPSILON;
00064   // just a simple test
00065   
00066   std::cout << "number of variables " << os_prob->osinstance->getVariableNumber() << std::endl;
00067   
00068 
00069   
00070 }
00071 
00072 
00073 
00074 /************************************************************************/
00075 OsiSolverInterface * OS_lp::initialize_solver_interface(){
00076 
00077         OsiClpSolverInterface * clp = new OsiClpSolverInterface;
00078         clp->messageHandler()->setLogLevel(0);
00079         return clp;
00080 }
00081 
00082 /************************************************************************/
00083 void OS_lp::initialize_new_search_tree_node(const BCP_vec<BCP_var*>& vars,
00084                                        const BCP_vec<BCP_cut*>& cuts,
00085                                        const BCP_vec<BCP_obj_status>& vstatus,
00086                                        const BCP_vec<BCP_obj_status>& cstatus,
00087                                        BCP_vec<int>& var_changed_pos,
00088                                        BCP_vec<double>& var_new_bd,
00089                                        BCP_vec<int>& cut_changed_pos,
00090                                        BCP_vec<double>& cut_new_bd)
00091 
00092   // Called at the beginning of the optimization of a node. 
00093   // The node LP is not yet solved.
00094 
00095 {
00096 
00097   in_strong = 0;
00098   
00099         //BCP_lp_param.hpp for a list of parameters
00100         //lets get a parameter -- should be true by default
00101         bool relSol = BCP_lp_user::get_param(BCP_lp_par::LpVerb_RelaxedSolution) ;
00102         std::cout  << relSol << std::endl;
00103         
00104         // now reset the value
00105         if(relSol == true){
00106                 BCP_lp_user::set_param( BCP_lp_par::LpVerb_RelaxedSolution, false);
00107         }else{
00108                 BCP_lp_user::set_param( BCP_lp_par::LpVerb_RelaxedSolution, true);
00109         }
00110          
00111         // see if it got reset
00112         relSol = BCP_lp_user::get_param(BCP_lp_par::LpVerb_RelaxedSolution) ;
00113         std::cout  <<  relSol << std::endl;
00114         
00115 
00116         //set another way
00117         //keep all constraints
00118         this->getLpProblemPointer()->par.set_entry(BCP_lp_par::IneffectiveConstraints, 0);
00119         // number of cuts to keep in the pool
00120         this->getLpProblemPointer()->par.set_entry(BCP_lp_par::IneffectiveBeforeDelete, 10000); 
00121         
00122         // turn off strong branching
00123         this->getLpProblemPointer()->par.set_entry(BCP_lp_par::MaxPresolveIter, -1);
00124         
00125 
00126 #ifdef USER_DATA
00127   MY_user_data *curr_ud = dynamic_cast<MY_user_data*> (get_user_data());
00128   curr_ud->is_processed = 1;
00129 #endif
00130 
00131 }
00132 
00133 /************************************************************************/
00134 void OS_lp::modify_lp_parameters(OsiSolverInterface* lp, bool in_strong_branching){
00135 
00136   // Called each time the node LP is solved
00137         
00138         
00139         /****
00140          * 
00141          *  BCP_lp_param.hpp for param doc. 
00142          *  BCP_lp_param.cpp for default values.
00143          *  to change a param in your user class: getLpProblemPointer()->par.set_entry(LpVerb_RelaxedSolution, false);
00144          *  to change a param in bb.par:  BCP_LpVerb_RelaxedSolution 0
00145          * 
00146          */
00147         
00148         
00149 
00150   // if (in_strong_branching) {
00151   //   in_strong = 1;
00152   //   lp->setIntParam(OsiMaxNumIterationHotStart, 50);
00153   // }
00154 
00155    // write the current LP in file lpnode.lp
00156    //lp->writeLp("lpnode", "lp");
00157    //cout << "LP node written in file lpnode.lp" << endl;
00158 
00159    // to write the current LP file in file lpnode.mps use the following:
00160    // lp->writeMps("lpnode", "mps", 0.0);
00161    // cout << "LP node written in file lpnode.mps" << endl;
00162 
00163 }
00164 
00165 
00166 
00167 /************************************************************************/
00168 BCP_solution* OS_lp::generate_heuristic_solution(const BCP_lp_result& lpres,
00169                             const BCP_vec<BCP_var*>& vars,
00170                             const BCP_vec<BCP_cut*>& cuts)  {
00171         //not implemented
00172         return NULL;
00173 }
00174 
00175 
00176 /********************************************************************/
00177 BCP_branching_decision OS_lp::select_branching_candidates(const BCP_lp_result& lpres,
00178                                  const BCP_vec<BCP_var*>& vars,
00179                                    const BCP_vec<BCP_cut*>& cuts,
00180                                    const BCP_lp_var_pool& local_var_pool,
00181                                    const BCP_lp_cut_pool& local_cut_pool,
00182                                    BCP_vec<BCP_lp_branching_object*>& cands,
00183                                    bool force_branch) {
00184         
00185         
00186           // Called at the end of each iteration. Possible return values are:
00187           // BCP_DoNotBranch_Fathomed : The node should be fathomed without branching
00188           // BCP_DoNotBranch :          BCP should continue to work on this node
00189           // BCP_DoBranch :             Branching must be done. In this case the 
00190           //                            method returns the branching object candidates 
00191           //                            in one of the arguments 
00192 
00193     
00194         std::cout << "INSIDE BRANCHING DECISION: TESTING VARIABLE TYPES " << std::endl;
00195         std::cout << "SIZE OF CUTS  =  " <<  cuts.size()  << std::endl;
00196         std::cout << "SIZE OF LOCAL CUTS POOL  =  " << local_cut_pool.size()   << std::endl;
00197 
00198         // Don't branch if cutting planes have been generated
00199         if( local_cut_pool.size() > 0 ) {
00200                 
00201                 cout << "select_branching_candidates() returns BCP_DoNotBranch"  << endl;
00202                 return(BCP_DoNotBranch);
00203 
00204         }else{
00205                 os_prob->haveBranched = true;
00206                 if  ( isIntSolution(lpres.x(),  vars,  BCP_lp_user::get_param(BCP_lp_par::IntegerTolerance)) == true) return BCP_DoNotBranch_Fathomed;
00207                 return BCP_lp_user::select_branching_candidates( lpres,
00208         vars, cuts, local_var_pool, local_cut_pool,
00209          cands, force_branch);
00210         }
00211 }// end OS_lp::select_branching_candidates
00212 
00213 
00214 /**************************************************************************/
00215 void OS_lp::set_user_data_for_children(BCP_presolved_lp_brobj* best, 
00216                                   const int selected)
00217 
00218   // Given the branching decision (parameter "best"; "selected" is the
00219   // index of the chosen branching decision in the candidate list), 
00220   // set the user data for the children.
00221 
00222 {
00223 #ifdef USER_DATA
00224   BCP_lp_branching_object *cand = best->candidate();
00225   MY_user_data *curr_ud = dynamic_cast<MY_user_data*> (get_user_data());
00226   real_user_data *curr_rud = curr_ud->p_rud;
00227 
00228   for(int i=0; i<cand->child_num; i++) {
00229     MY_user_data *ud = new MY_user_data(curr_rud->max_card_set_zero);
00230     real_user_data *rud = ud->p_rud;
00231 
00232     rud->card_set_zero = curr_rud->card_set_zero;
00233 
00234     for(int j=0; j<curr_rud->card_set_zero; j++) {
00235       rud->set_zero[j] = curr_rud->set_zero[j];
00236     }
00237 
00238     int ind_br = (*(cand->forced_var_pos))[0];
00239 
00240     if((*(cand->forced_var_bd))[2*i + 1] < EPS) {
00241       rud->set_zero[curr_rud->card_set_zero] = ind_br;
00242       (rud->card_set_zero)++;
00243     }
00244     best->user_data()[i] = ud;
00245   }
00246 #endif /* USER_DATA */
00247 } /* set_user_data_for_children */
00248 
00249 
00250 
00251 
00252 
00253 /************************************************************************/
00254 
00255 
00256 void  OS_lp::cuts_to_rows(const BCP_vec<BCP_var*>& vars, // on what to expand
00257                     BCP_vec<BCP_cut*>& cuts,       // what to expand
00258                     BCP_vec<BCP_row*>& rows,       // the expanded rows
00259                     // things that the user can use for lifting cuts if allowed
00260                     const BCP_lp_result& lpres,
00261                     BCP_object_origin origin, bool allow_multiple) {
00262 
00263     //return;
00264   // Required function when indexed or algorithmic cuts are used.
00265   // Describes how to get a row of the matrix from the representation of the
00266   // cut.
00267 
00268         std::cout << "Execute cuts_to_rows" << std::endl;
00269         std::cout << "CUTS SIZE = " << cuts.size() << std::endl;
00270         std::cout << "ROWS SIZE = " << rows.size() << std::endl;
00271         const int cutnum = cuts.size();
00272         for (int i=0; i<cutnum; ++i) {
00273                 const OsiRowCut* bcut = dynamic_cast<const OS_cut*>(cuts[i]);
00274                 if (bcut) {
00275     
00276                         rows.push_back(new BCP_row(bcut->row(), bcut->lb(), bcut->ub()));
00277                         continue;
00278                 }
00279                 throw BCP_fatal_error("Unknown cut type in cuts_to_rows.\n");
00280         }
00281 }
00282 
00283 /************************************************************************/
00284 
00285 void OS_lp::vars_to_cols(const BCP_vec<BCP_cut*>& cuts,
00286                      BCP_vec<BCP_var*>& vars,
00287                      BCP_vec<BCP_col*>& cols,
00288                      const BCP_lp_result& lpres,
00289                      BCP_object_origin origin, bool allow_multiple)
00290 {
00291 
00292         std::cout << "EXECUTE vars_to_cols  **************" << std::endl;
00293     static const CoinPackedVector emptyVector(false);
00294     const int numvars = vars.size();
00295     int i;
00296     for (i = 0; i < numvars; ++i) {
00297         const OS_var* v = dynamic_cast<const OS_var*>(vars[i]);
00298             // Since we do not generate cuts, we can just disregard the "cuts"
00299             // argument, since the column corresponding to the var is exactly
00300             // the flow (plus the entry in the appropriate convexity
00301             // constraint)
00302             BCP_col* col = new BCP_col(v->coinPackedVec, v->weight, 0.0, 1.0);
00303             //col->insert(data.numarcs + v->commodity, 1.0);
00304             
00305             cols.push_back( col);
00306             // Excercise: if we had generated cuts, then the coefficients for
00307             // those rows would be appended to the end of each column
00308     }
00309 }
00310 
00311 
00312 /************************************************************************/
00313 void OS_lp::process_lp_result(const BCP_lp_result& lpres,
00314                       const BCP_vec<BCP_var*>& vars,
00315                       const BCP_vec<BCP_cut*>& cuts,
00316                       const double old_lower_bound,
00317                       double& true_lower_bound,
00318                       BCP_solution*& sol,
00319                       BCP_vec<BCP_cut*>& new_cuts,
00320                       BCP_vec<BCP_row*>& new_rows,
00321                       BCP_vec<BCP_var*>& new_vars,
00322                       BCP_vec<BCP_col*>& new_cols){
00323         new_cuts.clear();
00324         new_rows.clear();
00325         // only process if LP relaxation is optimal
00326         if(getLpProblemPointer()->lp_solver->isAbandoned() ||
00327         getLpProblemPointer()->lp_solver->isProvenPrimalInfeasible() ||
00328       getLpProblemPointer()->lp_solver->isDualObjectiveLimitReached() ||
00329       getLpProblemPointer()->lp_solver->isIterationLimitReached() )  {
00330       true_lower_bound = old_lower_bound;
00331                 // seems like should be true but that leads to errors
00332                 getLpProblemPointer()->user_has_lp_result_processing = false;
00333                 std::cout << "TERMINATING IN PROCESSS LP RESULT WITHOUT CHECKING FOR CUTS" << std::endl;
00334                 return;
00335    }
00336 
00337         int i;
00338         /*
00339         if((os_prob->haveBranched == false || isIntSolution(lpres.x(),  vars,  BCP_lp_user::get_param(BCP_lp_par::IntegerTolerance)) == true) ) createcutsforbearcat(lpres,  new_cuts);  // call the tour-breaking cut procedure
00340 */
00341 
00342         double tol1 = 0.01;
00343         double tol2 = 0.01;
00344 
00345         if((os_prob->haveBranched == false || isIntSolution(lpres.x(),  vars,  BCP_lp_user::get_param(BCP_lp_par::IntegerTolerance)) == true) ) createcutsforbearcat(lpres,  new_cuts, tol1, tol2, os_prob->haveBranched);  // call the tour-breaking cut procedure
00346         //createcutsforbearcat(lpres,  new_cuts,  tol1, tol2, os_prob->haveBranched);
00347         //createCglCuts(lpres,  new_cuts);
00348         int cutnum = new_cuts.size();
00349         std::cout << "NUMBER CUTS GENERATED = " << os_prob->ttlcuts << std::endl;
00350         os_prob->ttlcuts = os_prob->ttlcuts + cutnum;   
00351     if(  cutnum == 0 ){
00352                 //true_lower_bound =  old_lower_bound;
00353         BCP_lp_user::process_lp_result(lpres, vars, cuts, 
00354                         old_lower_bound, true_lower_bound, sol, new_cuts,
00355                         new_rows, new_vars, new_cols);          
00356         return;
00357     }
00358 
00359         CoinPackedVector pv;
00360         int *pvIndexes = NULL;
00361         double *pvElements = NULL;
00362         int numElem;
00363         double lb;
00364         double ub;
00365 
00366         cout<< " new_cuts() size" << new_cuts.size() << std::endl;
00367 
00368         
00369 
00370         int k;
00371         for (i = 0; i < cutnum; ++i) {
00372                 const OsiRowCut* bcut = dynamic_cast<const OS_cut*>(new_cuts[i]);
00373            if (bcut) {
00374                         numElem = bcut->row().getNumElements();
00375                         pvIndexes = new int[ numElem];
00376                         pvElements = new double[ numElem];
00377                         for(k = 0; k < numElem; k++){
00378                                 pvIndexes[ k] = bcut->row().getIndices()[ k];
00379                                 pvElements[ k] = bcut->row().getElements()[ k];
00380                         }
00381                         lb = bcut->lb();
00382                         ub = bcut->ub();
00383                 //new_rows.push_back(new BCP_row(bcut->row(), bcut->lb(), bcut->ub()));
00384                         new_rows.push_back(new BCP_row(CoinPackedVector(numElem, pvIndexes, pvElements), lb, ub));
00385                         }else{
00386                         throw BCP_fatal_error("Unknown cut type in cuts_to_rows.\n");
00387             }
00388         }
00389         //new_cuts.clear();
00390         true_lower_bound =  lpres.objval();
00391         std::cout << "TRUE LOWER BOUND **************   "  << true_lower_bound << std::endl;
00392 }//end process_lp_result
00393 
00394 
00395 
00396 /************************************************************************/
00397 
00398 
00399         void  OS_lp::display_lp_solution(const BCP_lp_result& lpres,
00400                                  const BCP_vec<BCP_var*>& vars,
00401                                  const BCP_vec<BCP_cut*>& cuts,
00402                                  const bool final_lp_solution){
00403                 
00404         
00405                 //BCP_lp_user::display_lp_solution( lpres, vars, cuts,final_lp_solution);
00406                 return;
00407 // kipp write OSrL here?
00408 // if final_lp_solution is true print out some osrl.
00409 }
00410 
00411 /************************************************************************************************/
00412         void  OS_lp::createcutsforbearcat(const BCP_lp_result& lpres,
00413                                                                           BCP_vec<BCP_cut*>& new_cuts, double tol1, double tol2, bool isInt){
00414                                                   
00415 //os_prob->addtxtstr << " INSIDE CUT ADDITION SCOPE \n";
00416                 int i,j,ii,jj;
00417                 //int num_vars = vars.size();
00418                 const double *x = lpres.x();
00419                 
00420 
00421                 locs = os_prob->locs;
00422                 routes = os_prob->routes;
00423                 hubloc = os_prob->hubloc;
00424                 // CREATE VALUES, INDEXES & STARTS ARRAYS               
00425                 
00426                 int LocInRt; // total number of locs included in each route
00427                 map<int, int> SubProbLocs;// mapping master space to sub space
00428                 int rt;
00429                 
00430 
00431                                 
00432 
00433 for(rt=0; rt < routes; rt++)// ROUTE LOOP starts 
00434     {       LocInRt =0;
00435                         ii=0;
00436                         for(i=0; i < locs; i++)// to fill the values in alllocs; 1 - if a location is assigned to a route
00437                                 {if ( x[routes*i + rt ] > 0 )
00438                                                 {
00439                                                  SubProbLocs.insert (pair <int,int>(ii,i));
00440                                                  LocInRt++;
00441                                                  ii++;
00442                                                 }
00443 
00444                                  }
00445 
00446 
00447                 // OUTPUT - THE ROUTE ASSIGMENT
00448 
00449                 OSInstance *osinstance;
00450                 osinstance = new OSInstance();
00451                 
00452                 double *values = NULL; // values pointer  
00453                 int *indexes = NULL; //indexes pointer  
00454                 int *starts = NULL; // starts pointer
00455                 values = new double[4*(LocInRt-1)*LocInRt];// declare the array
00456                 indexes = new int[4*(LocInRt-1)*LocInRt];
00457                 starts = new int[2*(LocInRt-1)*LocInRt + 1];
00458 
00459                 ii=0;
00460                 jj=0;
00461                 for(i=0; i < LocInRt; i++)//creating alphas(i,j) for all combinations of i, j & thetas (i)
00462                    {for(j=0; j <LocInRt; j++)
00463                          { if( i!=j)
00464                                 { 
00465                           values[ii]= 1;
00466                                   values[ii+1]= -1;
00467                                   values[ii+2]= 1;
00468                                   values[ii+3]= -1;
00469 
00470                                   starts[jj] = 2 * jj;
00471                                   starts[jj + 1] = 2 * (jj + 1);
00472                                   jj = jj + 2; 
00473                                   if (i<j)
00474                                         {       indexes[ii] =   (LocInRt-1)*i+(j-1);
00475                                                 indexes[ii+1] = (LocInRt-1)*LocInRt+ i;
00476                                                 indexes[ii+2] = (LocInRt-1)*i+(j-1);
00477                                             indexes[ii+3] = (LocInRt-1)*LocInRt+ j;
00478                                                 ii= ii + 4;
00479                                         }
00480                                   else
00481                                         {       indexes[ii] =   (LocInRt-1)*i+j;
00482                                                 indexes[ii+1] = (LocInRt-1)*LocInRt+ i;
00483                                                 indexes[ii+2] = (LocInRt-1)*i+j;
00484                                                 indexes[ii+3] = (LocInRt-1)*LocInRt+ j;
00485                                                 ii= ii + 4;
00486                                         }
00487 
00488                              }
00489                          }
00490                   }        
00491                                                                           
00492             starts[jj] = 2 * jj;        
00493                 
00494                 // CREATE CONSTRAINTS
00495                 //for each LocInRt there are (LocInRt-1)*2 constraints; total cons = LocInRt*(LocInRt-1)*2;
00496 
00497                 osinstance->setConstraintNumber(LocInRt*(LocInRt-1)*2);
00498                 for (i=0; i<LocInRt*(LocInRt-1)*2;i++)
00499                         {osinstance->addConstraint(i,"",-OSDBL_MAX,0,0);}
00500                 
00501                 osinstance->setLinearConstraintCoefficients(4*(LocInRt-1)*LocInRt,false,values,0,(4*(LocInRt-1)*LocInRt)-1,
00502                                         indexes,0,(4*(LocInRt-1)*LocInRt)-1,starts,0,2*(LocInRt-1)*LocInRt);
00503                 
00504 
00505                 //os_prob->addtxtstr<< " \n";
00506                 
00507 
00508                 // DEFINE VARIABLES; count the number locations assigned in a given route ; 
00509                 // LocInRt*(LocInRt-1) for alphas, LocInRt for thetas => LocInRt*LocInRt;
00510                 osinstance->setVariableNumber(LocInRt*LocInRt);
00511                 for ( i = 0; i<LocInRt*LocInRt; i++)
00512                                 {if (i < LocInRt* (LocInRt - 1) )// for alphas
00513                                           osinstance->addVariable(i,"",-OSDBL_MAX,OSDBL_MAX,'C');
00514                             else                           // for thetas
00515                                           osinstance->addVariable(i,"",0,1,'C');
00516                                 }
00517                 //os_prob->addtxtstr<<" \n";
00518                 
00519                 // ***** CHANGE IS FROM HERE****////
00520                 // DEFINE sparse vector for OBJECTIVE FUNCTION coefficients
00521                                 
00522                 osinstance->setObjectiveNumber(1);// we always assume one objective function
00523                 SparseVector*objcoeff = new SparseVector(LocInRt*LocInRt);
00524                 for(i=0;i<LocInRt*LocInRt; i++)// initialize the vector ( creating dense vector )
00525                         {objcoeff->values[i] = 0;
00526                         objcoeff->indexes[i]= i;}
00527                 osinstance->addObjective(-1, "objfunction", "max",0.0, 1.0, objcoeff);// now, add the objective function
00528                 
00529                 
00530                 jj=0;
00531                 
00532                 // after creating dense objcoeffs, copying values from x vector ( xbar*alpha - copyin values for xbar)
00533                 for(map<int,int>::iterator iti = SubProbLocs.begin(); iti != SubProbLocs.end(); ++iti)
00534                         {for(map<int,int>::iterator itj = SubProbLocs.begin(); itj != SubProbLocs.end(); ++itj)
00535                                         {if ( iti->second != itj->second )
00536                                                   { if ( iti->second < itj->second )
00537                                                                 {if ( x[ locs*routes + (locs-1)*routes*iti->second + rt + routes*(itj->second - 1)] > 0 )
00538                                                                          { osinstance->bObjectivesModified = true;
00539                                                                                    osinstance->instanceData->objectives->obj[0]->coef[jj]->value = x[ locs*routes + (locs-1)*routes*iti->second + rt + routes*(itj->second - 1)];
00540                                                                                   }
00541                                                                                                               
00542                                                                 }
00543                                                                 
00544                                                    else
00545                                                        {if (x[locs*routes + (locs-1)*routes*iti->second + rt + routes*(itj->second)] > 0 )
00546                                                                            { osinstance->bObjectivesModified = true;
00547                                                                                          osinstance->instanceData->objectives->obj[0]->coef[jj]->value = x[locs*routes + (locs-1)*routes*iti->second + rt + routes*(itj->second)];                                                                                
00548                                                                                    }
00549                                                         }
00550                                    
00551                                                    if ( iti->second == hubloc-1 || itj->second == hubloc-1)// making alphas that incident to hub to zero
00552                                                                 { osinstance->bVariablesModified = true;
00553                                                                   osinstance->instanceData->variables->var[jj]->ub = 0;
00554                                                                   //os_prob->addtxtstr << " IT IS WORKING \n";
00555                                                                 }
00556                                                    jj++;
00557                                                 }
00558                                          }
00559                        }
00560                 
00561                 
00562                 for (i=0;i<LocInRt;i++)// adding -1s in for thetas as ObjCoeffs
00563                     { osinstance->bObjectivesModified = true;
00564                           osinstance->instanceData->objectives->obj[0]->coef[LocInRt*(LocInRt-1)+i]->value = -1;
00565                          }
00566                 
00567                 int CutsWereAdded = 0;
00568                 int rhsVal = 0;
00569                 i=0;
00570                 
00571                 while (i<LocInRt && CutsWereAdded == 0 ) //SEPERATION PROBLEM loop starts
00572                     {                                                    //with in each route, seperation problem need to be solved for each node in that route
00573                         //os_prob->addtxtstr << " SEPERATION PROBLEM LOOP FOR i =  " << i+1 << " \n";
00574                         if (i == 0)
00575                           {//osinstance->bVariablesModified = true; 
00576                            //osinstance->instanceData->variables->var[LocInRt*(LocInRt-1)+i]->ub = 0;
00577                            osinstance->bObjectivesModified = true;
00578                            osinstance->instanceData->objectives->obj[0]->coef[LocInRt*(LocInRt-1)+i]->value = 0;
00579                            }
00580                         else
00581                           { //osinstance->bVariablesModified = true;
00582                             //osinstance->instanceData->variables->var[LocInRt*(LocInRt-1)+i]->ub = 0;//make the theta variable upper bound zero for the ith node;
00583                             //osinstance->instanceData->variables->var[LocInRt*(LocInRt-1)+i-1]->ub = 1;// reset the UB of the previous theta variable to one;
00584                                  osinstance->bObjectivesModified = true;
00585                              osinstance->instanceData->objectives->obj[0]->coef[LocInRt*(LocInRt-1)+i]->value = 0;  
00586                                  osinstance->instanceData->objectives->obj[0]->coef[LocInRt*(LocInRt-1)+i-1]->value = -1;  
00587                            }
00588                         
00589                         // solve the separation problem
00590                                                 
00591                         // create SOLVER class and assign the instance to its data member
00592                         CoinSolver *solver;
00593                         solver = new CoinSolver();
00594                         solver->osinstance = osinstance;
00595                         solver->sSolverName ="clp";
00596                         solver->buildSolverInstance();
00597                         solver->solve();
00598                         //os_prob->addtxtstr << "\n";
00599                         //os_prob->addtxtstr << "\n";
00600                         //os_prob->addtxtstr << " PRINT THE MODEL \n "; 
00601                         //os_prob->addtxtstr << osinstance->printModel();
00602                         // first read the result in OSResult object
00603                         // creat an OSResult object from the string
00604                         OSrLReader *osrlreader = NULL;
00605                         OSResult *osresult = NULL;
00606                         osrlreader = new OSrLReader();
00607                         osresult  = osrlreader->readOSrL( solver->osrl);
00608                         
00609                         // check the solution status
00610                         std::string solStatus;
00611                         double optSolValue;
00612                         solStatus = osresult->getSolutionStatusType(0); // the argument is the solution index
00613                         optSolValue = osresult->getOptimalObjValue( -1, 0); //first index is objIdx, second is solution index
00614                         //os_prob->addtxtstr<< "optSolValue = " << optSolValue << "\n";
00615                         double tol = tol1;
00616                         if (isInt == true) tol = tol2;
00617                         if ( optSolValue > tol) // if the opt.sol > 0 STARTS
00618                                {// now get the primal solution
00619                                     //os_prob->addtxtstr<< " ADDING CUTS \n";
00620                                         int vecSize;
00621                                         std::vector<IndexValuePair*> primalValPair;
00622                                         primalValPair = osresult->getOptimalPrimalVariableValues( 0);
00623                                         vecSize = primalValPair.size();
00624                                 
00625                                         //os_prob->addtxtstr<<"THETA VARIABLES \n";
00626                                         for(map<int,int>::iterator iti = SubProbLocs.begin(); iti != SubProbLocs.end(); ++iti)
00627                                            { //os_prob->addtxtstr<< "" << primalValPair[LocInRt*(LocInRt - 1)+ iti ->first]->value << " ";
00628                                                  if ( primalValPair[LocInRt*(LocInRt - 1)+ iti ->first]->value > 0)
00629                                                            { ++rhsVal; }// count the theta variables which has value of 1
00630                                            }
00631 
00632                                         for(map<int,int>::iterator delj = SubProbLocs.begin(); delj != SubProbLocs.end();)
00633                                            { //cout<< "" << primalValPair[LocInRt*(LocInRt - 1)+ delj ->first]->value << " ";
00634                                              //cout<< "" << delj ->first << " ";
00635                                                  if ( primalValPair[LocInRt*(LocInRt - 1)+ delj ->first]->value == 0)
00636                                                          { SubProbLocs.erase(delj++);
00637                                                                 }// delete the zero valued theta variables
00638                                                  else
00639                                                                 ++delj;
00640                                                 }
00641 
00642                                         CutsWereAdded = 1;
00643                                         primalValPair.clear();
00644                                         
00645                                         }  // if the opt.sol > 0 ENDS
00646                 
00647                         // garbage collection
00648                         
00649                         delete solver;
00650                         solver = NULL;
00651                         delete osrlreader;
00652                         osrlreader = NULL;
00653                         ++i;
00654                                 
00655                     } // SEPERATION PROBLEM LOOP ends
00656                  
00657                  
00658                  if (CutsWereAdded ==1) // ADDING CUT starts
00659                    {OsiRowCut* rcut = new OsiRowCut();// rhsVal give you number of elements in the cutset;
00660                         int *cutind = new int[rhsVal*(rhsVal-1)]; // the cut column indexes
00661                         double *cutcoef = new double[ rhsVal*(rhsVal-1)];// the cut coefficients
00662                     int cut_nz = rhsVal*(rhsVal-1);// number of nonzeros in the cut
00663                         double cutrhs = rhsVal -1;// rhs value
00664                         
00665                         //os_prob->addtxtstr<< " \n";
00666                         //os_prob->addtxtstr<< " cut_nz = " << cut_nz << "\n";
00667                         //os_prob->addtxtstr<< " cutrhs = " << cutrhs << "\n";
00668                                                 
00669                         //os_prob->addtxtstr<< "ConsA"<<os_prob->conscount<<".. ";
00670                         ii = 0;
00671                         os_prob->conscount++;
00672                         for(map<int,int>::iterator iti = SubProbLocs.begin(); iti != SubProbLocs.end(); ++iti)
00673                                 {for(map<int,int>::iterator itj = SubProbLocs.begin(); itj != SubProbLocs.end(); ++itj)
00674                                         { //cout<< " iti->second " << iti->second << " itj->second "<< itj->second <<"\n";
00675                                           if ( iti->second != itj->second )
00676                                                 { if ( iti->second < itj->second )      
00677                                                         {       cutind[ii]      = locs*routes + (locs-1)*routes*iti->second + rt + routes*(itj->second - 1);}
00678                                                   else
00679                                                         {  cutind[ii] =    locs*routes + (locs-1)*routes*iti->second + rt + routes*(itj->second);}
00680                                                                                                                 
00681                                                 cutcoef[ii]= 1;
00682                                                 //os_prob->addtxtstr<<" cutcoeff = " <<cutcoef[ii]<<" cutind = "<<cutind[ii]<< "\n";
00683                                                 ++ii;
00684                                                 //os_prob->addtxtstr<<"X('"<< iti->second+1<<"',"<<"'"<<itj->second+1<<"',"<<"'"<<rt+1<<"' )" << "+";
00685                                                 
00686                                             }
00687                                         }
00688                                 }
00689                         
00690                         
00691                         
00692                         rcut->setLb(-BCP_DBL_MAX);
00693                 rcut->setUb(cutrhs);
00694                 rcut->setRow( cut_nz, cutind, cutcoef);
00695                 OS_cut* cut = new OS_cut( *rcut);
00696                 //algo_cuts.push_back( cut);
00697                         //os_prob->addtxtstr<< " algo_cuts = " << algo_cuts.size() << "\n";
00698                         new_cuts.push_back(cut);
00699                         
00700 
00701                         delete rcut;
00702                         rcut = NULL;
00703                         //delete cut;
00704                         //cut = NULL;
00705                         delete[] cutind;
00706                         cutind = NULL;
00707                         delete[] cutcoef;
00708                         cutcoef = NULL;
00709                         
00710                          
00711                                         
00712                           } // ADDING CUT ends
00713                                                    
00714                         
00715                  
00716                 // garbage collection
00717 
00718 
00719                 //os_prob->addtxtstr<< " clearing SubProbLocs " << "\n";
00720                 SubProbLocs.clear();
00721                 //os_prob->addtxtstr<< " cleared SubProbLocs " << "\n";
00722 
00723             //os_prob->addtxtstr<< " deleting osinstance " << "\n";
00724                 delete osinstance;
00725                 osinstance = NULL;      
00726                 //os_prob->addtxtstr<< " deleted osinstance " << "\n";
00727 
00728                 //os_prob->addtxtstr<< " deleting values " << "\n";
00729                 //delete[] values;
00730                 values =  NULL;
00731                 //os_prob->addtxtstr<< " deleted values " << "\n";
00732                 
00733                 //os_prob->addtxtstr<< " deleting indexes " << "\n";
00734                 //delete[] indexes;
00735                 indexes = NULL;
00736                 //os_prob->addtxtstr<< " deleted indexes " << "\n";
00737                 
00738                 //os_prob->addtxtstr<< " deleting starts " << "\n";
00739                 //delete[] starts;
00740                 //os_prob->addtxtstr<< " deleted starts " << "\n";
00741                 starts =  NULL;
00742                 
00743 
00744                 //os_prob->addtxtstr<< " deleting objcoeff " << "\n";
00745                 delete objcoeff;
00746                 objcoeff = NULL;
00747                 //os_prob->addtxtstr<< " deleted osinstance " << "\n";
00748 
00749                 
00750                                         
00751         }// ROUTE LOOP ends       
00752 
00753 }
00754 
00755 bool OS_lp::isIntSolution(const double *x, const BCP_vec<BCP_var*>& vars, const double intTol){
00756         int num_vars = vars.size();
00757         int i;
00758         
00759    for(i = 0; i < num_vars; i++) {  
00760 
00761         if( vars[ i]->var_type() < 2)   {
00762                 if((x[i] -floor( x[i])  > intTol) && (ceil( x[i]) - x[i] > intTol)) {
00763                         // we have a fractional integer variable
00764                                 return false;
00765                 }
00766         }
00767     }
00768         return  true;
00769 }// end isIntSolution
00770 
00771 void OS_lp::createCglCuts(const BCP_lp_result& lpres,BCP_vec<BCP_cut*>& new_cuts){
00772 
00773         OsiClpSolverInterface* my_lp_solver;
00774         my_lp_solver =  dynamic_cast<OsiClpSolverInterface *>(getLpProblemPointer()->lp_solver);
00775         CglGomory  gomory;
00776         OsiSolverInterface::ApplyCutsReturnCode acRc;
00777         OsiCuts my_cuts;
00778         double epsilon = .01;
00779         int i, k;
00780         // generate the Gomory constraints
00781         gomory.generateCuts(*my_lp_solver, my_cuts);  
00782         const double *x = lpres.x();
00783         CoinPackedVector pv;
00784         int *pvIndexes = NULL;
00785         double *pvElements = NULL;
00786         int numElem;
00787         double lhs = 0;
00788    OS_cut* cut;
00789         int ncuts = my_cuts.sizeRowCuts();
00790         
00791         const OsiRowCut **newRowCuts = new const OsiRowCut * [ncuts];
00792         std::cout <<  "sizeRowCuts() =    " << ncuts  << std::endl;
00793         for(i = 0; i < ncuts; i++) {
00794                 newRowCuts[i] = &my_cuts.rowCut(i); 
00795            cut = new OS_cut( *newRowCuts[i]);
00796            pv = newRowCuts[i]->row();
00797            pvIndexes = pv.getIndices();
00798            pvElements =  pv.getElements();
00799            numElem = pv.getNumElements();
00800                 lhs = 0;
00801            for(k = 0; k < numElem; k++){
00802                 lhs += pvElements[ k]*x[ pvIndexes[k] ];
00803                   //std::cout << pvElements[ k] << std::endl;
00804            }
00805                 if( (newRowCuts[i]->sense() == 'L')  && (lhs > newRowCuts[i]->rhs() +epsilon )  ){
00806                 new_cuts.push_back( cut);  
00807            }
00808         }          
00809         generated_cuts = (new_cuts.size() > 0);
00810         for(i = 0; i < ncuts; i++){
00811                         //delete newRowCuts[ i];
00812         }
00813         delete[] newRowCuts;
00814 } // end createCglCuts
00815 

Generated on Mon May 3 03:05:22 2010 by  doxygen 1.4.7