4511
правок
Irina (обсуждение | вклад) |
Irina (обсуждение | вклад) |
||
Строка 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>). | |||
Алгоритм для формулы k-КНФ представляет собой простую комбинацию '''Resolve''' и '''Search''': | |||
'''ResolveSat'''(КНФ-формула F, целое число s, целое положительное число I) | |||
<math>F_s</math> = Resolve(F, s). | |||
ResolveSat(КНФ-формула F, целое число s, целое положительное число I) | '''Search'''(<math>F_s</math>, I). | ||
Search( | |||
'''Анализ алгоритма ResolveSat''' | '''Анализ алгоритма ResolveSat''' | ||
Время выполнения ResolveSat(F, s, I) можно ограничить следующим образом. Resolve(F, s) добавляет не более O( | Время выполнения 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). | ||
правок