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