| 
				
				
								
			 | 
			
				
				
					
											Общий алгоритм решения задач, подобных Судоки, был разработан месье Лорьером в начале 70-х годов (см. книгу «Системы искусственного интеллекта», глава «Информационная система ALICE»).  Суть его состоит в следующем. Задача представляется в виде описания конечных дискретных переменных и в виде набора ограничений. Система решения задач ALICE содержала в себе систему считывания условий задачи, систему ветвления (перебора) и набор полиномиальных алгоритмов, которые позволяют сокращать перебор. После считывания задачи система ALICE автоматически (!) применяет полиномиальные алгоритмы для удаления недопустимых значений переменных (см. в Интернете «Распространение ограничений», «Метод вперед-назад», «Интервальный анализ»). Если обнаружено противоречие – задача не имеет решения. Если все переменные зафиксированы – найдено единственное решение. Если есть незафиксированные переменные – нужно ветвиться (делать шаг перебора): делается ветвление и для каждой ветки начинается все сначала. Т.е. никакого антагонизма между «перебором» и «логическим решением» нет в природе. Просто, в силу отсталости нашего образования, под «логическим методом решения задач» неокрепшие умы называют систему сжатия доменов переменных и систему распространения ограничений. Если в системе решения задачи есть подходящие полиномиальные алгоритмы, то решение находится легко. Если в системе мало «подходящих» алгоритмов - доля перебора в решении задачи растет. Отсюда, кстати следует бессмысленность NP-классификации, т.к. важен не столько сам факт экспоненциального нарастания сложности, сколько сама доля перебора в решении задачи. Сам я непосредственно участвую в разработке системы Quick NP, в которой можно решить многие задачи Судоки. Предложенные в обсуждения задачи с 81-м числом имеют точно по одному решению. Quick NP использует 3 и 6 узлов дерева поиска соответственно чтобы полностью решить задачи. Если не считать неудачные узлы ветвления (сразу после ветвления становится ясно, что есть противоречие), то можно сказать, что Quick NP решает эти задачи без перебора. Т.е. если не считать за узел перебора действий типа «переменная x не может равняться a, так как получаем противоречие», то Quick NP обходится полностью без перебора. Ниже приведено формальное описание задачи на NP-языке, который используется Quick NP. Project  Sudoki9 Module Main Field Lines () As IntegerCon Ins  As ' Создание клеток__ForAll(i  In Lines , Append(Check , Me:i , Dig :Lines (i )))Con InsFigs  As ' Создание столбцов, строк и квадратов__ForAll(i  In {1..9}, ____Append(Row , Me:i ) And Append(Col , Me:i ) And Append(Square , Me:i ))Class Row Var theChecks {} As Integer = Union(c  In Check , c .y =Me, c )Con Injs  As Inj(c  In theChecks , Check (c ).d ) ' Цифры в строках уникальныClass Col Var theChecks {} As Integer = Union(c  In Check , c .x =Me, c )Con Injs  As Inj(c  In theChecks , Check (c ).d ) ' Цифры в стобцах уникальныClass Square Var xStart  As Integer = (Me-1) Mod 3 * 3 + 1Var yStart  As Integer = (Me-1) \ 3 * 3 + 1Var theChecks {} As Integer = __Union(c  In Check , Between(c .x , xStart , xStart +2) And____Between(c .y , yStart , yStart +2), c )Con Injs  As Inj(c  In theChecks , Check (c ).d ) ' Цифры в квадратах уникальныClass Check Field Dig  As IntegerVar x  As Integer = Me - 9*(y -1)     ' Координата x клеткиVar y  As Integer = (Me - 1) \ 9 + 1 ' Координата y клеткиVar d  As If(Dig =0, {1..9}, {Dig })   ' Переменная цифры клеткиCon Save  As Store(x , y , d )Data $InFile Main (Lines )__1, {8,3,0, 6,0,0, 0,0,1,______0,0,6, 0,3,0, 0,8,0,______0,0,1, 8,0,0, 0,6,0,______0,0,0, 9,0,0, 0,4,0,______0,0,3, 0,7,0, 2,0,0,______0,7,0, 0,0,5, 0,0,0,______0,1,0, 0,0,4, 6,0,0,______0,5,0, 0,9,0, 8,0,0,______9,0,0, 0,0,6, 0,2,3}EndДелая пошаговое выполнение, можно увидеть, как система Quick NP находит решение. Можно увидеть состояние стека перебора, отсеченные значения, журнал отсечения, само решение и т.п. Ниже приведено описание задачи ХИТОРИ на NP-языке Project  Hitory Module Main Field Size  As IntegerCon InsCols  As ForAll(c  In {1..Size }, Append(Col , Me:c ))Con StartConn  As ' Начальная клетка поиска связности__If(Check (1).Used , Check (1).Conn , Check (2).Conn )Class Row Field Cols () As IntegerRef theChecks {} As Check .theRow Con InsChecks  As ' Создание матрицы__ForAll(c  In Cols , Append(Check , theRow :Me, theCol :c , v :Cols (c )))Con Unique  As    ' Не более одной уникального числа в строке__ForAll(i  In {1..Size },____Sum(c  In theChecks , c .v =i ) >= 2 ==>______Sum(c  In theChecks , c .v =i , c .Used ) <= 1)Class Col Ref theChecks {} As Check .theCol Con Unique  As__ForAll(i  In {1..Size }, ' Не более одного уникального числа в столбце____Sum(c  In theChecks , c .v =i ) >= 2 ==>______Sum(c  In theChecks , c .v =i , c .Used ) <= 1)Class Check Field v  As Integer     ' Число в клеткеVar Used  As Boolean    ' Истино, если клетка не вычеркиваетсяVar Conn  As Boolean    ' Переменная связностиRef theCol  As Col .theChecks  ' КолонкаRef theRow  As Row .theChecks  ' СтолбецVar Neibs {} As Integer = ' Соседние клетки__If(theCol >1, {Me-1}, {}) Union If(theCol <Size , {Me+1},{}) ____Union If(theRow >1, {Me-Size }, {}) Union If(theRow <Size , {Me+Size }, {})Con EmptyNoConn  As     ' Не вычеркивать соседние клетки__ForAll(c  In Neibs , c  < Me ==> Check (c ).Used +Used  >= 1)Con Conns  As           ' Обеспечение связности__Def(Conn ) And Dep(Conn ) And____If(Used , ForAll(i  In Neibs , Check (i ).Conn  ==> Conn ), Not Conn )Con Save  As Store(theCol , theRow , Used )Data $InFile Main (Size )__1, 15EndRow (Cols )___1, {  9,  3,  6,  4,  8,  8, 15,  6, 12,  1,  5,  2, 12,  3, 15 }___2, { 13,  4,  4,  5,  6, 10, 13, 14,  7, 14,  2, 14,  1, 11, 12 }___3, {  7,  9,  5, 15, 11,  9,  1, 10,  9,  3, 12,  4,  6,  5,  8 }___4, {  3,  4,  9,  7, 14,  7, 13, 12,  2,  6,  6, 13,  4, 10,  8 }___5, { 12, 15,  8, 13,  7,  5,  6, 11,  5, 14,  3, 13,  5,  9,  2 }___6, { 14,  6, 12,  4,  2,  9,  4,  4,  3, 15,  6,  8,  7, 13, 10 }___7, { 11,  2,  4,  6, 15, 15,  2,  1,  5,  9,  8,  4, 10,  3, 13 }___8, {  6, 14,  1, 11,  5, 12,  8,  3,  8, 10, 10, 15,  4,  2,  4 }___9, {  8, 12,  8, 10,  7,  2, 11,  6, 14,  4, 10,  9, 15,  5,  7 }__10, {  5, 13, 15,  3, 13,  3, 14, 10,  6, 12,  7, 12, 11,  1,  4 }__11, {  6, 10,  3,  1,  8,  4,  7,  2, 11,  7, 14,  7,  7, 15,  4 }__12, {  2,  8,  7, 12,  1,  4,  5,  9, 13, 13, 15, 13, 14,  8,  3 }__13, { 12,  8,  4,  1, 13, 14, 12,  7, 13,  5, 11,  3, 14,  9,  9 }__14, { 10,  4, 14, 10,  9,  6,  3,  7,  1,  7,  4,  6,  2,  7, 15 }__15, {  2,  7,  2,  9, 12, 14,  8, 13, 10,  6,  4, 14,  3, 13, 11 } EndСистема Quick NP, используя 1735 узлов дерева поиска, обнаружила 31 решение. Ниже приведено одно из них (а также набор удаляемых пар, если я неправильно что-то набил в матрице): Код: Row(Cols)    1, {  9,   ,  6,  4,   ,  8, 15,   , 12,  1,  5,  2,   ,  3,    }    2, { 13,  4,   ,  5,  6, 10,   , 14,  7,   ,  2,   ,  1, 11, 12 }    3, {  7,  9,  5, 15, 11,   ,  1, 10,   ,  3, 12,  4,  6,   ,  8 }    4, {  3,   ,  9,   , 14,  7,   , 12,  2,   ,  6, 13,  4, 10,    }    5, {   , 15,   , 13,  7,   ,  6, 11,   , 14,  3,   ,  5,   ,  2 }    6, { 14,  6, 12,   ,  2,  9,  4,   ,  3, 15,   ,  8,  7, 13, 10 }    7, { 11,   ,  4,  6,   , 15,  2,  1,   ,  9,  8,   , 10,   , 13 }    8, {   , 14,  1, 11,  5, 12,   ,  3,  8,   , 10, 15,   ,  2,    }    9, {  8, 12,   , 10,   ,  2, 11,  6, 14,  4,   ,  9, 15,  5,  7 }   10, {  5,   , 15,  3, 13,   , 14,   ,  6, 12,  7,   , 11,  1,  4 }   11, {  6, 10,  3,   ,  8,  4,   ,  2, 11,   , 14,  7,   , 15,    }   12, {  2,   ,  7, 12,  1,   ,  5,  9,   , 13, 15,   , 14,  8,  3 }   13, { 12,  8,   ,  1,   , 14,   ,  7, 13,  5, 11,  3,   ,  9,    }   14, { 10,   , 14,   ,  9,  6,  3,   ,  1,   ,  4,   ,  2,  7, 15 }   15, {   ,  7,  2,  9, 12,   ,  8, 13, 10,  6,   , 14,  3,   , 11 }  End
  Check(theCol, theRow)   2, 1   5, 1   8, 1   13, 1   15, 1   3, 2   7, 2   10, 2   12, 2   6, 3   9, 3   14, 3   2, 4   4, 4   7, 4   10, 4   15, 4   1, 5   3, 5   6, 5   9, 5   12, 5   14, 5   4, 6   8, 6   11, 6   2, 7   5, 7   9, 7   12, 7   14, 7   1, 8   7, 8   10, 8   13, 8   15, 8   3, 9   5, 9   11, 9   2, 10   6, 10   8, 10   12, 10   4, 11   7, 11   10, 11   13, 11   15, 11   2, 12   6, 12   9, 12   12, 12   3, 13   5, 13   7, 13   13, 13   15, 13   2, 14   4, 14   8, 14   10, 14   12, 14   1, 15   6, 15   11, 15   14, 15 End  Технологии на месте не стоят, а многих из обсуждавшихся здесь проблем/вопросов, не существует в природе уже десятки лет.  
					 					 | 
				 
				 
			 |