Sudoku (benchmarks)
Mix.install([
{:fixpoint, path: Path.join(System.get_env("HOME"), "projects/cpsolver")}
])
Logger.configure(level: :notice)
Section
IEx.Helpers.c(Path.join([System.get_env("HOME"),
"projects", "cpsolver",
"scripts/sudoku_benchmark.exs"]))
require Logger
alias CPSolver.Examples.Sudoku
alias CPSolver.Constraint.AllDifferent.{DC, BC, FWC, DC.Fast}
puzzle_file =
#"data/sudoku/clue17"
#"data/sudoku/top95"
"data/sudoku/hardest"
#"data/sudoku/puzzles5_forum_hardest_1905_11+"
#"data/sudoku/quasi_uniform_834"
num_instances = 100_000
num_threads = 8
alldiff_impl = Fast
{elapsed_times, success_count, failure_count, incorrect_count} =
SudokuBenchmark.run(
Path.join([System.get_env("HOME"),
"projects", "cpsolver",
puzzle_file]), num_instances, num_threads, 30_000, alldiff_impl)
|> Enum.with_index()
|> Enum.reduce({[], 0, 0, 0}, fn {s, problem_num}, {elapsed_acc, succ_acc, fail_acc, wrong_acc} ->
elapsed_acc = [s.statistics.elapsed_time | elapsed_acc]
s.solutions
|> List.first()
|> then(fn sol ->
if sol do
if Sudoku.check_solution(sol) do
#Logger.notice("OK")
{elapsed_acc, succ_acc + 1, fail_acc, wrong_acc}
else
Logger.error("Wrong solution for #{problem_num} ! #{sol}")
{elapsed_acc, succ_acc, fail_acc, wrong_acc + 1}
end
else
Logger.error("No solution for #{problem_num}")
{elapsed_acc, succ_acc, fail_acc + 1, wrong_acc}
end
end)
end)
#|> Enum.sort()
res = %{elapsed: elapsed_times, success: success_count, no_solution: failure_count, incorrect: incorrect_count}
res = Map.merge(res,
%{
source: puzzle_file,
shortest: Enum.min(res.elapsed),
longest: Enum.max(res.elapsed),
average: Enum.sum(res.elapsed) / length(res.elapsed),
total: Enum.sum(res.elapsed),
elapsed: Enum.sort(res.elapsed)
})