-
Notifications
You must be signed in to change notification settings - Fork 0
/
Astar_GAC.py
204 lines (204 loc) · 6.56 KB
/
Astar_GAC.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
import readfile as rf
import copy
import State
import time
import random
from collections import deque
#
algorithm_delay = 0
#
def create_dictionary(l):
d = {}
for n in xrange(l+1):
d[n] = []
return d
#
def add_states_to_dict(states, d):
for state in states:
try:
d[ state.get_heuristic() ].append( state )
except:
print "Algorithm failed - add_states_to_dict"
return False
return d
#
def generate_child_states2(state, constraints):
children = []
for index in state.nodes:
if len(state.nodes[index].domain) > 1:
for n in state.nodes[index].domain:
new_dict = copy.deepcopy(state.nodes)
new_dict[index].domain = [n]
temp_state = State.State(new_dict)
temp_state.set_assumption([index, n])
temp_state.set_parent(state)
children.append(temp_state)
if len(children)>=1:
return children
#
def get_best_state(all_states): #iterates and returns one state from the list with lowest heuristic
for i in all_states:
if all_states[i]:
return all_states[i][ random.randint(0, len(all_states[i])-1) ]
#
def create_GAC_constraint_queue(assumption, constraints):
queue = deque()
for C in constraints:
if C[0] == assumption:
queue.append( [C[1], C] )
elif C[1] == assumption:
queue.append( [C[0], C] )
return queue
#
def revice2(state, c):
if len(state.nodes[c[0]].domain) < 2:
return len(state.nodes[c[0]].domain)
elif c[0] == c[1][0] and len(state.nodes[c[1][1]].domain) == 1:
check_node = state.nodes[c[1][1]].domain[0]
elif c[0] == c[1][1] and len(state.nodes[c[1][0]].domain) == 1:
check_node = state.nodes[c[1][0]].domain[0]
else:
return len(state.nodes[c[0]].domain)
#
for change_node in state.nodes[c[0]].domain:
if change_node == check_node:
state.nodes[c[0]].domain.remove(change_node)
#print "changed node: ", state.nodes[c[0]].domain, "new len", len(state.nodes[c[0]].domain)
return len(state.nodes[c[0]].domain)
#
return len(state.nodes[c[0]].domain)
#
def extend_queue(x, constraints):
l = []
for C in constraints:
if C[0] == x:
l.append( [C[1], C] )
elif C[1] == x:
l.append( [C[0], C] )
return l
#
def Filter(state, queue, constraints):
while queue:
constraint = queue.popleft()#popper constraint fra ko
length_pre_revise = len(state.nodes[constraint[0]].domain)
length_post_revice = revice2(state, constraint)#kjorer revice paa constrainten som ble poppet
if length_pre_revise > length_post_revice:#hvis domenet har blitt forkortet maa nye constarints inn i ko
queue.extend( extend_queue(constraint[0], constraints) )
#
def is_valid_state(state, constraints):
unsatisfied_constraints = 0
for node in state.nodes:
if len(state.nodes[node].domain) == 0:
return False
for C in constraints:
if len(state.nodes[C[0]].domain) == 1 and len(state.nodes[C[1]].domain) == 1:
if state.nodes[C[0]].domain[0] == state.nodes[C[1]].domain[0]:
unsatisfied_constraints += 1
return False, unsatisfied_constraints
return True, unsatisfied_constraints
#
def is_done(state, constraints):
for c in constraints:
if len(state.nodes[c[0]].domain) != 1:
return False
elif len(state.nodes[c[1]].domain) != 1:
return False
elif state.nodes[c[0]].domain[0] == state.nodes[c[1]].domain[0]:
return False
return True
#
def Astar(start_state, constraints):
print "Calculating..."
start_time = time.time()
if show_gui:
import gui
all_states = create_dictionary(start_state.get_heuristic())
#
start_state.set_assumption([0, 0])
start_state.nodes[0].domain = [0]
queue = create_GAC_constraint_queue(start_state.get_assumption()[0], constraints)
Filter(start_state, queue, constraints)
start_state.set_heuristic( start_state.calculate_heuristic() )
all_states[start_state.get_heuristic()].append(start_state)
#
current_state = start_state
assumptions = 0
nodes_expanded = 0
while True:
new_states = generate_child_states2(current_state, constraints)
assumptions += len(new_states)
#nodes_expanded += len(new_states)
if len(new_states) != 0:
valid_states = []
parent = new_states[0].get_parent()
all_states[parent.get_heuristic()].remove(parent)
for new_state in new_states:
queue = create_GAC_constraint_queue(new_state.get_assumption()[0], constraints)
Filter(new_state, queue, constraints)
state_is_valid, unsatisfied_constraints = is_valid_state(new_state, constraints)
if state_is_valid:
new_state.set_heuristic( new_state.calculate_heuristic() )
valid_states.append(new_state)
else:
parent.nodes[new_state.get_assumption()[0]].domain.remove(new_state.get_assumption()[1])
#
state_is_valid, unsatisfied_constraints = is_valid_state(new_state, constraints)
if state_is_valid:
parent.set_heuristic(parent.calculate_heuristic())
all_states[parent.get_heuristic()].append(parent)
#
all_states = add_states_to_dict(valid_states, all_states)
current_state = get_best_state(all_states)
nodes_expanded += 1
time.sleep(algorithm_delay)
#
if is_done(current_state, constraints):
print "Done\n\n"
print "Number of vertices without color: 0"
print "Number of nodes in tree: ", len(current_state.nodes)
print "Number of unsatisfied constraints: ", unsatisfied_constraints
print "assumptions done: ", assumptions
print "Nodes nodes_expanded: ", nodes_expanded
print "\n\n"
if show_gui:
gui.circle_matrix = gui.generate_circle_matrix(current_state)
gui.app.processEvents()
print("--- %s seconds ---" % (time.time() - start_time))
print ""
print "Press ENTER to close gui, input 'n' to keep it open"
stri = str(raw_input(""))
if not (stri=="n" or stri=="N"):
import subprocess
subprocess.call("taskkill /F /IM python.exe", shell=True)
for C in constraints:
print current_state.nodes[C[0]].domain, current_state.nodes[C[1]].domain
print("--- %s seconds ---" % (time.time() - start_time))
print "--------------------------------------------"
return True
#
if show_gui:
gui.circle_matrix = gui.generate_circle_matrix(current_state)
gui.app.processEvents()
# time.sleep(1)
else:
all_states[current_state.get_heuristic()].remove(current_state)
current_state = get_best_state(all_states)
nodes_expanded += 1
#
if is_done(current_state, constraints):
print "ER FERDIG"
for C in constraints:
print current_state.nodes[C[0]].domain, current_state.nodes[C[1]].domain
if show_gui:
gui.circle_matrix = gui.generate_circle_matrix(current_state)
gui.app.processEvents()
time.sleep(5)
return True
#
show_gui = True
def run(delay):
if not show_gui:
s, c = rf.read_graph("graph6.txt")
Astar(s, c)
else:
algorithm_delay = delay