-
Notifications
You must be signed in to change notification settings - Fork 0
/
Main.py
119 lines (87 loc) · 2.69 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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import random
import argparse
import time
from BlocksWorldProblem import *
def generate_state(n):
# Create n discrete blocks and shuffle them for the initial state
blocks = list(range(n))
random.shuffle(blocks)
# Number of stacks on table (at least 1, at most n)
s = random.randint(1, n)
# Number of placed blocks
p = 0
# List of stacks of blocks
state = []
# Randomly fill the s - 1 first stacks
for i in range(s - 1):
stack = []
m = min(n - p, (n - p) - (s - i) + 1)
b = random.randint(1, m)
for j in range(b):
let = chr(ord('A') + blocks[p + j])
stack.append(let)
state.append(stack)
p = p + b
# Fill the s (last) stack
stack = []
for j in range(n - p):
let = chr(ord('A') + blocks[p + j])
stack.append(let)
state.append(stack)
state = [tuple(i) for i in state]
state = tuple(state)
return state
#_______________________________________________________________________
def print_state(state):
maxlen = max(map(len,state))
stacks = [tuple(reversed(x)) for x in state]
for i in range(maxlen, 0, -1):
for stack in stacks:
if len(stack) >= i:
print(stack[i-1], end ='\t')
else:
print(" ", end ='\t')
print("")
#_______________________________________________________________________
random.seed()
parser = argparse.ArgumentParser(description='Blocks World Problem')
parser.add_argument("--number", "-n", help="set total number of blocks", type=int)
args = parser.parse_args()
error=False
if args.number:
if args.number < 1 or args.number > 26:
print("The number of blocks must be a positive integer in range [1,26]")
error=True
else:
print("You must provide the number of blocks (positive integer in range [1,26])")
error=True
if error:
sys.exit(1)
initial = generate_state(args.number)
goal = generate_state(args.number)
p = BlocksWorldProblem(initial, goal)
print(" ")
print("Initial State: ", initial)
print_state(initial)
print(" ")
print("Unique Goal State: ", goal)
print_state(goal)
print(" ")
start = time.time()
s = astar_search(p)
end = time.time()
hours, rem = divmod(end-start, 3600)
minutes, seconds = divmod(rem, 60)
print("Elapsed time: {:0>2}:{:0>2}:{:05.2f}".format(int(hours),int(minutes),seconds))
print(" ")
sol = s.solution() # The sequence of actions to go from the root to this node
path = s.path() # The nodes that form the path from the root to this node
print("Solution: \n+{0}+\n|Action\t|\t\tState\t\t\t|Path Cost |\n+{0}+".format('-'*58))
for i in range(len(path)) :
state = path[i].state
cost = path[i].path_cost
action = "-"
if i > 0 : # The initial state has not an action that results to it
action = sol[i-1]
print("|{0}\t|{1}\t|{2}\t|".format(action, state, cost))
print("+{0}+".format('-'*42))