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;
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);
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);
00088 haveroot=true;
00089 cout<<"Declare a root\n";
00090 };
00091 }
00092
00093 if(haveroot==false) {
00094 put(vertex_color_t(),G,lastterm,1);
00095 cout<<"Declare last terminal as root\n";
00096 };
00097 };
00098
00099
00100
00101
00102
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;
00159 if(get(vertex_color_t(),G,u)==1) r=u;
00160 };
00161
00162 std::list<edge_descriptor> T;
00163 ComputeSteinerTree(G, r, R, T);
00164
00165 return 0;
00166 }