00001
00002
00003
00004 #include <cstdio>
00005
00006 #include "BCP_vg.hpp"
00007 #include "BCP_cg.hpp"
00008 #include "BCP_lp.hpp"
00009 #include "BCP_tm.hpp"
00010 #include "BCP_solution.hpp"
00011 #include "BCP_tm_user.hpp"
00012 #include "BCP_node_change.hpp"
00013
00014 static inline void
00015 BCP_tm_pack_root_cut(BCP_tm_prob* tm, const BCP_cut& cut)
00016 {
00017 BCP_buffer& buf = tm->msg_buf;
00018 const BCP_object_t obj_t = cut.obj_type();
00019 const BCP_obj_status stat = cut.status();
00020 const double lb = cut.lb();
00021 const double ub = cut.ub();
00022 buf.pack(obj_t).pack(stat).pack(lb).pack(ub);
00023 switch (obj_t) {
00024 case BCP_CoreObj:
00025 break;
00026 case BCP_AlgoObj:
00027 tm->packer->pack_cut_algo(&dynamic_cast<const BCP_cut_algo&>(cut), buf);
00028 break;
00029 default:
00030 throw BCP_fatal_error("BCP_tm_pack_root_cut: unexpected obj_t.\n");
00031 }
00032 }
00033
00034
00035
00036 void
00037 BCP_tm_save_root_cuts(BCP_tm_prob* tm)
00038 {
00039 if (! tm->cuts_remote.empty()) {
00040 throw BCP_fatal_error("\
00041 BCP: saving root cuts does not work at the moment. Must collect cuts from \n\
00042 the TMS processes before the root cuts could be saved. \n");
00043 }
00044 const BCP_string& cutfile = tm->param(BCP_tm_par::SaveRootCutsTo);
00045 if (cutfile.length() > 0 &&
00046 tm->phase == 0) {
00047 BCP_buffer& buf = tm->msg_buf;
00048 buf.clear();
00049 const BCP_obj_set_change& ch =
00050 tm->search_tree.root()->_data._desc->cut_change;
00051 if (ch.storage() != BCP_Storage_Explicit)
00052 throw BCP_fatal_error("Non-explicit cut storage in root!\n");
00053 const int num = ch._new_objs.size();
00054 buf.pack(num);
00055 for (int i = 0; i < num; ++i) {
00056 BCP_tm_pack_root_cut(tm, *tm->cuts_local[i]);
00057 }
00058 FILE* f = fopen(cutfile.c_str(), "w");
00059 size_t size = buf.size();
00060 if (fwrite(&size, 1, sizeof(size), f) != sizeof(size))
00061 throw BCP_fatal_error("SaveRootCutsTo write error.\n");
00062 if (fwrite(buf.data(), 1, size, f) != size)
00063 throw BCP_fatal_error("SaveRootCutsTo write error.\n");
00064 fclose(f);
00065 }
00066 }
00067
00068
00069
00070 void
00071 BCP_tm_wrapup(BCP_tm_prob* tm, BCP_lp_prob* lp,
00072 BCP_cg_prob* cg, BCP_vg_prob* vg, bool final_stat)
00073 {
00074 BCP_tm_save_root_cuts(tm);
00075
00076
00077 if (!tm->lp_stat)
00078 tm->lp_stat = new BCP_lp_statistics;
00079
00080 if (! lp) {
00081
00082 const std::vector<int>& lps = tm->lp_procs;
00083 const int num_lp = lps.size();
00084 BCP_lp_statistics* lp_stats = new BCP_lp_statistics[num_lp];
00085 BCP_lp_statistics this_lp_stat;
00086
00087 int i;
00088 for (i = 0; i < num_lp; ++i) {
00089 while (true) {
00090 tm->msg_env->receive(lps[i],
00091 BCP_Msg_LpStatistics,
00092 tm->msg_buf, 1);
00093 BCP_message_tag msgtag = tm->msg_buf.msgtag();
00094 if (msgtag == BCP_Msg_NoMessage) {
00095
00096 if (! tm->msg_env->alive(lps[i]))
00097 break;
00098 } else {
00099 break;
00100 }
00101 }
00102 lp_stats[i].unpack(tm->msg_buf);
00103 tm->lp_stat->add(lp_stats[i]);
00104 }
00105 for (i = 0; i < num_lp; ++i) {
00106 printf("LP # %i : node idle: %12.6f SB idle: %12.6f\n",
00107 lps[i], tm->lp_scheduler.node_idle(lps[i]),
00108 tm->lp_scheduler.sb_idle(lps[i]));
00109 }
00110 delete[] lp_stats;
00111 }
00112
00113 tm->stat.print(true , 0);
00114
00115 tm->user->display_final_information(lp ? lp->stat : *tm->lp_stat);
00116 }