道格拉斯-普克(Douglas-Peucker)Python实现及改进
Douglas-Peucker算法介绍
拉默-道格拉斯-普克算法(Ramer–Douglas–Peucker algorithm),又称道格拉斯-普克算法(Douglas–Peucker algorithm)和迭代端点拟合算法(iterative end-point fit algorithm),是一种将线段组成的曲线降采样为点数较少的类似曲线的算法。它是最早成功地用于制图综合的算法之一。
算法原理
算法的基本思路是对每一条曲线的首末点虚连一条直线,求所有点与直线的距离,并找出最大距离值dmax。用dmax与限差D相比:
若dmax < D,这条曲线上的中间点全部舍去;
若dmax ≥ D,保留dmax相应的坐标点,并以该点为界,把曲线分为两部分,对这两部分重复使用该方法。
算法步骤
- 输入一系列坐标点组成的曲线。
- 曲线第一个点A和最后一个点B连成一条直线AB。
- 确认一个阈值(这个值用于控制简化后曲线的精度)。
- 分别计算曲线上各点到这条直线的距离,并取出其中的最远距离与阈值进行比较。
- 如果最远距离大于阈值,则将该点保留,记为C,此时可以生成两条直线AC、CB,5.重复步骤4。
- 否则将该点舍弃。
Python实现
下面展示douglas_peucker核心代码:
def douglas_peucker(points=None, threshold=None):
"""
道格拉斯-普克算法
:param points: 二维数据点的list
:param threshold: 距离阈值
:return:
"""
if len(points) < 3:
return points
start_point, end_point = points[0], points[-1]
distances = [point_to_line_distance(point, start_point, end_point) for point in points]
# 若距离小于阈值,则返回首尾点
if max(distances) < threshold:
return [start_point, end_point]
# 若距离大于阈值,则左右两分支分别计算后拼接
else:
# 获取特定点的坐标
targer_idx = distances.index(max(distances))
left_filtered = douglas_peucker(points[: targer_idx + 1], threshold)
# print('左边:', left_filtered_points)
right_filtered = douglas_peucker(points[targer_idx:], threshold)
# print('右边:', right_filtered_points)
filtered = left_filtered
filtered.extend(right_filtered[1:])
return filtered
粒子群算法介绍
算法改进
粒子群优化算法(Particle Swarm Optimization,PSO)是进化计算的一个分支,是一种模拟自然界的生物活动的随机搜索算法。
PSO模拟了自然界鸟群捕食和鱼群捕食的过程。通过群体中的协作寻找到问题的全局最优解。可以在Douglas–Peucker算法基础上实现自动设置阈值操作。
算法概念
- 每个寻优的问题解都被想像成一只鸟,称为“粒子”。所有粒子都在一个D维空间进行搜索。
- 所有的粒子都由一个fitness function 确定适应值以判断目前的位置好坏。
- 每一个粒子必须赋予记忆功能,能记住所搜寻到的最佳位置。
- 每一个粒子还有一个速度以决定飞行的距离和方向。这个速度根据它本身的飞行经验以及同伴的飞行经验进行动态调整。
基础参数
1. 粒子(particle):一只鸟。`
2. 种群(population):鸟群。
3. 位置(position):一个粒子(鸟)当前所在的位置。
4. 经验(best):一个粒子(鸟)自身曾经离食物最近的位置。
5. 速度(velocity):一个粒子(鸟)飞行的速度。
6. 适应度(fitness):一个粒子(鸟)距离食物的远近。
算法步骤
流程图:
粒子群算法步骤:
1)根据问题需要, 随机生成粒子,粒子的数量可自行控制。
2)将粒子组成一个种群。
3)计算粒子的适应度值。即计算粒子距离最优值得远近。
4)更新种群中每个粒子的位置和速度。
5)满足退出条件就退出,不满足就转向步骤3)。
算法核心
从PSO算法流程图中可以看出,核心步骤是更新种群中每个粒子的位置和速度,而速度的更新是核心中的核心。
粒子速度更新公式如下:
v为粒子当前的速度,w为惯性因子(有速度就有运动惯性)。rand()为随机数生成函数,生成0~1之间的随机数。
position为粒子当前的位置,pbest为本粒子历史上最好的位置,gbest为种群中所有粒子中当前最好的位置。
c1和c2表示学习因子,分别向本粒子历史最好位置和种群中当前最好位置学习。
Python实现
下面展示粒子群算法核心代码:
def PSO(num_particles, max_iter, bounds, points, w=0.5, c1=0.01, c2=0.01):
particles = initialize_particles(num_particles, bounds)
global_best_position, global_best_value = calculate_global_best(points, particles)
for _ in tqdm(range(max_iter), desc=f'粒子群迭代'):
for particle in particles:
value = fitness_function(points, particle['position'])
if value < particle['best_value']:
particle['best_value'] = value
particle['best_position'] = particle['position']
if value < global_best_value:
global_best_value = value
global_best_position = particle['position']
update_particles(particles, global_best_position, w, c1, c2)
return global_best_position, global_best_value
参考资料
道格拉斯-普克算法(经纬度或坐标点抽稀)
粒子群优化算法(Particle Swarm Optimization)
粒子群算法(PSO)初识
粒子群(PSO)算法的理解与应用