QUBO++ Library with QUBO Solver APIs
Author: Koji Nakano, License: Non-commercial research and evaluation purposes without any guarantees.
qbpp_nqueen.hpp
Go to the documentation of this file.
1 
9 
10 #ifndef QBPP_NQUEEN_HPP
11 #define QBPP_NQUEEN_HPP
12 
13 #include "qbpp.hpp"
14 
15 namespace qbpp {
17 namespace nqueen {
18 
23 public:
24  enum class Mode { EXPAND, FAST, PARALLEL };
25 
26 private:
28  const int dim_;
32 
38  static qbpp::QuadModel expand_mode(int dim,
39  const Vector<Vector<qbpp::Var>> &X) {
40  // Create arrays of expressions to store the sums of the diagonals.
41 
42  auto a = qbpp::expr(2 * dim - 3);
43  auto b = qbpp::expr(2 * dim - 3);
44  for (int i = 0; i < 2 * dim - 3; i++) {
45  int k = i + 1;
46  for (int j = 0; j < dim; j++) {
47  if (k - j >= 0 && k - j < dim) {
48  a[i] += X[j][k - j];
49  }
50  }
51  int l = dim - i - 1;
52  for (int j = 0; j < dim; j++) {
53  if (l + j >= 0 && l + j < dim) {
54  b[i] += X[j][l + j];
55  }
56  }
57  }
58 
59  auto expr = qbpp::sum((qbpp::vector_sum(X) == 1) +
60  (qbpp::vector_sum(qbpp::transpose(X)) == 1)) +
61  qbpp::sum((0 <= a <= 1) + (0 <= b <= 1));
63 
64  return qbpp::QuadModel(expr);
65  }
66 
72  static qbpp::QuadModel fast_mode(int dim,
73  const Vector<Vector<qbpp::Var>> &X) {
74  qbpp::Expr expr = dim;
75  for (int x = 0; x < dim; ++x) {
76  for (int y = 0; y < dim; ++y) {
77  // Reward for placing a queen
78  expr -= X[x][y];
79  for (int i = x + 1; i < dim; ++i) {
80  // Penalty for placing two queens in the same row
81  expr += X[x][y] * X[i][y];
82  }
83  for (int j = y + 1; j < dim; ++j) {
84  // Penalty for placing two queens in the same column
85  expr += X[x][y] * X[x][j];
86  }
87  for (int d = 1; d < dim - x; ++d) {
88  if (y - d >= 0) {
89  // Penalty for placing two queens on the same anti-diagonal
90  expr += X[x][y] * X[x + d][y - d];
91  }
92  if (y + d < dim) {
93  // Penalty for placing two queens on the same diagonal
94  expr += X[x][y] * X[x + d][y + d];
95  }
96  }
97  }
98  }
100  }
101 
105  const Vector<Vector<qbpp::Var>> &X) {
106  qbpp::Vector<qbpp::Expr> exprs(dim);
107  tbb::parallel_for(0, dim, [&](int x) {
108  for (int y = 0; y < dim; ++y) {
109  // Reward for placing a queen
110  exprs[x] -= X[x][y];
111  for (int i = x + 1; i < dim; ++i) {
112  // Penalty for placing two queens in the same row
113  exprs[x] += X[x][y] * X[i][y];
114  }
115  for (int j = y + 1; j < dim; ++j) {
116  // Penalty for placing two queens in the same column
117  exprs[x] += X[x][y] * X[x][j];
118  }
119  for (int d = 1; d < dim - x; ++d) {
120  if (y - d >= 0) {
121  // Penalty for placing two queens on the same anti-diagonal
122  exprs[x] += X[x][y] * X[x + d][y - d];
123  }
124  if (y + d < dim) {
125  // Penalty for placing two queens on the same diagonal
126  exprs[x] += X[x][y] * X[x + d][y + d];
127  }
128  }
129  }
130  });
131 
132  return qbpp::QuadModel(simplify_as_binary(qbpp::sum(exprs) + dim));
133  }
134 
139  std::tuple<qbpp::QuadModel, int, Vector<Vector<qbpp::Var>>>
140  helper_func(int dim, Mode mode) {
141  Vector<Vector<qbpp::Var>> X(qbpp::var("X", dim, dim));
142  switch (mode) {
143  case Mode::EXPAND:
144  return {expand_mode(dim, X), dim, X};
145  case Mode::FAST:
146  return {fast_mode(dim, X), dim, X};
147  case Mode::PARALLEL:
148  return {parallel_mode(dim, X), dim, X};
149  default:
150  throw std::runtime_error("Invalid mode");
151  }
152  }
153 
160  std::tuple<qbpp::QuadModel, int, Vector<Vector<qbpp::Var>>> &&tuple)
161  : qbpp::QuadModel(std::get<0>(tuple)), dim_(std::get<1>(tuple)),
162  X_(std::get<2>(tuple)) {}
163 
164 public:
168  NQueenQuadModel(int dim, Mode mode)
169  : NQueenQuadModel(helper_func(dim, mode)) {}
170 
175  qbpp::Var get_var(int i, int j) const { return X_[i][j]; }
176 };
177 } // namespace nqueen
178 } // namespace qbpp
179 
180 #endif // QBPP_NQUEEN_HPP
Expr & simplify_as_binary()
Definition: qbpp.hpp:1956
Class to generate a QUBO model for the N-Queens problem.
Definition: qbpp_nqueen.hpp:22
qbpp::Var get_var(int i, int j) const
Gets the variable at (i, j)
NQueenQuadModel(int dim, Mode mode)
Constructor: Creates an N-Queens QUBO expression.
const int dim_
Dimension of the chessboard.
Definition: qbpp_nqueen.hpp:28
const Vector< Vector< qbpp::Var > > X_
2-dimensional vector of qbpp::Var representing the chessboard
Definition: qbpp_nqueen.hpp:31
static qbpp::QuadModel expand_mode(int dim, const Vector< Vector< qbpp::Var >> &X)
Generates qbpp::Expr for the N-Queens problem.
Definition: qbpp_nqueen.hpp:38
NQueenQuadModel(std::tuple< qbpp::QuadModel, int, Vector< Vector< qbpp::Var >>> &&tuple)
Constructor to initialize member variables.
std::tuple< qbpp::QuadModel, int, Vector< Vector< qbpp::Var > > > helper_func(int dim, Mode mode)
Helper function to compute initial values for member variables.
static qbpp::QuadModel parallel_mode(int dim, const Vector< Vector< qbpp::Var >> &X)
Generates the QUBO expression for the N-Queens problem using TBB in parallel.
static qbpp::QuadModel fast_mode(int dim, const Vector< Vector< qbpp::Var >> &X)
Generates the QUBO expression for the N-Queens problem.
Definition: qbpp_nqueen.hpp:72
Generates a QUBO Expression for the Graph Coloring Problem using QUBO++ library.
Definition: qbpp.hpp:53
Expr vector_sum(const T &items[[maybe_unused]])
Definition: qbpp.hpp:3282
Var var(const std::string &var_str)
Definition: qbpp.hpp:2172
Vector< Vector< Expr > > transpose(const Vector< Vector< T >> &vec)
Definition: qbpp.hpp:3618
Expr sum(const Vector< T > &items)
Definition: qbpp.hpp:3209
Expr simplify_as_binary(const Expr &expr)
Definition: qbpp.hpp:2759
Expr expr()
Definition: qbpp.hpp:2318
QUBO++, a C++ library for generating expressions for binary and spin variables.