00001
00002
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
00069
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
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
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
00156 for ( ; j < old_added_num; ++j) {
00157 _del_change_pos.unchecked_push_back(j);
00158 }
00159
00160 _deleted_num = _del_change_pos.size();
00161
00162
00163
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
00170 _del_change_pos.append(chpos);
00171
00172
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
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
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
00259 for ( ; j < old_added_num; ++j) {
00260 _del_change_pos.unchecked_push_back(j);
00261 }
00262
00263 _deleted_num = _del_change_pos.size();
00264
00265
00266
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
00273 _del_change_pos.append(chpos);
00274
00275
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 }