00001
00002
00003 #include <functional>
00004
00005 #include "BCP_message.hpp"
00006 #include "BCP_problem_core.hpp"
00007 #include "BCP_branch.hpp"
00008 #include "BCP_warmstart.hpp"
00009 #include "BCP_lp.hpp"
00010 #include "BCP_lp_user.hpp"
00011 #include "BCP_lp_branch.hpp"
00012 #include "BCP_lp_node.hpp"
00013 #include "BCP_lp_functions.hpp"
00014
00015 #include "BCP_USER.hpp"
00016
00017
00018 static inline void BCP_lp_pack_core(BCP_lp_prob& p);
00019 static inline void BCP_lp_pack_noncore_vars(BCP_lp_prob& p,
00020 BCP_vec<int>& deleted_pos);
00021 static inline void BCP_lp_pack_noncore_cuts(BCP_lp_prob& p,
00022 BCP_vec<int>& deleted_pos);
00023 static inline void BCP_lp_pack_indexed_pricing(BCP_lp_prob& p);
00024 static inline void BCP_lp_pack_warmstart(BCP_lp_prob& p,
00025 BCP_vec<int>& del_vars,
00026 BCP_vec<int>& del_cuts);
00027 static inline void BCP_lp_pack_user_data(BCP_lp_prob& p);
00028
00029
00030
00031 static inline int BCP_lp_pack_branching_info(BCP_lp_prob& p,
00032 BCP_presolved_lp_brobj* brobj);
00033
00034
00035
00036 static inline void
00037 BCP_lp_pack_core(BCP_lp_prob& p)
00038 {
00039 if (p.core->varnum() + p.core->cutnum() > 0){
00040 BCP_problem_core_change exp_bc(p.core->varnum(), p.node->vars,
00041 p.core->cutnum(), p.node->cuts);
00042 switch (p.node->tm_storage.core_change){
00043 case BCP_Storage_WrtCore:
00044 {
00045 BCP_problem_core_change wrtcore_bc(BCP_Storage_WrtCore,
00046 *p.core_as_change, exp_bc);
00047 wrtcore_bc.pack(p.msg_buf);
00048 }
00049 break;
00050
00051 case BCP_Storage_Explicit:
00052 exp_bc.pack(p.msg_buf);
00053 break;
00054
00055 case BCP_Storage_WrtParent:
00056 {
00057 BCP_problem_core_change wrtparent_bc(BCP_Storage_WrtParent,
00058 p.parent->core_as_change, exp_bc);
00059 BCP_problem_core_change wrtcore_bc(BCP_Storage_WrtCore,
00060 *p.core_as_change, exp_bc);
00061 if (exp_bc.pack_size() <= wrtparent_bc.pack_size()){
00062 if (exp_bc.pack_size() <= wrtcore_bc.pack_size()){
00063 exp_bc.pack(p.msg_buf);
00064 }else{
00065 wrtcore_bc.pack(p.msg_buf);
00066 }
00067 }else{
00068 if (wrtparent_bc.pack_size() < wrtcore_bc.pack_size()){
00069 wrtparent_bc.pack(p.msg_buf);
00070 }else{
00071 wrtcore_bc.pack(p.msg_buf);
00072 }
00073 }
00074 }
00075 break;
00076
00077 default:
00078 throw BCP_fatal_error("BCP_lp_pack_core() : Bad storage.\n");
00079 }
00080
00081
00082 p.parent->core_as_change.swap(exp_bc);
00083 }
00084 }
00085
00086
00087
00088 static inline void
00089 BCP_lp_pack_noncore_vars(BCP_lp_prob& p, BCP_vec<int>& deleted_pos)
00090 {
00091
00092
00093
00094
00095 deleted_pos.clear();
00096 BCP_var_set_change desc(p.node->vars.entry(p.core->varnum()),
00097 p.node->vars.end());
00098
00099 if (p.node->tm_storage.var_change == BCP_Storage_WrtParent) {
00100 BCP_var_set_change change(p.node->vars.entry(p.core->varnum()),
00101 p.node->vars.end(),
00102 p.parent->added_vars_index,
00103 p.parent->added_vars_desc);
00104
00105 deleted_pos.append(change._del_change_pos.begin(),
00106 change._del_change_pos.entry(change.deleted_num()));
00107
00108
00109 if (desc.pack_size() > change.pack_size())
00110 desc.swap(change);
00111 }
00112
00113
00114
00115 p.pack_var_set_change(desc);
00116 }
00117
00118
00119
00120 static inline void
00121 BCP_lp_pack_noncore_cuts(BCP_lp_prob& p, BCP_vec<int>& deleted_pos)
00122 {
00123
00124
00125
00126
00127 deleted_pos.clear();
00128 BCP_cut_set_change desc(p.node->cuts.entry(p.core->cutnum()),
00129 p.node->cuts.end());
00130
00131 if (p.node->tm_storage.cut_change == BCP_Storage_WrtParent) {
00132 BCP_cut_set_change change(p.node->cuts.entry(p.core->cutnum()),
00133 p.node->cuts.end(),
00134 p.parent->added_cuts_index,
00135 p.parent->added_cuts_desc);
00136
00137 deleted_pos.append(change._del_change_pos.begin(),
00138 change._del_change_pos.entry(change.deleted_num()));
00139
00140
00141 if (desc.pack_size() > change.pack_size())
00142 desc.swap(change);
00143 }
00144
00145
00146
00147 p.pack_cut_set_change(desc);
00148 }
00149
00150
00151
00152 static inline void
00153 BCP_lp_pack_indexed_pricing(BCP_lp_prob& p)
00154 {
00155 BCP_indexed_pricing_list& indexed_pricing = p.node->indexed_pricing;
00156 if (p.node->tm_storage.indexed_pricing != BCP_Storage_WrtParent) {
00157
00158 indexed_pricing.pack(p.msg_buf);
00159 } else {
00160 BCP_indexed_pricing_list* pricing_change =
00161 indexed_pricing.as_change(p.parent->indexed_pricing);
00162 if (pricing_change->pack_size() < indexed_pricing.pack_size())
00163 pricing_change->pack(p.msg_buf);
00164 else
00165 indexed_pricing.pack(p.msg_buf);
00166 delete pricing_change; pricing_change = 0;
00167 }
00168 }
00169
00170
00171
00172 static inline void
00173 BCP_lp_pack_warmstart(BCP_lp_prob& p,
00174 BCP_vec<int>& del_vars, BCP_vec<int>& del_cuts)
00175 {
00176 bool has_data = p.node->warmstart != 0;
00177 p.msg_buf.pack(has_data);
00178
00179 if (has_data) {
00180 if (p.node->tm_storage.warmstart != BCP_Storage_WrtParent) {
00181 p.user->pack_warmstart(p.node->warmstart, p.msg_buf);
00182 } else {
00183 double petol = 0.0;
00184 double detol = 0.0;
00185 p.lp_solver->getDblParam(OsiPrimalTolerance, petol);
00186 p.lp_solver->getDblParam(OsiDualTolerance, detol);
00187
00188 BCP_warmstart* ws_change =
00189 p.node->warmstart->as_change(p.parent->warmstart,
00190 del_vars, del_cuts, petol, detol);
00191 p.user->pack_warmstart(ws_change, p.msg_buf);
00192 delete ws_change;
00193 ws_change = 0;
00194 }
00195 }
00196 }
00197
00198
00199
00200 static inline void BCP_lp_pack_user_data(BCP_lp_prob& p)
00201 {
00202 bool has_data = p.node->user_data != 0;
00203 p.msg_buf.pack(has_data);
00204
00205 if (has_data) {
00206 p.user->pack_user_data(p.node->user_data, p.msg_buf);
00207 }
00208 }
00209
00210
00211
00212 static inline int
00213 BCP_lp_pack_branching_info(BCP_lp_prob& p, BCP_presolved_lp_brobj* lp_brobj)
00214 {
00215 const int child_num = lp_brobj->candidate()->child_num;
00216
00217
00218 BCP_vec<double> lpobj;
00219 lpobj.reserve(child_num);
00220 for (int i = 0; i < child_num; ++i) {
00221 lpobj.unchecked_push_back(lp_brobj->lpres(i).objval());
00222 }
00223
00224
00225 BCP_vec<double> qualities(lpobj);
00226
00227 const BCP_vec<BCP_child_action>& action = lp_brobj->action();
00228 const BCP_vec<BCP_user_data*>& user_data = lp_brobj->user_data();
00229
00230
00231 BCP_buffer& buf = p.msg_buf;
00232 buf.pack(p.node->dive).pack(action).pack(qualities).pack(lpobj);
00233
00234 for (int i = 0; i < child_num; ++i) {
00235 const int has_user_data = user_data[i] == 0 ? 0 : 1;
00236 buf.pack(has_user_data);
00237 if (has_user_data == 1) {
00238 p.user->pack_user_data(user_data[i], buf);
00239 }
00240 }
00241
00242 BCP_internal_brobj int_brobj(*lp_brobj->candidate());
00243 int_brobj.pack(buf);
00244
00245 int keep = -1;
00246 if (p.node->dive != BCP_DoNotDive){
00247 for (int i = child_num - 1; i >= 0; --i)
00248 if (action[i] == BCP_KeepChild)
00249 if (keep == -1)
00250 keep = i;
00251 else
00252 throw BCP_fatal_error("LP : Can't keep more than one child!\n");
00253 }
00254 return keep;
00255 }
00256
00257
00258
00259
00260
00261
00262 int BCP_lp_send_node_description(BCP_lp_prob& p,
00263 BCP_presolved_lp_brobj* brobj,
00264 BCP_message_tag msgtag)
00265 {
00266 BCP_buffer& buf = p.msg_buf;
00267 BCP_lp_node& node = *p.node;
00268
00269
00270 buf.clear();
00271 buf.pack(node.index).pack(node.quality).pack(node.true_lower_bound);
00272
00273 const bool send_desc = brobj || p.param(BCP_lp_par::SendFathomedNodeDesc);
00274
00275 buf.pack(send_desc);
00276
00277
00278
00279 if (send_desc) {
00280
00281 BCP_lp_pack_core(p);
00282
00283 BCP_vec<int> del_vars;
00284 BCP_lp_pack_noncore_vars(p, del_vars);
00285
00286 BCP_vec<int> del_cuts;
00287 BCP_lp_pack_noncore_cuts(p, del_cuts);
00288
00289
00290 BCP_lp_pack_indexed_pricing(p);
00291
00292
00293
00294 if (p.node->warmstart) {
00295 throw BCP_fatal_error("\
00296 LP: there is ws info in BCP_lp_send_node_description()!\n");
00297 }
00298
00299 CoinWarmStart* ws = p.lp_solver->getWarmStart();
00300 p.node->warmstart = BCP_lp_convert_CoinWarmStart(p, ws);
00301 BCP_lp_pack_warmstart(p, del_vars, del_cuts);
00302 BCP_lp_pack_user_data(p);
00303 }
00304
00305 int keep = -1;
00306
00307 if (brobj) {
00308
00309
00310 keep = BCP_lp_pack_branching_info(p, brobj);
00311
00312
00313
00314
00315
00316 p.node->dive = BCP_UnknownDivingStatus;
00317 p.msg_env->send(p.tree_manager,
00318 BCP_Msg_NodeDescriptionWithBranchingInfo, buf);
00319 }else{
00320
00321 p.msg_env->send(p.tree_manager, msgtag, buf);
00322 }
00323
00324 if (keep == -1){
00325
00326
00327 return -1;
00328 }
00329
00330
00331
00332
00333
00334
00335 if (p.node->dive == BCP_UnknownDivingStatus) {
00336
00337 p.msg_buf.clear();
00338 p.msg_env->receive(p.tree_manager, BCP_Msg_DivingInfo, buf, -1);
00339 BCP_lp_unpack_diving_info(p, p.msg_buf);
00340 }
00341
00342
00343
00344 if (p.node->index == -1) {
00345 keep = -1;
00346
00347
00348 brobj->keep_no_child();
00349 }
00350 return keep;
00351 }
00352
00353