-
Notifications
You must be signed in to change notification settings - Fork 0
/
Fox, Goose, Bag of beans (DLS)
105 lines (88 loc) · 3.16 KB
/
Fox, Goose, Bag of beans (DLS)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import numpy as np
import collections
class Cannibals(object):
def __init__(self):
self.initial = np.array([1, 1, 1, 1])
self.goal = np.array([0, 0, 0, 0])
def actions(self, state):
possible = np.array([[0,0,1,1], [0,1,0,1], [1,0,0,1], [0,0,0,1]])
sending = 1 - 2 * state[3]
moves = []
for p in possible:
ns_ws = np.add(np.multiply(sending, p), state)
ns_rs = np.subtract(np.array([1, 1, 1, 1]), ns_ws)
if ns_ws[0] < 0: #no boat on left side
continue
if ns_rs[0] < 0: #no boat on the right side
continue
if ns_ws[3] == 0: #for when the farmer isn't present
if ns_ws[0] == 1 and ns_ws[1] == 1:
continue
if ns_ws[1] == 1 and ns_ws[2] == 1:
continue
if ns_rs[3] == 0:
if ns_rs[0] == 1 and ns_rs[1] == 1:
continue
if ns_rs[1] == 1 and ns_rs[2] == 1:
continue
moves.append(p)
return moves
def result(self, state, possible):
new_state = np.copy(state)
sending = 1 - 2 * state[3]
new_state = np.add(np.multiply(sending, possible), state)
return new_state
def goal_test(self, state):
return np.array_equal(state, self.goal)
class Node:
def __init__(self, state, parent=None, possible=None):
self.state = state
self.parent = parent
self.possible = possible
self.depth = 0
if parent:
self.depth = parent.depth + 1
def __repr__(self):
return "{}".format(self.state)
def child_node(self, problem, possible):
next_state = problem.result(self.state, possible)
next_node = Node(next_state, self, possible)
return next_node
def path(self):
node, path_back = self, []
while node:
path_back.append(node)
node = node.parent
return list(reversed(path_back))
def depth_limited_search(problem, limit):
def recursive_dls(node, problem, limit):
explored = []
if problem.goal_test(node.state):
return node.path()[1:]
elif limit == 0:
return 'cutoff'
else:
cutoff_occurred = False
for act in problem.actions(node.state):
child = node.child_node(problem, act)
result = recursive_dls(child, problem, limit - 1)
if result == 'cutoff':
cutoff_occurred = True
elif result is not None:
return result
return 'cutoff' if cutoff_occurred else None
return recursive_dls(Node(problem.initial), problem, limit)
def iterative_deepening_search(problem):
for depth in range(1, 12):
result = depth_limited_search(problem, depth)
if result != 'cutoff':
return result
def main():
move = 0
result = iterative_deepening_search(Cannibals())
if result != None:
for state in result:
move = move + 1
print("# of moves ", move, state)
if __name__ == "__main__":
main()