00001 #include <boost/foreach.hpp>
00002 #include <boost/graph/adjacency_list.hpp>
00003 #include <boost/graph/depth_first_search.hpp>
00004 #include <boost/graph/graph_traits.hpp>
00005 #include <boost/graph/iteration_macros.hpp>
00006 #include <deque>
00007 #include <fstream>
00008 #include <iostream>
00009 #include <scil/scil.h>
00010 #include <scil/constraints/stableset.h>
00011 #include <string>
00012 #include <queue>
00013
00014 #define INPATH ""
00015
00016 using std::cout;
00017 using std::cerr;
00018 using std::endl;
00019 using std::ifstream;
00020 using std::atoi;
00021
00022 using namespace boost;
00023 using namespace SCIL;
00024
00025 typedef adjacency_list<vecS, vecS, undirectedS > Graph;
00026 typedef boost::graph_traits<Graph> GraphTraits;
00027 typedef GraphTraits::vertex_descriptor vertex_descriptor;
00028 typedef GraphTraits::edge_descriptor edge_descriptor;
00029
00030 typedef adjacency_list<vecS, vecS, bidirectionalS > diGraph;
00031 typedef boost::graph_traits<diGraph> diGraphTraits;
00032 typedef diGraphTraits::vertex_descriptor divertex_descriptor;
00033 typedef diGraphTraits::edge_descriptor diedge_descriptor;
00034
00036
00039 class dfs_back_visitor : public default_dfs_visitor {
00040 public:
00042 dfs_back_visitor (std::list<diedge_descriptor>* _back) : back(_back) {}
00044 void back_edge(diedge_descriptor e, const diGraph &G) const {
00045 back->push_back(e);
00046 }
00048 std::list<diedge_descriptor> *back;
00049 };
00050
00051
00058 bool readgraphComplement(const char* infile, Graph& uG,
00059 map<vertex_descriptor, double>& nc, map<vertex_descriptor, int>& node_mapG) {
00060
00061 diGraph G;
00062 std::string path(INPATH);
00063 path += infile;
00064 ifstream file(path.c_str());
00065 if( file.fail() ) {
00066 cerr << "%%%%%%%% Could not open file " << infile << endl;
00067 cerr << "%%%%%%%% tried " << path << endl;
00068 return false;
00069 }
00070
00071 char buf[1024];
00072 while( file.peek() != 'p' ) {
00073 file.getline(buf, 1024);
00074 }
00075
00076
00077 char c;
00078 int s, t, numnodes, numedges;
00079 double u;
00080 file >> c;
00081 file >> buf;
00082 file >> numnodes;
00083 file >> numedges;
00084
00085
00086
00087 for(int i = 0; i < numnodes; i++)
00088 add_vertex(G);
00089 diGraphTraits::vertex_iterator it, iit, it_end;
00090 for(tie(it, it_end) = vertices(G); it != it_end; it++)
00091 for( iit = it+1; iit != it_end; iit++) {
00092 add_edge(*it, *iit, G);
00093 add_edge(*iit, *it, G);
00094 }
00095
00096 std::vector<divertex_descriptor> an;
00097 BGL_FORALL_VERTICES(v, G, diGraph) {
00098 nc[v] = 1.0;
00099 an.push_back(v);
00100 }
00101
00102 while((file >> c) && file.good()) {
00103 if( c == 'e' ) {
00104 file >> s >> t;
00105
00106 add_edge(an[s-1], an[t-1], G);
00107 add_edge(an[t-1], an[s-1], G);
00108 }
00109 else if( c == 'n' ) {
00110 file >> s >> u;
00111 nc[an[s-1]] = u;
00112 }
00113 else
00114 file.getline(buf, 1024);
00115 }
00116
00117
00118 std::set<diedge_descriptor> parallel_edges;
00119 BGL_FORALL_EDGES(e, G, diGraph) {
00120 diGraphTraits::in_edge_iterator ie_it, ie_it_end;
00121 for(tie(ie_it, ie_it_end) = in_edges(target(e ,G), G);
00122 ie_it != ie_it_end && *ie_it != e; ie_it++) {
00123 if (source(*ie_it,G) == source(e, G)) {
00124 parallel_edges.insert(e);
00125 parallel_edges.insert(*ie_it);
00126 }
00127 }
00128 }
00129 diedge_descriptor e;
00130 BOOST_FOREACH(e, parallel_edges)
00131 remove_edge(e,G);
00132
00133
00134 std::list<diedge_descriptor> back_edges;
00135 dfs_back_visitor vis(&back_edges);
00136 depth_first_search(G, visitor(vis));
00137 BOOST_FOREACH(e, back_edges)
00138 remove_edge(e, G);
00139
00140
00141
00142
00143 BGL_FORALL_VERTICES(v, G, diGraph)
00144 add_vertex(uG);
00145 BGL_FORALL_EDGES(e, G, diGraph)
00146 add_edge(source(e, G), target(e, G), uG);
00147
00148 vertex_descriptor v;
00149 int i = 1;
00150 BOOST_FOREACH(v, an) {
00151 node_mapG[v] = i++;
00152 }
00153 return true;
00154 }
00155
00156
00157 class stableset_heuristic : public primal_heuristic {
00158 private:
00159 Graph& G;
00160 var_map<vertex_descriptor>& VM;
00161 map<vertex_descriptor, double> nc;
00162
00163 template <typename T>
00164 struct greater_second : std::binary_function<T, T, bool> {
00165 inline bool operator() (const T& lhs, const T& rhs) {
00166 return (lhs.second > rhs.second);
00167 }
00168 };
00169
00170 public:
00171 stableset_heuristic(Graph& G_, var_map<vertex_descriptor>& VM_,
00172 map<vertex_descriptor, double> nc_) : G(G_), VM(VM_), nc(nc_) { }
00173
00174 int heuristic(subproblem& S, solution& newSol) {
00175 cerr << "primal heuristic" << endl;
00176 newSol.save_solution(S);
00177 map<vertex_descriptor, bool> seen;
00178 BGL_FORALL_VERTICES(v, G, Graph)
00179 seen[v] = false;
00180 typedef std::pair<vertex_descriptor, double> entry_t;
00181 typedef std::priority_queue<entry_t, std::deque<entry_t>,
00182 greater_second<entry_t> > queue_t;
00183 queue_t prio;
00184 BGL_FORALL_VERTICES(v, G, Graph) {
00185 newSol.round_to_integer(VM[v]);
00186 prio.push(entry_t(v, out_degree(v, G)));
00187 }
00188
00189 bool stop = false;
00190 while (!prio.empty()) {
00191 stop = false;
00192 if( newSol.value(VM[(prio.top()).first]) < .5 ) {
00193 GraphTraits::adjacency_iterator it, it_end;
00194 for(tie(it,it_end) = adjacent_vertices((prio.top()).first,G);
00195 it != it_end; it++) {
00196 if( newSol.value(VM[*it]) > .5 ) {
00197 stop = true;
00198 break;
00199 }
00200 }
00201 if( !stop )
00202 newSol.set_value(VM[(prio.top()).first], 1.);
00203 }
00204 prio.pop();
00205 }
00206 return 1;
00207 }
00208 };
00209
00210
00211 int main(int argc, char** argv)
00212 {
00213 if( argc != 2 ) {
00214 cerr << "Please give the name of an input file!" << endl;
00215 return 1;
00216 }
00217
00218
00219 Graph G;
00220 map<vertex_descriptor, int> node_mapG;
00221 map<edge_descriptor, double> edge_mapG;
00222
00223 map<vertex_descriptor, double> nc;
00224 if( !readgraphComplement(argv[1], G, nc, node_mapG) )
00225 return 1;
00226
00227
00228 ILP_Problem IP(Optsense_Max);
00229 vertex_descriptor v;
00230 var_map<vertex_descriptor> VM;
00231 BGL_FORALL_VERTICES(v, G, Graph)
00232 VM[v]=IP.add_binary_variable(nc[v]);
00233
00234
00235 IP.add_sym_constraint(new STABLESET<Graph>(G, VM));
00236
00237
00238
00239
00240
00241
00242 IP.optimize();
00243
00244
00245 solution sol = IP.get_solution();
00246 double sum = 0.;
00247 cout << "\nName: " << argv[1] << endl;
00248 BGL_FORALL_VERTICES(v, G, Graph) {
00249 sum += sol.value(VM[v]) * nc[v];
00250 if( sol.value(VM[v]) > .9 ) cout << node_mapG[v] << " ";
00251 }
00252 cout << endl;
00253 cout.precision(2);
00254 cout << fixed << "solution value: " << sum << endl;
00255
00256 return 0;
00257 }