123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 |
- from z3 import *
- def all_smt(s, initial_terms):
- def block_term(s, m, t):
- s.add(t != m.eval(t, model_completion=True))
- def fix_term(s, m, t):
- s.add(t == m.eval(t, model_completion=True))
- def all_smt_rec(terms):
- if sat == s.check():
- m = s.model()
- yield m
- for i in range(len(terms)):
- s.push()
- block_term(s, m, terms[i])
- for j in range(i):
- fix_term(s, m, terms[j])
- yield from all_smt_rec(terms[i:])
- s.pop()
- yield from all_smt_rec(list(initial_terms))
- def main():
- s = Solver()
- # we use ints by normalizing all weights
- # (scaling them by 100, which does not change the result)
- products = [Int(f'g_{i}') for i in range(6)]
- max_weight = 1600
- weights = {
- 0: 240,
- 1: 275,
- 2: 335,
- 3: 355,
- 4: 420,
- 5: 580,
- }
- for i in range(6):
- # all products can be taken at least 0 times
- s.add(products[i] >= 0)
- # finally add the total weight constraint for problem
- s.add(sum([products[i] * weights[i] for i in range(6)]) == max_weight)
- # generate all models using all_smt for our products
- models = list(all_smt(s, products))
- print(f'there are {len(models)} models:')
- # finally we display our results
- for model in models:
- print(model)
- total = sum([model[products[i]] * weights[i] for i in range(6)])
- print(f'where {total == max_weight}')
- if __name__ == '__main__':
- main()
|