exercise8.py 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. from z3 import *
  2. def all_smt(s, initial_terms):
  3. def block_term(s, m, t):
  4. s.add(t != m.eval(t, model_completion=True))
  5. def fix_term(s, m, t):
  6. s.add(t == m.eval(t, model_completion=True))
  7. def all_smt_rec(terms):
  8. if sat == s.check():
  9. m = s.model()
  10. yield m
  11. for i in range(len(terms)):
  12. s.push()
  13. block_term(s, m, terms[i])
  14. for j in range(i):
  15. fix_term(s, m, terms[j])
  16. yield from all_smt_rec(terms[i:])
  17. s.pop()
  18. yield from all_smt_rec(list(initial_terms))
  19. def main():
  20. s = Solver()
  21. # we use ints by normalizing all weights
  22. # (scaling them by 100, which does not change the result)
  23. products = [Int(f'g_{i}') for i in range(6)]
  24. max_weight = 1600
  25. weights = {
  26. 0: 240,
  27. 1: 275,
  28. 2: 335,
  29. 3: 355,
  30. 4: 420,
  31. 5: 580,
  32. }
  33. for i in range(6):
  34. # all products can be taken at least 0 times
  35. s.add(products[i] >= 0)
  36. # finally add the total weight constraint for problem
  37. s.add(sum([products[i] * weights[i] for i in range(6)]) == max_weight)
  38. # generate all models using all_smt for our products
  39. models = list(all_smt(s, products))
  40. print(f'there are {len(models)} models:')
  41. # finally we display our results
  42. for model in models:
  43. print(model)
  44. total = sum([model[products[i]] * weights[i] for i in range(6)])
  45. print(f'where {total == max_weight}')
  46. if __name__ == '__main__':
  47. main()