00001 // Copyright (C) 2006, 2008 International Business Machines 00002 // Corporation and others. All Rights Reserved. 00003 // Authors: Andreas Waechter, Pierre Bonami 00004 00005 #include "BonminConfig.h" 00006 00007 #include "CoinPragma.hpp" 00008 00009 #define Verbose 00010 #include "BonQpBranchingSolver.hpp" 00011 00012 #ifdef COIN_HAS_FILTERSQP 00013 #include "BonFilterSolver.hpp" 00014 #include "BonBqpdSolver.hpp" 00015 #endif 00016 00017 namespace Bonmin 00018 { 00019 00020 QpBranchingSolver::QpBranchingSolver(OsiTMINLPInterface * solver) 00021 : 00022 StrongBranchingSolver(solver) 00023 {} 00024 00025 QpBranchingSolver::QpBranchingSolver(const QpBranchingSolver & rhs) : 00026 StrongBranchingSolver(rhs) 00027 {} 00028 00029 QpBranchingSolver & 00030 QpBranchingSolver::operator=(const QpBranchingSolver & rhs) 00031 { 00032 if (this != &rhs) { 00033 StrongBranchingSolver::operator=(rhs); 00034 } 00035 return *this; 00036 } 00037 00038 QpBranchingSolver::~QpBranchingSolver () 00039 { 00040 #ifdef TIME_BQPD 00041 printf("QPBRANCH Timings for %i sbs\n", times_.numsolve); 00042 printf("QPBRANCH %i pivots\n", times_.pivots); 00043 printf("QPBRANCH Creating : %g\n", times_.create); 00044 printf("QPBRANCH Solving : %g\n", times_.solve); 00045 printf("QPBRANCH Warming : %g\n", times_.warm_start); 00046 printf("QPBRANCH Resolving : %g\n", times_.resolve); 00047 #endif 00048 } 00049 00050 void QpBranchingSolver:: 00051 markHotStart(OsiTMINLPInterface* tminlp_interface) 00052 { 00053 TMINLP2TNLP* tminlp2tnlp = tminlp_interface->problem(); 00054 branching_tqp_ = new BranchingTQP(tminlp2tnlp); 00055 00056 first_solve_ = true; 00057 #ifdef COIN_HAS_FILTERSQP 00058 FilterSolver* filter_solver = 00059 dynamic_cast<FilterSolver*> (tminlp_interface->solver()); 00060 if (filter_solver) { 00061 Ipopt::SmartPtr<BqpdSolver> qp_solver = 00062 new BqpdSolver(RegOptions(), Options(), Jnlst(), tminlp_interface->prefix()); 00063 #if 1 00064 // Solve the QP with the original bounds and set the hot start 00065 // information 00066 TNLPSolver::ReturnStatus retstatus; 00067 retstatus = qp_solver->OptimizeTNLP(GetRawPtr(branching_tqp_)); 00068 if (retstatus == TNLPSolver::solvedOptimal || 00069 retstatus == TNLPSolver::solvedOptimalTol) { 00070 first_solve_ = false; 00071 qp_solver->markHotStart(); 00072 } 00073 #endif 00074 tqp_solver_ = GetRawPtr(qp_solver); 00075 //tqp_solver_ = new FilterSolver(RegOptions(), Options(), Jnlst()); 00076 } 00077 #endif 00078 if (IsNull(tqp_solver_)) { 00079 tqp_solver_ = tminlp_interface->solver()->clone(); 00080 } 00081 tqp_solver_->enableWarmStart(); 00082 } 00083 00084 void QpBranchingSolver:: 00085 unmarkHotStart(OsiTMINLPInterface* tminlp_interface) 00086 { 00087 // Free memory 00088 #ifdef TIME_BQPD 00089 BqpdSolver * qp_solver = dynamic_cast<BqpdSolver *>(GetRawPtr(tqp_solver_)); 00090 if(qp_solver) times_ += qp_solver->times(); 00091 #endif 00092 branching_tqp_ = NULL; 00093 tqp_solver_ = NULL; 00094 } 00095 00096 TNLPSolver::ReturnStatus QpBranchingSolver:: 00097 solveFromHotStart(OsiTMINLPInterface* tminlp_interface) 00098 { 00099 TNLPSolver::ReturnStatus retstatus; 00100 if (first_solve_) { 00101 retstatus = tqp_solver_->OptimizeTNLP(GetRawPtr(branching_tqp_)); 00102 } 00103 else { 00104 retstatus = tqp_solver_->ReOptimizeTNLP(GetRawPtr(branching_tqp_)); 00105 } 00106 00107 if (retstatus == TNLPSolver::solvedOptimal || 00108 retstatus == TNLPSolver::solvedOptimalTol) { 00109 // don't way we solve the problem, since otherwise the pseudo costs 00110 // are updated and that is maybe not so good??? 00111 //retstatus = TNLPSolver::iterationLimit; 00112 first_solve_ = false; 00113 } 00114 //retstatus = TNLPSolver::iterationLimit; 00115 return retstatus; 00116 } 00117 00118 }