00001 #ifndef PATH_CONSTRAINT_CC
00002 #define PATH_CONSTRAINT_CC
00003
00004
00005 using namespace SCIL;
00006 using namespace std;
00007
00008 #define VALONE 1000.0
00009
00010 template< typename Graph >
00011 class PATH<Graph>::path_cutset_inequality : public cons_obj {
00012 private:
00013 typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
00014 typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
00015
00016 Graph& G;
00017 var_map<edge_descriptor>& VM;
00018 std::map<vertex_descriptor,bool> cut;
00019 double rhs;
00020
00021 public:
00022
00023 path_cutset_inequality(Graph& Gt, var_map<edge_descriptor>& VM_, std::list<vertex>& L)
00024 : cons_obj(Greater, 1), G(Gt), VM(VM_) {
00025
00026 BGL_FORALL_VERTICES_T(v,G,Graph)
00027 cut[v] = false;
00028
00029 typename std::list<vertex>::const_iterator it;
00030 foreach(it,L)
00031 cut[*it]=true;
00032 }
00033
00034 void non_zero_entries(row& r) {
00035 BGL_FORALL_EDGES_T(e,G,Graph)
00036 if((VM[e] != 0) && (coeff(e)==1))
00037 r+=VM[e];
00038 }
00039
00040 virtual
00041 ~path_cutset_inequality() {};
00042
00043 double coeff(edge_descriptor e) {
00044 if((cut[source(e,G)]) && (!cut[target(e,G)])) return 1;
00045 return(0);
00046 };
00047 };
00048
00049
00050
00051 template< typename Graph >
00052 PATH<Graph>::PATH(Graph& G_, vertex u_, vertex v_, var_map<edge_descriptor>& VM_)
00053
00054
00055
00056
00057 : G(G_), u(u_), v(v_), VM(VM_), H(num_vertices(G_)) {
00058
00059
00060 if( !is_directed(G_) ) {
00061 cerr << "path.cc: The Graph G has to be directed" << endl;
00062
00063 }
00064
00065 BGL_FORALL_EDGES_T(e,G,Graph)
00066 if ( (VM[e]!=0) && (VM[e].type()!=Vartype_Binary) ) {
00067 cerr << "path.cc: All varibales in VM need to be Vartype_Binary" << endl;
00068 exit(1);
00069 }
00070
00071
00072 property_map<dGraph, edge_reverse_t>::type
00073 rev = get(edge_reverse, H);
00074 dedge e1,e2;
00075 BGL_FORALL_EDGES_T(e,G,Graph) {
00076 if(edge(source(e,G), target(e,G),H).second){
00077 GtoH[e]=edge(source(e,G), target(e,G),H).first;
00078 continue;
00079 }
00080 e1 = add_edge( source(e,G), target(e,G), H).first;
00081 e2 = add_edge( target(e,G), source(e,G), H).first;
00082 GtoH[e] = e1;
00083 rev[e1] = e2;
00084 rev[e2] = e1;
00085 }
00086
00087 feps = 1.0e-4;
00088 };
00089
00090
00091 template< typename Graph >
00092 void PATH<Graph>::dfs(dGraph& dG, dvertex u, std::vector<bool>& R) {
00093 R[u]=true;
00094 BGL_FORALL_OUTEDGES_T(u,e,dG,dGraph)
00095 if( !R[target(e,dG)] )
00096 dfs(dG, target(e,dG), R);
00097 };
00098
00099
00100 template< typename Graph >
00101 typename PATH<Graph>::status PATH<Graph>::standard_separation(subproblem& S) {
00102 if (S.configuration("PATH_Debug_Out")=="true")
00103 cerr << "PATH::standard_separation\n";
00104
00105
00106
00107
00108 property_map<dGraph, edge_capacity_t>::type
00109 cap = get(edge_capacity, H);
00110
00111 property_map<dGraph, edge_reverse_t>::type
00112 rev = get(edge_reverse, H);
00113
00114 property_map<dGraph, vertex_index_t>::type
00115 ind = get(vertex_index, H);
00116
00117 property_map<dGraph, edge_residual_capacity_t>::type
00118 rescap = get(edge_residual_capacity, H);
00119
00120 typedef map<vertex, default_color_type> color_map_t;
00121 color_map_t color_map;
00122 BGL_FORALL_VERTICES_T(v, H, dGraph) {
00123 color_map[v] = white_color;
00124 }
00125 associative_property_map<color_map_t> pm_color(color_map);
00126
00127 BGL_FORALL_EDGES_T(e,H,dGraph)
00128 cap[e]=0;
00129
00130 BGL_FORALL_EDGES_T(e,G,Graph) {
00131 if(VM[e] == 0)
00132 cap[GtoH[e]] = 1;
00133 else
00134 cap[GtoH[e]]=(int) (VALONE*S.value(VM[e]))+1;
00135 }
00136
00137
00138 boykov_kolmogorov_max_flow(H, cap, rescap, rev, pm_color,ind, u,v);
00139
00140
00141 std::list<vertex> mc;
00142 BGL_FORALL_VERTICES_T(v, H, dGraph)
00143 if(color_map[v]==black_color)
00144 mc.push_back(v);
00145
00146 int i=0;
00147 cons_obj* c=new path_cutset_inequality(G,VM,mc);
00148 if (c->violation(S) > feps) {
00149 i++;
00150 S.add_basic_constraint(new path_cutset_inequality(G, VM, mc), Dynamic);
00151 }
00152 delete c;
00153 if(i>0) {
00154 return constraint_found;
00155 }
00156 if(S.configuration("PATH_Debug_Out")=="true")
00157 cerr << "No path constraint\n";
00158 return no_constraint_found;
00159 }
00160
00161
00162 template< typename Graph >
00163 typename PATH<Graph>::status PATH<Graph>::feasible(solution& S) {
00164 if (S.originating_subproblem()->configuration("PATH_Debug_Out")=="true")
00165 cerr << "PATH::feasible\n";
00166
00167 dGraph H;
00168 std::map<vertex,dvertex> GtoH;
00169
00170 BGL_FORALL_VERTICES_T(v,G,Graph)
00171 GtoH[v] = add_vertex(H);
00172
00173 BGL_FORALL_EDGES_T(e,G,Graph) {
00174 if((VM[e]!=0) && (S.value(VM[e])>0.5))
00175 add_edge( GtoH[ source(e,G) ], GtoH[ target(e,G) ], H);
00176 }
00177
00178 std::vector<bool> R(num_vertices(H),false);
00179 dfs(H, GtoH[u], R);
00180
00181 if(R[GtoH[v]]) return feasible_solution;
00182 return infeasible_solution;
00183 };
00184
00185 template< typename Graph >
00186 void PATH<Graph>::info() {
00187 cout<<"Configurations:\n";
00188 cout<<"PATH_Debug_Out [true|false]\n";
00189 };
00190
00191 #undef VALONE
00192
00193 #endif