00001 #include<fstream>
00002 #include<scil/scil.h>
00003 #include<scil/constraints/tour.h>
00004 #include<scil/core/monomial.h>
00005 #include<boost/graph/adjacency_list.hpp>
00006 #include<boost/graph/iteration_macros.hpp>
00007
00008 using namespace std;
00009 using namespace SCIL;
00010
00011 typedef boost::adjacency_list<vecS, vecS, undirectedS> Graph;
00012 typedef boost::graph_traits<Graph> GraphTraits;
00013 typedef GraphTraits::vertex_descriptor vertex_descriptor;
00014 typedef GraphTraits::edge_descriptor edge_descriptor;
00015
00016 void read_instance(char* file_name, Graph& G, std::vector<edge_descriptor>& VE, var_map<edge_descriptor>& VM, std::vector<monomial>& lm, ILP_Problem& IP) {
00017
00018 ifstream file;
00019 file.open(file_name);
00020
00021 int n;
00022 file >> n;
00023
00024 vertex_descriptor v, w;
00025
00026 int m = (n*(n-1))/2;
00027
00028 std::pair<double,double> coord;
00029 std::vector<pair<double,double> > coordVector;
00030 for( int i = 0; i < n; i++ ) {
00031 add_vertex(G);
00032 file >> coord.first;
00033 file >> coord.second;
00034 coordVector.push_back(coord);
00035 }
00036
00037 BGL_FORALL_VERTICES(v, G, Graph){
00038 BGL_FORALL_VERTICES(w, G, Graph){
00039 if(v!=w){
00040 if(!edge(v,w,G).second)
00041 add_edge(v,w,G);
00042 }
00043 }
00044 }
00045
00046 edge_descriptor e;
00047 std::vector<var> VI;
00048 BGL_FORALL_EDGES(e, G, Graph) {
00049 VM[e] = IP.add_binary_variable(0.);
00050 VI.push_back(VM[e]);
00051 VE.push_back(e);
00052 }
00053
00054
00055 std::pair<double, double> v1,v2,vt,vector1,vector2;
00056 monomial mon;
00057 for( int i = 0; i < m; i++ ) {
00058 for( int j = 0; j < m; j++ ) {
00059 if( i != j ) {
00060 if( source(VE[i], G) == source(VE[j], G)) {
00061 vt = coordVector[source(VE[i], G)];
00062 v1 = coordVector[target(VE[i], G)];
00063 v2 = coordVector[target(VE[j], G)];
00064 vector1 = make_pair(v1.first - vt.first, v1.second - vt.second);
00065 vector2 = make_pair(vt.first - v2.first, vt.second - v2.second);
00066 } else if( source(VE[i], G) == target(VE[j], G) ) {
00067 vt = coordVector[source(VE[i], G)];
00068 v1 = coordVector[target(VE[i], G)];
00069 v2 = coordVector[source(VE[j], G)];
00070 vector1 = make_pair(v1.first - vt.first, v1.second - vt.second);
00071 vector2 = make_pair(vt.first - v2.first, vt.second - v2.second);
00072 } else if( target(VE[i], G) == source(VE[j], G) ) {
00073 vt = coordVector[source(VE[j], G)];
00074 v1 = coordVector[target(VE[j], G)];
00075 v2 = coordVector[source(VE[i], G)];
00076 vector1 = make_pair(v1.first - vt.first, v1.second - vt.second);
00077 vector2 = make_pair(vt.first - v2.first, vt.second - v2.second);
00078 } else if( target(VE[i], G) == target(VE[j], G) ) {
00079 vt = coordVector[target(VE[i], G)];
00080 v1 = coordVector[source(VE[i], G)];
00081 v2 = coordVector[source(VE[j], G)];
00082 vector1 = make_pair(v1.first - vt.first, v1.second - vt.second);
00083 vector2 = make_pair(vt.first - v2.first, vt.second - v2.second);
00084 } else
00085 continue;
00086
00087 double angle = acos(((vector1.first * vector2.first) + (vector1.second * vector2.second))/(sqrt((vector1.first * vector1.first) + (vector1.second * vector1.second)) * (sqrt((vector2.first * vector2.first) + (vector2.second * vector2.second)))));
00088
00089
00090 mon = monomial(angle, VI[i], VI[j]);
00091 std::vector<monomial>::iterator pos;
00092 if( lm.size()==0 ){
00093 lm.push_back(mon);
00094 IP.add_polynomial(mon);
00095 }
00096 else {
00097 pos = lower_bound(lm.begin(), lm.end(), mon);
00098 if( pos == lm.end() || !(*pos == mon)){
00099 lm.insert(pos, mon);
00100 IP.add_polynomial(mon);
00101 }
00102 }
00103 }
00104 }
00105 }
00106 cerr << "end read" << endl;
00107 }
00108
00109 int main(int argc, char** argv){
00110
00111 Graph G;
00112 std::vector<edge_descriptor> VE;
00113 var_map<edge_descriptor> VM;
00114 std::vector<monomial> lm;
00115 ILP_Problem IP(Optsense_Min);
00116
00117
00118 read_instance(argv[1], G, VE, VM, lm, IP);
00119
00120
00121 IP.add_sym_constraint(new TOUR<Graph>(G, VM));
00122
00123
00124 IP.optimize();
00125
00126
00127 edge_descriptor e;
00128 std::vector<edge_descriptor> v;
00129 solution s = IP.get_solution();
00130 BGL_FORALL_EDGES(e, G, Graph)
00131 if(s.value(VM[e]) > 0.9)
00132 v.push_back(e);
00133 std::vector<edge_descriptor>::iterator it = v.begin();
00134 int pos,start;
00135 start = source(*it, G);
00136 pos=target(*it, G);
00137 cout<<start<<endl;
00138 while(pos!=start) {
00139 it++;
00140 if(it==v.end())
00141 it=v.begin();
00142 if(source(*it, G) == pos) {
00143 cout<<pos<<endl;
00144 pos=target(*it, G);
00145 }else if(target(*it, G) == pos) {
00146 cout<<pos<<endl;
00147 pos=source(*it, G);
00148 }
00149 }
00150 return 0;
00151 };
00152
00153