Main Page   Class Hierarchy   Compound List   File List   Contact   Download   Symbolic Constraints   Examples  

atour.cc

00001 #ifndef ATOUR_CONSTRAINT_CC
00002 #define ATOUR_CONSTRAINT_CC
00003 
00004 #include<scil/scil.h>
00005 #include<scil/var_map.h>
00006 #include<LEDA/graph.h>
00007 #include<LEDA/graph_alg.h>
00008 #include<LEDA/set.h>
00009 #include<scil/constraints/atour.h>
00010 
00011 using namespace SCIL;
00012 using namespace LEDA;
00013 
00014 #define VALONE 1000000
00015 
00016 class ATOUR::dir_degree_equality : public cons_obj {
00017 private:
00018   const graph& G;
00019   node v;
00020   double deg;
00021   scil_map<edge>& VM;
00022   bool in;
00023   
00024 public:
00025 
00026   dir_degree_equality(subproblem& S_,
00027                   const graph& G_, node v_, scil_map<edge>& VM_,
00028                   double d, bool i_)
00029     /*{create The constraint $\sum_{e \in \delta(v)} x_e = d$, where $\delta(v)$ are the 
00030       edges which are adjacent to v and for which a variable was defined.}*/
00031     : cons_obj(Equal, d), G(G_), VM(VM_) { 
00032     v=v_; deg=d, in=i_; 
00033   };
00034 
00035   virtual
00036   ~dir_degree_equality()
00037   {};
00038   
00039   node gnode() { return v; };
00040   
00041   virtual void non_zero_entries(row& r) {
00042     edge e;
00043     if(in) {
00044       forall_out_edges(e, v) {
00045         r+=VM(e);
00046       }
00047     } else {
00048       forall_in_edges(e, v) {
00049         r+=VM(e);
00050       }
00051     };
00052   };
00053 };
00054 
00055 class ATOUR::dir_cutset_inequality : public cons_obj {
00056 private:
00057   graph& G;
00058   scil_map<edge>& VM;
00059   node_array<bool> cut;
00060   double rhs;
00061   
00062 public:
00063   
00064   dir_cutset_inequality(graph& Gt, scil_map<edge>& VM_, list<node>& L) 
00065     : cons_obj(Less, L.size()-1), G(Gt), VM(VM_) {
00066     node v;
00067     cut.init(G, false);
00068     forall(v,L) cut[v]=true;
00069   }
00070 
00071   void non_zero_entries(row& r) { 
00072     edge e;
00073     forall_edges(e,G) {
00074       if(coeff(e)==1) r+=VM(e);
00075     }
00076   }
00077 
00078   virtual
00079   ~dir_cutset_inequality() {};
00080 
00081   double coeff(edge e) { 
00082     if(e==nil) return 0;
00083     if((cut[G.source(e)]) && (cut[G.target(e)])) return 1;
00084     return(0);
00085   };
00086 };
00087 
00088 
00089 ATOUR::ATOUR(graph& G_, scil_map<edge>& VM_)
00090   : G(G_), VM(VM_)
00091 { };
00092 
00093 void ATOUR::init(subproblem& S) {
00094   node v;
00095   forall_nodes(v, G) {
00096     S.add_basic_constraint(new dir_degree_equality(S,G,v,VM,1, true));
00097     S.add_basic_constraint(new dir_degree_equality(S,G,v,VM,1, false));
00098   }
00099 }
00100   
00101 ATOUR::status ATOUR::separate(subproblem& S) {
00102   // Preperation
00103   int i=0;
00104   edge_array<int> val(G);
00105   edge e;
00106   forall_edges(e, G) val[e]=leda::max((int) (VALONE*S.value(VM(e))),0);
00107   
00108   // Heutistic
00109   graph H;
00110   node u;
00111   node_array<node> HtoG(H, G.number_of_nodes(), u);
00112   node_array<node> GtoH(G);
00113   
00114   forall_nodes(u, G) { GtoH[u]=H.new_node(); HtoG[GtoH[u]]=u; }
00115   
00116   forall_edges(e, G) if(val[e]>=VALONE-5)
00117     H.new_edge(GtoH[source(e)], GtoH[target(e)]);
00118 
00119   node_array<int> CC(H);
00120   int k=COMPONENTS(H,CC);
00121   list<node> CCL[k];
00122   forall_nodes(u,H) CCL[CC[u]].append(HtoG[u]);
00123   cout<<k<<" Connected Components\n";
00124 
00125   if(k>1) {
00126     for(int j=0;j<k;j++) {
00127       cons_obj* c=new dir_cutset_inequality(G,VM,CCL[j]);
00128       if (c->violated(S)) { 
00129         i++;
00130         S.add_basic_constraint(c, Dynamic); 
00131       } else delete c;
00132     }
00133   }
00134 
00135   // Heuristic succeeded?
00136   if(i>0) { 
00137     cout<<i<<" Heuristic\n"; return constraint_found; 
00138   }
00139   //return no_constraint_found;
00140 
00141   // exact separation
00142   list<node> mc=MIN_CUT(G, val);
00143   cons_obj* c=new dir_cutset_inequality(G,VM,mc);
00144   if (c->violated(S)) {
00145     i++; S.add_basic_constraint(c, Dynamic);
00146   } else delete c;
00147   if(i>0) {
00148     cout<<"Exact CUT fount inequality\n";
00149     return constraint_found;
00150   }
00151 /*
00152   H.del_all_edges();
00153 
00154   // Copy the edges with fractional value
00155   forall_edges(e, G) if((val[e]>=5) && (val[e]<=VALONE-5))
00156     H.new_edge(GtoH[source(e)], GtoH[target(e)]);
00157   
00158   // Compute the connected components
00159   {
00160     node_array<int> CC(H);
00161     int k=COMPONENTS(H,CC);
00162     list<node> CCL[k];
00163     forall_nodes(u,H) CCL[CC[u]].append(HtoG[u]);
00164 
00165     // Create the corresponding comb constraints and check for
00166     // violation
00167     node v;
00168     node_array<bool> R(G, false);
00169     node_array<bool> T(G, false);
00170     list<node> TL;
00171     if(k>1) {
00172       for(int j=0;j<k;j++) {
00173         row r;
00174         forall(v, CCL[j]) R[v]=true;
00175         double d=0;
00176         int t=0;
00177         forall_edges(e,G) {
00178           if((R[source(e)]) && (R[target(e)])) { 
00179             d+=S.value(VM(e));
00180             r+=VM(e);
00181           }
00182           if((R[source(e)]!=R[target(e)]) && (val[e]>VALONE-10)) {
00183             d+=S.value(VM(e));
00184             r+=VM(e);
00185             if(R[source(e)]) u=target(e); else u=source(e);
00186             if(T[u]==false) {
00187               t++;
00188               T[u]=true;
00189               TL.append(u);
00190             };
00191           };
00192         };
00193         if((t % 2==1) && (d>CCL[j].size()+(t-1)/2+0.01)) {
00194           i++;
00195           S.add_basic_constraint(r<=CCL[j].size()+(t-1)/2);
00196           cout<<"comb\n";
00197         };
00198         forall(v, CCL[j]) R[v]=false;
00199         forall(v,TL) T[v]=false;
00200         TL.clear();
00201       }
00202     }
00203   }
00204 */
00205   if(i>0) {
00206     return constraint_found;
00207   }
00208 
00209   return no_constraint_found;
00210 }
00211 
00212 ATOUR::status ATOUR::feasible(solution& S) {
00213   node_array<node> GtoH(G);
00214   graph H;
00215   node u;
00216   forall_nodes(u, G)
00217     GtoH[u]=H.new_node();
00218   edge e;
00219   forall_edges(e,G) {
00220     if(S.value(VM(e))>0.5) H.new_edge(GtoH[source(e)], GtoH[target(e)]);
00221   }
00222   if (Is_Connected(H)) return feasible_solution;
00223   return infeasible_solution;
00224 }
00225 #undef VALONE
00226 
00227 #endif

Generated on Tue Nov 16 15:18:13 2004 for SCIL by doxygen1.2.16