Насколько я знаю, не существует простой алгоритм для решения этой конкретной проблемы более эффективно, чем при использовании с возвратами подход.
Вы можете сделать это более разумно, чем просто перечислять все возможные решения. Эффективный способ сделать это: Программирование ограничений (CP) (или производные парадигмы, такие как Программирование логики Constraint (CLP)). В основном это сводится к рассуждениям об ограничениях , которые вы поставили на свою проблему, пытаясь уменьшить область переменных.
После уменьшения количества доменов вы делаете выбор , на котором позже вы можете вернуться назад. Сделав такой выбор, вы снова уменьшаете домены и, возможно, должны сделать дополнительный выбор.
Вы можете, например, использовать ECLIPSE (а не IDE, а средство программирования ограничение логики) для этого:
:- lib(ic).
:- import alldifferent/1 from ic_global.
:- import sumlist/2 from ic_global.
solve(Problem) :-
problem(Problem,N,LA,LB),
puzzle(N,LA,LB,Grid),
print_Grid(Grid).
puzzle(N,LA,LB,Grid) :-
N2 is N*N,
dim(Grid,[N,N]),
Grid[1..N,1..N] :: 1..N2,
(for(I,1,N), param(N,Grid,LA,LB) do
Sc is nth1(I,LA),
Lc is Grid[1..N,I],
sumlist(Lc,Sc),
Sr is nth1(I,LB),
Lr is Grid[I,1..N],
sumlist(Lr,Sr)
),
term_variables(Grid,Vars),
alldifferent(Vars),
labeling(Vars).
print_Grid(Grid) :-
dim(Grid,[N,N]),
(for(I,1,N), param(Grid,N) do
(for(J,1,N), param(Grid,I) do
X is Grid[I,J],
(var(X) -> write(" _") ; printf(" %2d", [X]))
), nl
), nl.
nth1(1,[H|_],H) :- !.
nth1(I,[_|T],H) :-
I1 is I-1,
nth1(I1,T,H).
problem(1,3,[14,14,17],[13,8,24]).
Программа основана на неопределенно my implementation for multi-sudoku. Теперь вы можете решить эту проблему с помощью Eclipse:
ECLiPSe Constraint Logic Programming System [kernel]
Kernel and basic libraries copyright Cisco Systems, Inc.
and subject to the Cisco-style Mozilla Public Licence 1.1
(see legal/cmpl.txt or http://eclipseclp.org/licence)
Source available at www.sourceforge.org/projects/eclipse-clp
GMP library copyright Free Software Foundation, see legal/lgpl.txt
For other libraries see their individual copyright notices
Version 6.1 #199 (x86_64_linux), Sun Mar 22 09:34 2015
[eclipse 1]: solve(1).
lists.eco loaded in 0.00 seconds
WARNING: module 'ic_global' does not exist, loading library...
queues.eco loaded in 0.00 seconds
ordset.eco loaded in 0.00 seconds
heap_array.eco loaded in 0.00 seconds
graph_algorithms.eco loaded in 0.03 seconds
max_flow.eco loaded in 0.00 seconds
flow_constraints_support.eco loaded in 0.00 seconds
ic_sequence.eco loaded in 0.01 seconds
ic_global.eco loaded in 0.05 seconds
2 5 6
3 1 4
9 8 7
Yes (0.05s cpu, solution 1, maybe more) ? ;
5 2 6
1 3 4
8 9 7
Yes (0.05s cpu, solution 2, maybe more) ? ;
2 6 5
3 1 4
9 7 8
Yes (0.05s cpu, solution 3, maybe more) ? ;
3 6 4
2 1 5
9 7 8
Yes (0.05s cpu, solution 4, maybe more) ? ;
6 2 5
1 3 4
7 9 8
Yes (0.05s cpu, solution 5, maybe more) ? ;
6 3 4
1 2 5
7 9 8
Yes (0.05s cpu, solution 6, maybe more) ? ;
2 6 5
4 1 3
8 7 9
Yes (0.05s cpu, solution 7, maybe more) ? ;
4 6 3
2 1 5
8 7 9
Yes (0.05s cpu, solution 8, maybe more) ?
6 2 5
1 4 3
7 8 9
Yes (0.05s cpu, solution 9, maybe more) ? ;
6 4 3
1 2 5
7 8 9
Yes (0.05s cpu, solution 10, maybe more) ? ;
No (0.06s cpu)
Один просто запрашивает solve(1)
и ограничение инструмент логического программирования делает все остальное. Таким образом, существует в общей сложности 10
решений.
Обратите внимание, что программа работает для произвольного N
, хотя - поскольку в худшем случае эта программа выполняет обратное отслеживание - очевидно, программа может решить проблемы только для разумного N
.
Эта проблема приводит к 9 неизвестных, но только 6 уравнений. Поэтому я ожидаю, что нет единственного решения. –
@TimBiegeleisen существует множество неявных ограничений, переменные должны быть уникальными целыми числами вне диапазона [1 .. N]. – Henry
«Грубая сила» - это алгоритм. – usr2564301