def expand(self, node): def proof_sum(children): return sum(c.pn for c in children) def disproof_min(children): return min(c.dpn for c in children) #print (node.proof,node.disproof,node.state.board) proof, disproof = self.findtable(node) # Terminate searching if not necessary, limit reached of TT limit reached if node.pn <= proof or node.dpn <= disproof or self.max_table_size <= self.get_size( ) or self.terminated: node.pn = proof node.dpn = disproof return # If node has no successors # check if game is finished self.evaluate_node(node) result = node.value if (result == 1 and node.node_type == "AND") or (result == 0 and node.node_type == "OR"): node.pn = float('inf') node.dpn = 0 self.putintable(node) return elif result in (1, 0): node.pn = 0 node.dpn = float('inf') self.putintable(node) return # Stored in transposition table to detect cycles self.putintable(node) children = [] # generate all children for a in node.state.allowed_actions(): new_state = node.state.perform_action(a) # find children in TT child_type = "AND" if node.node_type == "OR" else "OR" #child_node = Node(child_type,new_state,None,a) child_node = Node(node_type=child_type, state=new_state, parent=node, depth=node.depth + 1, action=a) child_proof, child_disproof = self.findtable(child_node) child_node.pn = child_proof child_node.dpn = child_disproof children.append(child_node) # iterative deepening, stop when TT max size is reached while node.pn > disproof_min(children) and node.dpn > proof_sum( children) and self.max_table_size > self.get_size( ) and not self.terminated: child, child_proof, child2_dpn = self.select_child(children) child.pn = node.dpn + child_proof - proof_sum(children) # e-trick if self.e: child.dpn = min(node.pn, child2_dpn * (1 + self.e)) else: child.dpn = min(node.pn, child2_dpn + 1) # Second level search if self.second_level and (not self.in_table(child)): res, size = self.second_level(child) if child.node_type == "OR": child.pn = res.pn child.dpn = res.dpn else: child.dpn = res.pn child.pn = res.dpn self.putintable(child, size=size) else: self.expand(child) # store search result node.pn = disproof_min(children) node.dpn = proof_sum(children) self.putintable(node)
def expand(self, node): def proof_sum(children): return sum(c.pn for c in children) def disproof_min(children): return min(c.dpn for c in children) #print (node.proof,node.disproof,node.state.board) proof, disproof = self.findtable(node) # Terminate searching if not necessary if proof == 0 or disproof == 0 or (proof >= node.pn and disproof >= node.dpn): node.pn = proof node.dpn = disproof return # If node has no successors # check if game is finished self.evaluate_node(node) result = node.value if (result == 1 and node.node_type == "AND") or (result == 0 and node.node_type == "OR"): node.pn = float('inf') node.dpn = 0 self.putintable(node) return elif result in (1, 0): node.pn = 0 node.dpn = float('inf') self.putintable(node) return # Stored in transposition table to avoid cycles self.putintable(node) # multiple iterative deepening while True: children = [] # generate all children for a in node.state.allowed_actions(): new_state = node.state.perform_action(a) # find children in TT child_type = "AND" if node.node_type == "OR" else "OR" child_node = Node(node_type=child_type, state=new_state, parent=node, depth=node.depth + 1, action=a) child_proof, child_disproof = self.findtable(child_node) child_node.pn = child_proof child_node.dpn = child_disproof children.append(child_node) if node.depth == 0: print([c.pn for c in children]) print([c.dpn for c in children]) print("_____") # terminate if thresholds reached if proof_sum(children) == 0 or disproof_min(children) == 0 or ( node.pn <= disproof_min(children) and node.dpn <= proof_sum(children)): node.pn = disproof_min(children) node.dpn = proof_sum(children) self.putintable(node) return proof = max(proof, disproof_min(children)) child = self.select_child(children, proof) if node.dpn > proof_sum(children) and ( child.pn <= child.dpn or node.pn <= disproof_min(children)): if self.e: child.pn *= (1 + self.e) else: child.pn += 1 else: if self.e: child.dpn *= (1 + self.e) else: child.dpn += 1 # Second level search if self.second_level and (not self.in_table(child)): res, size = self.second_level(child) if child.node_type == "OR": child.pn = res.pn child.dpn = res.dpn else: child.dpn = res.pn child.pn = res.dpn self.putintable(child, size=size) else: self.expand(child)
def expand(self, node, pn_threshold): c = self.findtable(node) # IF node already solved or pn exceeds threshold if c == 0 or c > pn_threshold: node.pn = c return # Initialize PN as 1 #if node.pn == None: node.pn = 1 # If node has no successors # check if game is finished self.evaluate_node(node) result = node.value if result == 0: node.pn = float('inf') self.putintable(node, pn_threshold) return elif result == 1: node.pn = 0 self.putintable(node, pn_threshold) return # Stored in transposition table to detect cycles self.putintable(node, pn_threshold) if node.node_type == "OR": # Recursive call of successor and nodes min_child = float('inf') for a in node.state.allowed_actions(): new_state = node.state.perform_action(a) child_node = Node(node_type="AND", state=new_state, parent=node, depth=node.depth + 1, action=a) self.expand(child_node, pn_threshold) min_child = min(min_child, child_node.pn) if child_node.pn == 0: break node.pn = min_child self.putintable(node, pn_threshold) return if node.node_type == "AND": # Dynamic evaluation child_pn = [] for a in node.state.allowed_actions(): new_state = node.state.perform_action(a) child_node = Node(node_type="OR", state=new_state, parent=node, depth=node.depth + 1, action=a) entry = self.findtable(child_node) child_pn.append(entry) if sum(child_pn) > pn_threshold: node.pn = sum(child_pn) self.putintable(node, pn_threshold) return # The recursive call of the successor OR nodes for i, a in enumerate(node.state.allowed_actions()): new_state = node.state.perform_action(a) # Recursive iterative deepening child_node = Node(node_type="OR", state=new_state, parent=node, depth=node.depth + 1, action=a) child_node.pn = 1 while child_node.pn != 0: self.expand(child_node, child_node.pn) # in case child is solved if child_node.pn == 0: break # if unsolved within threshold child_pn[i] = child_node.pn if sum(child_pn) > pn_threshold: node.pn = sum(child_pn) self.putintable(node, pn_threshold) return # All successor OR nodes of node n are solved node.pn = 0 self.putintable(node, pn_threshold) return