00001 #include <boost/foreach.hpp>
00002 #include <boost/graph/adjacency_list.hpp>
00003 #include <boost/graph/iteration_macros.hpp>
00004 #include <boost/graph/kruskal_min_spanning_tree.hpp>
00005 #include <boost/property_map/property_map.hpp>
00006 #include <fstream>
00007 #include <iostream>
00008 #include <scil/scil.h>
00009 #include <scil/constraints/cut.h>
00010 #include <string>
00011
00012
00013 #define INPATH ""
00014
00015 using std::cout;
00016 using std::cerr;
00017 using std::endl;
00018 using std::ifstream;
00019 using std::atoi;
00020
00021 using namespace boost;
00022 using namespace SCIL;
00023 using namespace std;
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 class mc_heuristic : public primal_heuristic {
00031 private:
00032 Graph& G;
00033 var_map<edge_descriptor>& VM;
00034 int start;
00035
00036 public:
00037 mc_heuristic(Graph& G_, var_map<edge_descriptor>& VM_)
00038 : G(G_), VM(VM_), start(1) { }
00039 int heuristic(subproblem& S, solution& newSol) {
00040 if( start > 0 ) {
00041 start--;
00042 return 0;
00043 }
00044
00045 typedef map<edge_descriptor, double> weight_map_t;
00046 typedef map<vertex_descriptor, size_t> vertex_index_t;
00047
00048 weight_map_t tc;
00049 edge_descriptor e;
00050 BGL_FORALL_EDGES(e, G, Graph)
00051 tc[e] = fabs(S.value(VM[e]) - .5);
00052 vertex_index_t vertex_index_map;
00053 int i = 0;
00054 vertex_descriptor v;
00055 BGL_FORALL_VERTICES(v, G, Graph)
00056 vertex_index_map[v] = i++;
00057
00058 associative_property_map<weight_map_t> pm_weight(tc);
00059 typedef associative_property_map<vertex_index_t> pm_vertex_index_t;
00060 pm_vertex_index_t pm_vertex_index(vertex_index_map);
00061
00062 list<edge_descriptor> tree;
00063
00064 kruskal_minimum_spanning_tree(G, back_inserter(tree), boost::weight_map
00065 (pm_weight).vertex_index_map(pm_vertex_index));
00066
00067 BGL_FORALL_EDGES(e, G, Graph)
00068 tc[e] = -1.;
00069
00070 BOOST_FOREACH(e, tree)
00071 tc[e] = S.value(VM[e]) > .5 ? 1. : 0.;
00072
00073 map<vertex_descriptor, bool> color;
00074 v = *(vertices(G).first);
00075 if(!SCIL::color_graph<Graph, vertex_descriptor, edge_descriptor>
00076 (G, v, tc, color)) {
00077 return 0;
00078 }
00079
00080 BGL_FORALL_EDGES(e, G, Graph)
00081 if( color[source(e, G)] != color[target(e, G)] )
00082 newSol.set_value(VM[e], 1.);
00083 else
00084 newSol.set_value(VM[e], 0.);
00085 return 1;
00086 }
00087
00088 };
00089
00090 bool readgraph(int base, const char* infile, Graph& G,
00091 map<vertex_descriptor, int>& vertex_index,
00092 map<edge_descriptor, double>& edge_property) {
00093 string path(INPATH);
00094 path += infile;
00095 ifstream file(path.c_str());
00096 if( file.fail() ) {
00097 cerr << "%%%%%%%% Could not open file " << infile << endl;
00098 cerr << "%%%%%%%% tried " << path << endl;
00099 exit(1);
00100 }
00101 double sign = 1.;
00102 if( base == -1 ) {
00103 base = 1;
00104 sign = -1.;
00105 }
00106
00107
00108
00109 char buf[1024];
00110 while( file.peek() != '#' )
00111 file.getline(buf, 1024);
00112
00113
00114 char c;
00115 int s, t, numnodes, numedges;
00116 double u;
00117 file >> c;
00118 file >> numnodes;
00119 file >> numedges;
00120
00121 vertex_descriptor* nodelist = new vertex_descriptor[numnodes];
00122
00123 for( int i = 0; i < numnodes; i++) {
00124 nodelist[i] = add_vertex(G);
00125 vertex_index[nodelist[i]]=i;
00126 }
00127
00128 while((file >> s >> t >> u) && file.good()) {
00129 edge_descriptor e;
00130 e = (add_edge(nodelist[s-base], nodelist[t-base], G)).first;
00131 edge_property[e] = sign * u;
00132 }
00133
00134 delete[]nodelist;
00135 return true;
00136 }
00137
00138
00139 int main(int argc, char** argv)
00140 {
00141 if( argc != 3 ) {
00142 cerr << "Please give the base of the node numbering";
00143 cerr << " and the name of an input file!" << endl;
00144 return 1;
00145 }
00146
00147
00148 Graph G;
00149 map<vertex_descriptor, int> vertex_index;
00150 map<edge_descriptor, double> edge_property;
00151 int base = atoi(argv[1]);
00152 readgraph(base, argv[2], G, vertex_index, edge_property);
00153
00154
00155 ILP_Problem IP(Optsense_Max);
00156 edge_descriptor e;
00157
00158
00159 row_map<edge_descriptor> VM;
00160 BGL_FORALL_EDGES(e, G, Graph)
00161 VM[e]=IP.add_binary_variable(edge_property[e]);
00162
00163
00164 CUT<Graph>* scc = new CUT<Graph>(G, VM);
00165 IP.add_sym_constraint(scc);
00166
00167
00168
00169 IP.optimize();
00170
00171
00172 solution sol = IP.get_solution();
00173 double optimum = IP.get_optimum();
00174 cout << "\nName: " << argv[2] << endl;
00175
00176 if(base == -1) optimum *= -1;
00177 cout.precision(2);
00178 cout << fixed << "solution value: " << optimum << endl;
00179
00180 list<vertex_descriptor> configuration = scc->getConfiguration(sol);
00181 vertex_descriptor v;
00182 BOOST_FOREACH(v, configuration)
00183 cout << vertex_index[v] + abs(base) << " ";
00184 cout << endl;
00185
00186 return 0;
00187 }
00188