/home/coin/SVN-release/OS-2.1.1/Bcp/src/LP/BCP_lp_msg_node_rec.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_message.hpp"
00005 #include "BCP_node_change.hpp"
00006 #include "BCP_warmstart.hpp"
00007 #include "BCP_lp_node.hpp"
00008 #include "BCP_lp_user.hpp"
00009 #include "BCP_lp.hpp"
00010 #include "BCP_lp_functions.hpp"
00011 
00012 static inline void
00013 BCP_lp_unpack_parent(BCP_lp_prob& p, BCP_buffer& buf, BCP_lp_node& node);
00014 
00015 static inline void
00016 BCP_lp_create_node(BCP_lp_prob& p, BCP_node_change& node_change);
00017 
00018 static inline void
00019 BCP_lp_create_core(BCP_lp_prob& p, BCP_node_change& node_change);
00020 static inline void
00021 BCP_lp_set_core(BCP_lp_prob& p, BCP_lp_node& node, BCP_problem_core_change& core);
00022 static inline void
00023 BCP_lp_modify_core(BCP_lp_node& node, BCP_problem_core_change& change);
00024 
00025 static inline void
00026 BCP_lp_create_added_vars(BCP_lp_prob& p, BCP_node_change& node_change);
00027 static inline void
00028 BCP_lp_create_added_cuts(BCP_lp_prob& p, BCP_node_change& node_change);
00029 
00030 static inline void
00031 BCP_lp_create_warmstart(BCP_lp_prob& p, BCP_node_change& node_change);
00032 
00033 //-----------------------------------------------------------------------------
00034 
00035 void BCP_lp_unpack_parent(BCP_lp_prob& p, BCP_buffer& buf, BCP_lp_node& node)
00036 {
00037     buf.unpack(p.parent->index);
00038     if (node.tm_storage.core_change == BCP_Storage_WrtParent){
00039         p.parent->core_as_change.unpack(buf);  // BCP_problem_core_change
00040         // make sure the parent's storage is Explicit (convert if it is
00041         // WrtCore now). This way later we can test for WrtParent easily.
00042         p.parent->core_as_change.ensure_explicit(*p.core_as_change);
00043     }
00044 
00045     assert(node.vars.size() == p.core->vars.size());
00046     if (node.tm_storage.var_change == BCP_Storage_WrtParent){
00047         // these are the vars present in the parent
00048         p.parent->var_set.unpack(buf);
00049 #ifdef PARANOID
00050         if (p.parent->var_set.storage() != BCP_Storage_Explicit)
00051             throw BCP_fatal_error("BCP_lp_unpack_parent(): oops 1\n");
00052 #endif
00053     } else {
00054         assert(p.parent->var_set._change.empty());
00055         assert(p.parent->var_set._new_objs.empty());
00056     }
00057 
00058     assert(node.cuts.size() == p.core->cuts.size());
00059     if (node.tm_storage.cut_change == BCP_Storage_WrtParent){
00060         // these are the cuts present in the parent
00061         p.parent->cut_set.unpack(buf);
00062 #ifdef PARANOID
00063         if (p.parent->cut_set.storage() != BCP_Storage_Explicit)
00064             throw BCP_fatal_error("BCP_lp_unpack_parent(): oops 1\n");
00065 #endif
00066     } else {
00067         assert(p.parent->cut_set._change.empty());
00068         assert(p.parent->cut_set._new_objs.empty());
00069     }
00070 
00071     if (node.tm_storage.warmstart == BCP_Storage_WrtParent) {
00072         const bool def = p.param(BCP_lp_par::ReportWhenDefaultIsExecuted);
00073         p.parent->warmstart = p.packer->unpack_warmstart(buf, def);
00074     }
00075 }
00076 
00077 //-----------------------------------------------------------------------------
00078 // The following two functions are needed below in BCP_lp_create_core()
00079 
00080 void BCP_lp_modify_core(BCP_lp_node& node, BCP_problem_core_change& change)
00081 {
00082     if (change.varnum() > 0)
00083         node.vars.set_lb_ub_st(change.var_pos.begin(), change.var_ch);
00084     if (change.cutnum() > 0)
00085         node.cuts.set_lb_ub_st(change.cut_pos.begin(), change.cut_ch);
00086 }
00087 
00088 void BCP_lp_set_core(BCP_lp_prob& p, BCP_lp_node& node,
00089                      BCP_problem_core_change& core)
00090 {
00091     switch (core.storage()) {
00092     case BCP_Storage_WrtCore:
00093         if (p.core->varnum() > 0)
00094             // this call sets the changes on the core
00095             node.vars.set_lb_ub_st(p.core_as_change->var_ch);
00096         if (p.core->cutnum() > 0)
00097             // this call sets the changes on the core
00098             node.cuts.set_lb_ub_st(p.core_as_change->cut_ch);
00099         BCP_lp_modify_core(node, core);
00100         break;
00101       
00102     case BCP_Storage_Explicit:
00103         if (core.varnum() > 0)
00104             // this call sets the changes on the core
00105             node.vars.set_lb_ub_st(core.var_ch);
00106         if (core.cutnum() > 0)
00107             // this call sets the changes on the core
00108             node.cuts.set_lb_ub_st(core.cut_ch);
00109         break;
00110       
00111     default:
00112         // impossible in this function
00113         throw BCP_fatal_error("BCP_lp_set_core: Impossible storage_type.\n");
00114     }
00115 }
00116 
00117 //-----------------------------------------------------------------------------
00118 
00119 void BCP_lp_create_core(BCP_lp_prob& p, BCP_node_change& node_change)
00120 {
00121     switch (p.node->tm_storage.core_change){
00122     case BCP_Storage_WrtCore:
00123         //in this case it'll copy the orig core first then update it
00124     case BCP_Storage_Explicit:
00125         // in this case it'll apply the core in node_change directly
00126         BCP_lp_set_core(p, *p.node, node_change.core_change);
00127         break;
00128 
00129     case BCP_Storage_WrtParent:
00130         // copy the parent lb/ub/status then apply the changes in node_change
00131         BCP_lp_set_core(p, *p.node, p.parent->core_as_change);
00132         BCP_lp_modify_core(*p.node, node_change.core_change);
00133         break;
00134 
00135     case BCP_Storage_NoData:
00136         // there are no core objects
00137         break;
00138 
00139     default:
00140         // impossible
00141         throw BCP_fatal_error("BCP_lp_create_core: Bad storage.\n");
00142     }
00143 }
00144 
00145 //-----------------------------------------------------------------------------
00146 
00147 void BCP_lp_create_added_vars(BCP_lp_prob& p, BCP_node_change& node_change)
00148     // When this function is called, the core vars are already listed in
00149     // p.node->vars, be careful not to destroy them
00150 {
00151     switch (p.node->tm_storage.var_change) {
00152     case BCP_Storage_WrtParent:
00153     case BCP_Storage_Explicit:
00154         break;
00155     case BCP_Storage_NoData:
00156         // there are no added vars
00157         return;
00158     case BCP_Storage_WrtCore:
00159     default:
00160         // impossible
00161         throw BCP_fatal_error("BCP_lp_create_added_vars: Bad storage.\n");
00162     }
00163     // WrtParent || Explicit
00164     // It happens so that in case of explicit storage parent.var_set is empty,
00165     // so this is still OK!!
00166     BCP_obj_set_change var_set = p.parent->var_set;
00167     var_set.update(node_change.var_change);
00168     assert(p.node->vars.size() == p.core->varnum() + var_set._change.size());
00169     assert(var_set._change.size() == var_set._new_objs.size());
00170     BCP_var** added_vars = &p.node->vars[0] + p.core->varnum();
00171     for (int i = var_set._change.size() - 1; i >= 0; --i) {
00172         added_vars[i]->change_lb_ub_st(var_set._change[i]);
00173     }
00174 }
00175 
00176 //-----------------------------------------------------------------------------
00177 
00178 void BCP_lp_create_added_cuts(BCP_lp_prob& p, BCP_node_change& node_change)
00179 {
00180     switch (p.node->tm_storage.cut_change) {
00181     case BCP_Storage_WrtParent:
00182     case BCP_Storage_Explicit:
00183         break;
00184     case BCP_Storage_NoData:
00185         // there are no added cuts
00186         return;
00187     case BCP_Storage_WrtCore:
00188     default:
00189         // impossible
00190         throw BCP_fatal_error("BCP_lp_create_added_cuts: Bad storage.\n");
00191     }
00192     // WrtParent || Explicit
00193     // It happens so that in case of explicit storage parent.cut_set is empty,
00194     // so this is still OK!!
00195     BCP_obj_set_change cut_set = p.parent->cut_set;
00196     cut_set.update(node_change.cut_change);
00197     assert(p.node->cuts.size() == p.core->cutnum() + cut_set._change.size());
00198     assert(cut_set._change.size() == cut_set._new_objs.size());
00199     BCP_cut** added_cuts = &p.node->cuts[0] + p.core->cutnum();
00200     for (int i = cut_set._change.size() - 1; i >= 0; --i) {
00201         added_cuts[i]->change_lb_ub_st(cut_set._change[i]);
00202     }
00203 }
00204 
00205 //-----------------------------------------------------------------------------
00206 
00207 void BCP_lp_create_warmstart(BCP_lp_prob& p, BCP_node_change& node_change)
00208 {
00209     switch (p.node->tm_storage.warmstart) {
00210     case BCP_Storage_WrtParent:
00211         p.node->warmstart = p.parent->warmstart->clone();
00212         p.node->warmstart->update(node_change.warmstart);
00213         break;
00214 
00215     case BCP_Storage_Explicit:
00216         p.node->warmstart = node_change.warmstart;
00217         node_change.warmstart = 0;
00218         break;
00219 
00220     case BCP_Storage_NoData:   // there's no warmstart info
00221         break;
00222 
00223     case BCP_Storage_WrtCore:
00224     default:
00225         // impossible
00226         throw BCP_fatal_error("BCP_lp_create_warmstart: Bad storage.\n");
00227     }
00228 }
00229 
00230 //-----------------------------------------------------------------------------
00231 
00232 void BCP_lp_create_node(BCP_lp_prob& p, BCP_node_change& node_change)
00233 {
00234     // we got to put together p.node from parent and node_change
00235     p.node->iteration_count = 0;
00236 
00237     BCP_lp_create_core(p, node_change);
00238     BCP_lp_create_added_vars(p, node_change);
00239     BCP_lp_create_added_cuts(p, node_change);
00240     BCP_lp_create_warmstart(p, node_change);
00241 }
00242 
00243 //#############################################################################
00244 
00245 void BCP_lp_unpack_active_node(BCP_lp_prob& p, BCP_buffer& buf)
00246 {
00247     const bool def = p.param(BCP_lp_par::ReportWhenDefaultIsExecuted);
00248 
00249     if (p.parent->warmstart != 0 || p.node->warmstart != 0) {
00250         throw BCP_fatal_error("\
00251 BCP_lp_unpack_active_node: parent's or node's warmstart is non-0.\n");
00252     }
00253 
00254     BCP_lp_node& node = *p.node;
00255     // unpack a few essential data
00256     buf.unpack(node.colgen).unpack(node.index).unpack(node.level)
00257         .unpack(node.quality).unpack(node.true_lower_bound)
00258         .unpack(node.dive);
00259 
00260     // unpack process information
00261     buf.unpack(node.cg);
00262     buf.unpack(node.cp);
00263     buf.unpack(node.vg);
00264     buf.unpack(node.vp);
00265 
00266     // unpack how the various pieces are stored in node
00267     buf.unpack(node.tm_storage.core_change)
00268         .unpack(node.tm_storage.var_change)
00269         .unpack(node.tm_storage.cut_change)
00270         .unpack(node.tm_storage.warmstart);
00271 
00272     if (node.level > 0)
00273         BCP_lp_unpack_parent(p, buf, node);
00274 
00275     BCP_node_change node_change;
00276     node_change.unpack(p.packer, def, buf);
00277 
00278     // Now unpack the full list of vars/cuts of the node
00279     int i, cnt;
00280     buf.unpack(cnt);
00281     assert(node.vars.size() == p.core->vars.size());
00282     node.vars.reserve(cnt+node.vars.size());
00283     for (i = 0; i < cnt; ++i) {
00284         node.vars.unchecked_push_back(p.unpack_var());
00285     }
00286     buf.unpack(cnt);
00287     assert(node.cuts.size() == p.core->cuts.size());
00288     node.cuts.reserve(cnt+node.cuts.size());
00289     for (i = 0; i < cnt; ++i) {
00290         node.cuts.unchecked_push_back(p.unpack_cut());
00291     }
00292 
00293     // Create the active node from the parent and from the last changes
00294     BCP_lp_create_node(p, node_change);
00295 
00296     // Delete the old user data
00297     delete p.node->user_data;
00298     bool has_data;
00299     buf.unpack(has_data);
00300     p.node->user_data = has_data ? p.packer->unpack_user_data(buf) : 0;
00301 }

Generated on Mon May 3 03:05:11 2010 by  doxygen 1.4.7