00001
00002
00003
00004 #include <map>
00005
00006 #include "BCP_math.hpp"
00007 #include "BCP_process.hpp"
00008 #include "BCP_lp.hpp"
00009 #include "BCP_tm.hpp"
00010 #include "BCP_problem_core.hpp"
00011 #include "BCP_tm_user.hpp"
00012 #include "BCP_var.hpp"
00013 #include "BCP_cut.hpp"
00014 #include "BCP_solution.hpp"
00015
00016 #include "BCP_warmstart.hpp"
00017
00018 double BCP_tm_prob::lb_multiplier = 1e12;
00019
00020 BCP_tm_prob::BCP_tm_prob() :
00021 BCP_process(0, -1),
00022 user(0),
00023 msg_env(0),
00024 lp_stat(0),
00025 feas_sol(0),
00026 upper_bound(BCP_DBL_MAX),
00027 core(0),
00028 core_as_change(0),
00029 next_cut_index_set_start(1),
00030 next_var_index_set_start(1),
00031 candidate_list()
00032 {}
00033
00034 BCP_tm_prob::~BCP_tm_prob()
00035 {
00036 delete user;
00037 delete packer;
00038
00039 delete lp_stat;
00040
00041 delete feas_sol;
00042
00043 delete core;
00044 delete core_as_change;
00045 }
00046
00047
00048
00049 void
00050 BCP_tm_stat::print(bool final, double t)
00051 {
00052 const int wait_stat_freq = 1200;
00053 bool do_print = false;
00054 if (final) {
00055 printf("TM: final statistics:\n");
00056 do_print = true;
00057 } else {
00058 if (floor(t/wait_stat_freq) > cnt) {
00059 cnt = static_cast<int>(floor(t/wait_stat_freq));
00060 printf("TM: statistics at %12.6f:\n", t);
00061 do_print = true;
00062 }
00063 }
00064 if (do_print) {
00065 for (int i = 0; i < num_lp; ++i) {
00066 if ((wait_time[i] > 5e-3) ||
00067 (numQueueLength[i]>0 && sumQueueLength[i]/numQueueLength[i] > 5)) {
00068 if (numQueueLength[i] > 0) {
00069 printf("TM: With %5i LP working: wait: %12.6f queue: %.2f\n",
00070 i, wait_time[i], sumQueueLength[i]/numQueueLength[i]);
00071 } else {
00072 printf("TM: With %5i LP working: wait: %12.6f queue: %.2f\n",
00073 i, wait_time[i], 0.0);
00074 }
00075 }
00076 }
00077 }
00078 }
00079
00080
00081
00082 void
00083 BCP_tm_prob::pack_var(const BCP_var& var)
00084 {
00085 const int bcpind = var.bcpind();
00086 const BCP_object_t obj_t = var.obj_type();
00087 const BCP_obj_status stat = var.status();
00088 const BCP_var_t var_t = var.var_type();
00089 const double obj = var.obj();
00090 const double lb = var.lb();
00091 const double ub = var.ub();
00092 msg_buf.pack(bcpind)
00093 .pack(obj_t).pack(stat).pack(var_t).pack(obj).pack(lb).pack(ub);
00094 switch (obj_t) {
00095 case BCP_CoreObj:
00096 break;
00097 case BCP_AlgoObj:
00098 packer->pack_var_algo(&dynamic_cast<const BCP_var_algo&>(var), msg_buf);
00099 break;
00100 default:
00101 throw BCP_fatal_error("BCP_tm_prob::_pack_var(): unexpected obj_t.\n");
00102 }
00103 }
00104
00105
00106
00107 BCP_var*
00108 BCP_tm_prob::unpack_var_without_bcpind(BCP_buffer& buf)
00109 {
00110 BCP_var* var = 0;
00111 BCP_object_t obj_t;
00112 BCP_var_t var_t;
00113 double obj, lb, ub;
00114 BCP_obj_status stat;
00115 buf.unpack(obj_t).unpack(stat)
00116 .unpack(var_t).unpack(obj).unpack(lb).unpack(ub);
00117 switch (obj_t) {
00118 case BCP_CoreObj:
00119 var = new BCP_var_core(var_t, obj, lb, ub);
00120 break;
00121 case BCP_AlgoObj:
00122 var = packer->unpack_var_algo(buf);
00123 var->set_var_type(var_t);
00124 var->change_bounds(lb, ub);
00125 var->set_obj(obj);
00126 break;
00127 default:
00128 throw BCP_fatal_error("BCP_tm_prob::_unpack_var(): unexpected obj_t.\n");
00129 }
00130 var->set_status(stat);
00131 return var;
00132 }
00133
00134
00135
00136 int
00137 BCP_tm_prob::unpack_var()
00138 {
00139 int bcpind;
00140 BCP_var* var = 0;
00141 msg_buf.unpack(bcpind);
00142 if (bcpind == 0) {
00143 throw BCP_fatal_error("BCP_tm_prob::unpack_var(): 0 bcpind.\n");
00144 }
00145 if (bcpind > 0) {
00146 if (vars_local.find(bcpind) != vars_local.end() ||
00147 vars_remote.find(bcpind) != vars_remote.end() ) {
00148 throw BCP_fatal_error("\
00149 BCP_tm_prob::unpack_var(): received a var with positive bcpind, \n\
00150 but the var already exists.\n");
00151 }
00152 } else {
00153 var = unpack_var_without_bcpind(msg_buf);
00154 if (vars_local.find(-bcpind) != vars_local.end() ||
00155 vars_remote.find(-bcpind) != vars_remote.end() ) {
00156
00157 delete var;
00158 } else {
00159 var->set_bcpind(-bcpind);
00160 vars_local[-bcpind] = var;
00161 }
00162 }
00163 return bcpind;
00164 }
00165
00166
00167
00168 void
00169 BCP_tm_prob::pack_cut(const BCP_cut& cut)
00170 {
00171 const int bcpind = cut.bcpind();
00172 const BCP_object_t obj_t = cut.obj_type();
00173 const BCP_obj_status stat = cut.status();
00174 const double lb = cut.lb();
00175 const double ub = cut.ub();
00176 msg_buf.pack(bcpind)
00177 .pack(obj_t).pack(stat).pack(lb).pack(ub);
00178 switch (obj_t) {
00179 case BCP_CoreObj:
00180 break;
00181 case BCP_AlgoObj:
00182 packer->pack_cut_algo(&dynamic_cast<const BCP_cut_algo&>(cut), msg_buf);
00183 break;
00184 default:
00185 throw BCP_fatal_error("BCP_tm_prob::_pack_cut(): unexpected obj_t.\n");
00186 }
00187 }
00188
00189
00190
00191 BCP_cut*
00192 BCP_tm_prob::unpack_cut_without_bcpind(BCP_buffer& buf)
00193 {
00194 BCP_cut* cut = 0;
00195 BCP_object_t obj_t;
00196 double lb, ub;
00197 BCP_obj_status stat;
00198 buf.unpack(obj_t).unpack(stat).unpack(lb).unpack(ub);
00199 switch (obj_t) {
00200 case BCP_CoreObj:
00201 cut = new BCP_cut_core(lb, ub);
00202 break;
00203 case BCP_AlgoObj:
00204 cut = packer->unpack_cut_algo(buf);
00205 cut->change_bounds(lb, ub);
00206 break;
00207 default:
00208 throw BCP_fatal_error("BCP_tm_prob::_unpack_cut(): unexpected obj_t.\n");
00209 }
00210 cut->set_status(stat);
00211 return cut;
00212 }
00213
00214
00215
00216 int
00217 BCP_tm_prob::unpack_cut()
00218 {
00219 int bcpind;
00220 BCP_cut* cut = 0;
00221 msg_buf.unpack(bcpind);
00222 if (bcpind == 0) {
00223 throw BCP_fatal_error("BCP_tm_prob::unpack_cut(): 0 bcpind.\n");
00224 }
00225 if (bcpind > 0) {
00226 if (cuts_local.find(bcpind) != cuts_local.end() ||
00227 cuts_remote.find(bcpind) != cuts_remote.end() ) {
00228 throw BCP_fatal_error("\
00229 BCP_tm_prob::unpack_cut(): received a cut with positive bcpind, \n\
00230 but the cut already exists.\n");
00231 }
00232 } else {
00233 cut = unpack_cut_without_bcpind(msg_buf);
00234 if (cuts_local.find(-bcpind) != cuts_local.end() ||
00235 cuts_remote.find(-bcpind) != cuts_remote.end() ) {
00236
00237 delete cut;
00238 } else {
00239 cut->set_bcpind(-bcpind);
00240 cuts_local[-bcpind] = cut;
00241 }
00242 }
00243 return bcpind;
00244 }