点击上方“小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达

罗素曾说:所有精确科学都被近似思想所主宰。本文介绍了近似算法及其对某些标准问题的适用性。

新冠大流行给世界带来了巨大的改变,全球科学家和研究人员在研制有效的疫苗。他们正在做的就是从广阔的样本空间中近似地收紧可能性范围,并尽力得到一些有效解。近似在我们的生活中发挥了重要作用。

以在线食品配送为例,我们经常从网上订购食物,享受快速送达的服务。但你想过这些 app 后端运行的什么算法让快递员在更短时间内抵达目的地吗?答案是近似算法。这类问题就是「旅行商问题」。

食品配送:旅行商问题的现实应用。

本文将介绍近似算法及其对某些标准问题的适用性,以及哪些因素会影响到特定算法的选择。

什么是近似算法?

近似算法是一种处理优化问题 NP 完全性的方式,它无法确保最优解。近似算法的目标是在多项式时间内尽可能地接近最优值。

它虽然无法给出精确最优解,但可以将问题收敛到最终解的近似值。其目标满足以下三个关键特性:

  • 能够在多项式时间内高效运行;

  • 能够给出最优解;

  • 对于每个问题实例均有效。

背景

数学表达式的评估常伴随常量、变量分析和方程的阶,可用于衡量近似的复杂度。此类评估将问题分解为 P 和 NP 难问题

P 问题和 NP 问题的策略

P 问题是指可以在多项式时间内求解的问题。

NP 表示不确定性多项式时间(nondeterministic polynomial time),NP 问题是指在多项式时间内近似验证答案的问题。但目前人们发现,很多此类问题需要指数时间才能求解。

P 和 NP 策略。

真正的争论在于 P=NP 还是 P≠NP。之前的一些研究证明这两种都是对的。如果一个问题是多项式次方,则存在多个最优算法。因此,在 NP 完全问题中,存在两种方法找到近优解,然后选择最适合的算法。

如果输入的大小比较小,则具备指数运行时间的算法可能会比较适合。

其次,通过用近似算法替代确定性算法,我们仍然能够在多项式时间内找到近优解。

近似算法的复杂度可以从输入大小和近似因子中推断出来。接下来,我们通过一些示例,深入探索这些算法如何应用到现实问题中。

分区问题

在计算机科学领域,该问题的定义是:给定多重正整数集 X,它可以被分割为两个元素之和相等的子集 X1 和 X2,即每个子集的数值之和与另一个子集相等。

例如,X={3,4,1,3,3,2,3,2,1} 可以被分割为 X1={3,3,2,3} 和 X2={4,2,3,1,1},二者的数值之和都是 11。

类似地,X={1,3,1,2,1,2} 可以被分成 X1={2,1,1,1} 和 X2={3,2},两个子集的数值之和都是 5。有趣的是,这不是唯一解。X1={1,3,1} 和 X2={2,1,2} 的数值之和也为 5,这表明存在多个可能的子集。

这就是 NP 完全问题,存在伪多项式时间动态规划解,可获得该问题的近优解。

方法和决定步骤

现在,我们开始分析这个问题,把它分解成数个单独的标准问题。这里,我们想要找出多重集的元素之和相等的子集,那么该问题就可以分解成以下两个问题:

  • 子集和问题:子集 X 的元素之和等于数字 W。

  • 多路数字分割:给定整数参数 W,确定如何将 X 分割成 W 个等额子集。

近似算法

如上所述,将分区问题分解为多路分割与子集和问题后,我们就可以考虑为这些问题而开发的算法,包括:

贪婪数字分割(Greedy number Partitioning)

该算法循环遍历所有数字,将每个数字分配给总和最小的子集。如果数字未以排序方式排列,则其运行时复杂度为 O(n),近似率约为 3/2。其 Python 伪代码如下:

def find_partition(numbers):"""Separate the available numbers into two eqal sum series.Args:numbers: collection of numbers, for example list of integers.Returns:Two lists of numbers."""X = []Y = []sum_X = 0sum_Y = 0for n in sorted(numbers, reverse=True):if sum_X < sum_Y:X.append(n)sum_X = sum_X + nelse:Y.append(n)sum_Y = sum_Y + nreturn (X, Y)

将数字排序,则运行时复杂度增加到 O(n logn),近似率增加到 7/6。如果数字在 [0,1] 范围内均匀分布,则近似率约为 1 + O(log logn/n)。

分区问题图示。

上图用二叉树的形式展示所有分区。树的根部表示集合中的最大数,每一级对应输入数字,每个独立分支对应不同的子集。遍历这些集合需要深度优先遍历(depth-first traversal),所需的空间复杂度为 O(n),时间复杂度为 O(2^n)。

适用性:

该算法可以根据情况进行修改,以便改善运行时复杂度。每一级的首要目标是构建一个分支,将当前数字分配给总和最小的子集。首先通过贪婪数字分割找出总和,然后切换到优化,得到全多项式时间近似解。

Karmarkar-Karp 算法

Karmarkar-Karp 算法指以降序方式排列数字的最大差分方法,该方法将差值替换掉原来的数字不断放进集合中。其 Java 伪代码实现如下:

int karmarkarKarpPartition(int[] baseArr) {    // create max heap    PriorityQueue<Integer> heap = new PriorityQueue<Integer>(baseArr.length, REVERSE_INT_CMP);for (int value : baseArr) {        heap.add(value);    }while (heap.size() > 1) {int val1 = heap.poll();    int val2 = heap.poll();    heap.add(val1 - val2);}return heap.poll();
}

该算法包含输入集 S 和参数 k。将 S 分割成 k 个子集,使这些子集中的数字总和相等,从而构建期望输出。该算法包含如下关键步骤:

  • 以降序方式排列数字;

  • 用差值替换掉原来的数字,直到只有一个数字;

  • 采用回溯算法,完成分区。

适用性:

该算法通过构建二叉树来假设分区。每一级表示一对数字,左侧的分支表示用差值替换数字,右侧的分支表示将差值放置在同一个子集中。该算法先通过最大差分求得解,然后继续寻找更好的近似解。它所需的空间复杂度为 O(n),但最糟糕的情况下所需的时间复杂度可能会达到 O(2^n)。

装箱问题

装箱问题有多种现实应用。例如,如何从根本上改善印度的垃圾管理系统。这个问题就可以通过装箱问题来解决,帮助当局决定 x 量的垃圾需要多少个垃圾箱。

集装箱船:装箱问题的现实应用。

在计算机科学领域中,该问题可用于多种内存管理技术。在该算法中,我们可以通过去除冗余和最小化空间浪费来包装不同形状和大小的对象。

例如:给定一个包含 n 个项的集合,每个项的大小分别为 s1,s2,..,sn (0<=si<=1, 1<=i<=n),如何将它们装进最少数量的箱子?

经典方法:

1. 邻近适应算法 (Next Fit):查看当前项是否适合当前箱子。如果适合,则将物品放置在箱子里,否则开启一个新的箱子。

我们来看一个示例:项是 0.5, 0.7, 0.5, 0.2, 0.4, 0.2, 0.5, 0.1, 0.6,箱子大小均为 1。

基于邻近适应算法的装箱解决方案(M = 箱子总数 = 6)。

2. 最先匹配法 (First Fit):按顺序浏览箱子,在第一个箱中放置新的项,直到放不下再启用新的箱子。

我们来看一个示例:项是 0.5, 0.7, 0.5, 0.2, 0.4, 0.2, 0.5, 0.1, 0.6,箱子的大小均为 1。

基于最先匹配法的装箱解决方案(M = 箱子总数 = 5)。

3. 最优匹配法 (Best Fit):按顺序浏览箱子,将每一个新的项放在最适合的箱子里。如果不适合,则创建一个新的箱子。

我们来看一个示例:项是 0.5, 0.7, 0.5, 0.2, 0.4, 0.2, 0.5, 0.1, 0.6,箱子的大小均为 1。

基于最优匹配法的装箱解决方案(M = 箱子总数 = 5)。

该方法的输出与最先匹配法相同,但该方法的优点是实现速度比 FFD 快,即时间复杂度为 O(nlogn)。

自然方法:

如果我们提前知道所有项的大小,那么自然的解决方案就是首先按照从大到小排序,然后应用以下启发式方法:

  • 最先匹配递减法

  • 最优匹配递减法

假设有相同的示例 0.7, 0.6, 0.5, 0.5, 0.5, 0.4, 0.2, 0.2, 0.1,则排序为 0.7, 0.6, 0.5, 0.5, 0.5, 0.4, 0.2, 0.2, 0.1。

优化方法(M = 箱子总数 = 4)。

参考文献:

1. https://cutt.ly/4hSDx2Y

2. https://cutt.ly/xhSDhEM

3. https://shorturl.at/hxCO5 

4.https://en.wikipedia.org/wiki/Bin_packing_problem#Approximation_algorithms_for_bin_packing 

5. https://en.wikipedia.org/wiki/Partition_problem 

6.https://www.javatpoint.com/daa-approximate-algorithms#:~:text=An%20Approximate%20Algorithm%20is%20a,at%20the%20most%20polynomial%20time

下载1:OpenCV-Contrib扩展模块中文版教程

在「小白学视觉」公众号后台回复:扩展模块中文教程即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。

下载2:Python视觉实战项目52讲

在「小白学视觉」公众号后台回复:Python视觉实战项目即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。

下载3:OpenCV实战项目20讲

在「小白学视觉」公众号后台回复:OpenCV实战项目20讲即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。

交流群

欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~

什么是近似算法?它适用于哪些问题?这篇文章给你答案相关推荐

  1. 简述汇编语言中的标号有什么规定_2020年秋季学期《汇编语言》在线考试 (适用于2020年12月份考试)【答案标准】...

    2020年秋季学期<汇编语言>在线考试 (适用于2020年12月份考试) 共29道题 总分:100分 答题中 剩余答题时间:88 : 06 单选题 问答题 论述题 一.单选题 共20题,4 ...

  2. 计算机控制中在线离线,2020年秋季学期《机电系统计算机控制》在线考试补考(适用于2021年4月份考试)【答案】...

    2020年秋季学期<机电系统计算机控制>在线考试补考(适用于2021年4月份考试) 共40道题 总分:100分 答题中 剩余答题时间:89 : 51 单选题 判断题 问答题 一.单选题 共 ...

  3. 适用于火车头7.6的翻译插件-亲测10000篇文章稳定不报错

    因为php插件带来的效率降低问题,如无特别说明,本博客开发的火车头插件一律使用C#开发   最近经常看到有人在找翻译插件,官方的翻译插件貌似只有V9版本的,而且用于火车头7.6的翻译插件已经不能用了, ...

  4. 考研励志--我考研时觉得非常好的一篇文章,适用于考研新手

    转自:http://bbs.kaoyan.com/t2679251p1 励志篇 这些天来,人们总向我讨教考研的经验,我一直搪塞着他们,因为我不想误导他们.他们想了解到的无非是公共课用什么资料,专业课如 ...

  5. 2020年,那些「引爆」了机器学习社区的热门论文、库和基准

    点击上方"AI遇见机器学习",选择"星标"公众号 重磅干货,第一时间送达 仅作学术分享,不代表本公众号立场,侵权联系删除 转载于:机器之心 2020 年出现了哪 ...

  6. 2020年,那些「引爆」了ML社区的热门论文、库和基准

    2020 年出现了哪些引爆机器学习社区的论文和库呢?哪些模型和方法登顶各领域基准排行榜呢?这篇文章给你答案. 机器之心报道,作者:杜伟 不平凡的 2020 年终于过去了!这一年,由于新冠肺炎疫情的影响 ...

  7. iPhone应用程序图标 - 精确半径?

    本文翻译自:iPhone App Icons - Exact Radius? I'm trying to create the icon for my iPhone app, but don't kn ...

  8. java –cp ./:_成为Java流大师–第3部分:终端操作

    java –cp ./: 比尔·盖茨曾经说过:"我选择一个懒惰的人去做一件困难的事情,因为一个懒惰的人会找到一个简单的方法来做." 关于流,没有什么比这更真实了. 在本文中,您将学 ...

  9. 成为Java流大师–第3部分:终端操作

    比尔·盖茨曾经说过:"我选择一个懒惰的人去做一件困难的事情,因为一个懒惰的人会找到一个简单的方法来做." 关于流,没有什么比这更真实了. 在本文中,您将学习Stream如何通过在调 ...

最新文章

  1. 机器学习处理流程、特征工程,模型设计实例
  2. 梯度下降和随机梯度下降为什么能下降?
  3. java中检测数据波动_在pyspark数据帧中检测异常值
  4. WTM 3.5发布,VUE来了!
  5. activiti 设置可选处理人_新品速递|高端系列!慧明DF系列线性相位处理专业音箱处理器...
  6. 程序员一般都浏览这些网站,不仅仅提升编程水平!
  7. 转:NAT traversal 的概念
  8. DevOps使用教程 华为云(5)迭代计划 进度管理
  9. 读取excel数据批量填充world
  10. win禁用shift切换输入法
  11. word2vec与相关应用
  12. win10禁用计算机维护,Win10自动维护是什么 Win10自动维护怎么关闭
  13. 结构体内数组arr[0]或者arr[1]变量的作用及使用方法
  14. PHP图片验证码无法显示的解决方案
  15. 白帽子-高端信息安全培训(攻防技术、渗透测试、安全产品、安全标准、风险评估、等级保护、项目实战)...
  16. 最形象的卷积神经网络详解:从算法思想到编程实现(转载)
  17. LaTeX常用格式学习笔记
  18. 依次输入十个数 输出最大的数 C语言实现
  19. 导致论文高被引的关键因素
  20. 使用编码器控制步进电机

热门文章

  1. 吴甘沙:天外飞“厕”、红绿灯消失,未来无人驾驶将被重新定义
  2. Python三十年技术演变史
  3. 刷新记录,算法开源!字节跳动获人体姿态估计竞赛双冠 | CVPR 2019
  4. 重新定义 AI 服务器架构
  5. Java如何校验两个文件内容是相同的?
  6. SpringBoot静态获取 bean的三种方式,你学会了吗?
  7. Spring 容器的启动过程
  8. Java 代码精简之道
  9. 刷了一个月算法,终于拿到了double的offer
  10. 如何阅读一份深度学习项目代码?