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

path.cc

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    /*{\Mcreate Ensures that there is a path from $u$ to $v$ in the graph
00054       selected by the edges in VM.\\
00055       For a demo see: ptsp.
00056       }*/
00057   : G(G_), u(u_), v(v_), VM(VM_), H(num_vertices(G_)) { 
00058 
00059    // Asure G uses vertex_index_t and vertices are ordered by [0...num_vertices)
00060    if( !is_directed(G_) ) {
00061       cerr << "path.cc: The Graph G has to be directed" << endl;
00062      // exit(1);
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    // add reverse edges to local copy of G  (used for max flow algo)
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    // Preparation
00105 
00106    /* calculate the capacity for each edge e coming from G 
00107     * remark: each reverse edge gets capacity 0 */
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    // exact separation
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
Generated on Mon Mar 28 22:03:49 2011 for SCIL by  doxygen 1.6.3