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
00033
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;
00126 file >> numedges;
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
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
00174 Graph G;
00175 map<vertex_descriptor, int> node_mapG;
00176 map<edge_descriptor, double> edge_mapG;
00177 map<vertex_descriptor, int> nc;
00178
00179 if( !readgraphFromTSPLIB(writeout, base, argv[filearg], G, nc, node_mapG,
00180 edge_mapG) )
00181 return 1;
00182
00183
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
00196 IP.add_sym_constraint(new MATCHING<Graph>(G, nc, VM));
00197
00198
00199 IP.optimize();
00200
00201
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