-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmain.py
97 lines (89 loc) · 3.73 KB
/
main.py
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
class WGC_Node:
incompatibilities = [
["c", "g", "w"],
["g", "w"],
["c", "g"]
]
def __init__(self, west=["w", "c", "g"], east=[], boat_side=False, children=[]):
self.west = west
self.east = east
self.boat_side = boat_side
self.children = children
def __str__(self):
return str(self.west) + str(self.east) + ("Left" if not self.boat_side else "Right")
def generate_children(self, previous_states, parent_map):
children = []
if not self.boat_side:
for i in self.west:
new_west = self.west[:]
new_west.remove(i)
new_east = self.east[:]
new_east.append(i)
if sorted(new_west) not in WGC_Node.incompatibilities and not WGC_Node.state_in_previous(previous_states, new_west, new_east, not self.boat_side):
child = WGC_Node(new_west, new_east, not self.boat_side, [])
children.append(child)
parent_map[child] = self
if sorted(self.west) not in WGC_Node.incompatibilities and not WGC_Node.state_in_previous(previous_states, self.west[:], self.east[:], not self.boat_side):
child = WGC_Node(self.west[:], self.east[:], not self.boat_side, [])
children.append(child)
parent_map[child] = self
else:
for i in self.east:
new_west = self.west[:]
new_west.append(i)
new_east = self.east[:]
new_east.remove(i)
if sorted(new_east) not in WGC_Node.incompatibilities and not WGC_Node.state_in_previous(previous_states, new_west, new_east, not self.boat_side):
child = WGC_Node(new_west, new_east, not self.boat_side, [])
children.append(child)
parent_map[child] = self
if sorted(self.east) not in WGC_Node.incompatibilities and not WGC_Node.state_in_previous(previous_states, self.west[:], self.east[:], not self.boat_side):
child = WGC_Node(self.west[:], self.east[:], not self.boat_side, [])
children.append(child)
parent_map[child] = self
self.children = children
@staticmethod
def state_in_previous(previous_states, west, east, boat_side):
return any(
sorted(west) == sorted(i.west) and
sorted(east) == sorted(i.east) and
boat_side == i.boat_side
for i in previous_states
)
def find_solution(root_node, use_bfs=False):
'''
Find a solution to the WGC Problem.
use_bfs: False for DFS, True for BFS
'''
to_visit = [root_node]
node = root_node
previous_states = []
parent_map = {root_node: None}
while to_visit:
node = to_visit.pop()
if not WGC_Node.state_in_previous(previous_states, node.west, node.east, node.boat_side):
previous_states.append(node)
node.generate_children(previous_states, parent_map)
if use_bfs:
to_visit = node.children + to_visit
else:
to_visit = to_visit + node.children
if sorted(node.east) == ["c", "g", "w"]:
solution = []
while node is not None:
solution = [node] + solution
node = parent_map[node]
return solution
return None
if __name__ == "__main__":
root = WGC_Node()
solution = find_solution(root, use_bfs=False)
print("DFS solution = [", end='')
for i in solution:
print(i, '\b, ', end='')
print("\b\b]")
solution = find_solution(root, use_bfs=True)
print("BFS solution = [", end='')
for i in solution:
print(i, '\b, ', end='')
print("\b\b]")