def test_equality(self): """ Examples of valid equality tests for NamedTuples """ p1 = Path.home() p2 = Path.cwd() n1a = TreeNode.new(p1) n1b = TreeNode.new(p1) n2a = TreeNode.new(p2) n2b = TreeNode.new(p2) for tn in (n1a, n1b, n2a, n2b): tn.add(Path("./data")) tn.add(Path("requirements.txt")) # NamedTuples implement compare assert n1a == n1b assert n1a != n1b._replace(files=[]) # Deep compare works case = "case_100" tn1 = Customs(case, FileType.PICKLE).read() tn2 = copy.deepcopy(tn1) assert tn1 == tn2 # Fragile - this is tied to case_100 dir list order tn2.dirs[16].dirs[0].files.append('foo') assert tn1 != tn2
def test_normalRamify_WithKeys(self): treeNode = TreeNode(1) treeNode.ramify(range(3), ['kid' + str(x) for x in range(3)]) self.assertEqual(treeNode.children, {'kid' + str(x): x for x in range(3)})
def next(self): self.head_node = self.head_q.get() str_world_state = str(self.head_node.world_state) if str_world_state not in self.explored_by_head: self.explored_by_head[str_world_state] = self.head_node self.expansion_count += 1 if str_world_state in self.explored_by_tail: self.tail_node = self.explored_by_tail[str_world_state] return False self.tail_node = self.tail_q.get() str_world_state = str(self.tail_node.world_state) if str_world_state not in self.explored_by_tail: self.explored_by_tail[str_world_state] = self.tail_node self.expansion_count += 1 if str_world_state in self.explored_by_head: self.head_node = self.explored_by_head[str_world_state] return False new_world_states = self.world.get_moves(self.head_node.world_state) for state in new_world_states: node = TreeNode(self.head_node, state) self.head_q.put(node) new_world_states = self.world.get_moves(self.tail_node.world_state) for state in new_world_states: node = TreeNode(self.tail_node, state) self.tail_q.put(node) return True
def main(): solver = Solution() for test in [[1, None, 2, None, None, 3]]: root = TreeNode() root.build_from_list(test) print(solver.preorderTraversal(root)) pass
def splitTree(self, node): """ according to best split feature, split datasets into multiple parts :@ param node: input Tree Node :@ rparam children of input node """ children = [] bestFeature = self.chooseSplitFeature(node) if bestFeature < 0: return children for key in node.uniformAttribute[bestFeature][1]: newDataSet = [] if key.startswith('<='): newDataSet = [ instance for instance in node.dataSet if instance[bestFeature] <= float(key.split('<= ')[1]) ] elif key.startswith('>'): newDataSet = [ instance for instance in node.dataSet if instance[bestFeature] > float(key.split('> ')[1]) ] else: newDataSet = [ instance for instance in node.dataSet if instance[bestFeature] == key ] newNode = TreeNode(newDataSet, copy.deepcopy(node.attribute), copy.deepcopy(node.classOutput)) newNode.splitFeatureName = node.attribute[bestFeature][0] newNode.splitFeatureValue = key children.append(newNode) return children
def test_errorRamify_childrenPresent(self): with self.assertRaises(Exception) as cm: treeNode = TreeNode(1) treeNode['child0'] = TreeNode(2) treeNode.ramify([1, 1]) self.assertEqual('Node already has 1 children', str(cm.exception))
def pruneTree(self, root: TreeNode) -> TreeNode: if not root: return None root.left = self.pruneTree(root.left) root.right = self.pruneTree(root.right) if root.val == 0 and not root.left and not root.right: return None return root
def __init__(self, centerPt=Point(0, 0, 'center'), dimension=1, max_points=1, max_depth=4): self.max_points = max_points self.max_depth = max_depth self.root = TreeNode(centerPt, dimension, max_points, max_depth, 0)
def test_errorSetItem_DifferentValueTypes(self): with self.assertRaises(Exception) as cm: treeNode = TreeNode(1) treeNode['child0'] = TreeNode(2.0) self.assertEqual( 'Parent and child nodes\' values must share the same type', str(cm.exception))
def build_from_traversals(preorder, inorder): if not preorder or not inorder: return None root_val = preorder[0] i = inorder.find(root_val) root = TreeNode(root_val) root.left = build_from_traversals(preorder[1:i+1], inorder[0:i]) root.right = build_from_traversals(preorder[i+1:], inorder[i+1:])
def build_from_traversals(preorder, inorder): if not preorder or not inorder: return None root_val = preorder[0] i = inorder.find(root_val) root = TreeNode(root_val) root.left = build_from_traversals(preorder[1:i + 1], inorder[0:i]) root.right = build_from_traversals(preorder[i + 1:], inorder[i + 1:])
def makeBalancedTree(nums): if not nums: return None midpoint = len(nums) / 2 node = TreeNode(nums[midpoint]) node.left = solution(nums[:midpoint]) node.right = solution(nums[(midpoint + 1):]) return node
def create_by_pre_order(values): value = values.pop(0) if value == 0: return None node = TreeNode(value=value) node.left = create_by_pre_order(values) node.right = create_by_pre_order(values) return node
def searchingByBFS(): #Pointing to the global variables global initialConfiguration global goalState global visitedNodes global nodesToExpand global success global stacksDoesntMatter #At the begin our current state is null actualNode = TreeNode(None, None, None, 0) #Creating the node for the initial configuration initialConfiguration = TreeNode(None, initialConfiguration, None, 0) #Initial state will be the first node to expand nodesToExpand.append(initialConfiguration) #Adding the first node to expand to the visited list visitedNodes.append(initialConfiguration.state) #Iterate while there are nodes to expand and the goal state has been not reached while (nodesToExpand and not (success)): actualNode = nodesToExpand.pop(0) visitedNodes.append(actualNode.state) if (isFinalState(actualNode.state)): success = actualNode return True #For the actual node, we need to expande it and check all the possible combinations for originStack in range(len(actualNode.state)): for destinationStack in range(len(actualNode.state)): expandedActualNode = copy.deepcopy(actualNode.state) #If origin is not empty, the origin and destination are different and the height in the destination is the correct #We can make a movement if (expandedActualNode[originStack] and originStack != destinationStack and len(expandedActualNode[destinationStack]) < maxHeight): #Remove from origin stack expandedActualNode[originStack].pop(0) #Add to destination stack expandedActualNode[destinationStack].append( actualNode.state[originStack][0]) #If the new state has not been visited if (not (visitedNodes.count(expandedActualNode))): #Calculate cost newCost = 1 + abs(originStack - destinationStack) + actualNode.cost #Create the new node newNode = TreeNode(actualNode, expandedActualNode, [originStack, destinationStack], newCost) #Add it as the list for expansion nodesToExpand.append(newNode) #Add it to the visited list #visitedNodes.append(newNode.state) return False
def deleteNode(self, root: TreeNode, key: int) -> TreeNode: """""" v_root = TreeNode(-1) v_root.right = root parent = v_root node = root while node: if node.val == key: break elif node.val > key: node = node.left else: node = node.right parent = node if not node: return root def find_max_from_left(node: TreeNode) -> TreeNode: """从BST树节点的左子树中找到值最大的节点""" if not node: return p = node node = node.left while node and node.right: p = node node = node.right p.right = None return node def find_min_from_right(node: TreeNode) -> TreeNode: """从BST树节点的右子树中找到值最小的节点""" if not node: return p = node node = node.right while node and node.left: p = node node = node.left p.left = None return node if node.left: max_sub_node = find_max_from_left(node) node.val = max_sub_node.val elif node.right: min_sub_node = find_min_from_right(node) node.val = min_sub_node.val else: if node.val < parent.val: parent.left = None else: parent.right = None return v_root.right
def build_coinflip_tree(k, value=""): ''' INPUT: int OUTPUT: TreeNode Return the root of a binary tree representing all the possible outcomes form flipping a coin k times. ''' node = TreeNode(value) if k != 0: node.left = build_coinflip_tree(k - 1, value + "H") node.right = build_coinflip_tree(k - 1, value + "T") return node
def build_coinflip_tree(k, value=""): """Return the root of a binary tree for flipping coin k times. Root represents all the possible outcomes from flipping a coin k times. Parameters ---------- int Returns ------- TreeNode """ node = TreeNode(value) if k != 0: node.left = build_coinflip_tree(k - 1, value + "H") node.right = build_coinflip_tree(k - 1, value + "T") return node
def searchingRecursive(initialState, visitedNodes): node = initialState nodeInitialState = node.state stateLength = len(nodeInitialState) cost = node.cost if(nodeInitialState == goalState): return node else: for i in range(0, stateLength): for j in range(0, stateLength): if ((len(nodeInitialState[j])) > 0 and i != j and (len(nodeInitialState[i])) < maxHeight): newState = copy.deepcopy(nodeInitialState) #Put the last container j -> i newState[i].append(newState[j].pop()) if (not(visitedNodes.count(newState))): movements = [i, j] #New cost #1 Picking up the container and Putting the container down + 1 for Moving the container one stack to the left or right + the accumulated cost of the path newCost = 1 + abs(i - j) + cost #New node newNode = TreeNode(node, newState, movements, newCost) #Visited list visitedNodes.append(newState) #Recursive call auxDFS = searchingRecursive(newNode, visitedNodes) if(auxDFS != None): return auxDFS return None
def aStar(): path = [] finalCost = 0 while nodesToExpand: node = nodesToExpand.pop() #Result found if isFinalState(node.state): finalCost, path = adaptSolution(node) return finalCost, path visitedNodes.append(node.state) for i, stack in enumerate(node.state): for j, new_stack in enumerate(node.state): auxState = copy.deepcopy(node.state) if i != j and len(stack) > 0 and len(new_stack) < maxHeight: newState, newStateCost = moveBlock(auxState, i, j) newNode = TreeNode(node, newState, [i, j], newStateCost + node.cost) #if the new node has not been visited, it is added to the visited list if newNode.state not in visitedNodes and not any( n.state == newNode.state for n in nodesToExpand): nodesToExpand.append(newNode) nodesToExpand.sort(key=operator.attrgetter('cost'), reverse=True) #if the node was visited before, we verify if the node's cost is higher than the new one else: for n in nodesToExpand: if n.state == newNode.state and n.cost > newNode.cost: nodesToExpand.remove(n) nodesToExpand.append(newNode) nodesToExpand.sort( key=operator.attrgetter('cost'), reverse=True) return finalCost, path
def translate(self): """ We serialize either a TreeNode or an id_dict. After reading, call this method to ensure all source formats are available. Assumes we have """ if self.treenode: # Create id_dict from TreeNode - only pickle self.id_dict = self.treenode.to_id_dict() self.tn_dict = self.treenode.to_tn_dict() elif self.id_dict: # Create TreeNode from id_dict - all other serializations # If serialization produces an id_dict, we must create the tn_dict self.tn_dict = {} for id, node in self.id_dict.items(): if node.is_dir(): self.tn_dict[id] = TreeNode(me=node, files=[], dirs=[]) # Define dir hierarchy # Also identify root node to remove one tn_dict traversal for tn in self.tn_dict.values(): if not tn.me.parent_id: self.treenode = tn else: self.tn_dict[tn.me.parent_id].dirs.append(tn) # Merge files into dir hierarchy for node in self.id_dict.values(): if not node.is_dir(): self.tn_dict[node.parent_id].files.append(node) else: raise ValueError("No internal format to translate.")
def test_basic_relation(self): parent = TreeNode(9) node = TreeNode(8) left = TreeNode(6) right = TreeNode(7) node.parent = parent node.left = left node.right = right self.assertEqual(id(node.parent), id(parent)) self.assertEqual(id(node.left), id(left)) self.assertEqual(id(node.right), id(right)) self.assertEqual(id(left.parent), id(node)) self.assertEqual(id(right.parent), id(node)) self.assertEqual(id(node.parent), id(parent)) self.assertEqual(id(parent.left), id(node)) self.assertTrue(parent.key > left.key) self.assertTrue(parent > left)
def collect_data_recurse(p: Path, tree_node: TreeNode, exclusions: Set[str]) -> None: """ Recurse dirs starting at tree_node, collecting information """ for item in p.iterdir(): # NOTE: If we cannot create the node, it will not be added and we will not recurse child = tree_node.add(item) if item.is_dir() and item.name not in exclusions and child: collect_data_recurse(item, child, exclusions)
def decision_tree(examples, attributes, bin_targets): all_same = check_all_same(bin_targets) if all_same: return TreeNode(None, True, bin_targets.iloc[0].iloc[0]) elif not attributes: # Majority Value return TreeNode(None, True, majority_value(bin_targets)) else: best_attribute = choose_best_decision_attr(examples, attributes, bin_targets) tree = TreeNode(best_attribute) for vi in range(0, 2): examples_i = examples.loc[examples[best_attribute] == vi] indices = examples_i.index.values bin_targets_i = bin_targets.ix[indices] if examples_i.empty: # Majority Value return TreeNode(None, True, majority_value(bin_targets)) else: attr = set(attributes) attr.remove(best_attribute) tree.set_child(vi, decision_tree(examples_i, attr, bin_targets_i)) return tree
def from_pre_post(pre: List[int], post: List[int]) -> TreeNode: if not pre: return None root = TreeNode(pre[0]) # 左右边界判定 if len(pre) == 1: return root left_val = pre[1] left_count = post.index(left_val) + 1 root.left = Construct.from_pre_post(pre[1:left_count + 1], post[0:left_count]) root.right = Construct.from_pre_post(pre[left_count + 1:], post[left_count:-1]) return root
def next(self): self.current = self.q.get() # self.print_status() if self.world.is_solved(self.current.world_state): return False new_world_states = self.world.get_moves(self.current.world_state) for state in new_world_states: node = TreeNode(self.current, state) self.q.put(node) return True
def insert(self, data, root=None): if self.root is None: if root is None: self.root = TreeNode(data) return else: self.root = root if root.data > data: if root.left is None: root.left = TreeNode(data) else: self.insert(data, root.left) elif root.data < data: if root.next is None: root.next = TreeNode(data) else: self.insert(data, root.next) else: print("value already exists")
def create_by_pre_in_order(values1, values2): if not values1 or not values2: return None root_value = values1[0] i = 0 while values2[i] != root_value: i += 1 left_values1 = values1[1:i + 1] left_values2 = values2[:i] right_values1 = values1[i + 1:] right_values2 = values2[i + 1:] node = TreeNode(value=root_value) node.left = create_by_pre_in_order(left_values1, left_values2) node.right = create_by_pre_in_order(right_values1, right_values2) return node
def dir_counts_recurse(node: TreeNode, indent: int = 0) -> None: """ Print all directories and node counts """ fc = len(node.files) dc = len(node.dirs) descendants = 0 for item in node.iter(): descendants += 1 print( f"{dc: >4} {fc: >4} {descendants: >4} {' ' * indent}/{node.me.name}" ) for d in node.dirs: dir_counts_recurse(d, indent + 2)
class DynamicQuadTree: def __init__(self, centerPt=Point(0, 0, 'center'), dimension=1, max_points=1, max_depth=4): self.max_points = max_points self.max_depth = max_depth self.root = TreeNode(centerPt, dimension, max_points, max_depth, 0) def __len__(self): return len(self.root) def __iter__(self): return iter(self.root) def __contains__(self, point): return self.root.exist(point) def insert(self, point): return self.root.insert(point) def remove(self, point): return self.root.remove(point) def update(self, new_point, old_point): return self.root.update(new_point, old_point) def query_range(self, boundary): return self.root.query_range(boundary) def knn(self, point, k): return self.root.knn(point, k)
def add_node(self, node, data, index): if data == -1: return node if node is None: return TreeNode(data) if index % 2 == 1: node.set_left(self.add_node(node.get_left(), data, index)) else: node.set_right(self.add_node(node.get_right(), data, index)) return node
def cross_validation_error(df_labels, N, df_data, segments): error_list = { 'anger': 1, 'disgust': 2, 'fear': 3, 'happiness': 4, 'sadness': 5, 'surprise': 6 } for e in cnst.EMOTIONS_LIST: total_error_for_emotion = 0 error_list[1] = 2 print("/\ Decision tree building for emotion:", e) binary_targets = util.filter_for_emotion(df_labels, cnst.EMOTIONS_DICT[e]) for test_seg in segments: test_df_data, test_df_targets, train_df_data, train_df_targets = util.divide_data( test_seg, N, df_data, df_labels) root = dtree.decision_tree(train_df_data, set(cnst.AU_INDICES), train_df_targets) TreeNode.plot_tree(root, e) # root = decision_tree(df_data, set(cnst.AU_INDICES), binary_targets) print("/\ Decision tree built.\n") count = 0 # Counts number of incorrectly predicted tests for i in test_df_data.index.values: count += 1 - TreeNode.dfs2(root, test_df_data.loc[i], test_df_targets.loc[i].at[0]) error = count / len(test_df_targets) total_error_for_emotion += error print() total_error_for_emotion /= 10 error_list[e] = total_error_for_emotion print() print("Total error:", total_error_for_emotion) print()
def buildSubTree(self, trainingExamples, currNode): """ method to build our tree - this build method uses OO concepts which we use during our prediction later on """ if self.attributesAndValues == []: return currNode divisionAttribute = self.getDivisionAttribute(trainingExamples) if currNode == None: # rootptr currNode = TreeNode(divisionAttribute.attrName) else: currNode.name = divisionAttribute.attrName # divide up our data based on the attribute we got back subLists = {} for attrValue in divisionAttribute.attrValues: subLists[attrValue] = [] for example in trainingExamples: # if the example attribute matches our division attributes, add training example to correct sublist for attribute in example.attributes: if attribute.attrName == divisionAttribute.attrName: subLists[attribute.attrValues[0]].append(example) # check if any of the sublists would require us to return a leaf node for subListKey in subLists: childNode = TreeNode() subList = subLists[subListKey] if subList == []: # no training examples, default to most common target value childNode.isLeaf = True childNode.targetValue = "p" currNode.childrenNodes[subListKey] = childNode elif self.isLeafNode(subList): childNode.isLeaf = True childNode.targetValue = subList[0].targetValue currNode.childrenNodes[subListKey] = childNode else: currNode.childrenNodes[subListKey] = childNode # recursively build using each sublist self.buildSubTree(subList, childNode) #return the root node with everything built on return currNode
def utSplitFeature(): """ unit test for function [chooseSplitFeature] """ from data_provider import data_provider attribute, dataset = data_provider('../test.arff') root = TreeNode(dataset, attribute) curTree = DecisionTree(root) bestFeature = curTree.chooseSplitFeature(root) try: assert (bestFeature == 0) print '[chooseSplitFeature] TEST PASS' except AssertionError: print '[chooseSplitFeature] TEST FAILED'
def utCreateTree(): """ unit test for function [createTree] examine the tree structure compared graph with: http://pages.cs.wisc.edu/~yliang/cs760_fall18/homework/hw2/diabetes/m=4.txt """ from data_provider import data_provider attribute, dataset = data_provider('../diabetes_train.arff') root = TreeNode(dataset, attribute) curTree = DecisionTree(root) curTree.createTree(root, 4) curTree.printTree(root, 0) print '---------------- please compare this graph with the url ------------------' print 'http://pages.cs.wisc.edu/~yliang/cs760_fall18/homework/hw2/diabetes/m=4.txt'
def build_coinflip_tree(k, flips=''): if k == 0: return None else: return TreeNode(flips, build_coinflip_tree(k - 1, flips + 'H'), build_coinflip_tree(k - 1, flips + 'T')) # node.left = build_coinflip_tree(node, k-1) # node.right = build_coinflip_tree(node, k-1) if __name__ == '__main__': # build a tree # 1 # / \ # 2 3 # / # 4 t1 = TreeNode(1) t1.left = TreeNode(2) t1.right = TreeNode(3) t1.left.left = TreeNode(4) # build a tree # 1 # / \ # 2 3 # / / # 4 5 t2 = TreeNode(1) t2.left = TreeNode(2) t2.right = TreeNode(3) t2.left.left = TreeNode(4) t2.right.left = TreeNode(5)
ltail.left = None ltail.right = None return root, ltail elif root.left is not None and root.right is not None: lhead, ltail = gao(root.left) rhead, rtail = gao(root.right) root.left = None root.right = lhead lhead.left = None ltail.left = None ltail.right = rhead rhead.left = None rtail.left = None rtail.right = None return root, rtail gao(root) solver = Solution() root5 = TreeNode() root5.build_from_list([1,2,3,4]) solver.flatten(root5) print(root5.to_dict()) root4 = TreeNode() root4.build_from_list([2,1,4,None,None,3,5]) solver.flatten(root4) print(root4.to_dict())
class Solution: # @param root, a tree node # @return a list of lists of integers def levelOrderBottom(self, root): if root is None: return [] result = [] cur_level = [root] next_level = [] while len(cur_level) > 0: values = [] for node in cur_level: values.append(node.val) if node.left is not None: next_level.append(node.left) if node.right is not None: next_level.append(node.right) cur_level = next_level next_level = [] result.append(values) return result[::-1] if __name__ == '__main__': root = TreeNode() root.build_from_list([3, 9, 20, None, None, 15, 7]) res = Solution().levelOrderBottom(root) print(res)
# bfs depth = 1 found_leaf = False cur_depth = [root] next_depth = [] while True: next_depth = [] for node in cur_depth: is_leaf = True if node.left is not None: next_depth.append(node.left) is_leaf = False if node.right is not None: next_depth.append(node.right) is_leaf = False if is_leaf is True: found_leaf = True break if found_leaf is True: break else: depth += 1 cur_depth = next_depth return depth if __name__ == '__main__': root = TreeNode() root.build_from_list(list(range(10))) print(Solution().minDepth(root))