00001 #ifndef TJOIN_CC
00002 #define TJOIN_CC
00003
00004 using namespace boost;
00005 using namespace SCIL;
00006 using namespace std;
00007
00008 template <typename Graph>
00009 TJOIN<Graph>::TJOIN(Graph& G_, var_map<edge_descriptor>& VM_, map<vertex_descriptor, bool>& T_)
00010 :G(G_), VM(VM_), T(T_)
00011 {
00012
00013 typedef typename GraphTraits::directed_category directed_category;
00014 bool graph_is_undirected = is_same<directed_category,undirected_tag>::value
00015 || is_base_and_derived<undirected_tag, directed_category>::value;
00016 BOOST_ASSERT(graph_is_undirected);
00017
00018 edge_descriptor e;
00019 vertex_descriptor v;
00020
00021 BGL_FORALL_EDGES_T(e, G, Graph) {
00022 if( VM[e].type() != Vartype_Binary ) {
00023 cerr << "TJOIN: All variables in VM need to be Vartype_Binary";
00024 cerr << endl;
00025 exit(1);
00026 }
00027 }
00028
00029
00030 unsigned int i = 0;
00031 BGL_FORALL_VERTICES_T(v, G, Graph)
00032 if(T[v]) i++;
00033 if(i % 2 == 1) {
00034 cerr << "TJOIN: T has to describe a vertex set of even cardinality" <<endl;
00035 exit(1);
00036 }
00037
00038
00039 BOOST_CONCEPT_ASSERT((VertexAndEdgeListGraphConcept<Graph>));
00040
00041 BOOST_CONCEPT_ASSERT((IncidenceGraphConcept<Graph>));
00042
00043 BOOST_CONCEPT_ASSERT((MutableGraphConcept<Graph>));
00044
00045 }
00046
00047 template <typename Graph>
00048 void TJOIN<Graph>::init(subproblem& S){
00049 if( S.configuration("TJOIN_Debug_Out")=="true" )
00050 cerr << "TJOIN::init\n";
00051 return;
00052 }
00053
00054 template <typename Graph>
00055 typename TJOIN<Graph>::status TJOIN<Graph>::feasible(solution& S){
00056 typename GraphTraits::out_edge_iterator out_i, out_end;
00057 vertex_descriptor v;
00058 unsigned int i;
00059 BGL_FORALL_VERTICES_T(v, G, Graph){
00060 i = 0;
00061 for(tie(out_i, out_end)=out_edges(v, G); out_i != out_end; out_i++)
00062 if(S.value(VM[*out_i]) > 0.5)
00063 i++;
00064 if((T[v] && (i % 2 == 0) || (!T[v] && (i % 2 == 1))))
00065 return infeasible_solution;
00066 }
00067 return feasible_solution;
00068 }
00069
00070 template <typename Graph>
00071 typename TJOIN<Graph>::status TJOIN<Graph>::standard_separation(subproblem& S){
00072 double min;
00073 edge_descriptor e;
00074 vertex_descriptor v, w;
00075 map<edge_descriptor, double> c;
00076 map<vertex_descriptor, vertex_descriptor> p;
00077 map<vertex_descriptor, double> fl;
00078 map<edge_descriptor, double> flow;
00079 vector<int> mincomp(num_vertices(G));
00080
00081
00082 BGL_FORALL_EDGES_T(e, G, Graph)
00083 c[e] = S.value(VM[e]);
00084
00085
00086 computeCutTree(G, c, p, fl);
00087
00088 #ifdef DEBUG_TJOIN
00089 BGL_FORALL_VERTICES_T(v, G, Graph)
00090 if(v == 0)
00091 continue;
00092 else
00093 cout<<v<<"-"<<p[v]<<": "<<fl[v]<<endl;
00094 #endif
00095
00096
00097 Graph H(num_vertices(G));
00098 BGL_FORALL_VERTICES_T(v, G, Graph)
00099 if(v == 0)
00100 continue;
00101 else
00102 flow[add_edge(v, p[v], H).first] = fl[v];
00103
00104
00105 min = 1.;
00106 BGL_FORALL_EDGES_T(e, H, Graph) {
00107 vertex_descriptor s = source(e,H);
00108 vertex_descriptor t = target(e,H);
00109 Graph H1(H);
00110 remove_edge(s,t,H1);
00111 vector<int> components(num_vertices(H1));
00112 int num = connected_components(H1, &components[0]);
00113
00114
00115 unsigned int i = 0;
00116 BGL_FORALL_VERTICES_T(w, H1, Graph)
00117 if(components[w] == 0)
00118 i++;
00119 if((i % 2 == 1) && (flow[e] <= min)) {
00120 min = flow[e];
00121 mincomp = components;
00122 }
00123 }
00124
00125 #ifdef DEBUG_TJOIN
00126 BGL_FORALL_VERTICES_T(v, G, Graph)
00127 cout<<v<<": "<<mincomp[v]<<endl;
00128 #endif
00129
00130 if(min < 1 - .001) {
00131
00132 row r;
00133 BGL_FORALL_EDGES_T(e, G, Graph)
00134 if((mincomp[source(e, G)] && !mincomp[target(e,G)]) || (mincomp[target(e, G)] && !mincomp[source(e, G)]))
00135 r += VM[e];
00136
00137 S.add_basic_constraint(r>=1);
00138 return constraint_found;
00139 }
00140 else
00141 return no_constraint_found;
00142 }
00143
00144 #endif