コード例 #1
0
class Tree:
	def __init__(self, data, max_depth=None, max_error=None):
		self._root = Node(data)
		self._root.set_tree(self)
		x = data[:, 0]
		y = data[:, 1]
		dim = np.array([x.max() - x.min(), y.max() - y.min()])
		corner = np.array([x.min(), y.min()])
		self._root.set_coordinates(corner + dim / 2., 1.2 * dim)
		self._max_depth = max_depth
		self._max_error = max_error
		self._kdTree = KDTree(data, 7)
		self._eval_node = []

	def eval(self, coordinates):
		center, dim = self._root.get_coordinates()
		left_bottom = center - dim / 2
		right_top = center + dim / 2
		above_left = coordinates - left_bottom
		below_top = coordinates - right_top
		# in boundary
		if len(above_left[above_left >= 0]) == 2 and len(below_top[below_top <= 0]) == 2:
			w, wf = self._root.eval(coordinates)
			return wf / w
		else:
			return -10000

	def get_root(self):
		return self._root

	def split_node(self, node):
		if self._max_depth is not None and node.get_depth() > self._max_depth:
			return
		# split the node
		if node.split_criteria(self._max_error):
			node.split(self)
			for child in node.get_children():
				self.split_node(child)

	def generate_tree(self, error=None):
		self._max_error = error * np.linalg.norm(self._root._dim)
		self.split_node(self._root)

	def draw_node(self, node, axis):
		center, dim = node.get_coordinates()
		left_bottom = center - dim / 2
		axis.add_patch(
			patches.Rectangle(
				(left_bottom[0], left_bottom[1]),  # (x,y)
				dim[0],  # width
				dim[1],  # height
				fill=False
			)
		)

		# leaf node
		data = node.get_data()
		rad = node.get_rad()
		if node.get_children() is None:
			if data is not None:
				axis.scatter(data[:, 0], data[:, 1])
				# rad = np.linalg.norm(dim) / 2 * 1.30
				axis.add_patch(
					patches.Circle(xy=(center[0], center[1]), radius=rad,
					               fill=False)
				)
			else:
				axis.add_patch(
					patches.Circle(xy=(center[0], center[1]), radius=rad,
					               fill=False, color='r')
				)

		if node.get_children() is not None:
			for child in node.get_children():
				self.draw_node(child, axis)

	def draw(self, axis):
		self.draw_node(self._root, axis)

	def draw_eval_node(self, axis):
		for node in self._eval_node:
			center, dim = node.get_coordinates()
			left_bottom = center - dim / 2
			axis.add_patch(
				patches.Rectangle(
					(left_bottom[0], left_bottom[1]),  # (x,y)
					dim[0],  # width
					dim[1],  # height
					fill=False
				)
			)

			data = node.get_data()
			if data is not None:
				axis.scatter(data[:, 0], data[:, 1])

			rad = node.get_rad()
			axis.add_patch(
				patches.Circle(xy=(center[0], center[1]), radius=rad,
				               fill=False)
			)