Я надеюсь на предложения о том, как это сделать:
Определение:
Ненаправленный граф G определяется множеством V вершин и множеством E ребер, где каждое ребро является подмножеством V размера два, то есть неупорядоченной парой {u, v} вершин. Цикл длины k в G - это последовательность v_1, ..., v_k различных вершин, для которых {v_1, v_2}, {v_2, v_3}, ..., {v_k-1, v_k}, {v_k, v_1 } - все ребра G. Гамильтонов цикл в G - это цикл длины n = | V |, т. е. цикл, проходящий через каждую вершину графа ровно один раз. Мы называем G гамильтонианом, если он имеет гамильтонов цикл.
Проблема:
Предоставьте логическую формулировку высказывания следующей задачи решения:
направленный граф G, является ли гамильтоновым? Состав будет проверен Z3.
Формат ввода будет:
4
0 1
1 2
2 3
3 0
1 3
где первое число представляет количество вершин, а остальные пары - все ребра в G.
Выходные данные должны быть: 0 1 2 3
Очевидно, что на выходе всегда будет некоторая перестановка чисел 1, ..., n-1, где n = | V | но я не понимаю, как работать с целыми числами, используя только логику предложения.
Любой совет приветствуется.
Привет.
Вот решение, которое работает для данного ввода. Если бы я мог написать процедуру на Perl, которая бы вырабатывала комбинации (n Выберите k) ребер, я мог бы обобщить это на любое количество входных данных:
(declare-const v0 Bool)
(declare-const v1 Bool)
(declare-const v2 Bool)
(declare-const v3 Bool)
(declare-const e1 Bool)
(declare-const e2 Bool)
(declare-const e3 Bool)
(declare-const e4 Bool)
(declare-const e5 Bool)
(assert (xor (and e1 e2 e3 e4) (and e1 e2 e3 e5) (and e1 e2 e4 e5) (and e1 e3 e4 e5) (and e2 e3 e4 e5)))
(assert (and v0 v1 v2 v3))
(assert (=> e1 (and v0 v1)))
(assert (=> e2 (and v1 v2)))
(assert (=> e3 (and v2 v3)))
(assert (=> e4 (and v3 v0)))
(assert (=> e5 (and v1 v3)))
(check-sat)
(get-model)