/home/coin/SVN-release/OS-2.0.0/Bcp/src/Member/BCP_problem_core.cpp

Go to the documentation of this file.
00001 // Copyright (C) 2000, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
00003 // #include <functional>
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 /*colordered*/)) {}
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 /*colordered*/);
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    // save the positions of the changed vars / cuts
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       // wrt core is shorter
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); // _storage becomes Explicit
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); // _storage becomes Explicit
00325       // deliberate fall-through
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 }

Generated on Mon Aug 3 03:02:15 2009 by  doxygen 1.4.7