00001 #ifndef STRONGLY_CONNECTED_CC
00002 #define STRONGLY_CONNECTED_CC
00003
00004
00005 using namespace SCIL;
00006 using namespace std;
00007 using namespace boost;
00008
00009 #define VALONE 10000
00010
00011
00012 template <typename Graph>
00013 StronglyConnected<Graph>::StronglyConnected(Graph& G_, var_map<edge_descriptor>& VM_)
00014
00015 {
00016
00017 BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept<Graph>));
00018
00019 BOOST_CONCEPT_ASSERT((VertexAndEdgeListGraphConcept<Graph>));
00020 srand(time(NULL));
00021 edge_descriptor e;
00022 vertex_descriptor v;
00023 BGL_FORALL_VERTICES_T(v, G_, Graph)
00024 add_vertex(G);
00025 BGL_FORALL_EDGES_T(e, G_, Graph){
00026 VM[add_edge(source(e, G_), target(e, G_), G).first] = VM_[e];
00027 if (VM_[e].type() != Vartype_Binary)
00028 {
00029 cerr << "stronglyconnected.cc: All variables in VM need ";
00030 cerr << "to be Vartype_Binary" << endl;
00031 exit(1);
00032 }
00033 }
00034 BGL_FORALL_EDGES_T(e, G, Graph){
00035 if(edge(target(e, G), source(e, G), G).second){
00036 edge_reverse[e] = edge(target(e, G), source(e, G), G).first;
00037 edge_reverse[edge_reverse[e]] = e;
00038 }
00039 else{
00040 edge_reverse[e] = add_edge(target(e, G), source(e, G), G).first;
00041 edge_reverse[edge_reverse[e]] = e;
00042 VM[edge_reverse[e]] = NULL;
00043 }
00044 }
00045 };
00046
00047 template <typename Graph>
00048 void StronglyConnected<Graph>::min_cut(vertex_descriptor u, map<edge_descriptor, int>& C, map<edge_descriptor, int>& F,
00049 map<vertex_descriptor, bool>& R, int& k) {
00050 R[u]=true;
00051 k++;
00052 edge_descriptor e;
00053 for(typename GraphTraits::out_edge_iterator it = out_edges(u, G).first; it != out_edges(u,G).second; it++)
00054 if((F[*it]!=C[*it]) && (!R[target(*it, G)])) {
00055 min_cut(target(*it, G), C, F, R, k);
00056 }
00057
00058 for(typename GraphTraits::in_edge_iterator it = in_edges(u, G).first; it != in_edges(u,G).second; it++)
00059 if((F[*it]!=0) && (!R[source(*it, G)])) {
00060 min_cut(source(*it, G), C, F, R, k);
00061 }
00062 };
00063
00064 template <typename Graph>
00065 typename StronglyConnected<Graph>::status StronglyConnected<Graph>::standard_separation(subproblem& S)
00066
00067 {
00068 if (S.configuration("StronglyConnected_Debug_Out")=="true")
00069 cerr << "StronglyConnected::standard_separation\n";
00070
00071 status sta=no_constraint_found;
00072
00073 capacity_map_t Cap;
00074 capacity_map_t Res;
00075 edge_descriptor e,f;
00076 int j;
00077 BGL_FORALL_EDGES_T(e, G, Graph) {
00078 if(VM[e] != NULL)
00079 j=(int) (VALONE*S.value(VM[e]));
00080 else
00081 j=0;
00082 Cap[e]=j;
00083 };
00084
00085 int nodenumber=rand() % num_vertices(G);
00086 typename GraphTraits::vertex_iterator node = vertices(G).first;
00087 node += nodenumber;
00088 vertex_descriptor w, u, v;
00089 v= *node;
00090
00091 vertex_index_t vertex_index_map;
00092 int i = 0;
00093 BGL_FORALL_VERTICES_T(v, G, Graph)
00094 vertex_index_map[v] = i++;
00095
00096
00097
00098 associative_property_map<capacity_map_t> cap_map(Cap);
00099 associative_property_map<capacity_map_t> res_map(Res);
00100 associative_property_map<vertex_index_t> pm_vertex_index(vertex_index_map);
00101 associative_property_map<edge_reverse_t> pm_edge_reverse(edge_reverse);
00102
00103 BGL_FORALL_VERTICES_T(u, G, Graph){
00104 if (u!=v) {
00105 for(int i=0; i<2; i++) {
00106 if(i==0) {
00107 w=u;
00108 j=boykov_kolmogorov_max_flow(G, cap_map, res_map,pm_edge_reverse,pm_vertex_index, u,v);
00109 } else {
00110 w=v;
00111 j=boykov_kolmogorov_max_flow(G, cap_map, res_map,pm_edge_reverse,pm_vertex_index, v, u);
00112 }
00113
00114 if(j<VALONE-100) {
00115
00116 map<vertex_descriptor, bool> R;
00117 vertex_descriptor x;
00118 BGL_FORALL_VERTICES_T(x, G, Graph)
00119 R[x]=false;
00120 capacity_map_t Flow;
00121 BGL_FORALL_EDGES_T(e, G, Graph)
00122 Flow[e] = Cap[e] - Res[e];
00123 j=0;
00124 min_cut(w, Cap, Flow, R, j);
00125 row r;
00126 BGL_FORALL_EDGES_T(f, G, Graph) {
00127 if((R[source(f, G)]) && (!R[target(f, G)])) {
00128 if(VM[f] != NULL)
00129 r+=VM[f];
00130 };
00131 }
00132 if(r.size() != 0){
00133 S.add_basic_constraint(r>=1);
00134 sta=constraint_found;
00135 }
00136 };
00137 };
00138 }
00139 }
00140 return sta;
00141 }
00142
00143 template <typename Graph>
00144 typename StronglyConnected<Graph>::status StronglyConnected<Graph>::feasible(solution& S) {
00145 if (S.originating_subproblem()->configuration("StronglyConnected_Debug_Out")=="true")
00146 cerr << "StronglyConnected::feasible\n";
00147 map<vertex_descriptor, vertex_descriptor> GtoH;
00148 Graph H;
00149 vertex_descriptor u;
00150 BGL_FORALL_VERTICES_T(u, G, Graph)
00151 GtoH[u]=add_vertex(H);
00152 edge_descriptor e;
00153 BGL_FORALL_EDGES_T(e, G, Graph) {
00154 if(S.value(VM[e])>0.5)
00155 add_edge(GtoH[source(e, G)], GtoH[target(e, G)], H);
00156 }
00157
00158 vector<int> component(num_vertices(H));
00159 int num_components = strong_components(H, &component[0]);
00160
00161 if (num_components==1)
00162 return feasible_solution;
00163 return infeasible_solution;
00164 }
00165
00166 template <typename Graph>
00167 void StronglyConnected<Graph>::info() {
00168 cout<<"Configurations:\n";
00169 cout<<"StronglyConnected_Debug_Out [true|false]\n";
00170 };
00171
00172 #undef VALONE
00173
00174 #endif