class TestSearchNode(TestCase): def setUp(self): self.searcher = SearchNode() def test_search(self): node = Node() self.assertEqual(self.searcher.search(node), 0); def test_search_not_Node(self): node = "t" self.assertEqual(self.searcher.search(node), -1); def test_setKey(self): node = Node() node.setKey(5) self.assertEqual(node.key, 5) self.assertEqual(node.value, 25) def test_setKeyAndValue(self): node = Node() node.setKeyAndValue(5, 10) self.assertEqual(node.key, 5) self.assertEqual(node.value, 10) def test_searchSingle(self): node = Node() node.setKey(3) result = node.search(3) self.assertEqual(node.value, 9) def test_searchFullTwoLevel(self): node = Node() node.setKey(3) node11 = Node() node11.setKey(2) node.left = node11 node12 = Node() node12.setKey(4) node.right = node12 node21 = Node() node21.setKey(5) node11.left = node21 node22 = Node() node22.setKey(6) node11.right = node22 node23 = Node() node23.setKeyAndValue(7, 14) node12.left = node23 node24 = Node() node24.setKeyAndValue(8,16) node12.right = node24 self.assertEqual(node.search(7).value, 14)
def a_star(problem, heuristic): current_node = SearchNode(problem.start_node, None, 0) frontier = PriorityQueue() # elements of the priority queue are 2-element lists of the form (priority, data) frontier.put([0, current_node]) explored = set() while True: if frontier.empty(): return None queue_element = frontier.get() current_node = queue_element[1] current_node_path_cost = current_node.get_path_cost() # goal test if problem.goal_test(current_node.node): return current_node.to_path() # return solution as path # add node ID to explored set explored.add(current_node.node.id) for edge in current_node.node.edges(): child = None if edge.child().id != current_node.node.id: child = edge.child() elif not edge.directed( ) and edge.parent().id != current_node.node.id: child = edge.parent() if child is not None: weight = float(edge['weight']) child_node = SearchNode(child, current_node, weight) child_path_cost = current_node_path_cost + weight fn = child_path_cost + heuristic(problem, child) # check that child is not in explored or frontier child_in_explored = child.id in explored child_in_frontier = False for item in frontier.queue: if item[1].node.id == child.id: child_in_frontier = True # if the child has a lower evaluation, replace the frontier node with child if fn < item[0]: item[0] = fn item[1] = child_node if not child_in_explored and not child_in_frontier: frontier.put([fn, child_node])
def __node_exist_or_create(self, node: str) -> None: """ Create node if it doesn't exist in graph :param node: node name :return: """ if node not in self.__nodes: self.__nodes[node] = SearchNode(node)
def from_parent(cls, parent): """ Factory method to create a shallow copy of the parent node with depth one greater and with the given parent node. :param parent: parent of new child node :return: a shallow copy of the parent node with depth one greater and with the given parent node """ child = SearchNode.from_parent(parent) child.grid = [[card for card in row] for row in parent.grid] return child
def test_queue_push(self): A = SearchNode('A') stack = SearchStack() result = stack.push(A) self.assertTrue(result) self.assertEquals(len(stack), 1) stack.push(A) self.assertEquals(len(stack), 1)
def test_queue_push(self): A = SearchNode('A') queue = SearchPriorityQueue() result = queue.push(A) self.assertTrue(result) self.assertEquals(len(queue), 1) queue.push(A) self.assertEquals(len(queue), 2)
def path_cost(self, end_node: SearchNode) -> float: """ Find the path cost given the end node (Two traversals of the path) :param end_node: :return: """ # Find path from last node path = self.get_path(end_node) if len(path) > 1: # Get the cost return SearchNode.cost(path[0], path[1:]) else: return 0
def test_advanced_pushpop(self): A = SearchNode('A') stack = SearchStack() result = stack.push(A) self.assertTrue(result) self.assertEquals(len(stack), 1) stack.push(A) self.assertEquals(len(stack), 1) stack.pop() stack.push(A) self.assertEquals(len(stack), 0)
def test_breadth_first_search(self): print('Test breadth') text = 'A B 1\nB C 1\nC B 1'.split('\n') search = SearchAlgo(text) path = search.breadth('A', 'C') known_path = ['A', 'B', 'C'] known_cost = 2 for idx, node in enumerate(path): self.assertEquals(node.name, known_path[idx]) self.assertEquals(SearchNode.cost(path[0], path[1:]), known_cost) path = search.breadth('C', 'C') self.assertEquals(len(path), 1) self.assertEquals(path[0].name, 'C')
def test_breadth_first_search(self): print("Test breadth") text = "A B 1\nB C 1\nC B 1".split("\n") search = SearchAlgo(text) path = search.breadth("A", "C") known_path = ["A", "B", "C"] known_cost = 2 for idx, node in enumerate(path): self.assertEquals(node.name, known_path[idx]) self.assertEquals(SearchNode.cost(path[0], path[1:]), known_cost) path = search.breadth("C", "C") self.assertEquals(len(path), 1) self.assertEquals(path[0].name, "C")
def Search(problem, strategy): global nodes global visitedStates visitedStates = [] nodes = queue.Queue() rootNode = SearchNode(problem.initialState, 0, 0, None, None) nodes.put(rootNode) while nodes.empty() == False: newNodes = queue.Queue() node = nodes.get() if problem.goalTestFunction(node.state): #GOAL return node childNodes = node.expand(problem.operators) for node in childNodes: if (tracker.stateExist(node.state, visitedStates) == False): newNodes.put(node) visitedStates.append(node.state) Queueingfunction(newNodes, strategy, problem) return
def bfs(problem): current_node = SearchNode(problem.start_node, None, 0) # check for solution if problem.goal_test(current_node.node): return current_node.to_path() # initialize frontier and explored set frontier = Queue() frontier.put(current_node) explored = set() while True: if frontier.empty(): return None current_node = frontier.get() # add node ID to explored set explored.add(current_node.node.id) for edge in current_node.node.edges(): child = None """ Some explanation is warranted here. Consider an edge (a, b). When iterating over the edges of node b, (a, b) will show up as an edge. If the edge is directed, then node a should not be considered a "child" of b However, if the edge is undirected, then node a IS a child of b """ if edge.child().id != current_node.node.id: child = edge.child() elif not edge.directed( ) and edge.parent().id != current_node.node.id: child = edge.parent() if child is not None: weight = float(edge['weight']) child_node = SearchNode(child, current_node, weight) # check that child is not in explored or frontier child_found = False for item in frontier.queue: if item.node.id == child.id: child_found = True if child.id in explored: child_found = True if not child_found: # goal test if problem.goal_test(child): return child_node.to_path() # insert child into the frontier frontier.put(child_node)
def best_first_search(self, start): self.openlist.append(start) # add to openlist while self.openlist: #print [x.State for x in self.openlist] #time.sleep(0.05) current = self.choosePop() # current is the node with the lowest f-value ( A-star). dfs=last in list bfs = first in list if self.onNodeupdate: self.onNodeupdate(current,self.closedlist,self.openlist) #if current node is the same as the goal node. We have found our path. #now retrace our path. if current.isFinished(): path = self.retracepath(current) generatednodes = len(self.openlist) + len(self.closedlist) #print path if self.pathDoneUpdate: self.pathDoneUpdate(path, generatednodes) return path self.closedlist.add(current) # adds current node to closed succecors = SearchNode.genereateChildren(current) # generating children # All the generated children for child in succecors: # iterate through the children if child.generatehash() in self.createdDict: # if generated before child = self.createdDict[child.generatehash()] if (current.g + current.cost) < child.g: # then found cheaper path to S child.setparent(current) if child in self.closedlist: self.propagatepathimprovement(child) else: # if not generated before self.createdDict[child.generatehash()] = child self.openlist.append(child) astar.ExpandedNodes +=1
def test_advanced_pushpop(self): A = SearchNode('A') queue = SearchPriorityQueue() result = queue.push(A) self.assertTrue(result) self.assertEquals(len(queue), 1) queue.push(A) self.assertEquals(len(queue), 2) queue.pop() queue.push(A) self.assertEquals(len(queue), 1) # Should pop other A and not return result = queue.pop() self.assertIsNone(result) self.assertEquals(len(queue), 0)
def push(self, node: SearchNode, placed_by: SearchNode = None) -> bool: """ Push node onto priority queue :param node: :param placed_by: :return: """ if node.name in self.visited: return False # Find cost of node we're pushing (TODO: Make less expensive to do this) cost = 0.0 if placed_by: pcost = self.path_cost(placed_by) wcost = placed_by.weight(node.name) cost = pcost + wcost # Append to queue self.structure.append((node, placed_by, cost)) # Sort structure on the 3rd item (cost) self.structure.sort(key=lambda tup: tup[2]) return True
def dfs(problem, depth_limit=-1): start_node = SearchNode(problem.start_node, None, 0) return dfs_recursive(start_node, problem, depth_limit)
def setUp(self): self.searcher = SearchNode()
elif search == 'ucs' or search == 'A*' or search == 'gbfs': dangerous_rooms = {} #dictionary of (state, path_cost) new_room = raw_input("Dangerous Room r c cost: ") while new_room: dr, dc, dcost = new_room.split() dangerous_rooms[(int(dr), int(dc))] = dcost new_room = raw_input("Dangerous Room r c cost: ") problem.dangerous_rooms = dangerous_rooms fringe = UCSFringe() elif search == 'iddfs': fringe = IDDFS(max_depth=maze.rows * maze.cols) else: raise Exception('invalid search') closed_list = SetClosedListWithCompression() initial_node = SearchNode(initial_state) if search == 'iddfs': initial_node.path_cost = 0 fringe.initial_node = initial_node fringe.closed_list = closed_list fringe.view0 = view0 fringe.put(initial_node) solution = graph_search(problem=problem, Node=initial_node, fringe=fringe, closed_list=closed_list, view0=view0) #============================================================================== # DO NOT CHANGE ANYTHING IN THIS SECTION.
def test_placed_by(self): A = SearchNode('A') B = SearchNode('B') C = SearchNode('C') D = SearchNode('D') queue = SearchPriorityQueue() A.add_link(B, 40) A.add_link(C, 1) A.add_link(D, 20) queue.push(A) queue.push(B, A) queue.push(C, A) queue.push(D, A) node = queue.pop() self.assertIsNone(queue.placed_by(node.name)) node = queue.pop() # C has shortest distance, self.assertEquals(node.name, 'C') self.assertEquals(queue.placed_by(node.name).name, 'A')
self.put(self.initial_node) def get(self): node = self.deque.pop() self.set.remove(node.state) if len(self) == 0: self.reset() return node if __name__ == '__main__': from SearchNode import SearchNode print "Testing stackfringe with search nodes from (0,0) -> (1,0) -> (1,1) by actions ['E', 'S']" fringe = Stack() state00 = (0, 0) node00 = SearchNode(state00) state01 = (0, 1) node01 = SearchNode(state01, node00, 'E', 1) state11 = (1, 1) node11 = SearchNode(state11, node01, 'S', 1) print(node00) print(node01) print(node11) print(fringe) fringe.put(node00) print(node00 in fringe) print(node01 in fringe) print(node11 in fringe) print(fringe)