def IterativeDFS(OPEN, limit): global COUNT, BACKLINKS, MAX_OPEN_LENGTH while OPEN != []: report(OPEN, COUNT) if len(OPEN) > MAX_OPEN_LENGTH: MAX_OPEN_LENGTH = len(OPEN) S = OPEN.pop(0) if Problem.GOAL_TEST(S): print(Problem.GOAL_MESSAGE_FUNCTION(S)) path = backtrace(S) print('Length of solution path found: ' + str(len(path) - 1) + ' edges') return True elif limit == 0: COUNT = COUNT - 1 return 'cutoff' L = [] for op in Problem.OPERATORS: if op.precond(S): COUNT += 1 new_state = op.state_transf(S) L.append(new_state) if (new_state in BACKLINKS) == False: BACKLINKS[new_state] = S result = IterativeDFS(L, limit - 1) if result == True: return True
def IterativeAStar(initial_state): global COUNT, BACKLINKS OPEN = [initial_state] CLOSED = [] BACKLINKS[Problem.HASHCODE(initial_state)] = -1 distance = {Problem.HASHCODE(initial_state): 0} while OPEN != []: S = OPEN[0] del OPEN[0] CLOSED.append(S) if Problem.GOAL_TEST(S): print(Problem.GOAL_MESSAGE_FUNCTION(S)) backtrace(S) return COUNT += 1 if (COUNT % 32) == 0: print(".", end="") if (COUNT % 128) == 0: print("COUNT = " + str(COUNT)) print("len(OPEN)=" + str(len(OPEN))) print("len(CLOSED)=" + str(len(CLOSED))) L = [] for op in Problem.OPERATORS: # Optionally uncomment the following when debugging # a new problem formulation. # print("Trying operator: "+op.name) if op.precond(S): new_state = op.state_transf(S) if not occurs_in(new_state, CLOSED): L.append(new_state) BACKLINKS[Problem.HASHCODE(new_state)] = S distance[Problem.HASHCODE( new_state)] = distance[Problem.HASHCODE(S)] + 1 # Uncomment for debugging: # print(Problem.DESCRIBE_STATE(new_state)) for s2 in L: for i in range(len(OPEN)): if Problem.DEEP_EQUALS(s2, OPEN[i]): del OPEN[i] break OPEN = L + OPEN OPEN = sorted( OPEN, key=lambda state: sort(state) + distance[Problem.HASHCODE(state)])
def BFS(initial_state): global COUNT, BACKLINKS, MAX_OPEN_LENGTH # STEP 1. Put the start state on a list OPEN OPEN = [initial_state] CLOSED = [] BACKLINKS[initial_state] = None # STEP 2. If OPEN is empty, output “DONE” and stop. while OPEN != []: report(OPEN, CLOSED, COUNT) if len(OPEN) > MAX_OPEN_LENGTH: MAX_OPEN_LENGTH = len(OPEN) # STEP 3. Select the first state on OPEN and call it S. # Delete S from OPEN. # Put S on CLOSED. # If S is a goal state, output its description S = OPEN.pop(0) CLOSED.append(S) if Problem.GOAL_TEST(S): print(Problem.GOAL_MESSAGE_FUNCTION(S)) path = backtrace(S) print('Length of solution path found: ' + str(len(path) - 1) + ' edges') return COUNT += 1 # STEP 4. Generate the list L of successors of S and delete # from L those states already appearing on CLOSED. L = [] for op in Problem.OPERATORS: if op.precond(S): new_state = op.state_transf(S) if not (new_state in CLOSED): L.append(new_state) if new_state not in BACKLINKS: BACKLINKS[new_state] = S # STEP 5. Delete from L any members of OPEN that occur on L. # Insert all members of L at the back of OPEN. for o in OPEN: for i in range(len(L)): if o == L[i]: del L[i] break OPEN = OPEN + L print_state_list("OPEN", OPEN)
def UCS(initial_state): '''Uniform Cost Search. This is the actual algorithm.''' global g, COUNT, BACKLINKS, MAX_OPEN_LENGTH, CLOSED, TOTAL_COST CLOSED = [] BACKLINKS[initial_state] = None TOTAL_COST = 0 # The "Step" comments below help relate UCS's implementation to # those of Depth-First Search and Breadth-First Search. OPEN = My_Priority_Queue() OPEN.insert(initial_state, 0) g[initial_state] = 0.0 while OPEN != []: if VERBOSE: report(OPEN, CLOSED, COUNT) if len(OPEN) > MAX_OPEN_LENGTH: MAX_OPEN_LENGTH = len(OPEN) (S, P) = OPEN.delete_min() # print("In Step 3, returned from OPEN.delete_min with results (S,P)= ", (str(S), P)) CLOSED.append(S) if Problem.GOAL_TEST(S): print(Problem.GOAL_MESSAGE_FUNCTION(S)) path = backtrace(S) print('Length of solution path found: ' + str(len(path) - 1) + ' edges') TOTAL_COST = P return path COUNT += 1 for op in Problem.OPERATORS: if op.is_applicable(S): new_state = op.apply(S) new_distance = P + new_state.edge_distance(S) if OPEN.__contains__(new_state): if OPEN.__getitem__(new_state) > new_distance: OPEN.__delitem__(new_state) OPEN.insert(new_state, new_distance) BACKLINKS[new_state] = S else: try: CLOSED.index(new_state) except: OPEN.insert(new_state, new_distance) BACKLINKS[new_state] = S return None
def IterativeBFS(initial_state): global COUNT, BACKLINKS OPEN = [initial_state] CLOSED = [] BACKLINKS[Problem.HASHCODE(initial_state)] = -1 while OPEN != []: S = OPEN[0] del OPEN[0] CLOSED.append(S) if Problem.GOAL_TEST(S): print(Problem.GOAL_MESSAGE_FUNCTION(S)) backtrace(S) return COUNT += 1 if (COUNT % 32) == 0: print(".", end="") if (COUNT % 128) == 0: print("COUNT = " + str(COUNT)) print("len(OPEN)=" + str(len(OPEN))) print("len(CLOSED)=" + str(len(CLOSED))) L = [] for op in Problem.OPERATORS: #Optionally uncomment the following when debugging #a new problem formulation. #print("Trying operator: "+op.name) if op.precond(S): new_state = op.state_transf(S) if not occurs_in(new_state, CLOSED): L.append(new_state) #Uncomment for debugging: #print(Problem.DESCRIBE_STATE(new_state)) # Don't visit duplicates states L = removeDuplicates(L, CLOSED) L = removeDuplicates(L, OPEN) # Append new states to visit to the end OPEN = OPEN + L # Add all the new states to the backtrace for state in L: BACKLINKS[Problem.HASHCODE(state)] = S
def UCS(initial_state): '''Uniform Cost Search. This is the actual algorithm.''' global g, COUNT, BACKLINKS, MAX_OPEN_LENGTH, CLOSED, TOTAL_COST CLOSED = [] BACKLINKS[initial_state] = None # The "Step" comments below help relate UCS's implementation to # those of Depth-First Search and Breadth-First Search. # STEP 1a. Put the start state on a priority queue called OPEN OPEN = My_Priority_Queue() OPEN.insert(initial_state, 0) # STEP 1b. Assign g=0 to the start state. g[initial_state] = 0.0 # STEP 2. If OPEN is empty, output “DONE” and stop. while False: # ***STUDENTS CHANGE THIS CONDITION*** # LEAVE THE FOLLOWING CODE IN PLACE TO INSTRUMENT AND/OR DEBUG YOUR IMPLEMENTATION if VERBOSE: report(OPEN, CLOSED, COUNT) if len(OPEN) > MAX_OPEN_LENGTH: MAX_OPEN_LENGTH = len(OPEN) # STEP 3. Select the state on OPEN having lowest priority value and call it S. # Delete S from OPEN. # Put S on CLOSED. # If S is a goal state, output its description (S, P) = OPEN.delete_min() #print("In Step 3, returned from OPEN.delete_min with results (S,P)= ", (str(S), P)) CLOSED.append(S) if Problem.GOAL_TEST(S): pass # ***STUDENTS CHANGE THE BODY OF THIS IF.*** #HANDLE THE BACKTRACING, RECORDING THE SOLUTION AND TOTAL COST, # AND RETURN THE SOLUTION PATH, TOO. COUNT += 1 # STEP 4. Generate each successor of S # and if it is already on CLOSED, delete the new instance. # ***STUDENTS IMPLEMENT THE GENERATION AND HANDLING OF SUCCESSORS HERE, # USING THE GIVEN PRIORITY QUEUE FOR THE OPEN LIST, AND # DETERMINING THE SHORTEST DISTANCE KNOWN SO FAR FROM THE INITIAL STATE TO # EACH SUCCESSOR.*** # STEP 6. Go to Step 2. return None # No more states on OPEN, and no goal reached.
def IterativeDFS(initial_state): #print("In RecDFS, with depth_limit="+str(depth_limit)+", current_state is ") #print(Problem.DESCRIBE_STATE(current_state)) global COUNT, BACKLINKS OPEN = [initial_state] CLOSED = [] BACKLINKS[initial_state] = None while OPEN != []: S = OPEN.pop(0) CLOSED.append(S) if Problem.GOAL_TEST(S): print(Problem.GOAL_MESSAGE_FUNCTION(S)) backtrace(S) return COUNT += 1 #if (COUNT % 32)==0: if True: #print(".",end="") #if (COUNT % 128)==0: if True: print("COUNT = " + str(COUNT)) print("len(OPEN)=" + str(len(OPEN))) print("len(CLOSED)=" + str(len(CLOSED))) L = [] for op in Problem.OPERATORS: if op.precond(S): new_state = op.state_transf(S) if not occurs_in(new_state, CLOSED): L.append(new_state) BACKLINKS[new_state] = S #print(Problem.DESCRIBE_STATE(new_state)) for s2 in L: for i in range(len(OPEN)): if (s2 == OPEN[i]): del OPEN[i] break OPEN = L + OPEN print_state_list("OPEN", OPEN)
def IterativeBFS(initial_state): global COUNT, BACKLINKS OPEN = [initial_state] CLOSED = [] BACKLINKS[initial_state] = None while OPEN != []: S = OPEN.pop(0) CLOSED.append(S) # DO NOT CHANGE THIS SECTION # the goal test, return path if reached goal if Problem.GOAL_TEST(S): print("\n" + Problem.GOAL_MESSAGE_FUNCTION(S)) backtrace(S) path = backtrace(S) return path, Problem.PROBLEM_NAME # DO NOT CHANGE THE CODE ABOVE # TODO: finish BFS implementation COUNT += 1 #if(COUNT % 32) == 0: if True: #print(".", end = "") #if (COUNT %128) == 0: if True: print("COUNT = " + str(COUNT)) print("len(OPEN) = " + str(len(OPEN))) print("len(CLOSED) = " + str(len(CLOSED))) L = [] for op in Problem.OPERATORS: if op.precond(S): new_state = op.state_transf(S) if not (new_state in CLOSED): if not (new_state in OPEN): L.append(new_state) BACKLINKS[new_state] = S OPEN = OPEN + L print_state_list("OPEN", OPEN)
def IterativeDFS(initial_state): global COUNT, BACKLINKS OPEN = [initial_state] CLOSED = [] BACKLINKS[initial_state] = -1 while OPEN != []: S = OPEN[0] del OPEN[0] CLOSED.append(S) if Problem.GOAL_TEST(S): print("\n" + Problem.GOAL_MESSAGE_FUNCTION(S)) backtrace(S) return COUNT += 1 if (COUNT % 32) == 0: #print(".",end="") if (COUNT % 128) == 0: print("COUNT = " + str(COUNT)) print("len(OPEN)=" + str(len(OPEN))) print("len(CLOSED)=" + str(len(CLOSED))) L = [] for op in Problem.OPERATORS: #Optionally uncomment the following when debugging #a new problem formulation. #print("Trying operator: "+op.name) if op.precond(S): new_state = op.state_transf(S) if not (new_state in OPEN) and not (new_state in CLOSED): L.append(new_state) BACKLINKS[new_state] = S #Uncomment for debugging: print(new_state) OPEN = L + OPEN print(len(OPEN))
def UCS(initial_state): '''Uniform Cost Search. This is the actual algorithm.''' global g, COUNT, BACKLINKS, MAX_OPEN_LENGTH, CLOSED, TOTAL_COST CLOSED = [] BACKLINKS[initial_state] = None # The "Step" comments below help relate UCS's implementation to # those of Depth-First Search and Breadth-First Search. # STEP 1a. Put the start state on a priority queue called OPEN OPEN = My_Priority_Queue() OPEN.insert(initial_state, 0) # STEP 1b. Assign g=0 to the start state. g[initial_state] = 0.0 # STEP 2. If OPEN is empty, output “DONE” and stop. while OPEN.__len__() > 0: # ***STUDENTS CHANGE THIS CONDITION*** # LEAVE THE FOLLOWING CODE IN PLACE TO INSTRUMENT AND/OR DEBUG YOUR IMPLEMENTATION if VERBOSE: report(OPEN, CLOSED, COUNT) if len(OPEN) > MAX_OPEN_LENGTH: MAX_OPEN_LENGTH = len(OPEN) # STEP 3. Select the state on OPEN having lowest priority value and call it S. # Delete S from OPEN. # Put S on CLOSED. # If S is a goal state, output its description (S, P) = OPEN.delete_min() #print("In Step 3, returned from OPEN.delete_min with results (S,P)= ", (str(S), P)) CLOSED.append(S) if Problem.GOAL_TEST(S): # ***STUDENTS CHANGE THE BODY OF THIS IF.*** #HANDLE THE BACKTRACING, RECORDING THE SOLUTION AND TOTAL COST, # AND RETURN THE SOLUTION PATH, TOO. print(Problem.GOAL_MESSAGE_FUNCTION(S)) path = backtrace(S) if len(path) < 2: TOTAL_COST = 0 else: TOTAL_COST = path[0].edge_distance(path[1]) for i in range(2, len(path)): TOTAL_COST += path[i - 1].edge_distance(path[i]) print('Total cost of solution path found: ' + str(TOTAL_COST)) return path COUNT += 1 # STEP 4. Generate each successor of S # and if it is already on CLOSED, delete the new instance. for op in Problem.OPERATORS: if op.precond(S): new_state = op.state_transf(S) if not (new_state in CLOSED): new_state_cost = g[S] + S.edge_distance(new_state) if new_state not in g or g[new_state] > new_state_cost: g[new_state] = new_state_cost BACKLINKS[new_state] = S if OPEN.__contains__(new_state): if OPEN.__getitem__(new_state) > new_state_cost: OPEN.__delitem__(new_state) OPEN.insert(new_state, new_state_cost) else: OPEN.insert(new_state, new_state_cost) # ***STUDENTS IMPLEMENT THE GENERATION AND HANDLING OF SUCCESSORS HERE, # USING THE GIVEN PRIORITY QUEUE FOR THE OPEN LIST, AND # DETERMINING THE SHORTEST DISTANCE KNOWN SO FAR FROM THE INITIAL STATE TO # EACH SUCCESSOR.*** # STEP 6. Go to Step 2. return None # No more states on OPEN, and no goal reached.
def AStar(initial_state): '''Uniform Cost Search. This is the actual algorithm.''' global g, COUNT, BACKLINKS, MAX_OPEN_LENGTH, CLOSED, TOTAL_COST CLOSED = [] BACKLINKS[initial_state] = None # The "Step" comments below help relate AStar's implementation to # those of Depth-First Search and Breadth-First Search. # STEP 1a. Put the start state on a priority queue called OPEN OPEN = My_Priority_Queue() OPEN.insert(initial_state, 0) # STEP 1b. Assign g=0 to the start state. g[initial_state]=0.0 # STEP 2. If OPEN is empty, output “DONE” and stop. while len(OPEN)>0: if VERBOSE: report(OPEN, CLOSED, COUNT) if len(OPEN)>MAX_OPEN_LENGTH: MAX_OPEN_LENGTH = len(OPEN) # STEP 3. Select the state on OPEN having lowest priority value and call it S. # Delete S from OPEN. # Put S on CLOSED. # If S is a goal state, output its description (S,P) = OPEN.delete_min() #print("In Step 3, returned from OPEN.delete_min with results (S,P)= ", (str(S), P)) CLOSED.append(S) if Problem.GOAL_TEST(S): print(Problem.GOAL_MESSAGE_FUNCTION(S)) path = backtrace(S) print('Length of solution path found: '+str(len(path)-1)+' edges') TOTAL_COST = g[S] print('Total cost of solution path found: '+str(TOTAL_COST)) return path COUNT += 1 # STEP 4. Generate each successors of S and delete # and if it is already on CLOSED, delete the new instance. gs = g[S] # Save the cost of getting to S in a variable. for op in Problem.OPERATORS: if op.precond(S): new_state = op.state_transf(S) if (new_state in CLOSED): #print("Already have this state, in CLOSED. del ...") del new_state continue edge_cost = S.edge_distance(new_state) new_g = gs + edge_cost test_g = gs + edge_cost + Problem.h(new_state) # If new_state already exists on OPEN: # If its new priority is less than its old priority, # update its priority on OPEN, and set its BACKLINK to S. # Else: forget out this new state object... delete it. if new_state in OPEN: #print("new_state is in OPEN already, so...") P = OPEN[new_state] if test_g < P: #print("New priority value is lower, so del older one") del OPEN[new_state] OPEN.insert(new_state, test_g) else: #print("Older one is better, so del new_state") del new_state continue else: #print("new_state was not on OPEN at all, so just put it on.") OPEN.insert(new_state, test_g) BACKLINKS[new_state] = S g[new_state] = new_g #print_state_queue("OPEN", OPEN) # STEP 6. Go to Step 2. return None # No more states on OPEN, and no goal reached.
def UCS(initial_state): '''Uniform Cost Search. This is the actual algorithm.''' global g, COUNT, BACKLINKS, MAX_OPEN_LENGTH, CLOSED, TOTAL_COST CLOSED = [] BACKLINKS[initial_state] = None # The "Step" comments below help relate UCS's implementation to # those of Depth-First Search and Breadth-First Search. # STEP 1a. Put the start state on a priority queue called OPEN OPEN = My_Priority_Queue() OPEN.insert(initial_state, 0) # STEP 1b. Assign g=0 to the start state. g[initial_state] = 0.0 # STEP 2. If OPEN is empty, output “DONE” and stop. while OPEN != []: # ***STUDENTS CHANGE THIS CONDITION*** # LEAVE THE FOLLOWING CODE IN PLACE TO INSTRUMENT AND/OR DEBUG YOUR IMPLEMENTATION if VERBOSE: report(OPEN, CLOSED, COUNT) if len(OPEN) > MAX_OPEN_LENGTH: MAX_OPEN_LENGTH = len(OPEN) # STEP 3. Select the state on OPEN having lowest priority value and call it S. # Delete S from OPEN. # Put S on CLOSED. # If S is a goal state, output its description (S, P) = OPEN.delete_min() #print("In Step 3, returned from OPEN.delete_min with results (S,P)= ", (str(S), P)) CLOSED.append(S) if Problem.GOAL_TEST(S): print(Problem.GOAL_MESSAGE_FUNCTION(S)) path = backtrace(S) TOTAL_COST = g[S] print('Length of solution path found: ' + str(len(path) - 1) + ' edges') print('The total cost is: ' + str(TOTAL_COST)) return #pass # ***STUDENTS CHANGE THE BODY OF THIS IF.*** #HANDLE THE BACKTRACING, RECORDING THE SOLUTION AND TOTAL COST, # AND RETURN THE SOLUTION PATH, TOO. COUNT += 1 # STEP 4. Generate each successor of S # and if it is already on CLOSED, delete the new instance. L = [] for op in Problem.OPERATORS: if op.precond(S): new_state = op.state_transf(S) if (new_state in OPEN): if (g[new_state] > g[S] + S.edge_distance(new_state)): g[new_state] = g[S] + S.edge_distance(new_state) BACKLINKS[new_state] = S elif not (new_state in CLOSED): print(g[S]) g[new_state] = g[S] + S.edge_distance(new_state) OPEN.insert(new_state, g[new_state]) BACKLINKS[new_state] = S for s2 in L: for (state, p) in OPEN.q: if (s2 == state): del OPEN[state] break for s3 in L: OPEN.insert(s3, g[s3]) # STEP 6. Go to Step 2. return 'None' # No more states on OPEN, and no goal reached.
def UCS(initial_state): '''Uniform Cost Search. This is the actual algorithm.''' global g, COUNT, BACKLINKS, MAX_OPEN_LENGTH, CLOSED, TOTAL_COST CLOSED = [] BACKLINKS[initial_state] = None # The "Step" comments below help relate UCS's implementation to # those of Depth-First Search and Breadth-First Search. # STEP 1a. Put the start state on a priority queue called OPEN OPEN = My_Priority_Queue() OPEN.insert(initial_state, 0) # STEP 1b. Assign g=0 to the start state. g[initial_state] = 0.0 # STEP 2. If OPEN is empty, output “DONE” and stop. while len(OPEN) > 0: # LEAVE THE FOLLOWING CODE IN PLACE TO INSTRUMENT AND/OR DEBUG YOUR IMPLEMENTATION if VERBOSE: report(OPEN, CLOSED, COUNT) if len(OPEN) > MAX_OPEN_LENGTH: MAX_OPEN_LENGTH = len(OPEN) # STEP 3. Select the state on OPEN having lowest priority value and call it S. # Delete S from OPEN. # Put S on CLOSED. # If S is a goal state, output its description (S, P) = OPEN.delete_min() # print("In Step 3, returned from OPEN.delete_min with results (S,P)= ", (str(S), P)) CLOSED.append(S) if Problem.GOAL_TEST(S): print(Problem.GOAL_MESSAGE_FUNCTION(S)) path = backtrace(S) print('Length of solution path found: ' + str(len(path) - 1) + ' edges') b0 = S e0 = 0 while b0 in BACKLINKS: if BACKLINKS[b0]: e0 += b0.edge_distance(BACKLINKS[b0]) b0 = BACKLINKS[b0] TOTAL_COST = e0 return path COUNT += 1 # STEP 4. Generate each successor of S # and if it is already on CLOSED, delete the new instance. # ***STUDENTS IMPLEMENT THE GENERATION AND HANDLING OF SUCCESSORS HERE, # USING THE GIVEN PRIORITY QUEUE FOR THE OPEN LIST, AND # DETERMINING THE SHORTEST DISTANCE KNOWN SO FAR FROM THE INITIAL STATE TO # EACH SUCCESSOR.*** for op in Problem.OPERATORS: if op.precond(S): new_state = op.state_transf(S) if not (new_state in CLOSED) and not OPEN.__contains__(new_state): b = S BACKLINKS[new_state] = S b = new_state e = 0 while b in BACKLINKS: if BACKLINKS[b]: e += b.edge_distance(BACKLINKS[b]) b = BACKLINKS[b] OPEN.insert(new_state, e) BACKLINKS[new_state] = S # STEP 6. Go to Step 2. return None # No more states on OPEN, and no goal reached.
def UCS(initial_state): '''Uniform Cost Search. This is the actual algorithm.''' global g, COUNT, BACKLINKS, MAX_OPEN_LENGTH, CLOSED, TOTAL_COST CLOSED = [] BACKLINKS[initial_state] = None # The "Step" comments below help relate UCS's implementation to # those of Depth-First Search and Breadth-First Search. # STEP 1a. Put the start state on a priority queue called OPEN OPEN = My_Priority_Queue() OPEN.insert(initial_state, 0) # STEP 1b. Assign g=0 to the start state. g[initial_state] = 0.0 # STEP 2. If OPEN is empty, output “DONE” and stop. while OPEN.__len__() != 0: # ***STUDENTS CHANGE THIS CONDITION*** # LEAVE THE FOLLOWING CODE IN PLACE TO INSTRUMENT AND/OR DEBUG YOUR IMPLEMENTATION if VERBOSE: report(OPEN, CLOSED, COUNT) if len(OPEN) > MAX_OPEN_LENGTH: MAX_OPEN_LENGTH = len(OPEN) # STEP 3. Select the state on OPEN having lowest priority value and call it S. # Delete S from OPEN. # Put S on CLOSED. # If S is a goal state, output its description (S, P) = OPEN.delete_min() #print("In Step 3, returned from OPEN.delete_min with results (S,P)= ", (str(S), P)) CLOSED.append(S) if Problem.GOAL_TEST(S): print(Problem.GOAL_MESSAGE_FUNCTION(S)) path = backtrace(S) print('Length of solution path found: ' + str(len(path) - 1) + 'edges') TOTAL_COST = P return path #pass # ***STUDENTS CHANGE THE BODY OF THIS IF.*** #HANDLE THE BACKTRACING, RECORDING THE SOLUTION AND TOTAL COST, # AND RETURN THE SOLUTION PATH, TOO. COUNT += 1 # STEP 4. Generate each successor of S # and if it is already on CLOSED, delete the new instance. # ***STUDENTS IMPLEMENT THE GENERATION AND HANDLING OF SUCCESSORS HERE, # USING THE GIVEN PRIORITY QUEUE FOR THE OPEN LIST, AND # DETERMINING THE SHORTEST DISTANCE KNOWN SO FAR FROM THE INITIAL STATE TO # EACH SUCCESSOR.*** for op in Problem.OPERATORS: if op.precond(S): new_state = op.state_transf(S) print(new_state) if not (new_state in CLOSED) and OPEN.__contains__(new_state) == False: OPEN.insert(new_state, P + S.edge_distance(new_state)) BACKLINKS[new_state] = S # STEP 5. Delete from OPEN any members of OPEN that occur on L. # Insert all members of L at the front of OPEN. #print_state_queue("OPEN", OPEN) print_state_queue('open', OPEN)
def a_star_search(initial_state): """A* search. This is the actual algorithm.""" global g, COUNT, BACKLINKS, MAX_OPEN_LENGTH, CLOSED, TOTAL_COST, f # We need to add g and f to the list of global variables used in the algorithm CLOSED = [] closed_values = {} # closed_values will track the f-value of closed states BACKLINKS[initial_state] = None # The "Step" comments below help relate UCS's implementation to # those of Depth-First Search and Breadth-First Search. # STEP 1a. Put the start state on a priority queue called open_ open_ = MyPriorityQueue() open_.insert(initial_state, h(initial_state)) # STEP 1b. Assign g=0 to the start state. g[initial_state] = 0.0 f[initial_state] = h(initial_state) # The f-value of the initial state is given entirely by its heuristic value. # STEP 2. If open_ is empty, output “DONE” and stop. while open_: if VERBOSE: report(open_, CLOSED, COUNT) if len(open_) > MAX_OPEN_LENGTH: MAX_OPEN_LENGTH = len(open_) # STEP 3. Select the state on open_ having lowest priority value and call it S. # Delete S from open_. # Put S on CLOSED. # If S is a goal state, output its description (S, p_) = open_.delete_min() # print("In Step 3, returned from open_.delete_min with results (S,P)= ", (str(S), P)) CLOSED.append(S) closed_values[S] = p_ # We store the f-value of the state, we put on closed, in closed_values if Problem.GOAL_TEST(S): print(Problem.GOAL_MESSAGE_FUNCTION(S)) path = backtrace(S) print('Length of solution path found: ' + str(len(path) - 1) + ' edges') TOTAL_COST = g[S] print('Total cost of solution path found: ' + str(TOTAL_COST)) return path COUNT += 1 # STEP 4. Generate each successors of S and delete # and if it is already on CLOSED, delete the new instance. gs = g[S] # Save the cost of getting to S in a variable. for op in Problem.OPERATORS: if op.precond(S): new_state = op.state_transf(S) edge_cost = S.edge_distance(new_state) new_g = gs + edge_cost new_f = new_g + h(new_state) # Additionally to the distance from the start, we also need to get the f-value of the new state, # given by the distance plus the heuristic value # Next we loop through closed... for i in range(len(CLOSED)): try: # and check if new_state already appears on closed. If so, we check which f-value is # lower and keep that element. if CLOSED[i] == new_state and closed_values[ CLOSED[i]] <= new_f: del new_state break elif CLOSED[i] == new_state and closed_values[ CLOSED[i]] > new_f: del closed_values[CLOSED[i]] # We need to make sure to also delete the entry in closed_values, which corresponds to # the deleted element. del CLOSED[i] except IndexError: # During debugging I ran into this error a few times. In the final version it no longer # occurs, but I will leave it in just in case. print( "Index i out of range when looping through closed.\ni = " + str(i) + "\nlen(CLOSED) = " + str(len(CLOSED))) continue # If new_state already exists on open_: # If its new priority is less than its old priority, # update its priority on open_, and set its BACKLINK to S. # Else: forget out this new state object... delete it. # if new_state in locals() or new_state in globals(): try: if new_state in open_: # print("new_state is in open_ already, so...") p2 = open_[new_state] if new_f < p2: # print("New priority value is lower, so del older one") del open_[new_state] open_.insert(new_state, new_f) # We need to insert new_f instead of new_g, in order for the algorithm to work properly. g[new_state] = new_g f[new_state] = new_f # It is crucial to only add the new values for g and f only down here to the dictionary, # as otherwise their values would also be written into the dictionary, if new_state # would be deleted instead of being added to open_. else: # print("Older one is better, so del new_state") del new_state continue else: # print("new_state was not on open_ at all, so just put it on.") open_.insert(new_state, new_f) g[new_state] = new_g f[new_state] = new_f # As stated above, we only now have to add new_f and new_g to the dictionary. BACKLINKS[new_state] = S except UnboundLocalError: # If we deleted new_state in line 190, because it already appeared on closed, # the program would crash when trying to check, if new_state is in open_. continue # print_state_queue("open_", open_) # STEP 6. Go to Step 2. return None # No more states on open_, and no goal reached.
def UCS(initial_state): '''Uniform Cost Search. This is the actual algorithm.''' global g, COUNT, BACKLINKS, MAX_OPEN_LENGTH, CLOSED, TOTAL_COST CLOSED = [] BACKLINKS[initial_state] = None # The "Step" comments below help relate UCS's implementation to # those of Depth-First Search and Breadth-First Search. # STEP 1a. Put the start state on a priority queue called OPEN OPEN = My_Priority_Queue() OPEN.insert(initial_state, 0) # STEP 1b. Assign g=0 to the start state. g[initial_state]=0.0 # STEP 2. If OPEN is empty, output “DONE” and stop. while OPEN != []: # ***STUDENTS CHANGE THIS CONDITION*** # LEAVE THE FOLLOWING CODE IN PLACE TO INSTRUMENT AND/OR DEBUG YOUR IMPLEMENTATION if VERBOSE: report(OPEN, CLOSED, COUNT) if len(OPEN)>MAX_OPEN_LENGTH: MAX_OPEN_LENGTH = len(OPEN) # STEP 3. Select the state on OPEN having lowest priority value and call it S. # Delete S from OPEN. # Put S on CLOSED. # If S is a goal state, output its description (S,P) = OPEN.delete_min() #print("In Step 3, returned from OPEN.delete_min with results (S,P)= ", (str(S), P)) distance = P CLOSED.append(S) if Problem.GOAL_TEST(S): print(Problem.GOAL_MESSAGE_FUNCTION(S)) path = backtrace(S) print('Length of solution path found: ' + str(len(path) - 1) + ' edges') print('The distance between start state and destination is:',str(distance)) return# ***STUDENTS CHANGE THE BODY OF THIS IF.*** #HANDLE THE BACKTRACING, RECORDING THE SOLUTION AND TOTAL COST, # AND RETURN THE SOLUTION PATH, TOO. COUNT += 1 # STEP 4. Generatex each successor of S # and if it is already on CLOSED, delete the new instance. # find links of s, and add them to open. # add backtrace # ***STUDENTS IMPLEMENT THE GENERATION AND HANDLING OF SUCCESSORS HERE, # USING THE GIVEN PRIORITY QUEUE FOR THE OPEN LIST, AND # DETERMINING THE SHORTEST DISTANCE KNOWN SO FAR FROM THE INITIAL STATE TO # EACH SUCCESSOR.*** if 'Eight Puzzle' in Problem.PROBLEM_NAME:#call problem's name to determine what method to use for dir in Problem.directions: if S.can_move(dir): new_S = S.move(dir) P = 1 if new_S not in CLOSED and new_S not in OPEN: BACKLINKS[new_S] = S g[new_S] = g[S] + P OPEN.insert(new_S, g[new_S]) elif 'France-Trip' in Problem.PROBLEM_NAME: i = 0 while True: # find out the # of neighbors(i) for S if not S.ith_neighbor_exists(i): for j in range(i): ne = S.move(j) # get neighbor name P = S.edge_distance(ne) # get distance to neighbor if ne not in CLOSED and ne not in OPEN: # make sure neighbor not in CLOSED BACKLINKS[ne] = S g[ne] = g[S] + P OPEN.insert(ne, g[ne]) break i += 1 # STEP 6. Go to Step 2. return None # No more states on OPEN, and no goal reached.