00001 #include <boost/graph/adjacency_list.hpp>
00002 #include <boost/graph/iteration_macros.hpp>
00003 #include <boost/property_map/property_map.hpp>
00004 #include <fstream>
00005 #include <iostream>
00006 #include <scil/scil.h>
00007 #include <scil/constraints/tour.h>
00008 #include <string>
00009
00010 using namespace boost;
00011 using namespace SCIL;
00012 using namespace std;
00013
00014 typedef adjacency_list<vecS, vecS, undirectedS> Graph;
00015 typedef boost::graph_traits<Graph> GraphTraits;
00016 typedef GraphTraits::vertex_descriptor vertex_descriptor;
00017 typedef GraphTraits::edge_descriptor edge_descriptor;
00018 typedef GraphTraits::vertex_iterator vertex_iterator;
00019
00020
00021 void readTsplibFile(Graph& G, const char*fileName, map<vertex_descriptor, double>& xp, map<vertex_descriptor, double>& yp)
00022 {
00023
00024
00025 FILE*tspFile= fopen(fileName,"r");
00026
00027 if(tspFile==NULL){
00028 std::cerr<<"TSPLIB file "<<fileName<<" could not be opened."<<std::endl;
00029 exit(1);
00030 }
00031
00032 const int maxCharPerLine= 1024;
00033 char lineBuf[maxCharPerLine+1];
00034 bool dimensionFound= false;
00035 bool typeFound= false;
00036 bool coordSectionFound= false;
00037 int nNodes_;
00038
00039 while(fgets(lineBuf,maxCharPerLine,tspFile)){
00040 if(strncmp(lineBuf,"DIMENSION",strlen("DIMENSION"))==0){
00041 if(sscanf(lineBuf,"DIMENSION : %d",&nNodes_)!=1){
00042 std::cerr<<"Error when reading dimension of problem."<<std::endl;
00043 exit(1);
00044 }
00045 dimensionFound= true;
00046 }
00047 else if(strncmp(lineBuf,"EDGE_WEIGHT_TYPE",strlen("EDGE_WEIGHT_TYPE"))
00048 ==0){
00049 if(strncmp(lineBuf,"EDGE_WEIGHT_TYPE : EUC_2D",
00050 strlen("EDGE_WEIGHT_TYPE : EUC_2D"))&&
00051 strncmp(lineBuf,"EDGE_WEIGHT_TYPE: EUC_2D",
00052 strlen("EDGE_WEIGHT_TYPE: EUC_2D"))){
00053 std::cerr<<"Invalid EDGE_WEIGHT_TYPE, must be EUC_2D."<<std::endl;
00054 exit(1);
00055 }
00056 typeFound= true;
00057 }
00058 else if(strncmp(lineBuf,"NODE_COORD_SECTION",strlen("NODE_COORD_SECTION"))
00059 ==0){
00060 coordSectionFound= true;
00061 break;
00062 }
00063 }
00064
00065 if(!typeFound){
00066 std::cerr<<"Keyword EDGE_WEIGHT_TYPE not found in file "<<fileName<<".";
00067 std::cerr<<std::endl;
00068 exit(1);
00069 }
00070
00071 if(!dimensionFound){
00072 std::cerr<<"Keyword DIMENSION not found in file "<<fileName<<".";
00073 std::cerr<<std::endl;
00074 exit(1);
00075 }
00076
00077 if(!coordSectionFound){
00078 std::cerr<<"Keyword NODE_COORD_SECTION not found in file "<<fileName;
00079 std::cerr<<"."<<std::endl;
00080 exit(1);
00081 }
00082
00083 vertex_descriptor v;
00084 for(int i = 0; i < nNodes_; i++){
00085 v=add_vertex(G);
00086 xp[v]=0;
00087 yp[v]=0;
00088 }
00089
00090 int nodeNumber;
00091 float x,y;
00092
00093 BGL_FORALL_VERTICES(v, G, Graph) {
00094 if(fscanf(tspFile,"%d %f %f",&nodeNumber,&x,&y)!=3){
00095 std::cerr<<"Error while reading coordinates of node "<<nodeNumber<<"."<<std::endl;
00096 exit(1);
00097 } else
00098 xp[v]=x;
00099 yp[v]=y;
00100 }
00101
00102 if(fclose(tspFile)){
00103 std::cerr<<"error in closing file "<<fileName<<"."<<std::endl;
00104 exit(1);
00105 }
00106
00107 return;
00108 }
00109
00110
00111
00112 int main(int argc, char ** argv) {
00113 Graph G;
00114 map<vertex_descriptor, double> xp,yp;
00115 readTsplibFile(G, argv[1], xp, yp);
00116
00117
00118 map<edge_descriptor, double> costs;
00119 vertex_iterator it1,it2;
00120 for(it1 = vertices(G).first; it1 != vertices(G).second; it1++){
00121 it2 = it1;
00122 it2++;
00123 for(;it2 != vertices(G).second; it2++){
00124 costs[add_edge(*it1, *it2, G).first] = sqrt((xp[*it1]-xp[*it2])*(xp[*it1]-xp[*it2])+(yp[*it1]-yp[*it2])*(yp[*it1]-yp[*it2]));
00125 }
00126 }
00127
00128 ILP_Problem IP(Optsense_Min);
00129
00130 var_map<edge_descriptor> VM;
00131 BGL_FORALL_EDGES(e,G, Graph) {
00132 VM[e]=IP.add_binary_variable(costs[e]);
00133 }
00134 IP.add_sym_constraint(new TOUR<Graph>(G,VM));
00135 IP.optimize();
00136
00137
00138
00139 cout<<"Optimal Solution Value: "<<IP.get_optimum()<<endl;
00140 cout<<"Tour: "<<endl;
00141 std::vector<edge_descriptor> v;
00142 solution s = IP.get_solution();
00143 BGL_FORALL_EDGES(e, G, Graph)
00144 if(s.value(VM[e]) > 0.9)
00145 v.push_back(e);
00146 std::vector<edge_descriptor>::iterator it = v.begin();
00147 unsigned int pos,start;
00148 start = source(*it, G);
00149 pos=target(*it, G);
00150 cout<<start<<endl;
00151 while(pos!=start) {
00152 it++;
00153 if(it==v.end())
00154 it=v.begin();
00155 if(source(*it, G) == pos) {
00156 cout<<pos<<endl;
00157 pos=target(*it, G);
00158 }else if(target(*it, G) == pos) {
00159 cout<<pos<<endl;
00160 pos=source(*it, G);
00161 }
00162 }
00163 }
00164