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

stronglyconnected.cc

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    /*{\Mcreate balbla }*/
00015 { 
00016    //Graph has to provide in_edges() and out_edges()
00017    BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept<Graph>));
00018    //Graph has to provide vertices() and edges()
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   /*{\Mop computes violated subtour-elimination constraints.}*/
00067 {
00068    if (S.configuration("StronglyConnected_Debug_Out")=="true")
00069       cerr << "StronglyConnected::standard_separation\n";
00070 
00071    status sta=no_constraint_found;
00072    // Preparation
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                // Make Constraint
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
Generated on Mon Mar 28 22:03:50 2011 for SCIL by  doxygen 1.6.3