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

maxcut.cc

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 //#define INPATH "/home/baumann/projects/scil/tests/"
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    //skip leading comments, i.e. ignore the line if the
00108    //first character is not a number
00109    char buf[1024];
00110    while( file.peek() != '#' ) //search for '#' indicating the size of the graph
00111       file.getline(buf, 1024);
00112 
00113    //read the size of the graph and the edge data
00114    char c;
00115    int s, t, numnodes, numedges;
00116    double u;
00117    file >> c;
00118    file >> numnodes; //read the number of nodes in the graph
00119    file >> numedges; //read the number of edges in the graph
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    //initialize the graph
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    //initialize the ILP
00155    ILP_Problem IP(Optsense_Max);
00156    edge_descriptor e;
00157    //FIXME
00158    //var_map<edge> VM;
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    //add the symbolic constraint
00164    CUT<Graph>* scc = new CUT<Graph>(G, VM);
00165    IP.add_sym_constraint(scc);
00166 
00167    //IP.set_primal_heuristic(new mc_heuristic(G, VM));
00168    //solve the problem
00169    IP.optimize();
00170 
00171    //output the solution
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 
Generated on Mon Mar 28 22:03:49 2011 for SCIL by  doxygen 1.6.3