00001
00002
00003 #include "CoinTime.hpp"
00004
00005 #include "BCP_vector.hpp"
00006 #include "BCP_tm_user.hpp"
00007 #include "BCP_tm.hpp"
00008 #include "BCP_lp.hpp"
00009 #include "BCP_solution.hpp"
00010 #include "BCP_var.hpp"
00011 #include "BCP_functions.hpp"
00012
00013
00014
00015 double BCP_tm_user::upper_bound() const { return p->ub(); }
00016
00017 double BCP_tm_user::lower_bound() const
00018 {
00019 return *(p->lower_bounds.begin()) / p->lb_multiplier;
00020 }
00021
00022
00023
00024
00025 char
00026 BCP_tm_user::get_param(const BCP_tm_par::chr_params key) const
00027 { return p->par.entry(key); }
00028 int
00029 BCP_tm_user::get_param(const BCP_tm_par::int_params key) const
00030 { return p->par.entry(key); }
00031 double
00032 BCP_tm_user::get_param(const BCP_tm_par::dbl_params key) const
00033 { return p->par.entry(key); }
00034 const BCP_string&
00035 BCP_tm_user::get_param(const BCP_tm_par::str_params key) const
00036 { return p->par.entry(key); }
00037
00038 void BCP_tm_user::set_param(const BCP_tm_par::chr_params key, const bool val)
00039 { p->par.set_entry(key, val); }
00040 void BCP_tm_user::set_param(const BCP_tm_par::chr_params key, const char val)
00041 { p->par.set_entry(key, val); }
00042 void BCP_tm_user::set_param(const BCP_tm_par::int_params key, const int val)
00043 { p->par.set_entry(key, val); }
00044 void BCP_tm_user::set_param(const BCP_tm_par::dbl_params key, const double val)
00045 { p->par.set_entry(key, val); }
00046 void BCP_tm_user::set_param(const BCP_tm_par::str_params key, const char * val)
00047 { p->par.set_entry(key, val); }
00048
00049
00050
00051 void
00052 BCP_tm_user::pack_module_data(BCP_buffer& buf, BCP_process_t ptype) {}
00053
00054
00055
00056 BCP_solution*
00057 BCP_tm_user::unpack_feasible_solution(BCP_buffer& buf)
00058 {
00059 if (p->param(BCP_tm_par::ReportWhenDefaultIsExecuted)) {
00060 printf(" TM: Default unpack_feasible_solution() executed.\n");
00061 }
00062
00063 BCP_solution_generic* soln = new BCP_solution_generic;
00064
00065 int varnum;
00066 buf.unpack(varnum);
00067
00068 double val;
00069 int bcpind;
00070 while (--varnum >= 0) {
00071 buf.unpack(val);
00072
00073
00074 buf.unpack(bcpind);
00075 BCP_var* var = p->unpack_var_without_bcpind(buf);
00076 var->set_bcpind(bcpind < 0 ? -bcpind : bcpind);
00077 soln->add_entry(var, val);
00078 }
00079 buf.unpack(val);
00080 soln->set_objective_value(val);
00081
00082 return soln;
00083 }
00084
00085
00086
00087 bool
00088 BCP_tm_user::replace_solution(const BCP_solution* old_sol,
00089 const BCP_solution* new_sol)
00090 {
00091 return false;
00092 }
00093
00094
00095
00097 int
00098 BCP_tm_user::process_id() const
00099 {
00100 return p->get_process_id();
00101 }
00102
00104 void
00105 BCP_tm_user::send_message(const int target, const BCP_buffer& buf)
00106 {
00107 p->msg_env->send(target, BCP_Msg_User, buf);
00108 }
00109
00111 void
00112 BCP_tm_user::broadcast_message(const BCP_process_t proc_type,
00113 const BCP_buffer& buf)
00114 {
00115 switch (proc_type) {
00116 case BCP_ProcessType_LP:
00117 p->msg_env->multicast(p->lp_procs.size(), &p->lp_procs[0],
00118 BCP_Msg_User, buf);
00119 break;
00120 case BCP_ProcessType_CP:
00121 throw BCP_fatal_error("\
00122 BCP_tm_user::broadcast_message: CP not yet implemented\n");
00123 break;
00124 case BCP_ProcessType_VP:
00125 throw BCP_fatal_error("\
00126 BCP_tm_user::broadcast_message: VP not yet implemented\n");
00127 break;
00128 #if ! defined(BCP_ONLY_LP_PROCESS_HANDLING_WORKS)
00129 case BCP_ProcessType_CG:
00130 p->msg_env->multicast(*p->slaves.cg, BCP_Msg_User, buf);
00131 break;
00132 case BCP_ProcessType_VG:
00133 p->msg_env->multicast(*p->slaves.vg, BCP_Msg_User, buf);
00134 break;
00135 #endif
00136 case BCP_ProcessType_Any:
00137 p->msg_env->multicast(p->lp_procs.size(), &p->lp_procs[0],
00138 BCP_Msg_User, buf);
00139 #if ! defined(BCP_ONLY_LP_PROCESS_HANDLING_WORKS)
00140 p->msg_env->multicast(*p->slaves.cg, BCP_Msg_User, buf);
00141 p->msg_env->multicast(*p->slaves.vg, BCP_Msg_User, buf);
00142 #endif
00143 break;
00144 case BCP_ProcessType_TM:
00145 case BCP_ProcessType_TS:
00146 case BCP_ProcessType_EndProcess:
00147 throw BCP_fatal_error("\
00148 BCP_tm_user::broadcast_message: broadcast to TM/TS/EndProcess...\n");
00149 default:
00150 throw BCP_fatal_error("BCP_tm_user::Unknown process type (%i)\n",
00151 proc_type);
00152 }
00153 }
00154
00157 void
00158 BCP_tm_user::process_message(BCP_buffer& buf)
00159 {
00160 throw BCP_fatal_error("\
00161 BCP_tm_user::process_message() invoked but not overridden!\n");
00162 }
00163
00164
00165
00166
00167 void
00168 BCP_tm_user::initialize_core(BCP_vec<BCP_var_core*>& vars,
00169 BCP_vec<BCP_cut_core*>& cuts,
00170 BCP_lp_relax*& matrix)
00171 {
00172 if (p->param(BCP_tm_par::ReportWhenDefaultIsExecuted)) {
00173 printf(" TM: Default BCP_tm_user::initialize_core() executed.\n");
00174 }
00175 }
00176
00177
00178
00179 void
00180 BCP_tm_user::create_root(BCP_vec<BCP_var*>& added_vars,
00181 BCP_vec<BCP_cut*>& added_cuts,
00182 BCP_user_data*& user_data)
00183 {
00184 if (p->param(BCP_tm_par::ReportWhenDefaultIsExecuted)) {
00185 printf(" TM: Default BCP_tm_user::create_root() executed.\n");
00186 }
00187 }
00188
00189
00190
00191 void
00192 BCP_tm_user::display_feasible_solution(const BCP_solution* sol)
00193 {
00194 if (p->param(BCP_tm_par::ReportWhenDefaultIsExecuted)) {
00195 printf("\
00196 TM: Default BCP_tm_user::display_feasible_solution() executed.\n");
00197 }
00198
00199 const BCP_solution_generic* gsol =
00200 dynamic_cast<const BCP_solution_generic*>(sol);
00201 if (! gsol) {
00202 throw BCP_fatal_error("\
00203 BCP_tm_user::display_feasible_solution() invoked with non-generic sol.\n");
00204 }
00205
00206 gsol->display();
00207 }
00208
00209
00212 void
00213 BCP_tm_user::display_node_information(BCP_tree& search_tree,
00214 const BCP_tm_node& node)
00215 {
00216 }
00217
00218
00222 void
00223 BCP_tm_user::display_node_information(BCP_tree& search_tree,
00224 const BCP_tm_node& node,
00225 bool after_processing_node)
00226 {
00227 }
00228
00229
00231 void
00232 BCP_tm_user::display_final_information(const BCP_lp_statistics& lp_stat)
00233 {
00234 if (p->param(BCP_tm_par::TmVerb_FinalStatistics)) {
00235 printf("TM: Running time: %.3f\n", CoinWallclockTime() - p->start_time);
00236 printf("TM: search tree size: %i ( processed %i ) max depth: %i\n",
00237 int(p->search_tree.size()), int(p->search_tree.processed()),
00238 p->search_tree.maxdepth());
00239 lp_stat.display();
00240
00241 if (! p->feas_sol) {
00242 printf("TM: No feasible solution is found\n");
00243 } else {
00244 printf("TM: The best solution found has value %f\n",
00245 p->feas_sol->objective_value());
00246 if (p->param(BCP_tm_par::TmVerb_BestFeasibleSolution)) {
00247 p->user->display_feasible_solution(p->feas_sol);
00248 }
00249 }
00250 }
00251 }
00252
00253
00254
00255 void
00256 BCP_tm_user::init_new_phase(int phase,
00257 BCP_column_generation& colgen,
00258 CoinSearchTreeBase*& candidates)
00259 {
00260 if (p->param(BCP_tm_par::ReportWhenDefaultIsExecuted)) {
00261 printf(" TM: Default init_new_phase() executed.\n");
00262 }
00263 colgen = BCP_DoNotGenerateColumns_Fathom;
00264 switch (p->param(BCP_tm_par::TreeSearchStrategy)) {
00265 case BCP_BestFirstSearch:
00266 candidates = new CoinSearchTree<CoinSearchTreeCompareBest>;
00267 break;
00268 case BCP_BreadthFirstSearch:
00269 candidates = new CoinSearchTree<CoinSearchTreeCompareBreadth>;
00270 break;
00271 case BCP_DepthFirstSearch:
00272 candidates = new CoinSearchTree<CoinSearchTreeCompareDepth>;
00273 break;
00274 case BCP_PreferredFirstSearch:
00275 candidates = new CoinSearchTree<CoinSearchTreeComparePreferred>;
00276 break;
00277 }
00278 }
00279
00280
00281
00282 void
00283 BCP_tm_user::change_candidate_heap(CoinSearchTreeManager& candidates,
00284 const bool new_solution)
00285 {
00286 if (new_solution) {
00287 candidates.newSolution(p->ub());
00288 } else {
00289 candidates.reevaluateSearchStrategy();
00290 }
00291 }