# 10-7-4 Water Jug Problem # Get 2 units of water in the 7-container or the 4-container # Starting state is (0,7,4) # Operations are F10, F7, F4, T107, T104, T710, T74, T410, T47 # Goal states are (x,2,z) and (x,y,2) operations = { 'F10' : lambda x, y, z: [10, y, z], 'F7' : lambda x, y, z: [x, 7, z], 'F4' : lambda x, y, z: [x, y, 4], 'T107' : lambda x, y, z: [0, y+x, z] if y+x<=7 else [x-(7-y), 7, z], 'T104' : lambda x, y, z: [0, y, z+x] if z+x<=4 else [x-(4-z), y, 4], 'T710' : lambda x, y, z: [x+y, 0, z] if x+y<=10 else [10, y-(10-x), z], 'T74' : lambda x, y, z: [x, 0, z+y] if z+y<=4 else [x, y-(4-z), 4], 'T410' : lambda x, y, z: [x+z, y, 0] if x+z<=10 else [10, y, z-(10-x)], 'T47' : lambda x, y, z: [x, y+z, 0] if y+z<=7 else [x, 7, z-(7-y)], } def dfs(state, visited, solution): solution.append(state) if state[1] == 2 or state[2] == 2: return True for (op, transition) in operations.items(): next = transition(*state) if str(next) not in visited and dfs(next, visited|{str(next)}, solution): return True solution.pop() return False solution = [] if dfs([0,7,4], set(), solution): print(solution)
A B C D E F G H ----------------------------- 0 - - - - - - - 1 - - 4 8 - - 3 - 4 7 7 - 4 4 7 5 - 4 7 5 8 6 6 6
1 2 1 A-------->B-------->C-------->D | | | 4 | 2 | | v 1 v 1 E F<--------G-------->H
$ python3 bellman_ford.py S A B C D E F G H I 0 - - - - - - - - - 0 7 - 6 - 6 5 - - - 0 7 11 5 8 6 4 - 9 - 0 7 11 5 7 6 4 9 7 - 0 7 11 5 7 6 4 8 7 8 0 7 11 5 7 6 4 8 7 7 0 7 11 5 7 6 4 8 7 7 0 7 11 5 7 6 4 8 7 7 0 7 11 5 7 6 4 8 7 7 0 7 11 5 7 6 4 8 7 7 0 7 11 5 7 6 4 8 7 7
Subset Sum, for positive integers.
import unittest
# This script illustrates subset summing using dynamic programming in Python.
#
# It turns out there is a way to do this in Python by brute-force using
# the built-in combinations function from itertools. It is very cool, and
# I thought you might love to see it. It works like this:
#
# from itertools import chain, combinations
#
# def has_subset_sum(s, k):
# for subset in chain.from_iterable(combinations(s, r) for r in range(len(s)+1)):
# if sum(subset) == k:
# return True
# return False
def has_subset_sum(s, k):
if len(s) == 0:
return k == 0
low = sum(x for x in s if x < 0)
high = sum(x for x in s if x > 0)
prev_table = [False] * (high - low +1)
for value in s:
table = prev_table[:]
for test_value in range(low, high+1):
index = test_value - low
if prev_table[index] or \
value == test_value or \
(0 < index-value < len(table) and prev_table[index-value]):
table[index] = True
if test_value == k:
return True
prev_table = table
return False
class SubsetSumTestCase(unittest.TestCase):
def test_it(self):
self.assertTrue(has_subset_sum(set([]), 0))
self.assertTrue(has_subset_sum({4}, 4))
self.assertFalse(has_subset_sum({4}, 8))
self.assertTrue(has_subset_sum({4, -1}, 4))
self.assertTrue(has_subset_sum({4, -1}, 3))
self.assertTrue(has_subset_sum({4, -1}, -1))
self.assertFalse(has_subset_sum({4, -1}, 40))
self.assertFalse(has_subset_sum({4, -1}, -80))
def test_a_specific_example(self):
s = {-3, -4, 1, 4}
for k in (-7, -6, -4, -3, -2, 0, 1, 2, 4, 5):
self.assertTrue(has_subset_sum(s, k))
for k in (-10, -9, -8, -5, -1, 3, 6, 7, 8, 9):
self.assertFalse(has_subset_sum(s, k))
unittest.main()