【GIS算法】——道格拉斯-普克(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相应的坐标点,并以该点为界,把曲线分为两部分,对这两部分重复使用该方法。

算法步骤

  1. 输入一系列坐标点组成的曲线。
  2. 曲线第一个点A和最后一个点B连成一条直线AB。
  3. 确认一个阈值(这个值用于控制简化后曲线的精度)。
  4. 分别计算曲线上各点到这条直线的距离,并取出其中的最远距离与阈值进行比较。
  5. 如果最远距离大于阈值,则将该点保留,记为C,此时可以生成两条直线AC、CB,5.重复步骤4。
  6. 否则将该点舍弃。

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算法基础上实现自动设置阈值操作。
Alt

算法概念

  • 每个寻优的问题解都被想像成一只鸟,称为“粒子”。所有粒子都在一个D维空间进行搜索。
  • 所有的粒子都由一个fitness function 确定适应值以判断目前的位置好坏。
  • 每一个粒子必须赋予记忆功能,能记住所搜寻到的最佳位置。
  • 每一个粒子还有一个速度以决定飞行的距离和方向。这个速度根据它本身的飞行经验以及同伴的飞行经验进行动态调整。

基础参数
1. 粒子(particle):一只鸟。`
2. 种群(population):鸟群。
3. 位置(position):一个粒子(鸟)当前所在的位置。
4. 经验(best):一个粒子(鸟)自身曾经离食物最近的位置。
5. 速度(velocity):一个粒子(鸟)飞行的速度。
6. 适应度(fitness):一个粒子(鸟)距离食物的远近。

算法步骤

流程图:Alt
粒子群算法步骤:

1)根据问题需要, 随机生成粒子,粒子的数量可自行控制。

2)将粒子组成一个种群。

3)计算粒子的适应度值。即计算粒子距离最优值得远近。

4)更新种群中每个粒子的位置和速度。

5)满足退出条件就退出,不满足就转向步骤3)。

算法核心

从PSO算法流程图中可以看出,核心步骤是更新种群中每个粒子的位置和速度,而速度的更新是核心中的核心。

粒子速度更新公式如下:
Alt
v为粒子当前的速度,w为惯性因子(有速度就有运动惯性)。rand()为随机数生成函数,生成0~1之间的随机数。

position为粒子当前的位置,pbest为本粒子历史上最好的位置,gbest为种群中所有粒子中当前最好的位置。

c1c2表示学习因子,分别向本粒子历史最好位置和种群中当前最好位置学习。

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)算法的理解与应用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值