00001
00002
00003 #ifndef _MC_CUT_H
00004 #define _MC_CUT_H
00005
00006 #include <algorithm>
00007
00008 #include "CoinHelperFunctions.hpp"
00009
00010 #include "BCP_mempool.hpp"
00011 #include "BCP_cut.hpp"
00012
00013 class BCP_buffer;
00014 class BCP_row;
00015 class MC_problem;
00016 class MC_solution;
00017
00018
00019
00020 enum MC_cut_t {
00021 MC_cut_t__cycle,
00022 MC_cut_t__explicit_dense
00023 };
00024
00025 enum MC_EdgeOrdering {
00026 MC_MstEdgeOrderingPreferZero,
00027 MC_MstEdgeOrderingPreferOne,
00028 MC_MstEdgeOrderingPreferExtreme
00029 };
00030
00031
00032
00033 class MC_cycle_cut : public BCP_cut_algo {
00034 private:
00035 MC_cycle_cut(const MC_cycle_cut&);
00036 MC_cycle_cut& operator=(const MC_cycle_cut&);
00037 private:
00038 static BCP_MemPool memPool;
00039 public:
00040 static inline void * operator new(size_t size) {
00041 return memPool.alloc(size);
00042 }
00043 static inline void operator delete(void *p, size_t size) {
00044 memPool.free(p, size);
00045 }
00046 public:
00047 int cycle_len;
00048 int pos_edges;
00049 int* edges;
00050 public:
00051 MC_cycle_cut(const int* ei, const int pos, const int len) :
00052 BCP_cut_algo(-1e40, pos-1.0), cycle_len(len), pos_edges(pos), edges(0) {
00053 if (len > 0) {
00054 edges = new int[len];
00055 CoinDisjointCopyN(ei, len, edges);
00056 }
00057 }
00058 MC_cycle_cut(BCP_buffer& buf);
00059 ~MC_cycle_cut() {
00060 delete[] edges;
00061 }
00062
00063 void pack(BCP_buffer& buf) const;
00064 };
00065
00066
00067
00068 class MC_explicit_dense_cut : public BCP_cut_algo {
00069 private:
00070 MC_explicit_dense_cut(const MC_explicit_dense_cut&);
00071 MC_explicit_dense_cut& operator=(const MC_explicit_dense_cut&);
00072 private:
00073 static BCP_MemPool memPool;
00074 public:
00075 static inline void * operator new(size_t size) {
00076 return memPool.alloc(size);
00077 }
00078 static inline void operator delete(void *p, size_t size) {
00079 memPool.free(p, size);
00080 }
00081 public:
00082 double rhs;
00083 double * coeffs;
00084 int varnum;
00085 public:
00086 MC_explicit_dense_cut(const double ub, const int num,
00087 const double * elements) :
00088 BCP_cut_algo(-1e40, ub), rhs(ub), coeffs(new double[num]), varnum(num)
00089 {
00090 CoinDisjointCopyN(elements, num, coeffs);
00091 }
00092 MC_explicit_dense_cut(BCP_buffer& buf);
00093 ~MC_explicit_dense_cut() {
00094 delete[] coeffs;
00095 }
00096
00097 void pack(BCP_buffer& buf) const;
00098 };
00099
00100
00101
00102 inline bool
00103 MC_cycle_cut_less(const BCP_cut* bc0, const BCP_cut* bc1) {
00104 const MC_cycle_cut* c0 = dynamic_cast<const MC_cycle_cut*>(bc0);
00105 const MC_cycle_cut* c1 = dynamic_cast<const MC_cycle_cut*>(bc1);
00106 if (c0->cycle_len < c1->cycle_len)
00107 return true;
00108 if (c1->cycle_len < c0->cycle_len)
00109 return false;
00110 if (c0->pos_edges < c1->pos_edges)
00111 return true;
00112 if (c1->pos_edges < c0->pos_edges)
00113 return false;
00114 return memcmp(c0->edges, c1->edges, c0->cycle_len * sizeof(int)) < 0;
00115 }
00116
00117 inline bool
00118 MC_cycle_cut_equal(const BCP_cut* bc0, const BCP_cut* bc1) {
00119 const MC_cycle_cut* c0 = dynamic_cast<const MC_cycle_cut*>(bc0);
00120 const MC_cycle_cut* c1 = dynamic_cast<const MC_cycle_cut*>(bc1);
00121 return (c0->cycle_len == c1->cycle_len &&
00122 c0->pos_edges == c1->pos_edges &&
00123 memcmp(c0->edges, c1->edges, c0->cycle_len * sizeof(int)) == 0);
00124 }
00125
00126
00127
00128 MC_solution*
00129 MC_mst_heur(const MC_problem & mc, const double * x, const double * w,
00130 const double alpha, const double beta,
00131 const MC_EdgeOrdering edge_ordering,
00132 const int heurswitchround,
00133 const bool do_edge_switch_heur, const int struct_switch_heur);
00134
00135
00136
00137 MC_solution*
00138 MC_mst_cutgen(const MC_problem& mc, const double* x, const double* w,
00139 const double alpha, const double beta,
00140 const MC_EdgeOrdering edge_ordering,
00141 const int heurswitchround,
00142 const bool do_edge_switch_heur, const int struct_switch_heur,
00143 const double minviol, const int maxnewcuts,
00144 BCP_vec<BCP_cut*>& new_cuts, BCP_vec<BCP_row*>& new_rows);
00145
00146
00147
00148 void
00149 MC_kruskal(const MC_problem& mc, const int * edgeorder, const double* x,
00150 int * nodesign, int * edges_in_tree);
00151
00152
00153
00154 void
00155 MC_kruskal(const MC_problem& mc, const int * edgeorder, const double* x,
00156 int * nodesign, int * parentnode, int * parentedge);
00157
00158
00159
00160 void
00161 MC_generate_shortest_path_cycles(const MC_problem& mc, const double* x,
00162 const bool generate_all_cuts,
00163 const double minviol,
00164 BCP_vec<BCP_cut*>& new_cuts,
00165 BCP_vec<BCP_row*>& new_rows);
00166
00167
00168
00169 void
00170 MC_test_ising_four_cycles(const int n, const int* cycles,
00171 const double* x, const double minviol,
00172 BCP_vec<BCP_cut*>& cuts, BCP_vec<BCP_row*>& rows);
00173
00174 void
00175 MC_test_ising_triangles(const int n, const int* triangles,
00176 const double* x, const double minviol,
00177 BCP_vec<BCP_cut*>& cuts, BCP_vec<BCP_row*>& rows);
00178
00179 #endif