00001
00002
00003 #include <fstream>
00004
00005 #include "BCP_tm.hpp"
00006 #include "MC_tm.hpp"
00007 #include "MC_cut.hpp"
00008 #include "MC_init.hpp"
00009
00010
00011
00012 int main(int argc, char* argv[])
00013 {
00014 MC_initialize mc_init;
00015 return bcp_main(argc, argv, &mc_init);
00016 }
00017
00018
00019
00020 void
00021 MC_tm::pack_module_data(BCP_buffer& buf, BCP_process_t ptype)
00022 {
00023 switch (ptype) {
00024 case BCP_ProcessType_LP:
00025 lp_par.pack(buf);
00026 break;
00027 default:
00028 abort();
00029 }
00030 mc.pack(buf);
00031 }
00032
00033
00034
00035 BCP_solution*
00036 MC_tm::unpack_feasible_solution(BCP_buffer& buf)
00037 {
00038 MC_solution* new_sol = new MC_solution;
00039 new_sol->unpack(buf);
00040 if (new_sol->objective_value() > best_soln.objective_value())
00041 best_soln = *new_sol;
00042 return new_sol;
00043 }
00044
00045
00046
00047 void
00048 MC_tm::initialize_core(BCP_vec<BCP_var_core*>& vars,
00049 BCP_vec<BCP_cut_core*>& cuts,
00050 BCP_lp_relax*& matrix)
00051 {
00052 int i;
00053 const int m = mc.num_edges;
00054
00055 vars.reserve(m);
00056 for (i = 0; i < m; ++i) {
00057 vars.unchecked_push_back(new BCP_var_core(BCP_BinaryVar,
00058 mc.edges[i].cost, 0, 1));
00059 }
00060 }
00061
00062
00063
00064 void
00065 MC_tm::create_root(BCP_vec<BCP_var*>& added_vars,
00066 BCP_vec<BCP_cut*>& added_cuts,
00067 BCP_user_data*& user_data)
00068 {
00069 if (added_cuts.size() > 0)
00070 return;
00071
00072
00073 int i, j;
00074 const int n = mc.num_nodes;
00075 const int m = mc.num_edges;
00076 double* x = new double[m];
00077
00078
00079
00080 const MC_graph_edge* edges = mc.edges;
00081 for (i = 0; i < m; ++i)
00082 x[i] = edges[i].cost > 0.0 ? 0.0 : 1.0;
00083
00084 const int improve_round = lp_par.entry(MC_lp_par::HeurSwitchImproveRound);
00085 const bool edge_switch = lp_par.entry(MC_lp_par::DoEdgeSwitchHeur);
00086 const int struct_switch = ( lp_par.entry(MC_lp_par::StructureSwitchHeur) &
00087 ((1 << mc.num_structure_type) - 1) );
00088 MC_solution* sol = NULL;
00089
00090 BCP_vec<BCP_row*> new_rows;
00091 if (mc.ising_four_cycles || mc.ising_triangles) {
00092 const int grid = static_cast<int>(sqrt(mc.num_nodes + 1.0));
00093 const int grid_nodes = grid*grid;
00094 if (mc.ising_four_cycles)
00095 MC_test_ising_four_cycles(grid_nodes, mc.ising_four_cycles,
00096 x, 0.9, added_cuts, new_rows);
00097 if (mc.ising_triangles)
00098 MC_test_ising_triangles(2*grid_nodes, mc.ising_triangles,
00099 x, 0.9, added_cuts, new_rows);
00100 getTmProblemPointer()->ub(0.0);
00101 BCP_vec<int> sig(n, 1);
00102 sol = new MC_solution(sig, mc, improve_round, edge_switch, struct_switch);
00103 } else {
00104
00105 sol = MC_mst_cutgen(mc, x, NULL, 1.0, 0.0,
00106 MC_MstEdgeOrderingPreferExtreme,
00107 improve_round, edge_switch, struct_switch,
00108 0.9, COIN_INT_MAX, added_cuts, new_rows);
00109 }
00110
00111
00112 getTmProblemPointer()->ub(sol->objective_value());
00113 getTmProblemPointer()->feas_sol = sol;
00114
00115 delete[] x;
00116
00117
00118 purge_ptr_vector(new_rows);
00119
00120
00121 std::sort(added_cuts.begin(), added_cuts.end(), MC_cycle_cut_less);
00122 const int cutnum = added_cuts.size();
00123 for (j = 0, i = 1; i < cutnum; ++i) {
00124 if (MC_cycle_cut_equal(added_cuts[j], added_cuts[i])) {
00125 delete added_cuts[i];
00126 added_cuts[i] = NULL;
00127 } else {
00128 j = i;
00129 }
00130 }
00131
00132
00133 for (j = 0, i = 0; i < cutnum; ++i) {
00134 if (added_cuts[i] != NULL) {
00135 added_cuts[j++] = added_cuts[i];
00136 }
00137 }
00138 added_cuts.erase(added_cuts.entry(j), added_cuts.end());
00139 }
00140
00141
00142
00143 void
00144 MC_tm::display_feasible_solution(const BCP_solution* sol)
00145 {
00146 const MC_solution* mc_sol = dynamic_cast<const MC_solution*>(sol);
00147 if (! mc_sol) {
00148 throw BCP_fatal_error("\
00149 MC_tm::display_feasible_solution() invoked with non-MC_solution.\n");
00150 }
00151
00152 if (mc.ising_problem) {
00153 const int grid = static_cast<int>(sqrt(mc.num_nodes + 1.0));
00154 const int grid_size = grid * grid;
00155 const BCP_vec<int>& sig = mc_sol->sig;
00156 double field = 0;
00157 for (int i = grid_size - 1; i >= 0; --i) {
00158 field += sig[i];
00159 }
00160 if (field < 0)
00161 field = -field;
00162 field /= grid_size;
00163 const double energy =
00164 (- mc.sum_edge_weight + 2 * mc_sol->objective_value()) /
00165 (mc.scaling_factor * grid_size);
00166 printf("MC: field: %.6f energy: %.6f\n", field, energy);
00167 }
00168
00169 if (tm_par.entry(MC_tm_par::DisplaySolutionSignature)) {
00170 mc_sol->display(tm_par.entry(MC_tm_par::SolutionFile));
00171 }
00172 }