QUBO++ Library with QUBO Solver APIs
Author: Koji Nakano, License: Non-commercial research and evaluation purposes without any guarantees.
tsp_easy.cpp
Go to the documentation of this file.
1 
7 #include <boost/program_options.hpp>
8 
9 #include "qbpp.hpp"
10 #include "qbpp_easy_solver.hpp"
11 #include "qbpp_misc.hpp"
12 #include "qbpp_tsp.hpp"
13 
14 namespace po = boost::program_options;
15 
18 
19  public:
21  : qbpp::easy_solver::EasySolver(tsp_quad_model),
23 
24  void callback(const qbpp::Sol &sol, double tts) const override {
25  static std::optional<qbpp::energy_t> prev_energy = std::nullopt;
26  std::lock_guard<std::mutex> lock(callback_mutex_);
27  if (!prev_energy.has_value() || sol.get_energy() < prev_energy.value()) {
28  qbpp::tsp::TSPSol tsp_sol(tsp_quad_model, sol);
29  std::cout << "TTS = " << std::fixed << std::setprecision(3)
30  << std::setfill('0') << tts << "s ";
31  tsp_sol.print();
32  prev_energy = sol.get_energy();
33  }
34  }
35 };
36 
43 int main(int argc, char **argv) {
44  po::options_description desc(
45  "Solve a randomly generated Traveling Salesman Problem (TSP) using the "
46  "QUBO++ Easy Solver.");
47  // clang-format off
48  desc.add_options()
49  ("help,h", "Display this help message.")
50  ("nodes,n", po::value<uint32_t>()->default_value(10), "Specify the number of nodes in the TSP map.")
51  ("time,t", po::value<uint32_t>()->default_value(10), "Set the time limit in seconds.")
52  ("seed,s", po::value<uint32_t>(), "Set the random seed to reproduce the TSP map.")
53  ("output,o", po::value<std::string>(), "Specify the output file (e.g., png, svg) to save the TSP solution.")
54  ("fix,f", "Fix node 0 as the starting node.");
55  // clang-format on
56 
57  po::variables_map vm;
58  try {
59  po::store(po::parse_command_line(argc, argv, desc), vm);
60  } catch (const std::exception &e) {
61  std::cout << "Wrong arguments. Please use -h/--help option to see the "
62  "usage.\n";
63  return 1;
64  }
65  po::notify(vm);
66 
67  if (vm.count("help")) {
68  std::cout << desc << std::endl;
69  return 0;
70  }
71 
73  uint32_t nodes = vm["nodes"].as<uint32_t>();
75  uint32_t time_limit = vm["time"].as<uint32_t>();
77  bool fix_first = vm.count("fix");
78 
79  // Set the random seed for deterministic behavior if seed is provided.
80  if (vm.count("seed")) {
81  qbpp::misc::RandomGenerator::set_seed(vm["seed"].as<uint32_t>());
82  } else {
84  }
85 
86  std::cout << "Generating random TSP Map with " << nodes << " nodes"
87  << std::endl;
88  qbpp::tsp::TSPMap tsp_map;
89  tsp_map.gen_random_map(nodes);
90 
91  std::cout << "Generating a TSP QUBO expression" << std::endl;
92  qbpp::tsp::TSPQuadModel tsp_quad_model(tsp_map, fix_first);
93 
94  std::cout << "Variables = " << tsp_quad_model.var_count()
95  << " Linear Terms = " << tsp_quad_model.term_count(1)
96  << " Quadratic Terms = " << tsp_quad_model.term_count(2)
97  << std::endl;
98 
99  std::cout << "Generating an EasySolver object" << std::endl;
100  MyEasySolver solver(tsp_quad_model);
101 
102  solver.set_time_limit(time_limit);
103 
104  std::cout << "Solving the TSP" << std::endl;
105  auto sol = solver.search();
106 
107  qbpp::tsp::TSPSol tsp_sol(tsp_quad_model, sol);
108  tsp_sol.print();
109 
110  if (vm.count("output")) {
112  for (uint32_t i = 0; i < nodes; ++i) graph.add_node(tsp_map[i]);
113 
114  for (uint32_t i = 0; i < nodes; ++i)
115  graph.add_edge(tsp_sol[i], tsp_sol[(i + 1) % nodes]);
116 
117  graph.draw(vm["output"].as<std::string>());
118  }
119 }
void callback(const qbpp::Sol &sol, double tts) const override
Definition: tsp_easy.cpp:24
MyEasySolver(const qbpp::tsp::TSPQuadModel &tsp_quad_model)
Definition: tsp_easy.cpp:20
const qbpp::tsp::TSPQuadModel & tsp_quad_model
Definition: tsp_easy.cpp:17
vindex_t var_count() const
Definition: qbpp.hpp:1154
size_t term_count(vindex_t deg) const
Definition: qbpp.hpp:1258
energy_t get_energy() const
Definition: qbpp.hpp:1545
EasySolver(const qbpp::QuadModel &quad_model, std::shared_ptr< qbpp::SolHolder > sol_holder_ptr=nullptr)
void set_time_limit(uint32_t limit)
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
Generates a QUBO Expression for the Graph Coloring Problem using QUBO++ library.
Definition: qbpp.hpp:53
QUBO++, a C++ library for generating expressions for binary and spin variables.
Easy QUBO Solver for solving QUBO problems.
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 Easy ...
Definition: tsp_easy.cpp:43