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

spantree.cc

00001 #ifndef SPAN_TREE_CC
00002 #define SPAN_TREE_CC
00003 
00004 #include<scil/scil.h>
00005 #include<LEDA/graph.h>
00006 #include<LEDA/graph_alg.h>
00007 #include<LEDA/set.h>
00008 #include<scil/constraints/spantree.h>
00009 
00010 using namespace SCIL;
00011 using namespace LEDA;
00012 
00013 #define VALONE 10000
00014 
00015 class SpanTree::st_cutset_inequality : public cons_obj {
00016 private:
00017   graph& G;
00018   scil_map<edge>& VM;
00019   node_array<bool> cut;
00020   double rhs;
00021   
00022 public:
00023   
00024   st_cutset_inequality(graph& Gt, scil_map<edge>& VM_, list<node>& L) 
00025   : cons_obj(Greater, 1), G(Gt), VM(VM_) {
00026     node v;
00027     cut.init(G, false);
00028     forall(v,L) cut[v]=true;
00029   }
00030 
00031   void non_zero_entries(row& r) { 
00032     edge e;
00033     forall_edges(e,G) {
00034       if(coeff(e)==1) r+=VM(e);
00035     }
00036   }
00037 
00038   virtual
00039   ~st_cutset_inequality() {};
00040 
00041   double coeff(edge e) { 
00042     if(e==nil) return 0;
00043     if(cut[G.source(e)] != cut[G.target(e)]) return 1;
00044     return(0);
00045   };
00046 };
00047 
00048 
00049 SpanTree::SpanTree(graph& G_, scil_map<edge>& VM_)
00050   : G(G_), VM(VM_)
00051 { };
00052 
00053 void SpanTree::init(subproblem& S) {
00054   row r;
00055   edge e;
00056   forall_edges(e, G) { r+=VM(e); }
00057   S.add_basic_constraint(r == G.number_of_nodes()-1);
00058   
00059   node v;
00060   GtoH.init(G);
00061   GtoH1.init(G);
00062   GtoH2.init(G);
00063   forall_nodes(v, G) {
00064     GtoH[v]=H.new_node();
00065   };
00066 
00067   forall_edges(e, G) {
00068     GtoH1[e]=H.new_edge(GtoH[source(e)], GtoH[target(e)]);
00069     GtoH2[e]=H.new_edge(GtoH[target(e)], GtoH[source(e)]);
00070   };
00071 
00072   son=H.new_node();
00073   tan=H.new_node();
00074   forall_nodes(v, G) {
00075     H.new_edge(son, GtoH[v]);
00076     H.new_edge(GtoH[v], tan);
00077   };
00078   
00079   Cap.init(H);
00080 }
00081 
00082 void SpanTree::min_cut(node u, edge_array<int>& C, edge_array<int>& F, 
00083                        node_array<bool>& R, int& k) {
00084   R[u]=true;
00085   k++;
00086   edge e;
00087   forall_out_edges(e, u) if((F[e]!=C[e]) && (!R[target(e)])) {
00088     min_cut(target(e), C, F, R, k);
00089   };
00090   forall_in_edges(e, u) if((F[e]!=0) && (!R[source(e)])) {
00091     min_cut(source(e), C, F, R, k);
00092   };
00093 };
00094 
00095 SpanTree::status SpanTree::separate(subproblem& S) {
00096 
00097   cout<<"Separation SpanTree\n";
00098 
00099   status sta=no_constraint_found;
00100   // Preperation
00101   int j, k;
00102   node_array<int> Con(H);
00103   edge e,f;
00104   forall_edges(e, G) { 
00105     j=(int) (VALONE*S.value(VM(e)));
00106     if(j<0) j=0;
00107     Cap[GtoH1[e]]=j;
00108     Cap[GtoH2[e]]=j;
00109     Con[GtoH[source(e)]]+=j;
00110     Con[GtoH[target(e)]]+=j;
00111   };
00112   
00113   forall_out_edges(e, son) {
00114     Cap[e]=leda_max(Con[target(e)]-2*VALONE,0);
00115   };
00116   forall_in_edges(e, tan) {
00117     Cap[e]=leda_max(2*VALONE-Con[source(e)],0);
00118   };
00119   
00120   if(sta==constraint_found) return sta;            
00121   
00122   edge_array<int> Flow(H);
00123   forall_out_edges(e, son) {
00124     k=Cap[e];
00125     Cap[e]=1000*VALONE;
00126     j=MAX_FLOW(H, son, tan, Cap, Flow);
00127     // Make Constraint
00128     node_array<bool> R(H, false);
00129     j=0;
00130     min_cut(son, Cap, Flow, R, j);
00131     row r;
00132     double d=0;
00133     forall_edges(f, G) {
00134       if((R[GtoH[source(f)]]) && (R[GtoH[target(f)]])) {
00135         r+=VM(f);
00136         d+=S.value(VM(f));
00137       };
00138       }
00139     if(d>((double) j)-1.99) {
00140       S.add_basic_constraint(r<=j-2, Dynamic);
00141       sta=constraint_found;
00142     };
00143     Cap[e]=k;
00144   };
00145   return sta;
00146 }
00147 
00148 SpanTree::status SpanTree::feasible(solution& S) {
00149   node_array<node> GtoH(G);
00150   graph H;
00151   node u;
00152   forall_nodes(u, G)
00153     GtoH[u]=H.new_node();
00154   edge e;
00155   forall_edges(e,G) {
00156     if(S.value(VM(e))>0.5) H.new_edge(GtoH[source(e)], GtoH[target(e)]);
00157   }
00158   node_array<int> C(H);
00159   int i=COMPONENTS(H, C);
00160   if (i==1) return feasible_solution;
00161   cout<<"integer feasible, but infeasible\n";
00162   return infeasible_solution;
00163 }
00164 
00165 #undef VALONE
00166 
00167 #endif

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