算法复杂度主方法

有时候,我们要评估一个算法的复杂度,但是算法被分散为几个递归的子问题,这样评估起来很难,有一个数学公式可以很快地评估出来。

一、复杂度主方法

主方法,也可以叫主定理。对于那些用分治法,有递推关系式的算法,可以很快求出其复杂度。

定义如下:

如果对证明感兴趣的可以翻阅书籍:《算法导论》。如果觉得太难思考,可以跳过该节。

由于主定理的公式十分复杂,所以这里有一种比较简化的版本来计算:

二、举例

  1. 二分搜索,每次问题规模减半,只查一个数,递推过程之外的查找复杂度为O(1),递推运算时间公式为:T(n) = T(n/2) + O(1)
  2. 快速排序,每次随机选一个数字作为划分进行排序,每次问题规模减半,递推过程之外的排序复杂度为O(n),递推运算时间递推公式为:T(n) = 2T(n/2) + O(n)

按照简化版的主定理,可以知道:

二分查找:a = 1,b = 2,d = 0,可以知道a = b^d,所以二分查找的时间复杂度为:O(logn)

快速排序:a = 2,b = 2,d = 1,可以知道a = b^d,所以快速排序的时间复杂度为:O(nlogn)

强调:并非所有递推关系式都可应用主定理,但是大部分情况下都可以。

因为需要较多的数学知识,所以我们只简单介绍到这里。

延伸-计算理论:P和NP问题

在计算机科学中,有一个专门的分支研究问题的可计算性,叫做计算理论。

我们用计算机算法来解决一个问题,如果一个问题被证明很难计算,或者只能暴力枚举来解决,那么我们就不必花大力气去质疑使用的算法是不是错了,为什么这么慢,计算怎么久都没出结果,到底有没有更好的算法。

计算机科学把一个待解决的问题分类为:P问题,NP问题,NPC问题,NP-hard问题。

一、P 和 NP 问题

类似于O(1)O(logn)O(n)等复杂度,规模n出现在底数的位置,计算机能在多项式时间解决,我们称为多项式级的复杂。

类似于O(n!)O(2^n)等复杂度,规模n出现在顶部的位置,计算机能在非多项式时间解决,我们称为非多项式级的复杂度。

如果一个问题,可以用一个算法在多项式时间内解决,它称为P问题(PPolynominal的缩写,多项式)。

比如求1加到100的总和,它的时间复杂度是O(n),是多项式时间。

然而有些问题,只能用枚举的方式求解,时间复杂度是指数级别,非多项式时间,但是只要有一个解,我们能在多项式时间验证这个解是对的,这类问题称为NP问题。

也就是说,如果我们只能靠猜出问题的一个解,然后可以用多项式时间来验证这个解,这些问题都是NP问题。

所以,按照定义,所有的P问题都是NP问题。

计算理论延伸出了图灵机理论,自动机=算法。

有两种自动机,一种是确定性自动机,机器从一个状态到另外一个状态的变化,只有一个分支可以走,而非确定性自动机,从一个状态到另外一个状态,有多个分支可以走。P问题都可以用两种机器来解决,当非确定性自动机退化就变成了确定性自动机,而NP问题只能用非确定性自动机来解决。

自动机对NNP问题的定义:

可以在确定性自动机以多项式时间解决的问题,称为P问题,可以在多项式时间验证答案的问题称为NP问题。而NP问题是可以在非确定型自动机以多项式时间解决的问题(NP两字为Non-deterministicPolynomial的缩写,非确定多项式)。

数学,计算机科学,哲学,三个学科其实交融在一起,自动机是一台假想的机器,世界其实也可以认为是一个假想的机器,所以世界可以等于一台自动机吗,大家可以发挥想象力,在以后的日子里慢慢体会,建议购买书籍《计算理论》补习相关知识。

二、NPC 和 NP-hard 问题

存在这样一个NP问题,所有的NP问题都可以约化成它。换句话说,只要解决了这个问题,那么所有的NP问题都解决了。其定义要满足2个条件:

  1. 它得是一个NP问题。
  2. 所有的NP问题都可以约化到它。

这种问题称为NP完全问题(NPC)。按照这种定义,NP问题要比NPC问题的范围广。

那什么是NP-hard问题,其定义要满足2个条件:

  1. 所有的NP问题都可以约化到它。
  2. 它不是一个NP问题。

也就是说,NP-hard问题更难,你只要解决了NP-hard问题,那么所有的NP问题都可以解决。但是,这个问题本身不是一个NP问题,也就是解不能在多项式时间内被验证。

比如你有一个交际网,每个人是一个节点,认识的人之间相连。你要通过一个最快、最省钱、最能提升你个人形象、最没有威胁、最不影响你日常生活的方式认识一个萌妹,你怎么证明你认识这个萌妹是最省钱的呢?-来自知乎回答。

我们一旦发现一个问题是NPC问题,那么我们很难去准确求出其解,只能暴力枚举,靠猜。

三、总结

各类问题可以用这个图来表示:

"P=NP" 问题的目标,就是想要知道PNP这两个集合是否相等。为了证明两个集合(AB)相等,一般都要证明两个方向:

  1. A包含B
  2. B包含A

我们已经说过NP包含了P。因为任何一个非确定性机器,都能被当成一个确定性的机器来用。你只要不使用它的“超能力”,在每个分支点只探索一条路径就行。

所以 "P=NP" 就在于P是否也包含了NP。也就是说,如果只使用确定性计算机,能否在多项式时间之内,解决所有非确定性计算机能在多项式时间内解决的问题。

系列文章入口

我是陈星星,欢迎阅读我亲自写的 数据结构和算法(Golang实现),文章首发于 阅读更友好的GitBook

数据结构和算法(Golang实现)(10)基础知识-算法复杂度主方法的更多相关文章

  1. 数据结构和算法(Golang实现)(9)基础知识-算法复杂度及渐进符号

    算法复杂度及渐进符号 一.算法复杂度 首先每个程序运行过程中,都要占用一定的计算机资源,比如内存,磁盘等,这些是空间,计算过程中需要判断,循环执行某些逻辑,周而反复,这些是时间. 那么一个算法有多好, ...

  2. 数据结构和算法(Golang实现)(4)简单入门Golang-结构体和方法

    结构体和方法 一.值,指针和引用 我们现在有一段程序: package main import "fmt" func main() { // a,b 是一个值 a := 5 b : ...

  3. C#基础知识学习(1)方法的重写和隐藏

    做了1年多了C#,发现些项目过程中很多基础东西都不是很清晰,基础不够牢固.现在开始复习基础知识并做重点记录 方法需要被重写的时候,可以在方法前加入virtual使方法变成虚方法. 这样我们可以重新写个 ...

  4. 算法导论 - 基础知识 - 算法基础(插入排序&归并排序)

    在<算法导论>一书中,插入排序作为一个例子是第一个出现在该书中的算法. 插入排序: 对于少量元素的排序,它是一个有效的算法. 插入排序的工作方式像许多人排序一手扑克牌.开始时,我们手中牌为 ...

  5. 1.10 基础知识——GP3.1 制度化 & GP3.2 收集改进信息

    摘要: GP3.1是要求建立组织级的关于该过程的制度.标准.模版等全套体系,要求覆盖该PA所有的SP和GP.GP3.2 体现的是持续改进,每个过程都应该收集相应的改进信息. 正文: GP3.1 Est ...

  6. Oracle优化器基础知识之访问数据的方法

    目录 一.访问数据的方法 1.直接访问数据 2.访问索引 一.访问数据的方法 Oracle访问表中数据的方法有两种,一种是直接表中访问数据,另外一种是先访问索引,如果索引数据不符合目标SQL,就回表, ...

  7. python基础知识02-序列类型的方法

    列表的方法: 增:append() insert() extend()只能添加序列类型. .改li[0]= '123' li.insert(2,'123') 2个参数,位置,值 li.remove(' ...

  8. scrapy基础知识之 使用FormRequest.from_response()方法模拟用户登录:

    通常网站通过 实现对某些表单字段(如数据或是登录界面中的认证令牌等)的预填充 使用Scrapy抓取网页时,如果想要预填充或重写像用户名.用户密码这些表单字段, 可以使用 FormRequest.fro ...

  9. python基础知识五 各类型数据方法补充,转换,分类,编码+坑中菜

    3.9各类型数据方法补充,转换,分类,编码,坑中菜 3.9.1数据类型方法补充 1.str:不可变 补充方法 s1.capitalize():首字母大写 s1 = "alex" s ...

随机推荐

  1. Natas31 Writeup(Perl 远程命令执行)

    Natas31: 源码如下: my $cgi = CGI->new; if ($cgi->upload('file')) { my $file = $cgi->param('file ...

  2. Spring Cloud 系列之 Netflix Hystrix 服务容错

    什么是 Hystrix Hystrix 源自 Netflix 团队于 2011 年开始研发.2012年 Hystrix 不断发展和成熟,Netflix 内部的许多团队都采用了它.如今,每天在 Netf ...

  3. mysql事务原理及MVCC

    mysql事务原理及MVCC 事务是数据库最为重要的机制之一,凡是使用过数据库的人,都了解数据库的事务机制,也对ACID四个 基本特性如数家珍.但是聊起事务或者ACID的底层实现原理,往往言之不详,不 ...

  4. 学习vue前的准备工作

    起步 1.扎实的HTML/CSS/Javascript基本功,这是前置条件. 2.不要用任何的构建项目工具,只用最简单的<script>,把教程里的例子模仿一遍,理解用法.不推荐上来就直接 ...

  5. vnpy源码阅读学习(8):关于app

    关于app 在入口程序中,我们看到了把 gateway,app, 各类的engine都添加到mainEngine中来.不难猜测gateway主要是处理跟外部的行情,接口各方面的代码,通过别人的文章也不 ...

  6. 从源码学习Java并发的锁是怎么维护内部线程队列的

    从源码学习Java并发的锁是怎么维护内部线程队列的 在上一篇文章中,凯哥对同步组件基础框架- AbstractQueuedSynchronizer(AQS)做了大概的介绍.我们知道AQS能够通过内置的 ...

  7. 强化学习之二:Q-Learning原理及表与神经网络的实现(Q-Learning with Tables and Neural Networks)

    本文是对Arthur Juliani在Medium平台发布的强化学习系列教程的个人中文翻译.(This article is my personal translation for the tutor ...

  8. Android初级控件

    Android初级控件 从今天开始就对Android进行正式的学习,首先先来学习一下初级的控件 1.TextView  文本框,用于显示文字,不可编辑. 常用属性 android:autoLink   ...

  9. TensorFlow RNN 教程和代码

    分析: 看 TensorFlow 也有一段时间了,准备按照 GitHub 上的教程,敲出来,顺便整理一下思路. RNN部分 定义参数,包括数据相关,训练相关. 定义模型,损失函数,优化函数. 训练,准 ...

  10. Pytest系列(1) - 快速入门和基础讲解

    如果你还想从头学起Pytest,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1690628.html 前言 目前有两种纯测试的测试框架, ...