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

qmst.cc

00001 #include<iostream>
00002 #include<scil/scil.h>
00003 #include<scil/constraints/spantree.h>
00004 #include<scil/core/monomial.h>
00005 #include <boost/foreach.hpp>
00006 #include <boost/graph/adjacency_list.hpp>
00007 #include <boost/graph/graph_traits.hpp>
00008 #include <boost/graph/iteration_macros.hpp>
00009 #include <boost/graph/kruskal_min_spanning_tree.hpp>
00010 
00011 using namespace SCIL;
00012 using namespace std;
00013 using namespace boost;
00014 
00015 typedef adjacency_list<vecS, vecS, undirectedS> Graph;
00016 typedef boost::graph_traits<Graph> GraphTraits;
00017 typedef GraphTraits::vertex_descriptor vertex_descriptor;
00018 typedef GraphTraits::edge_descriptor edge_descriptor;
00019 
00020 class qmst_heuristic : public primal_heuristic {
00021    private:
00022       Graph& G;
00023       var_map<edge_descriptor>& VM;
00024 
00025    public:
00026       qmst_heuristic(Graph& G_, var_map<edge_descriptor>& VM_)
00027          : G(G_), VM(VM_)
00028       { }
00029 
00030       int heuristic(subproblem& S, solution& newSol) {
00031          edge_descriptor e;
00032          map<edge_descriptor, int> tc;
00033          BGL_FORALL_EDGES(e, G, Graph) {
00034             tc[e] = int(10. * (1. - (S.value(VM[e]))));
00035          }
00036 
00037          list<edge_descriptor> tree;
00038 
00039          typedef map<edge_descriptor, int> weight_map_t;
00040          typedef map<vertex_descriptor, size_t> vertex_index_t;   
00041 
00042          vertex_index_t vertex_index_map;
00043          int i = 0;
00044          BGL_FORALL_VERTICES(v, G, Graph)
00045             vertex_index_map[v] = i++;
00046          
00047          associative_property_map<weight_map_t> pm_weight(tc);
00048          associative_property_map<vertex_index_t> pm_vertex_index(vertex_index_map);
00049 
00050          kruskal_minimum_spanning_tree(G, back_inserter(tree), boost::weight_map(pm_weight).vertex_index_map(pm_vertex_index));
00051 
00052          BGL_FORALL_EDGES(e, G, Graph) {
00053             newSol.set_value(VM[e], 0.);
00054          }
00055          BOOST_FOREACH(e, tree) {
00056             newSol.set_value(VM[e], 1.);
00057          }
00058          S.GM.extendSolution(newSol);
00059 
00060          return 1;
00061       }
00062       
00063 };
00064 
00065 void read_inst(const char* file_name, Graph& G, var_map<edge_descriptor>& VM, ILP_Problem& IP) {
00066 
00067    ifstream file;
00068    file.open(file_name);
00069 
00070    int m, n, h1, h2, t1, t2, w;
00071    file >> n >> m;
00072    vector<vertex_descriptor> nm(n+1);
00073    edge_descriptor* em = new edge_descriptor[n*n];
00074 
00075    //initialize node array
00076    for( int i = 1; i <= n; i++ )
00077       nm[i] = add_vertex(G);
00078 
00079    //read edges from file and add a corresponding variable to the IP
00080    for( int i = 0; i < m; i++ ) {
00081       file >> t1 >> h1 >> w;
00082       em[(t1-1)*n+(h1-1)] = add_edge(nm[t1], nm[h1], G).first;
00083       VM[em[(t1-1)*n+(h1-1)]] = IP.add_binary_variable(w);
00084    }
00085 
00086    //read values of the nonlinear part of objective function and add corresponding monomials to the IP
00087    for( int i = 0; i < m*(m-1); i++ ) {
00088       file >> t1 >> h1 >> t2 >> h2 >> w;
00089       IP.add_polynomial(VM[em[(t1-1)*n+(h1-1)]] *  VM[em[(t2-1)*n+(h2-1)]] *  w);
00090    }
00091 
00092    file.close();
00093    return;
00094 }
00095 
00096 int main(int argc, char** argv) 
00097 {
00098    ILP_Problem IP(Optsense_Min);
00099 
00100    Graph G;
00101    var_map<edge_descriptor> VM;
00102    read_inst(argv[1], G, VM, IP);
00103 
00104    
00105    IP.add_sym_constraint(new SpanTree<Graph>(G, VM));
00106    
00107    IP.set_primal_heuristic(new qmst_heuristic(G, VM));
00108 
00109    IP.optimize();
00110 
00111    cout<<"optimal solution: "<<IP.get_optimum()<<endl;
00112 
00113    cout<<"spanning tree: "<<endl;
00114    BGL_FORALL_EDGES(e, G, Graph)
00115       if(IP.get_solution(VM[e]))
00116          cout<<e<<endl;
00117    
00118    return 0;
00119 }
00120 
Generated on Mon Mar 28 22:03:49 2011 for SCIL by  doxygen 1.6.3