/home/coin/SVN-release/OS-2.4.1/Bcp/examples/MaxCut/TM/MC_tm.cpp

Go to the documentation of this file.
00001 // Copyright (C) 2000, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
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   // Do a couple of MST based cut generations with 0 as the primal solution
00072   // and with slight perturbations on the costs.
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   // Set x to be the optimal solution to the unconstrainted optimization
00079   // problem
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     // Not an Ising problem, use MST cuts to generate initial cuts;
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   // update best upper bound
00112   getTmProblemPointer()->ub(sol->objective_value());
00113   getTmProblemPointer()->feas_sol = sol;
00114 
00115   delete[] x;
00116 
00117   // get rid of the row representations
00118   purge_ptr_vector(new_rows);
00119 
00120   // keep unique cuts only (delete the duplicates)
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   // get rid of the NULL pointers
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 }

Generated on Thu Nov 10 03:05:37 2011 by  doxygen 1.4.7