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