QUBO++ Library with QUBO Solver APIs
Author: Koji Nakano, License: Non-commercial research and evaluation purposes without any guarantees.
tsp_grb.cpp
Go to the documentation of this file.
1 
7 #include <boost/program_options.hpp>
8 
9 #include "qbpp.hpp"
10 #include "qbpp_grb.hpp"
11 #include "qbpp_misc.hpp"
12 #include "qbpp_tsp.hpp"
13 
14 namespace po = boost::program_options;
15 
20  std::optional<qbpp::energy_t> target_energy;
21 
22  public:
31 
36  void callback() override {
37  if (where == GRB_CB_MIPSOL) {
38  auto sol = get_sol();
39  qbpp::tsp::TSPSol tsp_sol(tsp_quad_model, sol);
40  std::cout << "TTS = " << std::fixed << std::setprecision(3)
41  << std::setfill('0') << qbpp::get_time() << "s ";
42  tsp_sol.print();
43  if (target_energy.has_value() && sol.get_energy() <= target_energy) {
44  abort();
45  }
46  }
47  }
48 };
49 
56 int main(int argc, char **argv) {
57  // clang-format off
58  po::options_description desc(
59  "Solving the randomly generated TSP using QUBO++ Easy Solver");
60  desc.add_options()("help,h", "produce help message")
61  ("nodes,n", po::value<uint32_t>()->default_value(10),"set the number of nodes in the TSP map")
62  ("time,t", po::value<uint32_t>()->default_value(10), "set time limit in seconds")
63  ("tsp_seed,s", po::value<uint32_t>(), "set the random seed for the TSP map")
64  ("output,o", po::value<std::string>(), "set the output file (png, svg, etc) to save the TSP solution")
65  ("fix,f", "fix node 0 as the starting node");
66  // clang-format on
67 
68  po::variables_map vm;
69  try {
70  po::store(po::parse_command_line(argc, argv, desc), vm);
71  } catch (const std::exception &e) {
72  std::cout << "Wrong arguments. Please use -h/--help option to see the "
73  "usage.\n";
74  return 1;
75  }
76  po::notify(vm);
77 
78  if (vm.count("help")) {
79  std::cout << desc << std::endl;
80  return 0;
81  }
82 
84  uint32_t nodes = vm["nodes"].as<uint32_t>();
86  uint32_t time_limit = vm["time"].as<uint32_t>();
88  bool fix_first = vm.count("fix");
89 
90  // Set the random seed for deterministic behavior if seed is provided.
91  if (vm.count("tsp_seed")) {
92  qbpp::misc::RandomGenerator::set_seed(vm["tsp_seed"].as<uint32_t>());
93  } else {
95  }
96 
97  std::cout << "Generating random TSP Map with " << nodes << " nodes"
98  << std::endl;
99  qbpp::tsp::TSPMap tsp_map;
100  tsp_map.gen_random_map(nodes);
101 
102  std::cout << "Generating a TSP QUBO model" << std::endl;
103  qbpp::tsp::TSPQuadModel tsp_quad_model(tsp_map, fix_first);
104 
105  std::cout << "Variables = " << tsp_quad_model.var_count()
106  << " Linear Terms = " << tsp_quad_model.term_count(1)
107  << " Quadratic Terms = " << tsp_quad_model.term_count(2)
108  << std::endl;
109 
110  qbpp_grb::QuadModel grb_model(tsp_quad_model);
111  grb_model.set_time_limit(time_limit);
112  GRB_Callback grb_callback(tsp_quad_model, 0);
113  grb_model.set(grb_callback);
114 
115  std::cout << "Solving the TSP" << std::endl;
116  auto sol = grb_model.optimize();
117 
118  qbpp::tsp::TSPSol tsp_sol(tsp_quad_model, sol);
119  tsp_sol.print();
120 
121  if (vm.count("output")) {
123  for (uint32_t i = 0; i < nodes; ++i) graph.add_node(tsp_map[i]);
124 
125  for (uint32_t i = 0; i < nodes; ++i)
126  graph.add_edge(tsp_sol[i], tsp_sol[(i + 1) % nodes]);
127 
128  graph.draw(vm["output"].as<std::string>());
129  }
130 }
Class to define Gurobi callback function for factorization.
Definition: tsp_grb.cpp:18
std::optional< qbpp::energy_t > target_energy
Definition: tsp_grb.cpp:20
const qbpp::tsp::TSPQuadModel & tsp_quad_model
Definition: tsp_grb.cpp:19
GRB_Callback(const qbpp::tsp::TSPQuadModel &tsp_quad_model, qbpp::energy_t target_energy)
Construct a new grb callback object.
Definition: tsp_grb.cpp:26
void callback() override
callback function for Gurobi optimizer.
Definition: tsp_grb.cpp:36
vindex_t var_count() const
Definition: qbpp.hpp:1154
size_t term_count(vindex_t deg) const
Definition: qbpp.hpp:1258
static void set_seed(uint32_t seed=1)
Definition: qbpp_misc.hpp:41
Class to draw a simple undirected graph.
Definition: qbpp_tsp.hpp:206
void add_edge(unsigned int node1, unsigned int node2)
Add an edge to the graph.
Definition: qbpp_tsp.hpp:235
void draw(std::string filename)
Draw the graph in a file.
Definition: qbpp_tsp.hpp:248
void add_node(int x, int y, const std::string &label="")
Add a node to the graph.
Definition: qbpp_tsp.hpp:221
Class to generates a random map for the TSP with n nodes.
Definition: qbpp_tsp.hpp:30
void gen_random_map(uint32_t n)
Generate a random map with n nodes.
Definition: qbpp_tsp.hpp:284
Class to store the QUBO expression for the Traveling Salesman Problem (TSP).
Definition: qbpp_tsp.hpp:103
Class to store a Tour of the TSP.
Definition: qbpp_tsp.hpp:143
void print() const
Print the tour.
Definition: qbpp_tsp.hpp:177
Class to manage a callback function called by Gurobi Optimizer.
Definition: qbpp_grb.hpp:149
Sol get_sol()
Get the solution obtained by Gurobi Optimizer.
Definition: qbpp_grb.hpp:274
Callback(const QuadModel &quad_model)
Constructor: a new Callback object.
Definition: qbpp_grb.hpp:169
Class to store a QUBO model using Gurobi Optimizer through QUBO++ library.
Definition: qbpp_grb.hpp:42
Sol optimize()
Optimize the QUBO model.
Definition: qbpp_grb.hpp:260
void set_time_limit(uint32_t time_limit)
Sets time limit to the Gurobi model.
Definition: qbpp_grb.hpp:76
void set(const std::string &key, const std::string &val)
Sets a parameter to the Gurobi environment.
Definition: qbpp_grb.hpp:70
Namespace to use Gurobi optimizer from QUBO++ library.
Definition: qbpp_grb.hpp:25
double get_time()
Definition: qbpp.hpp:3815
ENERGY_TYPE energy_t
Definition: qbpp.hpp:130
QUBO++, a C++ library for generating expressions for binary and spin variables.
QUBO++ interface to call Gurobi Optimizer.
A miscellaneous library used for sample programs of the QUBO++ library.
Generates a QUBO Expression for the Traveling Salesman Problem (TSP) using QUBO++ library.
int main(int argc, char **argv)
Main function to generate a random map and solve the Traveling Salesman Problem (TSP) using the Gurob...
Definition: tsp_grb.cpp:56