Download
//Copyright 2018 Maria Andreina Francisco Rodriguez (andreina@comp.nus.edu.sg)
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
//http ://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
#include "ortools/base/commandlineflags.h"
#include "ortools/constraint_solver/constraint_solveri.h"
DEFINE_int32(
size, 0,
"Size of the problem. If equal to 0, will test several sizes.");
namespace operations_research {
void printSolutionArray(std::vector<IntVar*> arrayOfVars);
void nqueens(int64 numQueens) {
// Instantiate the solver.
Solver solver("nQueens");
//const int64 numQueens = 13;
// Decision variables
std::vector<IntVar*> board;
solver.MakeIntVarArray(numQueens, 0, numQueens - 1, "Board", &board);
// Constraints
// Each queen must be on a different row and column
solver.AddConstraint(solver.MakeAllDifferent(board));
// Each queen must be on a different diagonal
std::vector<IntVar*> diag1(numQueens);
std::vector<IntVar*> diag2(numQueens);
for (int i = 0; i < numQueens; i++) {
diag1[i] = solver.MakeSum(board[i], i)->Var();
diag2[i] = solver.MakeSum(board[i], -i)->Var();
}
solver.AddConstraint(solver.MakeAllDifferent(diag1));
solver.AddConstraint(solver.MakeAllDifferent(diag2));
// Branching heuristics
DecisionBuilder* const db = solver.MakePhase(board,
Solver::CHOOSE_MIN_SIZE,
Solver::ASSIGN_CENTER_VALUE);
// Search!
solver.Solve(db);
int numSolutions = 0;
// Print
while (solver.NextSolution()) {
numSolutions++;
std::cout << "Solution " << numSolutions << " :";
printSolutionArray(board);
}
const int64 elapsedTime = solver.wall_time();
std::cout << "Total number of solutions: " << numSolutions << "\n";
std::cout << "Total elapsed time: " << elapsedTime << " milliseconds.\n";
}
// Prints the values of an array of variables between squre brakets
void printSolutionArray(std::vector<IntVar*> arrayOfVars) {
int i = 0;
int size = arrayOfVars.size();
std::cout << "[";
while (i < size) {
std::cout << arrayOfVars[i]->Value();
i++;
}
std::cout << "]\n";
}
}
int main(int argc, char** argv) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
if (FLAGS_size != 0) {
std::cout << "Solving for a board of size: " << FLAGS_size << "\n";
operations_research::nqueens(FLAGS_size);
}
else {
for (int size = 4; size < 10; size++) {
std::cout << "Solving for a board of size: " << size << "\n";
operations_research::nqueens(size);
}
}
return 0;
}