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

steiner.cc

00001 #include<sstream>
00002 #include<scil/scil.h>
00003 #include<scil/constraints/path.h>
00004 
00005 using namespace std;
00006 using namespace boost;
00007 
00008 
00009 struct vertex_reached_t {
00010   typedef vertex_property_tag kind;
00011 };
00012 
00013 struct edge_cost_t {
00014   typedef edge_property_tag kind;
00015 };
00016 
00017 typedef property<vertex_color_t, int> vertexProperty;   // replace with boost::default_color_type..... -1=red, 0=white, 1=green
00018 typedef property<edge_cost_t, double> edgeProperty;
00019 typedef boost::adjacency_list<vecS,vecS,bidirectionalS,vertexProperty,edgeProperty > Graph;
00020 
00021 typedef graph_traits<Graph>::vertex_descriptor vertex_descriptor;
00022 typedef graph_traits<Graph>::edge_descriptor edge_descriptor;
00023 
00024 double strToDouble(const char* s){
00025   return atof(s);
00026 }
00027 
00028 void read_steinlib(Graph& G, const char* fname) {
00029   int n, i, j, k;
00030 
00031   ifstream ifs(fname);  
00032   std::string s;
00033   vertex_descriptor lastterm;
00034   edge_descriptor e;
00035   std::string prefix;
00036 
00037   while(!ifs.eof()) {
00038 
00039     getline(ifs,s);
00040 
00041     istringstream is(s);
00042     is >> prefix;
00043 
00044     if(prefix=="Nodes") {
00045       is >> n;
00046       cout<<n<<" Nodes\n";
00047       for(i=0; i<n; i++) {
00048         add_vertex(G);
00049       };
00050     };
00051     if(prefix=="E") {
00052       is>>i;
00053       is>>j;
00054       std::string s2;
00055       is>>s2;
00056       add_edge(i-1,j-1,strToDouble(s2.c_str()),G);
00057       add_edge(j-1,i-1,strToDouble(s2.c_str()),G);
00058     };
00059     if(prefix=="A") {
00060       is>>i;
00061       is>>j;
00062       std::string s2;
00063       is>>s2;
00064       if(s2!="1000000000") {
00065         add_edge(i-1,j-1,strToDouble(s2.c_str()),G);
00066       };
00067       is>>s2;
00068       if(s2!="1000000000") {
00069         add_edge(j-1,i-1,strToDouble(s2.c_str()),G);
00070       }
00071     };
00072     if(prefix=="T") {
00073       is >> i;
00074       put(vertex_color_t(),G,i-1,-1);   // color = red
00075       lastterm = i-1;
00076     };
00077     if(prefix=="DD") {
00078       is>>i;
00079       is>>j;
00080       is>>k;
00081     };
00082   };
00083 
00084   bool haveroot=false;
00085   BGL_FORALL_VERTICES(u,G,Graph) {
00086     if( in_degree(u,G)==0 ) {
00087       put(vertex_color_t(),G,u,1);      // color = green
00088       haveroot=true;
00089       cout<<"Declare a root\n";
00090     };
00091   }
00092 
00093   if(haveroot==false) {
00094       put(vertex_color_t(),G,lastterm,1);       // color = green
00095       cout<<"Declare last terminal as root\n";
00096   };
00097 };
00098 
00099 
00100 
00101 //void ComputeSteinerTree(Graph& G, edge_array<double>& Cost, node r,
00102 //                      node_array<bool>& R, std::list<edge>& T) {
00103 void ComputeSteinerTree(Graph& G, vertex_descriptor r, std::vector<bool>& R, std::list<edge_descriptor>& T) {
00104  
00105   cout<<"setupm\n";
00106 
00107   ILP_Problem IP(Optsense_Min);
00108 
00109   cout<<"setup problem\n";
00110 
00111   var_map<edge_descriptor> VM;
00112   BGL_FORALL_EDGES(e,G,Graph) { 
00113     double cost = get(edge_cost_t(),G,e);
00114     VM[e]=IP.add_binary_variable(cost);
00115   }
00116 
00117   BGL_FORALL_VERTICES(u, G, Graph) {
00118     if(R[u]) {
00119       IP.add_sym_constraint(new PATH<Graph>(G, r, u, VM));
00120       row r;
00121       BGL_FORALL_INEDGES(u,e,G,Graph) r+=VM[e];
00122       IP.add_basic_constraint(r==1);
00123     } else if(u!=r) {
00124        row r;
00125        BGL_FORALL_INEDGES(u,e,G,Graph)  r+=VM[e];
00126        BGL_FORALL_OUTEDGES(u,e,G,Graph) r-=VM[e];
00127        IP.add_basic_constraint(r<=0);
00128     }
00129   }
00130 
00131   cout<<"start optimization\n";
00132   IP.optimize();
00133   
00134   BGL_FORALL_EDGES(e,G,Graph) {
00135     if(IP.get_solution(VM[e])==1) T.push_back(e);
00136   }
00137 } 
00138 
00139 
00140 int main(int argc, char** argv)
00141 {
00142   cout.precision(10);
00143 
00144   char* s;
00145   if(argc<2) {
00146     cout<<"Filename : ";
00147     cin>>s;
00148   }else
00149     s = argv[1];
00150 
00151   Graph G;
00152   read_steinlib(G, s); 
00153 
00154     
00155   std::vector<bool> R(num_vertices(G),false); 
00156   vertex_descriptor r;
00157   BGL_FORALL_VERTICES(u,G,Graph) {
00158     if(get(vertex_color_t(),G,u)==-1) R[u]=true;        // color = red
00159     if(get(vertex_color_t(),G,u)==1) r=u;               // color = green 
00160   };
00161 
00162   std::list<edge_descriptor> T;
00163   ComputeSteinerTree(G, r, R, T);
00164 
00165   return 0;
00166 }
Generated on Mon Mar 28 22:03:50 2011 for SCIL by  doxygen 1.6.3