K-КНФ-алгоритмы на основе поиска с возвратом: различия между версиями

Перейти к навигации Перейти к поиску
м
Строка 47: Строка 47:
         '''then''' output(u); '''exit''';
         '''then''' output(u); '''exit''';
       '''end''' /* конец цикла repeat */
       '''end''' /* конец цикла repeat */
   output("Невыполнимо");
   output("Невыполнима");




Алгоритм '''ResolveSat''' получается в результате сочетания '''Search''' с шагом предварительной обработки, заключающейся в ''ограниченном разложении'' формулы. Между дизъюнктами <math>C_1 \;</math> и <math>C_2 \;</math> возникает ''конфликт'' на переменной v, если один из них содержит v, а другой – <math>\bar{v}</math>. <math>C_1 \;</math> и <math>C_2 \;</math> представляют собой ''разложимую пару'', если они конфликтуют точно на одной переменной v. Для таких пар их ''резольвентой'', обозначаемой <math>R(C_1, C_2) \;</math>, будет являться дизъюнкт <math>C = D_1 \vee D_2 \;</math>, где <math>D_1 \;</math> и <math>D_2 \;</math> получаются удалением v и <math>\bar{v}</math> из <math>C_1 \;</math> и <math>C_2 \;</math>, соответственно. Легко заметить, что любое присваивание, при котором <math>C_1 \;</math> и <math>C_2 \;</math> выполнимы, влечет также и выполнимость C. Следовательно, если F является выполнимой КНФ-формулой, содержащей разложимую пару <math>C_1 \;</math>, <math>C_2 \;</math>, то формула <math>F' = F \wedge R(C_1, C_2)</math> будет иметь те же удовлетворяющие условию выполнимости присваивания, что и F. Разложимая пара <math>C_1, C_2 \;</math> является ''s-ограниченной'', если  <math>|C_1|, |C_2| \le s</math> и <math>|R(C_1, C_2)| \le s</math>. Следующая процедура расширяет формулу F до формулы <math>F_s \;</math>, применяя s-ограниченное разложение максимально возможное количество раз.
Алгоритм '''ResolveSat''' получается в результате сочетания '''Search''' с шагом предварительной обработки, заключающейся в ''ограниченном разложении'' формулы. Между дизъюнктами <math>C_1 \;</math> и <math>C_2 \;</math> возникает ''конфликт'' на переменной v, если один из них содержит v, а другой – <math>\bar{v}</math>. <math>C_1 \;</math> и <math>C_2 \;</math> представляют собой ''разложимую пару'', если они конфликтуют точно на одной переменной v. Для таких пар их ''резольвентой'', обозначаемой <math>R(C_1, C_2) \;</math>, будет являться дизъюнкт <math>C = D_1 \vee D_2 \;</math>, где <math>D_1 \;</math> и <math>D_2 \;</math> получаются удалением v и <math>\bar{v}</math> из <math>C_1 \;</math> и <math>C_2 \;</math>, соответственно. Легко заметить, что любое присваивание, при котором <math>C_1 \;</math> и <math>C_2 \;</math> выполнимы, влечет также и выполнимость C. Следовательно, если F является выполнимой КНФ-формулой, содержащей разложимую пару <math>C_1 \;</math>, <math>C_2 \;</math>, то формула <math>F' = F \wedge R(C_1, C_2)</math> будет иметь те же удовлетворяющие условию выполнимости присваивания, что и F. Разложимая пара <math>C_1, C_2 \;</math> является ''s-ограниченной'', если  <math>|C_1|, |C_2| \le s</math> и <math>|R(C_1, C_2)| \le s</math>. Следующая процедура расширяет формулу <math>F \;</math> до формулы <math>F_s \;</math>, применяя s-ограниченное разложение максимально возможное количество раз.




Resolve(КНФ-формула F, целое число s)
'''Resolve'''(КНФ-формула F, целое число s)
  <math>F_s = F</math>.
  '''while''' <math>F_s</math> содержит s-ограниченную разложимую пару <math>C_1, C_2</math>, такую, что <math>R(C_1, C_2) \notin F_s</math>
        <math>F_s = F_s \wedge R(C_1, C_2)</math>.
  '''return''' (<math>F_s</math>).


Fs = F.


while Fs содержит s-ограниченную разложимую пару C1, C2
Алгоритм для формулы k-КНФ представляет собой простую комбинацию '''Resolve''' и '''Search''':


with R(C1;C2) 26Fs Fs = FsAR(d,C2). return (Fs).


Алгоритм для формулы k-КНФ представляет собой простую комбинацию Resolve и Search:
'''ResolveSat'''(КНФ-формула F, целое число s, целое положительное число I)
 
  <math>F_s</math> = Resolve(F, s).
ResolveSat(КНФ-формула F, целое число s, целое положительное число I)
  '''Search'''(<math>F_s</math>, I).
 
Fs =Resolve(F, s).
 
Search(Fs, I).




'''Анализ алгоритма ResolveSat'''
'''Анализ алгоритма ResolveSat'''


Время выполнения ResolveSat(F, s, I) можно ограничить следующим образом. Resolve(F, s) добавляет не более O(ns) дизъюнктов к F за счет сравнения пар дизъюнктов, так что прямолинейная реализация будет выполняться за время n3spoly(n) (эту границу можно улучшить, однако ее улучшение не повлияет на асимптотику основного результата). Search(Fs, I) требует I(jFj + ns)poly(n) времени. Следовательно, полное время выполнения ResolveSat(F, s, I) можно грубо ограничить сверху значением (n3s + I(jFj + ns))poly(n). If s = O(n/log n), общее время выполнения можно ограничить значением IjFj2O(n), поскольку ns = 2O(n). Для этого нужно взять в качестве s некоторую константу достаточно большой величины или медленно растущую функцию от n. Таким образом, s(n) будет стремиться к бесконечности с n, но будет оставаться в пределах O(log n).
Время выполнения ResolveSat(F, s, I) можно ограничить следующим образом. '''Resolve'''(F, s) добавляет не более <math>O(n^s) \;</math> дизъюнктов к F за счет сравнения пар дизъюнктов, так что прямолинейная реализация будет выполняться за время <math>n^{3s}poly(n) \;</math> (эту границу можно улучшить, однако ее улучшение не повлияет на асимптотику основного результата). '''Search'''(<math>F_s, \; I</math>) требует <math>I(|F| + n^s)poly(n) \;</math> времени. Следовательно, полное время выполнения '''ResolveSat'''(F, s, I) можно грубо ограничить сверху значением <math>(n^{3s} + I(|F| + n^s))poly(n) \;</math>. If s = O(n/log n), общее время выполнения можно ограничить значением <math>I|F|2^{O(n)} \;</math>, поскольку <math>n^s = 2^{O(n)} \;</math>. Для этого нужно взять в качестве s некоторую константу достаточно большой величины или ''медленно растущую'' функцию от n. Таким образом, s(n) будет стремиться к бесконечности с n, но будет оставаться в пределах O(log n).




В случае, если функция F оказывается невыполнимой, алгоритм Search(F, I) всегда выдает результат «невыполнима». Таким образом, единственной проблемой остается нахождение верхней границы в случае, когда F выполнима. Обозначим за x(F) вероятность того, что Modify(F it,y) найдет некоторое присваивание, обеспечивающее выполнимость. Тогда для выполнимой функции F вероятность ошибки Search(F, I) равна (1 - r(F))1 < e~It(F\, что не превышает e~" при условии I > nlx{F). Следовательно, достаточно получить хорошую верхнюю границу для T(F).
В случае, если функция F оказывается невыполнимой, алгоритм '''Search'''(F, I) всегда выдает результат «невыполнима». Таким образом, единственной проблемой остается нахождение верхней границы в случае, когда F выполнима. Обозначим за x(F) вероятность того, что Modify(F it,y) найдет некоторое присваивание, обеспечивающее выполнимость. Тогда для выполнимой функции F вероятность ошибки Search(F, I) равна (1 - r(F))1 < e~It(F\, что не превышает e~" при условии I > nlx{F). Следовательно, достаточно получить хорошую верхнюю границу для T(F).




4511

правок

Навигация