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
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
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