Вероятно, существует множество подходов, но один из них может выглядеть следующим образом:
Для каждой подсказки C_i
вы вводите новые вспомогательные переменные:
# NV_?_j = position j is not visible (in regards to clue i)
NV_i_1, NV_i_2, ... NV_i_n
Подсказка состоит в том, чтобы указать правильную мощность (различные подходы; вы выбрали как)
sum(NV_1_?) = clue-hint(C_1)
Теперь вопрос состоит в том, как ограничить NV
:
NV_i_1 = true
всегда действительный NV_i_j = true <-> there exists a HIGHER value EARLIER
Это быстро растет, но я рекомендую следующий подход (который не должен быть проблемой для тех размеров, которые я видел на ваших связанных страницах; хотя SAT является менее естественный подход, чем, например, CP):
Для N=5
, ограниченного вашим ограничением для всех различий, есть C(N, 2) = 10
уникальных пар без симметрии:
1 2 2 3 3 4 4 5
1 3 2 4 3 5
1 4 2 5
1 5
You теперь будут использовать эти пары в отношении:
- парных позиций (1 - N)
- парных значений (1 - N)
Предполагая, что ваш переменные решения - это тензор некоторого тензора ранга 3 (позиция строки, позиция столбца, значение в унарной кодировке) с размерами (N, N, N):
X111 = row = 1 | column = 1 | value = 1
X112 = row = 1 | column = 1 | value = 2
...
X121 = row = 1 | column = 2 | value = 1
...
NV_i_j = true <-> there exists a HIGHER value EARLIER
можно выразить как (мы предполагаем, что ключ активен в некотором столбце здесь):
NV_i_1 <-> true # fact
# pairs compared: position 1 2
NV_i_2 <-> (X115 ^ X124) | (X115 ^ X123) | ... | (x112 ^ X121)
# pairs compared: position 1 3 + position 2 3
# 3 compared to 1 and 2 -> existence of HIGHER value EARLIER (2 positions)
NV_i_3 <-> (X115 ^ X134) | (X115 ^ X133) | ... | (x112 ^ X131) |
(X125 ^ X134) | (X125 ^ X133) | ... | (x122 ^ X131)
...
# pairs compared: position 1 5 + position 2 5 + position 3 5 + position 4 5
NV_i_5 <-> (X115 ^ X154) | (X115 ^ X153) | ... | (x112 ^ X151) |
(X125 ^ X154) | (X125 ^ X153) | ... | (x122 ^ X151)
...
(X145 ^ X154) | (X145 ^ X153) | ... | (x142 ^ X151)
Теперь осталась только одна вещь (и я не буду это показывать):
- преобразование этих компонентов в cnf
- вы уже сделали некоторую кардинальную кодировку для вашего all-diff разложения
- можно использовать повторно для количества элементов, необходимых для подсказок
- для
NV
ограничения: - я рекомендую использовать внешние инструменты (sympy, mathematica, ...) вместо того, чтобы делать это вручную
- я также рекомендую передать это в некоторые функции который передается чем-то вроде подматрицы вашего тензора (тензора, где строка или столбец, где активна подсказка, отщепляется) +
clue_n