z3-z3-4.13.0.examples.python.hamiltonian.hamiltonian.py Maven / Gradle / Ivy
The newest version!
############################################
# Copyright (c) Microsoft Corporation. All Rights Reserved.
#
# Check if the given graph has a Hamiltonian cycle.
#
# Author: Ganesh Gopalakrishnan [email protected]
############################################
from z3 import *
def gencon(gr):
"""
Input a graph as an adjacency list, e.g. {0:[1,2], 1:[2], 2:[1,0]}.
Produces solver to check if the given graph has
a Hamiltonian cycle. Query the solver using s.check() and if sat,
then s.model() spells out the cycle. Two example graphs from
http://en.wikipedia.org/wiki/Hamiltonian_path are tested.
=======================================================
Explanation:
Generate a list of Int vars. Constrain the first Int var ("Node 0") to be 0.
Pick a node i, and attempt to number all nodes reachable from i to have a
number one higher (mod L) than assigned to node i (use an Or constraint).
=======================================================
"""
L = len(gr)
cv = [Int('cv%s'%i) for i in range(L)]
s = Solver()
s.add(cv[0]==0)
for i in range(L):
s.add(Or([cv[j]==(cv[i]+1)%L for j in gr[i]]))
return s
def examples():
# Example Graphs: The Dodecahedral graph from http://en.wikipedia.org/wiki/Hamiltonian_path
grdodec = { 0: [1, 4, 5],
1: [0, 7, 2],
2: [1, 9, 3],
3: [2, 11, 4],
4: [3, 13, 0],
5: [0, 14, 6],
6: [5, 16, 7],
7: [6, 8, 1],
8: [7, 17, 9],
9: [8, 10, 2],
10: [9, 18, 11],
11: [10, 3, 12],
12: [11, 19, 13],
13: [12, 14, 4],
14: [13, 15, 5],
15: [14, 16, 19],
16: [6, 17, 15],
17: [16, 8, 18],
18: [10, 19, 17],
19: [18, 12, 15] }
import pprint
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(grdodec)
sdodec=gencon(grdodec)
print(sdodec.check())
print(sdodec.model())
# =======================================================
# See http://en.wikipedia.org/wiki/Hamiltonian_path for the Herschel graph
# being the smallest possible polyhedral graph that does not have a Hamiltonian
# cycle.
#
grherschel = { 0: [1, 9, 10, 7],
1: [0, 8, 2],
2: [1, 9, 3],
3: [2, 8, 4],
4: [3, 9, 10, 5],
5: [4, 8, 6],
6: [5, 10, 7],
7: [6, 8, 0],
8: [1, 3, 5, 7],
9: [2, 0, 4],
10: [6, 4, 0] }
pp.pprint(grherschel)
sherschel=gencon(grherschel)
print(sherschel.check())
# =======================================================
if __name__ == "__main__":
examples()