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

tsp.cc

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 //works on complete graphs!
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    //calculate costs
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   //examine the solution
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 
Generated on Mon Mar 28 22:03:51 2011 for SCIL by  doxygen 1.6.3