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

perfectBmatching.cc

00001 #include <boost/graph/adjacency_list.hpp>
00002 #include <boost/graph/graph_traits.hpp>
00003 #include <boost/graph/iteration_macros.hpp>
00004 #include <scil/constraints/matching.h>
00005 #include <scil/scil.h>
00006 
00007 #include<iostream>
00008 #include<fstream>
00009 #include<string>
00010 
00011 #define INPATH ""
00012 
00013 using std::cout;
00014 using std::cerr;
00015 using std::endl;
00016 using std::ifstream;
00017 using std::atoi;
00018 
00019 using namespace boost;
00020 using namespace SCIL;
00021 using namespace std;
00022 
00023 typedef adjacency_list<vecS, vecS, undirectedS> Graph;
00024 typedef boost::graph_traits<Graph> GraphTraits;
00025 typedef GraphTraits::vertex_descriptor vertex_descriptor;
00026 typedef GraphTraits::edge_descriptor edge_descriptor;
00027 
00028 struct coord {
00029    double x, y;
00030 };
00031 
00032 //this function reads a graph in TSPLIB format with euclidian edge weights
00033 //if writeout is true the graph is output in edge format
00034 bool readgraphFromTSPLIB(bool writeout, int base, const char* infile, Graph& G, 
00035                          map<vertex_descriptor, int>& nc,
00036                          map<vertex_descriptor, int>& node_mapG,
00037                          map<edge_descriptor, double>& edge_mapG) {
00038    string path(INPATH);
00039    path += infile;
00040    ifstream file(path.c_str());
00041    if( file.fail() ) {
00042       cerr << "%%%%%%%% Could not open file " << infile << endl;
00043       cerr << "%%%%%%%% tried " << path << endl;
00044       exit(1);
00045    }
00046    double sign = 1.;
00047    if( base == -1 ) {
00048       base = 1;
00049       sign = -1.;
00050    }
00051 
00052    int count = 0;
00053    std::string in;
00054    do {
00055       getline(file, in);
00056    } while( (in.compare(0, 8, "DIMENSION", 0, 8) != 0) && (count++ < 100) ) ;
00057    int pos = in.find_last_of(' ');
00058    int numnodes = atoi(in.substr(pos+1, in.length()-pos-1).c_str());
00059 
00060    do {
00061       getline(file, in);
00062    } while( (in.compare(0, 9, "NODE_COORD_SECTION", 0, 9) != 0) && (count++ < 100) ) ;
00063 
00064    vertex_descriptor* nodelist = new vertex_descriptor[numnodes];
00065 
00066    for( int i = 0; i < numnodes; i++) {
00067       nodelist[i] = add_vertex(G);
00068       node_mapG[nodelist[i]] = i;
00069    }
00070 
00071    map<vertex_descriptor, coord> coords;
00072 
00073    BGL_FORALL_VERTICES(v, G, Graph)
00074       nc[v] = 0;
00075    int s;
00076    for( int i = 0; i < numnodes; i++) {
00077       file >> s >> coords[nodelist[i]].x >> coords[nodelist[i]].y;
00078       nc[nodelist[i]] = 1;
00079    }
00080 
00081    double xd, yd;
00082    int dist;
00083    for( int i = 0; i < numnodes; i++ ) {
00084       for( int j = i + 1; j < numnodes; j++ ) {
00085          xd = coords[nodelist[i]].x - coords[nodelist[j]].x;
00086          yd = coords[nodelist[i]].y - coords[nodelist[j]].y;
00087          dist = int(sqrt(xd * xd + yd * yd) + .5);
00088          edge_mapG[(add_edge(nodelist[i], nodelist[j], G)).first] = dist;
00089       }
00090    }
00091 
00092    if(writeout) {
00093       cout << num_vertices(G) << " " << num_edges(G) << endl;
00094       BGL_FORALL_EDGES(e, G, Graph) {
00095          cout << node_mapG[source(e, G)] << " " << node_mapG[target(e, G)];
00096          cout << " " << edge_mapG[e] << endl;
00097       }
00098       return false;
00099    }
00100 
00101    delete[]nodelist;
00102    return true;
00103 }
00104 
00105 bool readgraph(int base, const char* infile, Graph& G, 
00106                map<vertex_descriptor, int>& nc,
00107                map<vertex_descriptor, int>& node_mapG,
00108                map<edge_descriptor, double>& edge_mapG) {
00109    string path(INPATH);
00110    path += infile;
00111    ifstream file(path.c_str());
00112    if( file.fail() ) {
00113       cerr << "%%%%%%%% Could not open file " << infile << endl;
00114       cerr << "%%%%%%%% tried " << path << endl;
00115       exit(1);
00116    }
00117    double sign = 1.;
00118    if( base == -1 ) {
00119       base = 1;
00120       sign = -1.;
00121    }
00122 
00123    int s, t, numnodes, numedges;
00124    double u;
00125    file >> numnodes; //read the number of nodes in the graph
00126    file >> numedges; //read the number of edges in the graph
00127 
00128    vertex_descriptor* nodelist = new vertex_descriptor[numnodes];
00129 
00130    for( int i = 0; i < numnodes; i++) {
00131       nodelist[i] = add_vertex(G);
00132       node_mapG[nodelist[i]] = i;
00133    }
00134 
00135    BGL_FORALL_VERTICES(v, G, Graph)
00136       nc[v] = 0;
00137    for( int i = 0; i < numnodes; i++) {
00138       //file >> s;
00139       nc[nodelist[i]] = 1;
00140    }
00141 
00142    while((file >> s >> t >> u) && file.good()) {
00143       edge_mapG[(add_edge(nodelist[s-base],nodelist[t-base],G)).first]=sign*u;
00144    }
00145 
00146    delete[]nodelist;
00147    return true;
00148 }
00149 
00150 
00151 int main(int argc, char** argv)
00152 {
00153    if( argc < 2 ) {
00154       cerr << "Please give the name of an input file!" << endl;
00155       return 1;
00156    }
00157    cerr << "Start Matching-Example";
00158 
00159    int base = 1;
00160    int filearg = 1;
00161    bool writeout = false;
00162 
00163    if( (argc == 3) ) {
00164       cerr << argv[1] << endl;
00165       if( argv[1][0] == 'p' ) {
00166       writeout = true;
00167       filearg = 2;
00168    }
00169    else 
00170       return 1;
00171    }
00172 
00173    //initialize the graph
00174    Graph G;
00175    map<vertex_descriptor, int> node_mapG;
00176    map<edge_descriptor, double> edge_mapG;
00177    map<vertex_descriptor, int> nc;
00178    //if( !readgraph(base, argv[1], G, nc) )
00179    if( !readgraphFromTSPLIB(writeout, base, argv[filearg], G, nc, node_mapG,
00180                             edge_mapG) )
00181       return 1;
00182 
00183    //initialize the ILP
00184    ILP_Problem IP(Optsense_Min);
00185    edge_descriptor e;
00186    var_map<edge_descriptor> VM;
00187    list<var> vl;
00188    var va;
00189 
00190    BGL_FORALL_EDGES(e, G, Graph) {
00191       vl.push_back(IP.add_binary_variable(edge_mapG[e]));
00192       VM[e] = vl.back();
00193    }
00194 
00195    //add the symbolic constraint
00196    IP.add_sym_constraint(new MATCHING<Graph>(G, nc, VM));
00197 
00198    //solve the problem
00199    IP.optimize();
00200 
00201    //output the solution
00202    solution sol =  IP.get_solution();
00203    double sum = 0.;
00204    cout << "\nName: " << argv[1] << endl;
00205    BGL_FORALL_EDGES(e, G, Graph) {
00206       sum += double(edge_mapG[e]) * sol.value(VM[e]);
00207       if( sol.value(VM[e]) > .9 ) {
00208          cout << node_mapG[source(e, G)] + base << " -- ";
00209          cout << node_mapG[target(e, G)] + base << endl;
00210       }
00211    }
00212    cout << endl;
00213    cout.precision(2);
00214    cout << fixed << "solution value: " << sum << endl;
00215 
00216    return 0;
00217 }
00218 
Generated on Mon Mar 28 22:03:49 2011 for SCIL by  doxygen 1.6.3