00001 #ifndef SCIL_TOUR_CC
00002 #define SCIL_TOUR_CC
00003
00004 using namespace SCIL;
00005 using namespace std;
00006
00007 #define VALONE 1000000
00008
00009 template <typename Graph>
00010 class TOUR<Graph>::degree_equality : public cons_obj
00011 {
00012 private:
00013 const Graph& G;
00014 vertex_descriptor v;
00015 double deg;
00016 var_map<edge_descriptor>& VM;
00017
00018 public:
00019
00020
00021
00022
00023
00024 degree_equality(const Graph& G_, vertex_descriptor v_, var_map<edge_descriptor>& VM_,
00025 double d)
00026 : cons_obj(Equal, d), G(G_), VM(VM_) {
00027 v=v_; deg=d;
00028 };
00029
00030 virtual
00031 ~degree_equality()
00032 {};
00033
00034 vertex_descriptor gnode() { return v; };
00035
00036
00037
00038 virtual void non_zero_entries(row& r) {
00039 edge_descriptor e;
00040 BGL_FORALL_OUTEDGES_T(v, e, G, Graph) {
00041 r+=VM[e];
00042 }
00043 };
00044 };
00045
00046 template <typename Graph>
00047 class TOUR<Graph>::cutset_inequality : public cons_obj {
00048 private:
00049 Graph& G;
00050 var_map<edge_descriptor>& VM;
00051 map<vertex_descriptor, bool> cut;
00052 double rhs;
00053
00054 public:
00055
00056 cutset_inequality(Graph& Gt, var_map<edge_descriptor>& VM_, list<vertex_descriptor>& L)
00057 : cons_obj(Greater, 2), G(Gt), VM(VM_)
00058 {
00059 vertex_descriptor v;
00060 BGL_FORALL_VERTICES_T(v, G, Graph)
00061 cut[v] = false;
00062 BOOST_FOREACH(v, L)
00063 cut[v] = true;
00064 };
00065
00066 void non_zero_entries(row& r) {
00067 edge_descriptor e;
00068 BGL_FORALL_EDGES_T(e, G, Graph) {
00069 if(coeff(e)==1) r+=VM[e];
00070 }
00071 }
00072
00073 virtual
00074 ~cutset_inequality() {};
00075
00076 double coeff(edge_descriptor e) {
00077 if(cut[source(e, G)] != cut[target(e, G)]) return 1;
00078 return 0;
00079 };
00080 };
00081
00082 template <typename Graph>
00083 TOUR<Graph>::TOUR(Graph& G_, var_map<edge_descriptor>& VM_)
00084 : G(G_), VM(VM_) {
00085 edge_descriptor e;
00086 feps = 1.0e-4;
00087 BGL_FORALL_EDGES_T(e, G, Graph)
00088 if(VM[e].type() != Vartype_Binary) {
00089 cerr << "tour.cc: All variables in VM need to be Vartype_Binary" << endl;
00090 exit(1);
00091 }
00092 };
00093
00094 template <typename Graph>
00095 void TOUR<Graph>::init(subproblem& S) {
00096 if(S.configuration("TOUR_Debug_Out")=="true")
00097 cerr << "TOUR::init\n";
00098 vertex_descriptor v;
00099 BGL_FORALL_VERTICES_T(v, G, Graph) {
00100 S.add_basic_constraint(new degree_equality(G,v,VM,2));
00101 }
00102 };
00103
00104
00105 template <typename Graph>
00106 typename TOUR<Graph>::status TOUR<Graph>::standard_separation(subproblem& S) {
00107 if(S.configuration("TOUR_Debug_Out")=="true")
00108 cerr << "TOUR::standard_separation\n";
00109 return separation(S, false);
00110 }
00111
00112 template <typename Graph>
00113 typename TOUR<Graph>::status TOUR<Graph>::fast_separation(subproblem& S) {
00114 if(S.configuration("TOUR_Debug_Out")=="true")
00115 cerr << "TOUR::fast_separation\n";
00116 return separation(S, true);
00117 }
00118
00119
00120
00121 template <typename Graph>
00122 typename TOUR<Graph>::status TOUR<Graph>::separation(subproblem& S, bool fast_separation) {
00123
00124
00125 int i=0;
00126 map<edge_descriptor, int> val;
00127 edge_descriptor e;
00128 BGL_FORALL_EDGES_T(e, G, Graph) {
00129 val[e]=(int) (VALONE*S.value(VM[e]));
00130 }
00131
00132
00133
00134
00135
00136 Graph H;
00137 vertex_descriptor u;
00138 map<vertex_descriptor, vertex_descriptor> HtoG;
00139 map<vertex_descriptor, vertex_descriptor> GtoH;
00140
00141
00142 int index = 0;
00143 map<vertex_descriptor, int> vertex_index;
00144 BGL_FORALL_VERTICES_T(u, G, Graph) {
00145 GtoH[u]=add_vertex(H);
00146 HtoG[GtoH[u]]=u;
00147 vertex_index[GtoH[u]] = index;
00148 index++;
00149 }
00150
00151
00152 BGL_FORALL_EDGES_T(e, G, Graph) if(val[e]>=VALONE-5)
00153 add_edge(GtoH[source(e, G)], GtoH[target(e, G)], H);
00154
00155
00156 vector<int> CC(num_vertices(H));
00157 int k = connected_components(H, &CC[0]);
00158 list<vertex_descriptor> CCL[k];
00159 BGL_FORALL_VERTICES_T(u,H, Graph) CCL[CC[vertex_index[u]]].push_back(HtoG[u]);
00160
00161
00162
00163 if(k>1) {
00164 for(int j=0;j<k;j++) {
00165 cons_obj* c=new cutset_inequality(G,VM,CCL[j]);
00166 if (c->violation(S) > feps) {
00167 i++;
00168 S.add_basic_constraint(c, Dynamic);
00169 } else delete c;
00170 }
00171 }
00172
00173
00174 if(i>0) {
00175 cout<<i<<" Heuristic\n";
00176 return constraint_found;
00177 }
00178
00179
00180 if(fast_separation)
00181 return no_constraint_found;
00182
00183
00184
00185
00186
00187 MC<Graph> mc;
00188 MIN_CUT<Graph> *min_cut = new MIN_CUT<Graph>(G, val);
00189 min_cut->run();
00190 mc = min_cut->minCut;
00191 delete min_cut;
00192 list<vertex_descriptor> cut;
00193 BOOST_FOREACH( vertex_descriptor v, mc.nodes )
00194 cut.push_back(v);
00195
00196
00197 cons_obj* c=new cutset_inequality(G,VM,cut);
00198 if (c->violation(S) > feps) {
00199 i++; S.add_basic_constraint(c, Dynamic);
00200 } else delete c;
00201
00202
00203 if(i>0) {
00204 return constraint_found;
00205 }
00206
00207 BGL_FORALL_VERTICES_T(u, H, Graph)
00208 clear_vertex(u, H);
00209
00210
00211 BGL_FORALL_EDGES_T(e, G, Graph)
00212 if((val[e]>=5) && (val[e]<=VALONE-5))
00213 add_edge(GtoH[source(e, G)], GtoH[target(e, G)], H);
00214
00215
00216 {
00217 vector<int> CC(num_vertices(H));
00218 int k=connected_components(H,&CC[0]);
00219 list<vertex_descriptor> CCL[k];
00220 BGL_FORALL_VERTICES_T(u,H, Graph) CCL[CC[vertex_index[u]]].push_back(HtoG[u]);
00221
00222
00223
00224 vertex_descriptor v;
00225 map<vertex_descriptor, bool> R;
00226 if(k>1) {
00227 BGL_FORALL_VERTICES_T(v, G, Graph)
00228 R[v] = false;
00229 for(int j=0;j<k;j++) {
00230 row r;
00231 BOOST_FOREACH(v, CCL[j]) R[v]=true;
00232 double d=0;
00233 int t=0;
00234 BGL_FORALL_EDGES_T(e,G, Graph) {
00235 if((R[source(e, G)]) && (R[target(e, G)])) {
00236 d+=S.value(VM[e]);
00237 r+=VM[e];
00238 }
00239 if((R[source(e, G)]!=R[target(e, G)]) && (val[e]>VALONE-10)) {
00240 d+=S.value(VM[e]);
00241 r+=VM[e];
00242 t++;
00243 };
00244 };
00245 if((t % 2==1) && (d>CCL[j].size()+(t-1)/2+0.01)) {
00246 i++;
00247 S.add_basic_constraint(r<=CCL[j].size()+(t-1)/2);
00248 cout<<"comb\n";
00249 };
00250 BOOST_FOREACH(v, CCL[j]) R[v]=false;
00251 }
00252 }
00253 }
00254 if(i>0) {
00255 return constraint_found;
00256 }
00257
00258 return no_constraint_found;
00259 };
00260
00261
00262 template <typename Graph>
00263 typename TOUR<Graph>::status TOUR<Graph>::feasible(solution& S) {
00264 if(S.originating_subproblem()->configuration("TOUR_Debug_Out")=="true")
00265 cerr << "TOUR::feasible\n";
00266
00267
00268
00269
00270
00271 map<vertex_descriptor, vertex_descriptor> GtoH;
00272 Graph H;
00273 vertex_descriptor u;
00274 BGL_FORALL_VERTICES_T(u, G, Graph)
00275 GtoH[u]=add_vertex(H);
00276 edge_descriptor e;
00277 BGL_FORALL_EDGES_T(e,G, Graph) {
00278 if(S.value(VM[e])>0.5) add_edge(GtoH[source(e, G)], GtoH[target(e, G)], H);
00279 }
00280
00281
00282 BGL_FORALL_VERTICES_T(u,H, Graph) if (out_degree(u, H)!=2) return infeasible_solution;
00283
00284
00285 vector<int> comp(num_vertices(H));
00286 int cc = connected_components(H,&comp[0]);
00287 if (cc == 1) return feasible_solution;
00288 return infeasible_solution;
00289 };
00290
00291 template<typename Graph>
00292 void TOUR<Graph>::info() {
00293 cout<<"Method: Cutting Planes\n\n";
00294
00295 cout<<"Configurations:\n";
00296 cout<<"TOUR_heuristic_only [true|false]\n";
00297 cout<<"TOUR_Debug_Out [true|false]\n";
00298 };
00299
00300 #undef VALONE
00301
00342 #endif