-
Notifications
You must be signed in to change notification settings - Fork 0
/
module2.py
212 lines (161 loc) · 6.9 KB
/
module2.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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
#!/usr/bin/python
# -*- coding: utf-8 -*-
from common.astargac import AStarGAC
from common.gac import GAC
from common.gacstate import GACState
from common.printer import Printer
from common.makefunc import makefunc
from module2.constraint import Constraint
from module2.gui import Gui
from module2.variable import Variable
import os
import glob
import platform
class Module2Runner:
def __init__(self):
self.astar_gac = AStarGAC()
# This method is just used to print the introduction and chose the parser
self.start()
def start(self):
# Print introduction lines
Module2Runner.print_introduction()
# Present different parser options
self.parse_files()
@staticmethod
def print_introduction():
Printer.print_border_top()
Printer.print_content('IT3105 :: Module 2 :: GAC + A*')
Printer.print_border_middle()
def parse_files(self):
# Set to None to avoid "referenced before assigned" complaint
input_choice_graph = None
input_choice_k = None
# Get all boards from directory
graphs = glob.glob('module2/graphs/*.txt')
# Present different graphs to the user
while True:
Printer.print_content('Available graphs: ')
Printer.print_border_middle()
# Print list of boards
idx = 0
for b in graphs:
Printer.print_content('[' + str(idx) + ']: ' + b, align='left')
idx += 1
Printer.print_border_bottom()
# Get the user input
input_choice_graph = raw_input('[0-' + str(len(graphs) - 1) + ']: ')
Printer.print_newline()
# Validate input
try:
input_choice_graph = int(input_choice_graph)
if input_choice_graph < 0 or input_choice_graph >= len(graphs):
raise AssertionError('')
break
except (AssertionError, ValueError):
Printer.print_border_top()
Printer.print_content('Invalid input, try again')
Printer.print_border_middle()
# Get suggested K value for this graph
graph_suggested_k = None
graph_suggested_k_temp = graphs[input_choice_graph].split('.')[0].split('-')[-1]
if 'k' in graph_suggested_k_temp:
graph_suggested_k = int(graph_suggested_k_temp.replace('k', ''))
# Get the K value
Printer.print_border_top()
while True:
if graph_suggested_k is not None:
Printer.print_content('Set K value for this graph, suggested value is ' + str(graph_suggested_k))
else:
Printer.print_content('Set K value for this graph')
Printer.print_border_bottom()
# Get the user input
input_choice_k = raw_input('[4-9]: ')
Printer.print_newline()
# Validate input
try:
input_choice_k = int(input_choice_k)
if input_choice_k < 4 or input_choice_k > 9:
raise AssertionError('')
break
except (AssertionError, ValueError):
Printer.print_border_top()
Printer.print_content('Invalid input, try again')
Printer.print_border_middle()
# Parse the file the user chose
self.parse_file(str(graphs[input_choice_graph]), input_choice_k)
def parse_file(self, file_name, k_value):
gac = GAC()
# Read all lines in the file while stripping the ending newline
lines = [line.rstrip('\n') for line in open(file_name)]
vertices_and_edges = map(int, lines[0].split(' '))
# Create vertices
for i in range(1, vertices_and_edges[0] + 1):
# Get the state
state = map(float, lines[i].split(' '))
# Init new Node and set the correct values
variable = Variable(i)
variable.state = (state[1], state[2])
variable.domain = range(k_value)
# Add node to CSP class
gac.variables.append(variable)
# Create constraints
for i in range(vertices_and_edges[0] + 1, len(lines)):
new_constraint = Constraint()
# Set the correct constraint
new_constraint.method = makefunc(['n'], 'n[0] != n[1]')
# Get the constraint line
constraint_line = map(int, lines[i].split(' '))
# Loop all vars in the constraint
for var in constraint_line:
new_constraint.vars.append(var)
# Apply the new constraint to the list
GAC.Constraints.append(new_constraint)
# Set the correct gac for GACState
GACState.GAC = GAC
# Create the initial csp state
gac_state = GACState()
gac_state.gac = gac
gac_state.type = GACState.START
# Set the csp state to astar_gac
self.astar_gac.gac_state = gac_state
# Begin CSP
self.astar_gac.start()
# Run the GUI
self.run()
def run(self):
# Set reference to GAC
Gui.GAC = GAC
# Create new instance of GUI
gui = Gui()
# Set reference to AStarCSP here
gui.astar_gac = self.astar_gac
# Draw the initial drawing
gui.draw_once()
# If OS X, swap to TKInter window
if platform.system() == 'Darwin':
os.system('''/usr/bin/osascript -e 'tell app "Finder" to set frontmost of process "Python" to true' ''')
# Start the GUI
gui.after(0, gui.task)
# Start the event mainloop here
gui.mainloop()
# Set the terminal to the frontmost process (expects iTerm to be the chosen terminal)
if platform.system() == 'Darwin':
os.system('''/usr/bin/osascript -e 'tell app "Finder" to set frontmost of process "iTerm" to true' ''')
# Pretty print
Printer.print_border_top()
Printer.print_content('Counts')
Printer.print_border_middle()
# Get verticies without color
uncolored = 0
for var in gui.astar_gac.gac_state.gac.variables:
if len(var.domain) != 1:
uncolored += 1
# Print the stats
Printer.print_content('Unsatisfied constraints: ' + str(0), align='left') # If we get here it is impossible to have unsatisfied constraints
Printer.print_content('Vertices without color: ' + str(uncolored), align='left')
Printer.print_content('Nodes in search tree (A* generated states): ' + str(len(gui.astar_gac.astar.states)), align='left')
Printer.print_content('Nodes popped and expanded (A* open closed list): ' + str(len(gui.astar_gac.astar.closed)), align='left')
Printer.print_content('Solution path length: ' + str(len(gui.astar_gac.astar.goal_path())), align='left')
# Print closing border
Printer.print_border_bottom()
Module2Runner()