00001
00002
00003 #include <CoinDistance.hpp>
00004 #include "BCP_error.hpp"
00005 #include "BCP_buffer.hpp"
00006 #include "BCP_obj_change.hpp"
00007
00008
00009
00010
00011
00012 void
00013 BCP_obj_set_change::update(const BCP_obj_set_change& objs_change)
00014 {
00015 if (objs_change.storage() == BCP_Storage_Explicit){
00016 _new_objs.clear();
00017 _change.clear();
00018 }else{
00019 if (objs_change.deleted_num() > 0){
00020 BCP_vec<int>::const_iterator firstdel =
00021 objs_change._del_change_pos.begin();
00022 BCP_vec<int>::const_iterator lastdel =
00023 objs_change._del_change_pos.entry(objs_change.deleted_num());
00024 _new_objs.erase_by_index(firstdel, lastdel);
00025 _change.erase_by_index(firstdel, lastdel);
00026 }
00027 }
00028 if (objs_change.added_num() > 0) {
00029 _new_objs.append(objs_change._new_objs);
00030 _change.append(objs_change._change.entry(objs_change.changed_num() -
00031 objs_change.added_num()),
00032 objs_change._change.end());
00033 }
00034 if (objs_change.changed_num() - objs_change.added_num() > 0){
00035 #if PARANOID
00036 if (objs_change.storage() != BCP_Storage_WrtParent)
00037 throw BCP_fatal_error("BCP_obj_set_change::update(): oops\n");
00038 #endif
00039 BCP_vec<BCP_obj_change>::const_iterator firstch =
00040 objs_change._change.begin();
00041 BCP_vec<BCP_obj_change>::const_iterator lastch =
00042 objs_change._change.entry(objs_change.changed_num() -
00043 objs_change.added_num());
00044 BCP_vec<int>::const_iterator firstchpos =
00045 objs_change._del_change_pos.entry(objs_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_obj_set_change::swap(BCP_obj_set_change& x)
00058 {
00059 std::swap(_storage, x._storage);
00060 std::swap(_deleted_num, x._deleted_num);
00061 _del_change_pos.swap(x._del_change_pos);
00062 _change.swap(x._change);
00063 _new_objs.swap(x._new_objs);
00064 }
00065
00066
00067
00068 int
00069 BCP_obj_set_change::pack_size() const
00070 {
00071 return ( 5 * sizeof(int) + _del_change_pos.size() * sizeof(int) +
00072 _change.size() * BCP_obj_change::pack_size() +
00073 _new_objs.size() * sizeof(int) );
00074 }
00075
00076
00077
00078 void
00079 BCP_obj_set_change::pack(BCP_buffer& buf) const
00080 {
00081 buf.pack(_storage);
00082 buf.pack(_deleted_num);
00083 buf.pack(_del_change_pos);
00084 buf.pack(_change);
00085 buf.pack(_new_objs);
00086 }
00087
00088
00089
00090 void
00091 BCP_obj_set_change::unpack(BCP_buffer& buf)
00092 {
00093 buf.unpack(_storage);
00094 buf.unpack(_deleted_num);
00095 buf.unpack(_del_change_pos);
00096 buf.unpack(_change);
00097 buf.unpack(_new_objs);
00098 }
00099
00100
00101
00102 void
00103 BCP_obj_set_change::print() const
00104 {
00105 printf(" storage: %i\n", _storage);
00106 printf(" deleted_num: %i\n", _deleted_num);
00107 if (_deleted_num > 0) {
00108 printf(" deleted pos:\n");
00109 for (int i = 0; i < _deleted_num; ++i) {
00110 printf(" %i\n", _del_change_pos[i]);
00111 }
00112 }
00113 int pos = _deleted_num;
00114 int chpos = 0;
00115 const int changed = _del_change_pos.size() - _deleted_num;
00116 if (changed > 0) {
00117 printf(" changed pos/newval:\n");
00118 for (int chpos = 0; chpos < changed; ++chpos, ++pos) {
00119 printf(" pos %i, status %i, lb %f, ub %f\n",
00120 _del_change_pos[pos],
00121 _change[chpos].stat, _change[chpos].lb, _change[chpos].ub);
00122 }
00123 }
00124 if (added_num() > 0) {
00125 printf(" new bcpind/newval:\n");
00126 for (int i = 0; i < added_num(); ++i, ++chpos) {
00127 printf(" bcpind %i, status %i, lb %f, ub %f\n",
00128 _new_objs[i],
00129 _change[chpos].stat, _change[chpos].lb, _change[chpos].ub );
00130 }
00131 }
00132 }
00133
00134
00135 #if 0
00136
00137
00138 void
00139 BCP_var_set_change::update(const BCP_var_set_change& vars_change)
00140 {
00141 if (vars_change.storage() == BCP_Storage_Explicit){
00142 _new_vars.clear();
00143 _change.clear();
00144 }else{
00145 if (vars_change.deleted_num() > 0){
00146 BCP_vec<int>::const_iterator firstdel =
00147 vars_change._del_change_pos.begin();
00148 BCP_vec<int>::const_iterator lastdel =
00149 vars_change._del_change_pos.entry(vars_change.deleted_num());
00150 _new_vars.erase_by_index(firstdel, lastdel);
00151 _change.erase_by_index(firstdel, lastdel);
00152 }
00153 }
00154 if (vars_change.added_num() > 0) {
00155 _new_vars.append(vars_change._new_vars);
00156 _change.append(vars_change._change.entry(vars_change.changed_num() -
00157 vars_change.added_num()),
00158 vars_change._change.end());
00159 }
00160 if (vars_change.changed_num() - vars_change.added_num() > 0){
00161 #if PARANOID
00162 if (vars_change.storage() != BCP_Storage_WrtParent)
00163 throw BCP_fatal_error("BCP_update_varset_and_changes(): oops\n");
00164 #endif
00165 BCP_vec<BCP_obj_change>::const_iterator firstch =
00166 vars_change._change.begin();
00167 BCP_vec<BCP_obj_change>::const_iterator lastch =
00168 vars_change._change.entry(vars_change.changed_num() -
00169 vars_change.added_num());
00170 BCP_vec<int>::const_iterator firstchpos =
00171 vars_change._del_change_pos.entry(vars_change.deleted_num());
00172 while (firstch != lastch) {
00173 _change[*firstchpos] = *firstch;
00174 ++firstch;
00175 ++firstchpos;
00176 }
00177 }
00178 }
00179
00180
00181
00182 void
00183 BCP_obj_set_change::pack(BCP_buffer& buf)
00184 {
00185 buf.pack(_storage);
00186 buf.pack(_deleted_num);
00187 buf.pack(_del_change_pos);
00188 buf.pack(_change);
00189 buf.pack(_new_objs);
00190 }
00191
00192
00193
00194 void
00195 BCP_obj_set_change::unpack(BCP_buffer& buf)
00196 {
00197 buf.unpack(_storage);
00198 buf.unpack(_deleted_num);
00199 buf.unpack(_del_change_pos);
00200 buf.unpack(_change);
00201 buf.unpack(_new_objs);
00202 }
00203
00204
00205
00206 void
00207 BCP_cut_set_change::update(const BCP_cut_set_change& cuts_change)
00208 {
00209 if (cuts_change.storage() == BCP_Storage_Explicit){
00210 _new_cuts.clear();
00211 _change.clear();
00212 }else{
00213 if (cuts_change.deleted_num() > 0){
00214 BCP_vec<int>::const_iterator firstdel =
00215 cuts_change._del_change_pos.begin();
00216 BCP_vec<int>::const_iterator lastdel =
00217 cuts_change._del_change_pos.entry(cuts_change.deleted_num());
00218
00219
00220 _new_cuts.erase_by_index(firstdel, lastdel);
00221 _change.erase_by_index(firstdel, lastdel);
00222 }
00223 }
00224 if (cuts_change.added_num() > 0) {
00225 _new_cuts.append(cuts_change._new_cuts);
00226 _change.append(cuts_change._change.entry(cuts_change.changed_num() -
00227 cuts_change.added_num()),
00228 cuts_change._change.end());
00229 }
00230 if (cuts_change.changed_num() - cuts_change.added_num() > 0){
00231 #if PARANOID
00232 if (cuts_change.storage() != BCP_Storage_WrtParent)
00233 throw BCP_fatal_error("BCP_update_cutset_and_changes(): oops\n");
00234 #endif
00235 BCP_vec<BCP_obj_change>::const_iterator firstch =
00236 cuts_change._change.begin();
00237 BCP_vec<BCP_obj_change>::const_iterator lastch =
00238 cuts_change._change.entry(cuts_change.changed_num() -
00239 cuts_change.added_num());
00240 BCP_vec<int>::const_iterator firstchpos =
00241 cuts_change._del_change_pos.entry(cuts_change.deleted_num());
00242 while (firstch != lastch) {
00243 _change[*firstchpos] = *firstch;
00244 ++firstch;
00245 ++firstchpos;
00246 }
00247 }
00248 }
00249
00250
00251
00252
00253 BCP_var_set_change::BCP_var_set_change(BCP_vec<BCP_var*>::const_iterator first,
00254 BCP_vec<BCP_var*>::const_iterator last):
00255 _storage(BCP_Storage_Explicit), _deleted_num(0),
00256 _del_change_pos(), _change(), _new_vars()
00257 {
00258 if (first != last) {
00259 const int added_var_num = coinDistance(first, last);
00260 _change.reserve(added_var_num);
00261 _new_vars.reserve(added_var_num);
00262 while (first != last) {
00263 const BCP_var* var = *first;
00264 _change.unchecked_push_back(BCP_obj_change(var->lb(), var->ub(),
00265 var->status()));
00266 _new_vars.unchecked_push_back(*first);
00267 ++first;
00268 }
00269 }
00270 }
00271
00272
00273
00274 BCP_var_set_change::
00275 BCP_var_set_change(BCP_vec<BCP_var*>::const_iterator first,
00276 BCP_vec<BCP_var*>::const_iterator last,
00277 const BCP_vec<int>& added_bcpind,
00278 const BCP_vec<BCP_obj_change>& added_desc) :
00279 _storage(BCP_Storage_WrtParent), _deleted_num(0),
00280 _del_change_pos(), _change(), _new_vars()
00281 {
00282 const int new_added_num = coinDistance(first, last);
00283 const int old_added_num = added_bcpind.size();
00284 _del_change_pos.reserve(old_added_num);
00285
00286 BCP_vec<int> chpos;
00287 chpos.reserve(new_added_num);
00288
00289 int i, j;
00290
00291
00292 for (i = 0, j = 0; i < new_added_num && j < old_added_num; ++j) {
00293 const BCP_var* const var = *(first + i);
00294 const BCP_obj_change& added = added_desc[j];
00295 if (var->bcpind() == added_bcpind[j]) {
00296
00297 if (var->lb() != added.lb || var->ub() != added.ub ||
00298 var->status() != added.stat)
00299 chpos.unchecked_push_back(i);
00300 ++i;
00301 } else {
00302 _del_change_pos.unchecked_push_back(j);
00303 }
00304 }
00305
00306 for ( ; j < old_added_num; ++j) {
00307 _del_change_pos.unchecked_push_back(j);
00308 }
00309
00310 _deleted_num = _del_change_pos.size();
00311
00312
00313
00314 _new_vars.reserve(new_added_num - i);
00315 for ( ; i < new_added_num; ++i){
00316 _new_vars.unchecked_push_back(*(first + i));
00317 chpos.unchecked_push_back(i);
00318 }
00319
00320 _del_change_pos.append(chpos);
00321
00322
00323 const int chnum = chpos.size();
00324 _change.reserve(chnum);
00325 for (i = 0; i < chnum; ++i) {
00326 const BCP_var* const var = *(first + chpos[i]);
00327 _change.unchecked_push_back(BCP_obj_change(var->lb(), var->ub(),
00328 var->status()));
00329 }
00330 }
00331
00332
00333
00334 void
00335 BCP_var_set_change::swap(BCP_var_set_change& x)
00336 {
00337 std::swap(_storage, x._storage);
00338 std::swap(_deleted_num, x._deleted_num);
00339 _del_change_pos.swap(x._del_change_pos);
00340 _change.swap(x._change);
00341 _new_vars.swap(x._new_vars);
00342 }
00343
00344
00345
00346 int
00347 BCP_var_set_change::pack_size() const
00348 {
00349 return ( _del_change_pos.size() * sizeof(int) +
00350 _change.size() * BCP_obj_change::pack_size() +
00351 _new_vars.size() * (sizeof(bool) + sizeof(int)) );
00352 }
00353
00354
00355
00356 BCP_cut_set_change::BCP_cut_set_change(BCP_vec<BCP_cut*>::const_iterator first,
00357 BCP_vec<BCP_cut*>::const_iterator last):
00358 _storage(BCP_Storage_Explicit), _deleted_num(0),
00359 _del_change_pos(), _change(), _new_cuts()
00360 {
00361 if (first != last) {
00362 const int added_cut_num = coinDistance(first, last);
00363 _change.reserve(added_cut_num);
00364 _new_cuts.reserve(added_cut_num);
00365 while (first != last) {
00366 const BCP_cut* cut = *first;
00367 _change.unchecked_push_back(BCP_obj_change(cut->lb(), cut->ub(),
00368 cut->status()));
00369 _new_cuts.unchecked_push_back(*first);
00370 ++first;
00371 }
00372 }
00373 }
00374
00375
00376
00377 BCP_cut_set_change::
00378 BCP_cut_set_change(BCP_vec<BCP_cut*>::const_iterator first,
00379 BCP_vec<BCP_cut*>::const_iterator last,
00380 const BCP_vec<int>& added_bcpind,
00381 const BCP_vec<BCP_obj_change>& added_desc) :
00382 _storage(BCP_Storage_WrtParent), _deleted_num(0),
00383 _del_change_pos(), _change(), _new_cuts()
00384 {
00385 const int new_added_num = coinDistance(first, last);
00386 const int old_added_num = added_bcpind.size();
00387 _del_change_pos.reserve(old_added_num);
00388
00389 BCP_vec<int> chpos;
00390 chpos.reserve(new_added_num);
00391
00392 int i, j;
00393
00394
00395 for (i = 0, j = 0; i < new_added_num && j < old_added_num; ++j) {
00396 const BCP_cut* const cut = *(first + i);
00397 const BCP_obj_change& added = added_desc[j];
00398 if (cut->bcpind() == added_bcpind[j]) {
00399
00400 if (cut->lb() != added.lb || cut->ub() != added.ub ||
00401 cut->status() != added.stat)
00402 chpos.unchecked_push_back(i);
00403 ++i;
00404 } else {
00405 _del_change_pos.unchecked_push_back(j);
00406 }
00407 }
00408
00409 for ( ; j < old_added_num; ++j) {
00410 _del_change_pos.unchecked_push_back(j);
00411 }
00412
00413 _deleted_num = _del_change_pos.size();
00414
00415
00416
00417 _new_cuts.reserve(new_added_num - i);
00418 for ( ; i < new_added_num; ++i){
00419 _new_cuts.unchecked_push_back(*(first + i));
00420 chpos.unchecked_push_back(i);
00421 }
00422
00423 _del_change_pos.append(chpos);
00424
00425
00426 const int chnum = chpos.size();
00427 _change.reserve(chnum);
00428 for (i = 0; i < chnum; ++i) {
00429 const BCP_cut* const cut = *(first + chpos[i]);
00430 _change.unchecked_push_back(BCP_obj_change(cut->lb(), cut->ub(),
00431 cut->status()));
00432 }
00433 }
00434
00435
00436
00437 void
00438 BCP_cut_set_change::swap(BCP_cut_set_change& x)
00439 {
00440 std::swap(_storage, x._storage);
00441 std::swap(_deleted_num, x._deleted_num);
00442 _del_change_pos.swap(x._del_change_pos);
00443 _change.swap(x._change);
00444 _new_cuts.swap(x._new_cuts);
00445 }
00446
00447
00448
00449 int
00450 BCP_cut_set_change::pack_size() const
00451 {
00452 return ( _del_change_pos.size() * sizeof(int) +
00453 _change.size() * BCP_obj_change::pack_size() +
00454 _new_cuts.size() * (sizeof(bool) + sizeof(int)) );
00455 }
00456 #endif