00001
00002
00003 #include <functional>
00004 #include "BCP_message.hpp"
00005 #include "BCP_node_change.hpp"
00006 #include "BCP_warmstart.hpp"
00007 #include "BCP_lp_node.hpp"
00008 #include "BCP_lp_user.hpp"
00009 #include "BCP_lp.hpp"
00010 #include "BCP_lp_functions.hpp"
00011
00012 static inline void
00013 BCP_lp_unpack_parent(BCP_lp_prob& p, BCP_buffer& buf, BCP_lp_node& node);
00014
00015 static inline void
00016 BCP_lp_create_node(BCP_lp_prob& p, BCP_node_change& node_change);
00017
00018 static inline void
00019 BCP_lp_create_core(BCP_lp_prob& p, BCP_node_change& node_change);
00020 static inline void
00021 BCP_lp_set_core(BCP_lp_prob& p, BCP_lp_node& node, BCP_problem_core_change& core);
00022 static inline void
00023 BCP_lp_modify_core(BCP_lp_node& node, BCP_problem_core_change& change);
00024
00025 static inline void
00026 BCP_lp_create_added_vars(BCP_lp_prob& p, BCP_node_change& node_change);
00027 static inline void
00028 BCP_lp_create_added_cuts(BCP_lp_prob& p, BCP_node_change& node_change);
00029
00030 static inline void
00031 BCP_lp_create_warmstart(BCP_lp_prob& p, BCP_node_change& node_change);
00032
00033
00034
00035 void BCP_lp_unpack_parent(BCP_lp_prob& p, BCP_buffer& buf, BCP_lp_node& node)
00036 {
00037 buf.unpack(p.parent->index);
00038 if (node.tm_storage.core_change == BCP_Storage_WrtParent){
00039 p.parent->core_as_change.unpack(buf);
00040
00041
00042 p.parent->core_as_change.ensure_explicit(*p.core_as_change);
00043 }
00044
00045 assert(node.vars.size() == p.core->vars.size());
00046 if (node.tm_storage.var_change == BCP_Storage_WrtParent){
00047
00048 p.parent->var_set.unpack(buf);
00049 #ifdef PARANOID
00050 if (p.parent->var_set.storage() != BCP_Storage_Explicit)
00051 throw BCP_fatal_error("BCP_lp_unpack_parent(): oops 1\n");
00052 #endif
00053 } else {
00054 assert(p.parent->var_set._change.empty());
00055 assert(p.parent->var_set._new_objs.empty());
00056 }
00057
00058 assert(node.cuts.size() == p.core->cuts.size());
00059 if (node.tm_storage.cut_change == BCP_Storage_WrtParent){
00060
00061 p.parent->cut_set.unpack(buf);
00062 #ifdef PARANOID
00063 if (p.parent->cut_set.storage() != BCP_Storage_Explicit)
00064 throw BCP_fatal_error("BCP_lp_unpack_parent(): oops 1\n");
00065 #endif
00066 } else {
00067 assert(p.parent->cut_set._change.empty());
00068 assert(p.parent->cut_set._new_objs.empty());
00069 }
00070
00071 if (node.tm_storage.warmstart == BCP_Storage_WrtParent) {
00072 const bool def = p.param(BCP_lp_par::ReportWhenDefaultIsExecuted);
00073 p.parent->warmstart = p.packer->unpack_warmstart(buf, def);
00074 }
00075 }
00076
00077
00078
00079
00080 void BCP_lp_modify_core(BCP_lp_node& node, BCP_problem_core_change& change)
00081 {
00082 if (change.varnum() > 0)
00083 node.vars.set_lb_ub_st(change.var_pos.begin(), change.var_ch);
00084 if (change.cutnum() > 0)
00085 node.cuts.set_lb_ub_st(change.cut_pos.begin(), change.cut_ch);
00086 }
00087
00088 void BCP_lp_set_core(BCP_lp_prob& p, BCP_lp_node& node,
00089 BCP_problem_core_change& core)
00090 {
00091 switch (core.storage()) {
00092 case BCP_Storage_WrtCore:
00093 if (p.core->varnum() > 0)
00094
00095 node.vars.set_lb_ub_st(p.core_as_change->var_ch);
00096 if (p.core->cutnum() > 0)
00097
00098 node.cuts.set_lb_ub_st(p.core_as_change->cut_ch);
00099 BCP_lp_modify_core(node, core);
00100 break;
00101
00102 case BCP_Storage_Explicit:
00103 if (core.varnum() > 0)
00104
00105 node.vars.set_lb_ub_st(core.var_ch);
00106 if (core.cutnum() > 0)
00107
00108 node.cuts.set_lb_ub_st(core.cut_ch);
00109 break;
00110
00111 default:
00112
00113 throw BCP_fatal_error("BCP_lp_set_core: Impossible storage_type.\n");
00114 }
00115 }
00116
00117
00118
00119 void BCP_lp_create_core(BCP_lp_prob& p, BCP_node_change& node_change)
00120 {
00121 switch (p.node->tm_storage.core_change){
00122 case BCP_Storage_WrtCore:
00123
00124 case BCP_Storage_Explicit:
00125
00126 BCP_lp_set_core(p, *p.node, node_change.core_change);
00127 break;
00128
00129 case BCP_Storage_WrtParent:
00130
00131 BCP_lp_set_core(p, *p.node, p.parent->core_as_change);
00132 BCP_lp_modify_core(*p.node, node_change.core_change);
00133 break;
00134
00135 case BCP_Storage_NoData:
00136
00137 break;
00138
00139 default:
00140
00141 throw BCP_fatal_error("BCP_lp_create_core: Bad storage.\n");
00142 }
00143 }
00144
00145
00146
00147 void BCP_lp_create_added_vars(BCP_lp_prob& p, BCP_node_change& node_change)
00148
00149
00150 {
00151 switch (p.node->tm_storage.var_change) {
00152 case BCP_Storage_WrtParent:
00153 case BCP_Storage_Explicit:
00154 break;
00155 case BCP_Storage_NoData:
00156
00157 return;
00158 case BCP_Storage_WrtCore:
00159 default:
00160
00161 throw BCP_fatal_error("BCP_lp_create_added_vars: Bad storage.\n");
00162 }
00163
00164
00165
00166 BCP_obj_set_change var_set = p.parent->var_set;
00167 var_set.update(node_change.var_change);
00168 assert(p.node->vars.size() == p.core->varnum() + var_set._change.size());
00169 assert(var_set._change.size() == var_set._new_objs.size());
00170 BCP_var** added_vars = &p.node->vars[0] + p.core->varnum();
00171 for (int i = var_set._change.size() - 1; i >= 0; --i) {
00172 added_vars[i]->change_lb_ub_st(var_set._change[i]);
00173 }
00174 }
00175
00176
00177
00178 void BCP_lp_create_added_cuts(BCP_lp_prob& p, BCP_node_change& node_change)
00179 {
00180 switch (p.node->tm_storage.cut_change) {
00181 case BCP_Storage_WrtParent:
00182 case BCP_Storage_Explicit:
00183 break;
00184 case BCP_Storage_NoData:
00185
00186 return;
00187 case BCP_Storage_WrtCore:
00188 default:
00189
00190 throw BCP_fatal_error("BCP_lp_create_added_cuts: Bad storage.\n");
00191 }
00192
00193
00194
00195 BCP_obj_set_change cut_set = p.parent->cut_set;
00196 cut_set.update(node_change.cut_change);
00197 assert(p.node->cuts.size() == p.core->cutnum() + cut_set._change.size());
00198 assert(cut_set._change.size() == cut_set._new_objs.size());
00199 BCP_cut** added_cuts = &p.node->cuts[0] + p.core->cutnum();
00200 for (int i = cut_set._change.size() - 1; i >= 0; --i) {
00201 added_cuts[i]->change_lb_ub_st(cut_set._change[i]);
00202 }
00203 }
00204
00205
00206
00207 void BCP_lp_create_warmstart(BCP_lp_prob& p, BCP_node_change& node_change)
00208 {
00209 switch (p.node->tm_storage.warmstart) {
00210 case BCP_Storage_WrtParent:
00211 p.node->warmstart = p.parent->warmstart->clone();
00212 p.node->warmstart->update(node_change.warmstart);
00213 break;
00214
00215 case BCP_Storage_Explicit:
00216 p.node->warmstart = node_change.warmstart;
00217 node_change.warmstart = 0;
00218 break;
00219
00220 case BCP_Storage_NoData:
00221 break;
00222
00223 case BCP_Storage_WrtCore:
00224 default:
00225
00226 throw BCP_fatal_error("BCP_lp_create_warmstart: Bad storage.\n");
00227 }
00228 }
00229
00230
00231
00232 void BCP_lp_create_node(BCP_lp_prob& p, BCP_node_change& node_change)
00233 {
00234
00235 p.node->iteration_count = 0;
00236
00237 BCP_lp_create_core(p, node_change);
00238 BCP_lp_create_added_vars(p, node_change);
00239 BCP_lp_create_added_cuts(p, node_change);
00240 BCP_lp_create_warmstart(p, node_change);
00241 }
00242
00243
00244
00245 void BCP_lp_unpack_active_node(BCP_lp_prob& p, BCP_buffer& buf)
00246 {
00247 const bool def = p.param(BCP_lp_par::ReportWhenDefaultIsExecuted);
00248
00249 if (p.parent->warmstart != 0 || p.node->warmstart != 0) {
00250 throw BCP_fatal_error("\
00251 BCP_lp_unpack_active_node: parent's or node's warmstart is non-0.\n");
00252 }
00253
00254 BCP_lp_node& node = *p.node;
00255
00256 buf.unpack(node.colgen).unpack(node.index).unpack(node.level)
00257 .unpack(node.quality).unpack(node.true_lower_bound)
00258 .unpack(node.dive);
00259
00260
00261 buf.unpack(node.cg);
00262 buf.unpack(node.cp);
00263 buf.unpack(node.vg);
00264 buf.unpack(node.vp);
00265
00266
00267 buf.unpack(node.tm_storage.core_change)
00268 .unpack(node.tm_storage.var_change)
00269 .unpack(node.tm_storage.cut_change)
00270 .unpack(node.tm_storage.warmstart);
00271
00272 if (node.level > 0)
00273 BCP_lp_unpack_parent(p, buf, node);
00274
00275 BCP_node_change node_change;
00276 node_change.unpack(p.packer, def, buf);
00277
00278
00279 int i, cnt;
00280 buf.unpack(cnt);
00281 assert(node.vars.size() == p.core->vars.size());
00282 node.vars.reserve(cnt+node.vars.size());
00283 for (i = 0; i < cnt; ++i) {
00284 node.vars.unchecked_push_back(p.unpack_var());
00285 }
00286 buf.unpack(cnt);
00287 assert(node.cuts.size() == p.core->cuts.size());
00288 node.cuts.reserve(cnt+node.cuts.size());
00289 for (i = 0; i < cnt; ++i) {
00290 node.cuts.unchecked_push_back(p.unpack_cut());
00291 }
00292
00293
00294 BCP_lp_create_node(p, node_change);
00295
00296
00297 delete p.node->user_data;
00298 bool has_data;
00299 buf.unpack(has_data);
00300 p.node->user_data = has_data ? p.packer->unpack_user_data(buf) : 0;
00301 }