00001
00002
00003
00004 #include "BCP_error.hpp"
00005 #include "BCP_buffer.hpp"
00006 #include "BCP_problem_core.hpp"
00007 #include "BCP_var.hpp"
00008 #include "BCP_cut.hpp"
00009 #include "BCP_matrix.hpp"
00010 #include "BCP_branch.hpp"
00011
00012
00013
00014 inline void BCP_problem_core::clear() {
00015 delete matrix; matrix = 0;
00016 purge_ptr_vector(cuts);
00017 purge_ptr_vector(vars);
00018 }
00019
00020
00021
00022 BCP_problem_core::BCP_problem_core() :
00023 vars(), cuts(), matrix(new BCP_lp_relax(true )) {}
00024
00025 BCP_problem_core::~BCP_problem_core()
00026 {
00027 clear();
00028 }
00029
00030
00031
00032 void BCP_problem_core::pack(BCP_buffer& buf) const
00033 {
00034 buf.pack(vars.size());
00035 if (vars.size() > 0) {
00036 BCP_vec<BCP_var_core*>::const_iterator vi = vars.begin() - 1;
00037 const BCP_vec<BCP_var_core*>::const_iterator lastvi = vars.end();
00038 while (++vi != lastvi) {
00039 const BCP_var_core& var = **vi;
00040 const int bcpind = var.bcpind();
00041 const BCP_object_t obj_t = var.obj_type();
00042 const BCP_obj_status stat = var.status();
00043 const BCP_var_t var_t = var.var_type();
00044 const double obj = var.obj();
00045 const double lb = var.lb();
00046 const double ub = var.ub();
00047 buf.pack(bcpind)
00048 .pack(obj_t).pack(stat).pack(var_t).pack(obj).pack(lb).pack(ub);
00049 }
00050 }
00051
00052 buf.pack(cuts.size());
00053 if (cuts.size() > 0) {
00054 BCP_vec<BCP_cut_core*>::const_iterator ci = cuts.begin() - 1;
00055 const BCP_vec<BCP_cut_core*>::const_iterator lastci = cuts.end();
00056 while (++ci != lastci) {
00057 BCP_cut_core& cut = **ci;
00058 const int bcpind = cut.bcpind();
00059 const BCP_object_t obj_t = cut.obj_type();
00060 const BCP_obj_status stat = cut.status();
00061 const double lb = cut.lb();
00062 const double ub = cut.ub();
00063 buf.pack(bcpind).pack(obj_t).pack(stat).pack(lb).pack(ub);
00064 }
00065 }
00066
00067 matrix->pack(buf);
00068 }
00069
00070
00071
00072 void BCP_problem_core::unpack(BCP_buffer& buf)
00073 {
00074 clear();
00075 size_t size;
00076 int bcpind;
00077 BCP_object_t obj_t;
00078 BCP_obj_status stat;
00079 BCP_var_t var_t;
00080 double obj;
00081 double lb;
00082 double ub;
00083
00084 buf.unpack(size);
00085 if (size > 0) {
00086 BCP_var_core* bvar;
00087 for (vars.reserve(size); size; --size) {
00088 buf.unpack(bcpind)
00089 .unpack(obj_t).unpack(stat)
00090 .unpack(var_t).unpack(obj).unpack(lb).unpack(ub);
00091 bvar = new BCP_var_core(var_t, obj, lb, ub);
00092 bvar->set_bcpind(bcpind);
00093 bvar->set_status(stat);
00094 vars.unchecked_push_back(bvar);
00095 }
00096 }
00097
00098 buf.unpack(size);
00099 if (size > 0) {
00100 BCP_cut_core* bcut;
00101 for (cuts.reserve(size); size; --size) {
00102 buf.unpack(bcpind).unpack(obj_t).unpack(stat).unpack(lb).unpack(ub);
00103 bcut = new BCP_cut_core(lb, ub);
00104 bcut->set_bcpind(bcpind);
00105 bcut->set_status(stat);
00106 cuts.unchecked_push_back(bcut);
00107 }
00108 }
00109
00110 matrix = new BCP_lp_relax(true );
00111 matrix->unpack(buf);
00112 }
00113
00114
00115
00116 inline void BCP_problem_core_change::clear() {
00117 var_pos.clear();
00118 var_ch.clear();
00119 cut_pos.clear();
00120 cut_ch.clear();
00121 }
00122
00123 #if 0
00124 BCP_problem_core_change&
00125 BCP_problem_core_change::operator=(const BCP_problem_core_change& x) {
00126 _storage = x._storage;
00127 var_pos = x.var_pos;
00128 var_ch = x.var_ch;
00129 cut_pos = x.cut_pos;
00130 cut_ch = x.cut_ch;
00131 return *this;
00132 }
00133 #endif
00134
00135
00136
00137 BCP_problem_core_change&
00138 BCP_problem_core_change::operator=(const BCP_problem_core& core) {
00139 clear();
00140 _storage = BCP_Storage_Explicit;
00141
00142 var_ch.reserve(core.varnum());
00143 BCP_vec<BCP_var_core*>::const_iterator vi = core.vars.begin();
00144 const BCP_vec<BCP_var_core*>::const_iterator lastvi = core.vars.end();
00145 for ( ; vi != lastvi; ++vi)
00146 var_ch.unchecked_push_back(BCP_obj_change((*vi)->lb(), (*vi)->ub(),
00147 BCP_ObjNotRemovable));
00148 cut_ch.reserve(core.cutnum());
00149 BCP_vec<BCP_cut_core*>::const_iterator ci = core.cuts.begin();
00150 const BCP_vec<BCP_cut_core*>::const_iterator lastci = core.cuts.end();
00151 for ( ; ci != lastci; ++ci)
00152 cut_ch.unchecked_push_back(BCP_obj_change((*ci)->lb(), (*ci)->ub(),
00153 BCP_ObjNotRemovable));
00154 return *this;
00155 }
00156
00157
00158
00159 BCP_problem_core_change::BCP_problem_core_change(int bvarnum,
00160 BCP_var_set& vars,
00161 int bcutnum,
00162 BCP_cut_set& cuts) :
00163 _storage(BCP_Storage_Explicit), var_pos(), var_ch(), cut_pos(), cut_ch()
00164 {
00165 _storage = BCP_Storage_Explicit;
00166 var_ch.reserve(bvarnum);
00167 #if 0
00168 BCP_var_set::const_iterator vari;
00169 const BCP_var_set::const_iterator lastvari = vars.entry(bvarnum);
00170 for (vari = vars.begin(); vari != lastvari; ++vari)
00171 var_ch.unchecked_push_back(BCP_obj_change((*vari)->lb(), (*vari)->ub(),
00172 (*vari)->status()));
00173 #else
00174 for (int i = 0; i < bvarnum; ++i) {
00175 const BCP_var* v = vars[i];
00176 var_ch.unchecked_push_back(BCP_obj_change(v->lb(),v->ub(), v->status()));
00177 }
00178 #endif
00179 cut_ch.reserve(bcutnum);
00180 BCP_cut_set::const_iterator cuti;
00181 const BCP_cut_set::const_iterator lastcuti = cuts.entry(bcutnum);
00182 for (cuti = cuts.begin(); cuti != lastcuti; ++cuti)
00183 cut_ch.unchecked_push_back(BCP_obj_change((*cuti)->lb(), (*cuti)->ub(),
00184 (*cuti)->status()));
00185 }
00186
00187
00188
00189 BCP_problem_core_change::
00190 BCP_problem_core_change(BCP_storage_t storage,
00191 BCP_problem_core_change& ocore,
00192 BCP_problem_core_change& ncore) :
00193 _storage(storage), var_pos(), var_ch(), cut_pos(), cut_ch()
00194 {
00195 if (storage != BCP_Storage_WrtParent && storage != BCP_Storage_WrtCore) {
00196 throw BCP_fatal_error("\
00197 BCP_problem_core_change() : bad proposed storage\n");
00198 }
00199
00200 if (ocore.storage() != BCP_Storage_Explicit)
00201 throw BCP_fatal_error("BCP_problem_core_change() : bad ocore storage\n");
00202 if (ncore.storage() != BCP_Storage_Explicit)
00203 throw BCP_fatal_error("BCP_problem_core_change() : bad ncore storage\n");
00204
00205 int i;
00206
00207 const int bvarnum = ncore.varnum();
00208 var_pos.reserve(bvarnum);
00209 var_ch.reserve(bvarnum);
00210 for (i = 0; i < bvarnum; ++i) {
00211 if (ocore.var_ch[i] != ncore.var_ch[i]) {
00212 var_pos.unchecked_push_back(i);
00213 var_ch.unchecked_push_back(ncore.var_ch[i]);
00214 }
00215 }
00216
00217 const int bcutnum = ncore.cutnum();
00218 cut_pos.reserve(bcutnum);
00219 cut_ch.reserve(bcutnum);
00220 for (i = 0; i < bcutnum; ++i) {
00221 if (ocore.cut_ch[i] != ncore.cut_ch[i]) {
00222 cut_pos.unchecked_push_back(i);
00223 cut_ch.unchecked_push_back(ncore.cut_ch[i]);
00224 }
00225 }
00226 }
00227
00228
00229
00230 void
00231 BCP_problem_core_change::ensure_explicit(const BCP_problem_core_change& ecore)
00232 {
00233 if (_storage == BCP_Storage_Explicit)
00234 return;
00235 if (_storage != BCP_Storage_WrtCore)
00236 throw BCP_fatal_error("\
00237 BCP_problem_core_change::ensure_explicit() : bad current storage\n");
00238 if (ecore.storage() != BCP_Storage_Explicit)
00239 throw BCP_fatal_error("\
00240 BCP_problem_core_change::ensure_explicit() : bad ecore storage\n");
00241
00242 BCP_problem_core_change new_core;
00243 new_core.update(ecore, *this);
00244 swap(new_core);
00245 }
00246
00247
00248
00249 void
00250 BCP_problem_core_change::
00251 make_wrtcore_if_shorter(const BCP_problem_core_change& ecore)
00252 {
00253 if (_storage != BCP_Storage_Explicit)
00254 throw BCP_fatal_error("\
00255 BCP_problem_core_change::make_wrtcore_if_shorter() : bad storage\n");
00256 if (ecore.storage() != BCP_Storage_Explicit)
00257 throw BCP_fatal_error("\
00258 BCP_problem_core_change::make_wrtcore_if_shorter() : bad ecore storage\n");
00259 if (varnum() != ecore.varnum())
00260 throw BCP_fatal_error("\
00261 BCP_problem_core_change::make_wrtcore_if_shorter() : nonequal sizes\n");
00262
00263 int i;
00264
00265
00266 BCP_vec<int> chvar;
00267 chvar.reserve(ecore.varnum());
00268
00269 const int bvarnum = var_ch.size();
00270 for (i = 0; i < bvarnum; ++i)
00271 if (var_ch[i] != ecore.var_ch[i])
00272 chvar.unchecked_push_back(i);
00273
00274 BCP_vec<int> chcut;
00275 chcut.reserve(ecore.cutnum());
00276
00277 const int bcutnum = cut_ch.size();
00278 for (i = 0; i < bcutnum; ++i)
00279 if (cut_ch[i] != ecore.cut_ch[i])
00280 chcut.unchecked_push_back(i);
00281
00282 if ((chvar.size() + chcut.size()) * sizeof(int) <
00283 (ecore.varnum() - chvar.size() + ecore.cutnum() - chcut.size()) *
00284 BCP_obj_change::pack_size()) {
00285
00286 _storage = BCP_Storage_WrtCore;
00287 var_pos.swap(chvar);
00288 var_ch.keep_by_index(var_pos);
00289 cut_pos.swap(chcut);
00290 cut_ch.keep_by_index(cut_pos);
00291 }
00292 }
00293
00294
00295
00296 void BCP_problem_core_change::swap(BCP_problem_core_change& other)
00297 {
00298 std::swap(_storage, other._storage);
00299
00300 var_pos.swap(other.var_pos);
00301 var_ch.swap(other.var_ch);
00302 cut_pos.swap(other.cut_pos);
00303 cut_ch.swap(other.cut_ch);
00304 }
00305
00306
00307
00308 void BCP_problem_core_change::update(const BCP_problem_core_change& expl_core,
00309 const BCP_problem_core_change& ch_core)
00310 {
00311 switch (ch_core._storage){
00312 case BCP_Storage_Explicit:
00313 operator=(ch_core);
00314 break;
00315
00316 case BCP_Storage_NoData:
00317 _storage = BCP_Storage_NoData;
00318 break;
00319
00320 case BCP_Storage_WrtCore:
00321 if (expl_core.storage() != BCP_Storage_Explicit)
00322 throw BCP_fatal_error("BCP_problem_core_change::update():\n\
00323 ch_core's WrtCore, but expl_core's not Explicit\n");
00324 operator=(expl_core);
00325
00326
00327 case BCP_Storage_WrtParent:
00328 if (_storage != BCP_Storage_Explicit)
00329 throw BCP_fatal_error("BCP_problem_core_change::update():\n\
00330 _storage isn't Explicit && ch_core's WrtParent\n");
00331 var_ch.update(ch_core.var_pos, ch_core.var_ch);
00332 cut_ch.update(ch_core.cut_pos, ch_core.cut_ch);
00333 break;
00334
00335 default:
00336 throw BCP_fatal_error("\
00337 BCP_problem_core_change::update(): bad ch_core storage!\n");
00338 break;
00339 }
00340 }
00341
00342
00343
00344 int BCP_problem_core_change::pack_size() const {
00345 int siz = sizeof(BCP_storage_t);
00346 siz += sizeof(int) + sizeof(int) * var_pos.size();
00347 siz += sizeof(int) + BCP_obj_change::pack_size() * var_ch.size();
00348 siz += sizeof(int) + sizeof(int) * cut_pos.size();
00349 siz += sizeof(int) + BCP_obj_change::pack_size() * cut_ch.size();
00350 return siz;
00351 }
00352
00353
00354
00355 void BCP_problem_core_change::pack(BCP_buffer& buf) const {
00356 buf.pack(_storage);
00357 if (_storage != BCP_Storage_NoData)
00358 buf.pack(var_pos).pack(cut_pos).pack(var_ch).pack(cut_ch);
00359 }
00360
00361
00362
00363 void BCP_problem_core_change::unpack(BCP_buffer& buf) {
00364 buf.unpack(_storage);
00365 if (_storage != BCP_Storage_NoData)
00366 buf.unpack(var_pos).unpack(cut_pos).unpack(var_ch).unpack(cut_ch);
00367 }