Python 写一个kd树的生成

先写一个util.py

import math


def distance(x1, x2):
    dist = 0
    for i in range(len(x1)):
        dist += (x1[i]-x2[i])**2
    return math.sqrt(dist)


def sort( X, k, efrom, eto):
    for i in range(efrom, eto):
        for j in range(i+1,eto+1):
            if X[i][k] > X[j][k]:
                X[i], X[j] = X[j], X[i]

再写个KDTree的生成,kdt.py

import util


class Node:
    def __init__(self, _layer):
        self.layer = _layer
        self.elem = None


    def kd(self, X, layer, efrom, eto,  k):
        #
        util.sort(X, layer, efrom, eto)

        median = efrom + (eto - efrom + 1) // 2
        self.elem = X[median]

        layer += 1
        layer %= k
        if median > efrom:
            self.lchild = Node(layer)
            self.lchild.kd(X, layer, efrom,  median - 1, k)
        if median < eto:
            self.rchild = Node(layer)
            self.rchild.kd(X, layer, median + 1, eto, k)

class KDTree:
    def __init__(self, _k):
        self.k = _k

    def growing(self, X):
        root = Node(0)
        root.kd(X, 0, 0, len(X) - 1, self.k)
        print (root.rchild.elem)

测试一下

import kdt

k = 2
X = [[2, 3],[5,4],[9,6], [4, 7], [8,1], [7,2]]

tree = kdt.KDTree(k)
tree.growing(X)
print(X)

下面看怎么找最近邻节点和KNN算法。

好的,下面是一个基于PID算法的蒸汽发生器水位控制系统的Python代码示例: ```python import random import matplotlib.pyplot as plt class SteamGenerator: def __init__(self, max_level, kp, ki, kd): self.max_level = max_level self.level = 0 self.is_on = False self.kp = kp self.ki = ki self.kd = kd self.set_point = 50 self.error = 0 self.prev_error = 0 self.integral = 0 self.derivative = 0 self.time = [] self.level_data = [] self.set_point_data = [] def turn_on(self): self.is_on = True print("Steam generator turned on.") def turn_off(self): self.is_on = False print("Steam generator turned off.") def generate_steam(self): if self.is_on and self.level > 0: print("Steam generated.") else: print("Steam generator is off or water level is too low.") def adjust_water_level(self, level): if self.is_on: if level > self.max_level: self.level = self.max_level elif level < 0: self.level = 0 else: self.level = level self.error = self.set_point - self.level self.integral += self.error self.derivative = self.error - self.prev_error output = self.kp * self.error + self.ki * self.integral + self.kd * self.derivative self.prev_error = self.error if output > 100: output = 100 elif output < 0: output = 0 print("Water level adjusted to {}.".format(self.level)) print("Controller output: {:.2f}".format(output)) self.time.append(len(self.time)) self.level_data.append(self.level) self.set_point_data.append(self.set_point) return output else: print("Steam generator is off.") return 0 if __name__ == '__main__': generator = SteamGenerator(100, 0.5, 0.05, 0.05) generator.turn_on() for i in range(100): # 模拟水位传感器检测到的水位数值 water_level = random.randint(0, 150) # 控制水位 output = generator.adjust_water_level(water_level) # 生成蒸汽 generator.generate_steam() # 绘制水位曲线和设定值曲线 plt.plot(generator.time, generator.level_data, 'b-', label='Water Level') plt.plot(generator.time, generator.set_point_data, 'r--', label='Set Point') plt.legend(loc='upper left') plt.xlabel('Time') plt.ylabel('Water Level') plt.title('Steam Generator Water Level Control') plt.pause(0.01) # 关闭蒸汽发生器 if i == 50: generator.turn_off() plt.show() ``` 这个代码示例中,我们在 `SteamGenerator` 类的构造函数中添加了PID控制器的参数:比例系数kp、积分系数ki和微分系数kd。我们还添加了设定值`set_point`、误差`error`、上次误差`prev_error`、积分项`integral`和微分项`derivative`,用于计算控制器的输出。我们还添加了 `time`、`level_data` 和 `set_point_data` 三个列表,用于记录每次水位控制的时间、水位数值和设定值。 在 `adjust_water_level` 方法中,我们首先计算误差、积分项和微分项,并根据控制器的参数计算输出。然后,我们对输出进行限幅处理,将其限制在0到100之间。最后,我们更新误差和时间,将水位数值和设定值添加到对应的列表中,并返回输出值。 在主程序中,我们创建了一个 `SteamGenerator` 对象,并设置了PID控制器的参数。接着,我们开启蒸汽发生器,并进入一个循环中模拟水位传感器的检测过程。我们使用 `random` 模块来模拟水位传感器随机检测到的水位数值,并将其作为参数传递给 `adjust_water_level` 方法来调整蒸汽发生器的水位,并获取控制器的输出。我们在每次循环中调用 `generate_steam` 方法生成蒸汽,并使用 `matplotlib` 模块绘制水位曲线和设定值曲线。在第50次循环时,我们关闭了蒸汽发生器。最后,我们调用 `plt.show()` 方法显示绘制的曲线。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值