Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

BCP_obj_change.cpp

00001 // Copyright (C) 2000, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
00003 #include <CoinDistance.hpp>
00004 #include "BCP_error.hpp"
00005 #include "BCP_buffer.hpp"
00006 #include "BCP_obj_change.hpp"
00007 #include "BCP_var.hpp"
00008 #include "BCP_cut.hpp"
00009 
00010 //#############################################################################
00011 
00012 void
00013 BCP_var_set_change::update(const BCP_var_set_change& vars_change)
00014 {
00015    if (vars_change.storage() == BCP_Storage_Explicit){
00016       _new_vars.clear();
00017       _change.clear();
00018    }else{
00019       if (vars_change.deleted_num() > 0){
00020          BCP_vec<int>::const_iterator firstdel =
00021             vars_change._del_change_pos.begin();
00022          BCP_vec<int>::const_iterator lastdel =
00023             vars_change._del_change_pos.entry(vars_change.deleted_num());
00024          _new_vars.erase_by_index(firstdel, lastdel);
00025          _change.erase_by_index(firstdel, lastdel);
00026       }
00027    }
00028    if (vars_change.added_num() > 0) {
00029       _new_vars.append(vars_change._new_vars);
00030       _change.append(vars_change._change.entry(vars_change.changed_num() -
00031                                                vars_change.added_num()),
00032                      vars_change._change.end());
00033    }
00034    if (vars_change.changed_num() - vars_change.added_num() > 0){
00035 #if PARANOID
00036       if (vars_change.storage() != BCP_Storage_WrtParent)
00037          throw BCP_fatal_error("BCP_update_varset_and_changes(): oops\n");
00038 #endif
00039       BCP_vec<BCP_obj_change>::const_iterator firstch =
00040          vars_change._change.begin();
00041       BCP_vec<BCP_obj_change>::const_iterator lastch =
00042          vars_change._change.entry(vars_change.changed_num() -
00043                                    vars_change.added_num());
00044       BCP_vec<int>::const_iterator firstchpos =
00045          vars_change._del_change_pos.entry(vars_change.deleted_num());
00046       while (firstch != lastch) {
00047          _change[*firstchpos] = *firstch;
00048          ++firstch;
00049          ++firstchpos;
00050       }
00051    }
00052 }
00053 
00054 //#############################################################################
00055 
00056 void
00057 BCP_cut_set_change::update(const BCP_cut_set_change& cuts_change)
00058 {
00059    if (cuts_change.storage() == BCP_Storage_Explicit){
00060       _new_cuts.clear();
00061       _change.clear();
00062    }else{
00063       if (cuts_change.deleted_num() > 0){
00064          BCP_vec<int>::const_iterator firstdel =
00065             cuts_change._del_change_pos.begin();
00066          BCP_vec<int>::const_iterator lastdel =
00067             cuts_change._del_change_pos.entry(cuts_change.deleted_num());
00068          // BCP_vec<BCP_cut*>& cutset =
00069          //   dynamic_cast<BCP_vec<BCP_cut*>&>(*this);
00070          _new_cuts.erase_by_index(firstdel, lastdel);
00071          _change.erase_by_index(firstdel, lastdel);
00072       }
00073    }
00074    if (cuts_change.added_num() > 0) {
00075       _new_cuts.append(cuts_change._new_cuts);
00076       _change.append(cuts_change._change.entry(cuts_change.changed_num() -
00077                                                cuts_change.added_num()),
00078                      cuts_change._change.end());
00079    }
00080    if (cuts_change.changed_num() - cuts_change.added_num() > 0){
00081 #if PARANOID
00082       if (cuts_change.storage() != BCP_Storage_WrtParent)
00083          throw BCP_fatal_error("BCP_update_cutset_and_changes(): oops\n");
00084 #endif
00085       BCP_vec<BCP_obj_change>::const_iterator firstch =
00086          cuts_change._change.begin();
00087       BCP_vec<BCP_obj_change>::const_iterator lastch =
00088          cuts_change._change.entry(cuts_change.changed_num() -
00089                                    cuts_change.added_num());
00090       BCP_vec<int>::const_iterator firstchpos =
00091          cuts_change._del_change_pos.entry(cuts_change.deleted_num());
00092       while (firstch != lastch) {
00093          _change[*firstchpos] = *firstch;
00094          ++firstch;
00095          ++firstchpos;
00096       }
00097    }
00098 }
00099 
00100 //#############################################################################
00101 //#############################################################################
00102 
00103 BCP_var_set_change::BCP_var_set_change(BCP_vec<BCP_var*>::const_iterator first,
00104                                        BCP_vec<BCP_var*>::const_iterator last):
00105    _storage(BCP_Storage_Explicit), _deleted_num(0),
00106    _del_change_pos(), _change(), _new_vars()
00107 {
00108    if (first != last) {
00109       const int added_var_num = coinDistance(first, last);
00110       _change.reserve(added_var_num);
00111       _new_vars.reserve(added_var_num);
00112       while (first != last) {
00113          const BCP_var* var = *first;
00114          _change.unchecked_push_back(BCP_obj_change(var->lb(), var->ub(),
00115                                                     var->status()));
00116          _new_vars.unchecked_push_back(*first);
00117          ++first;
00118       }
00119    }
00120 }
00121 
00122 //-----------------------------------------------------------------------------
00123 
00124 BCP_var_set_change::
00125 BCP_var_set_change(BCP_vec<BCP_var*>::const_iterator first,
00126                    BCP_vec<BCP_var*>::const_iterator last,
00127                    const BCP_vec<BCP_IndexType>& added_bcpind,
00128                    const BCP_vec<BCP_obj_change>& added_desc) :
00129    _storage(BCP_Storage_WrtParent), _deleted_num(0),
00130    _del_change_pos(), _change(), _new_vars()
00131 {
00132    const int new_added_num = coinDistance(first, last);
00133    const int old_added_num = added_bcpind.size();
00134    _del_change_pos.reserve(old_added_num);
00135 
00136    BCP_vec<int> chpos;
00137    chpos.reserve(new_added_num);
00138 
00139    int i, j;
00140 
00141    // first check how many entry has been deleted from oldvars
00142    for (i = 0, j = 0; i < new_added_num && j < old_added_num; ++j) {
00143       const BCP_var* const var = *(first + i);
00144       const BCP_obj_change& added = added_desc[j];
00145       if (var->bcpind() == added_bcpind[j]) {
00146          // added_bcpind ALWAYS has real indices, so this really separates
00147          if (var->lb() != added.lb || var->ub() != added.ub ||
00148              var->status() != added.stat)
00149             chpos.unchecked_push_back(i);
00150          ++i;
00151       } else {
00152          _del_change_pos.unchecked_push_back(j);
00153       }
00154    }
00155    // append the remains of old_added to _del_change_pos
00156    for ( ; j < old_added_num; ++j) {
00157       _del_change_pos.unchecked_push_back(j);
00158    }
00159    // _deleted_num is the current length of _del_change_pos
00160    _deleted_num = _del_change_pos.size();
00161 
00162    // the rest are the set of really new vars, and also the position of those
00163    // vars must be appended to chpos.
00164    _new_vars.reserve(new_added_num - i);
00165    for ( ; i < new_added_num; ++i){
00166       _new_vars.unchecked_push_back(*(first + i));
00167       chpos.unchecked_push_back(i);
00168    }
00169    // append chpos to _del_change_pos to get the final list
00170    _del_change_pos.append(chpos);
00171 
00172    // finally, create _change: just pick up things based on chpos
00173    const int chnum = chpos.size();
00174    _change.reserve(chnum);
00175    for (i = 0; i < chnum; ++i) {
00176       const BCP_var* const var = *(first + chpos[i]);
00177       _change.unchecked_push_back(BCP_obj_change(var->lb(), var->ub(),
00178                                                  var->status()));
00179    }
00180 }
00181 
00182 //-----------------------------------------------------------------------------
00183 
00184 void
00185 BCP_var_set_change::swap(BCP_var_set_change& x)
00186 {
00187    std::swap(_storage, x._storage);
00188    std::swap(_deleted_num, x._deleted_num);
00189    _del_change_pos.swap(x._del_change_pos);
00190    _change.swap(x._change);
00191    _new_vars.swap(x._new_vars);
00192 }
00193 
00194 //-----------------------------------------------------------------------------
00195 
00196 int 
00197 BCP_var_set_change::pack_size() const
00198 {
00199    return ( _del_change_pos.size() * sizeof(int) +
00200             _change.size() * BCP_obj_change::pack_size() +
00201             _new_vars.size() * (sizeof(bool) + sizeof(int)) );
00202 }
00203 
00204 //#############################################################################
00205 
00206 BCP_cut_set_change::BCP_cut_set_change(BCP_vec<BCP_cut*>::const_iterator first,
00207                                        BCP_vec<BCP_cut*>::const_iterator last):
00208    _storage(BCP_Storage_Explicit), _deleted_num(0),
00209    _del_change_pos(), _change(), _new_cuts()
00210 {
00211    if (first != last) {
00212       const int added_cut_num = coinDistance(first, last);
00213       _change.reserve(added_cut_num);
00214       _new_cuts.reserve(added_cut_num);
00215       while (first != last) {
00216          const BCP_cut* cut = *first;
00217          _change.unchecked_push_back(BCP_obj_change(cut->lb(), cut->ub(),
00218                                                     cut->status()));
00219          _new_cuts.unchecked_push_back(*first);
00220          ++first;
00221       }
00222    }
00223 }
00224 
00225 //-----------------------------------------------------------------------------
00226 
00227 BCP_cut_set_change::
00228 BCP_cut_set_change(BCP_vec<BCP_cut*>::const_iterator first,
00229                    BCP_vec<BCP_cut*>::const_iterator last,
00230                    const BCP_vec<BCP_IndexType>& added_bcpind,
00231                    const BCP_vec<BCP_obj_change>& added_desc) :
00232    _storage(BCP_Storage_WrtParent), _deleted_num(0),
00233    _del_change_pos(), _change(), _new_cuts()
00234 {
00235    const int new_added_num = coinDistance(first, last);
00236    const int old_added_num = added_bcpind.size();
00237    _del_change_pos.reserve(old_added_num);
00238 
00239    BCP_vec<int> chpos;
00240    chpos.reserve(new_added_num);
00241 
00242    int i, j;
00243 
00244    // first check how many entry has been deleted from oldcuts
00245    for (i = 0, j = 0; i < new_added_num && j < old_added_num; ++j) {
00246       const BCP_cut* const cut = *(first + i);
00247       const BCP_obj_change& added = added_desc[j];
00248       if (cut->bcpind() == added_bcpind[j]) {
00249          // added_bcpind ALWAYS has real indices, so this really separates
00250          if (cut->lb() != added.lb || cut->ub() != added.ub ||
00251              cut->status() != added.stat)
00252             chpos.unchecked_push_back(i);
00253          ++i;
00254       } else {
00255          _del_change_pos.unchecked_push_back(j);
00256       }
00257    }
00258    // append the remains of old_added to _del_change_pos
00259    for ( ; j < old_added_num; ++j) {
00260       _del_change_pos.unchecked_push_back(j);
00261    }
00262    // _deleted_num is the current length of _del_change_pos
00263    _deleted_num = _del_change_pos.size();
00264 
00265    // the rest are the set of really new cuts, and also the position of those
00266    // cuts must be appended to chpos.
00267    _new_cuts.reserve(new_added_num - i);
00268    for ( ; i < new_added_num; ++i){
00269       _new_cuts.unchecked_push_back(*(first + i));
00270       chpos.unchecked_push_back(i);
00271    }
00272    // append chpos to _del_change_pos to get the final list
00273    _del_change_pos.append(chpos);
00274 
00275    // finally, create _change: just pick up things based on chpos
00276    const int chnum = chpos.size();
00277    _change.reserve(chnum);
00278    for (i = 0; i < chnum; ++i) {
00279       const BCP_cut* const cut = *(first + chpos[i]);
00280       _change.unchecked_push_back(BCP_obj_change(cut->lb(), cut->ub(),
00281                                                  cut->status()));
00282    }
00283 }
00284 
00285 //-----------------------------------------------------------------------------
00286 
00287 void
00288 BCP_cut_set_change::swap(BCP_cut_set_change& x)
00289 {
00290    std::swap(_storage, x._storage);
00291    std::swap(_deleted_num, x._deleted_num);
00292    _del_change_pos.swap(x._del_change_pos);
00293    _change.swap(x._change);
00294    _new_cuts.swap(x._new_cuts);
00295 }
00296 
00297 //-----------------------------------------------------------------------------
00298 
00299 int 
00300 BCP_cut_set_change::pack_size() const
00301 {
00302    return ( _del_change_pos.size() * sizeof(int) +
00303             _change.size() * BCP_obj_change::pack_size() +
00304             _new_cuts.size() * (sizeof(bool) + sizeof(int)) );
00305 }

Generated on Wed Dec 3 14:32:30 2003 for BCP by doxygen 1.3.5