算法

大O表示法

你。 提交于 2020-03-04 18:48:57
大O表示法???这是什么东西?? 大O表示法 其实并没有多么高大上, 而是一种特殊的表示法,指出了算法的速度有多快 。这种表示法简单易懂,非常明了,所以应用广泛。 举个例子,就如我上一篇博客中提到的 二分查找(https://blog.csdn.net/qq_45835827/article/details/104651718) 。如果用大O表示法来分别表示简单查找和二分查找的速度为: 简单查找 :O(n) 二分查找 :O(log 2 n) 这就是 大O表示法 ,前面的O有点大。 因为在很多时候,如果只是告诉你算法花了多长时间是没有用的,而是需要知道运行时间如何随list的增长而增长。大O表示法的用武之地就在于此。也就是之前所说的,大O表示法指出了算法的速度有多快。 下面给大家介绍一些常见的大O运行时间 O(log 2 n),对数时间,例如:二分查找。 O(log n),线性时间,例如:简单查找。 O(n * log 2 n),例如:快速排序(可以参考我的另外一篇博客)。 O(log n 2 )例如:选择排序(可以参考我的另外一篇博客)。 O(log n!)例如:用于旅行商问题。 大家可能也注意到了一点, 大O表示法指出了最糟情况下的运行时间 。怎么去理解这个性质呢?其实就是说该算法最糟运行的时间大O表示法所指代的时间,这是一个保证。比如说,小明心里想的数字为50

排序算法汇总---C++实现各个排序

岁酱吖の 提交于 2020-03-04 18:36:53
排序汇总: 下图为各个排序的时空复杂度: 冒泡排序: //冒泡排序 void bubble_sort ( vector < int > & v ) { for ( int i = 0 ; i < v . size ( ) - 1 ; i ++ ) { //n-1趟 for ( int j = 0 ; j < v . size ( ) - i - 1 ; j ++ ) { //n-趟数-1 if ( v [ j ] > v [ j + 1 ] ) { int temp = v [ j ] ; v [ j ] = v [ j + 1 ] ; v [ j + 1 ] = temp ; } } } } 2.直接插入排序: //直接插入排序 void insert_sort ( vector < int > & v ) { for ( int i = 1 ; i < v . size ( ) ; i ++ ) { for ( int j = i ; j > 0 ; j -- ) { if ( v [ j ] < v [ j - 1 ] ) { int temp = v [ j ] ; v [ j ] = v [ j - 1 ] ; v [ j - 1 ] = temp ; } } } } 希尔排序(改进的插入排序): //希尔排序 void shell_sort ( vector < int

数据结构与算法(一):浅谈数据结构

喜欢而已 提交于 2020-03-04 17:27:54
什么是数据结构 简单来说, 数据结构+算法=程序。 传统上,我们把数据结构分为 逻辑结构 和 物理结构 。 逻辑结构 :是指数据对象中数据元素之间的互相关系,也是我们今后最需要关注和讨论的问题。 物理结构 :是指数据的逻辑结构在计算机中的存储形式。 逻辑结构: 集合结构:内部除了同属一个集合外,没有其他关系。 线性结构:线性结构中的数据元素之间是一对一的关系。 树形结构:树形结构中的数据元素之间存在一种一对多的层次关系。 图形结构:图形结构的数据元素是多对多的关系。 物理结构: 数据元素的存储结构形式有两种:顺式存储结构和链式存储结构。 顺序存储结构:是把数据元素存放在地址连续的存储单元里,其数据间的逻辑关系和物理关系是一致的。 例如我们编程语言的数组结构就是典型的顺序存储结构。 链式存储结构:从顺序存储结构我们想到了日常生活中的排队,但现实生活中,我们发现不是完全如此。 例如排队时,有人被迫离开队伍去上洗手间,还有人不遵守基本道德规范插队,这些情况会破坏 存储结构的基本原则 。面对这样时常要变化的结构,顺序存储结构是不安全的,所以引出 链式存储结构 。 例如现在的银行、医院叫号系统,排队时无论你在哪里,只需要关注你的“号”有没有被叫到。 链式存储结构就是这样的原理,把数据元素存放在任意的存储单元里,这组存储单元可以是连续的,也可以是不连续的。 很显然

基于LDA的SRDA算法

☆樱花仙子☆ 提交于 2020-03-04 17:27:25
LDA 线性判别分析 (LDA)是一种常用的保持类别可分性的特征提取方法。LDA的投影函数通常是通过 最大化类间协方差和同时最小化类内协方差 得到的。它被广泛应用于信息处理的许多领域,如机器学习、数据挖掘、信息检索和模式识别等。然而,LDA的计算涉及到密集矩阵的特征分解,这在时间和内存上都很昂贵。具体来说,LDA具有O(m n t+t3)时间复杂度,需要O(m n+mt+nt)内存,其中m是样本数,n是特征数,t=min(m,n)。当m和n都较大时,应用LDA是不可行的。 基于统计分析的子空间方法 分析人脸识别的主流方法是基于统计分析的子空间方法 人脸的图像维数通常很大,而其在高维空间分布很不紧凑,不利于分类,而且计算复杂度很大,因此通常将图像投影到低维的子空间进行判别。 子空间方法是根据一定目标来找线性或者非线性的变换,使原始信号压缩到一个低维的子空间中,让数据在该子空间的分布更加紧凑为数据的描述提供更好的手段,并且使其计算复杂度降低。 子空间有向图嵌入 用一个低维向量来表示图上的点,此向量保持了数据点间的相似度,此相识度可通过具有数据点集统计或者几何性的相似矩阵来描述。 点的向量表达式由一定约束条件下拉普拉斯矩阵的主要特征值对应的特征向量确定。 谱方法理论 谱方法是数学领域里一种经典的分析和代数方法,在高维数据的低维表示和聚类问题中有着广泛的应用。

机器学习的分类与回归算法

那年仲夏 提交于 2020-03-04 17:22:01
前言:根据机器学习的数据集的目标值是离散or连续,处理的算法包含分类、回归两大类 sklearn的使用教程 https://www.jianshu.com/p/6ada34655862 目录 分类算法 k近邻算法 朴素贝叶斯 决策树、随机森林 分类回归 回归算法 线性回归 分类算法 k近邻算法 算法思想:一个样本与数据集中的k个样本最相似,如果k个样本中的大多数属于一个类别,则认识该样本属于这个类别; 最常见的两点之间或多点之间的距离表示法,又称之为欧几里得度量,它定义于欧几里得空间中。n维空间中两个点x1(x11,x12,…,x1n)与 x2(x21,x22,…,x2n)间的欧氏距离 实现: https://www.cnblogs.com/xiaotan-code/p/6680438.html from sklearn.neighbors import KNeighborsClassifier # 导包 knn = KNeighborsClassifer() # 定义一个分类器对象 knn.fit([特征值],[目标值]) # 调用模型 朴素贝叶斯 算法思想 : https://blog.csdn.net/Growing_hacker/article/details/89790230 实现 from sklearn.naive_bayes import MultinomialNB

模型剪枝学习笔记 --- Channel Pruning via Automatic Structure Search

可紊 提交于 2020-03-04 16:10:01
Channel Pruning via Automatic Structure Search 代码: https://github.com/lmbxmu/ABCPruner 论文下载链接: https://arxiv.org/abs/2001.08565 该论文是 厦大&鹏程实验室&北大&腾讯优图新提出的一种基于生物启发式搜索算法-人工蜂群(artifical bee colony)算法(ABC)的通道剪枝算法。 引入了类似传统机器学习中常用的生物进化算法—遗传,蚁群,布谷鸟算法的ABC,感觉挺有意思。 摘要 通道(channel)剪枝是压缩深度神经网络的主要方法之一。为此,大多数现有的剪枝方法着重于通过重要性/优化或基于经验法则设计的正则化来选择通道(filters),这会导致次剪枝。 在本文中,我们提出了一种新的基于人工蜂群(artifical bee colony)算法(ABC)的通道剪枝方法,称为ABCPruner,其目的是有效地找到最佳的剪枝结构,即每一层中的通道数,而不是选择“重要”通道。为了解决深层网络中难以剪枝的庞大组合,我们首先建议缩小保留通道限于特定空间的组合,这样可以大大减少剪枝结构的组合。然后,将对最佳剪枝结构的搜索公式化为一个优化问题,并集成ABC算法以自动方式解决该问题,以减少人为干扰。事实证明,ABCPruner更为有效,这也使端对端的微调得以有效进行

最短路之Floyd算法

╄→гoц情女王★ 提交于 2020-03-04 14:10:38
问题 已知一张有向图,求出每个点到其他点的最短路径,也就是多源最短路径的问题。 解析 Floyd算法的本质是一种动态规划的思想,它的转移方程为:mp[i,j]=min(mp[i,k]+mp[k,j],mp[i,j]),其中mp[i,j]代表从i点到j点的最短距离,所以可以枚举i点和j点,更新每个i到j的最短距离再枚举k,但是这样枚举计算mp[i,j],因为不能确定枚举的所有到k点为最短路径,一旦确定后,之后不会修改,所以应该先枚举k,再枚举i,j,这样就实现了Floyd算法。 从任意节点i到任意节点j的最短路径不外乎2种可能: 1)直接从节点i到节点j。 2)从节点i经过若干个节点k到节点j。 所以,我们假设mp(i,j)为节点i到节点j的最短路径的距离,对于每一个节点k,我们检查mp(i,k)+mp(k,j)<mp(i,j)是否成立,如果成立,证明从节点i到节点k再到节点j的路径比节点i直接到节点j的路径短,我们便设置mp(i,j)=mp(i,k)+mp(k,j),这样一来,当我们遍历完所有节点k,mp(i,j)中记录的便是节点i到节点j的最短路径的距离。 初始的距离矩阵: 0 2 6 4 inf 0 3 inf 7 inf 0 1 5 inf 12 0 本题的最短路径矩阵: 0 2 5 4 9 0 3 4 6 8 0 1 5 7 10 0 设计 枚举顶点k ∈ [ 1 , n

数据结构与算法系列八(递归见面礼)

你离开我真会死。 提交于 2020-03-04 12:56:40
1.引子 1.1.为什么要学习数据结构与算法? 有人说,数据结构与算法,计算机网络,与操作系统都一样,脱离日常开发,除了面试这辈子可能都用不到呀! 有人说,我是做业务开发的,只要熟练API,熟练框架,熟练各种中间件,写的代码不也能“飞”起来吗? 于是问题来了:为什么还要学习数据结构与算法呢? #理由一: 面试的时候,千万不要被数据结构与算法拖了后腿 #理由二: 你真的愿意做一辈子CRUD Boy吗 #理由三: 不想写出开源框架,中间件的工程师,不是好厨子 1.2.如何系统化学习数据结构与算法? 我想好了,还是需要学习数据结构与算法。但是我有两个困惑: 1.如何着手学习呢? 2.有哪些内容要学习呢? 学习方法推荐: #学习方法 1.从基础开始,系统化学习 2.多动手,每一种数据结构与算法,都自己用代码实现出来 3.思路更重要:理解实现思想,不要背代码 4.与日常开发结合,对应应用场景 学习内容推荐: 数据结构与算法内容比较多,我们本着实用原则,学习经典的、常用的数据结构、与常用算法 #学习内容: 1.数据结构的定义 2.算法的定义 3.复杂度分析 4.常用数据结构 数组、链表、栈、队列 散列表、二叉树、堆 跳表、图 5.常用算法 递归、排序、二分查找 搜索、哈希、贪心、分治 动态规划、字符串匹配 2.考考你 到目前为止,基于线性表的数据结构我们都看完了,简单回顾一下,它们是:数组

排序算法之冒泡排序

回眸只為那壹抹淺笑 提交于 2020-03-04 11:38:12
排序算法之冒泡排序 分析思路 :冒泡排序,顾名思义就是像冒气泡一样,可以从前冒到后,也可以从后冒到前。这里以从后冒到前,从小到大排序举例:从最后一个值开始,不断将其与前一个值进行比较,如果后面的值比前面的值要小,那就进行交换,这样遍历一次之后,序列第一个位置就已经是最小的值了,如此循环,O(n2)之后就可以全部排好序。 编程思路 : 顺序存储:如果序列为数组,我们可以采用两重for循环。第一重for循环用于记录未排好序序列的起点,第二重for循环用于遍历、比较和交换。 链式存储:如果序列为链表,我们可以采用双指针。第一个指针用于记录未排好序子链的起点,第二个指针用于遍历、比较和交换。(链式存储只能从前冒到后) 具体代码 : 顺序存储 void Emit_Bubble_Sort(int array[],int n) { for (int i = 0; i < n; i++) { for (int j = n-1; j > 0; j--) { if (array[j] < array[j - 1]) { int temp = array[j]; array[j] = array[j - 1]; array[j - 1] = temp; } } } } 链式存储 void Emit_Bubble_Sort(Node *Head) { Node *p=Head->next,*q=Head-

SSL握手过程

徘徊边缘 提交于 2020-03-04 10:47:01
1. 客户端将它所支持的 算法列表 和一个用作产生密钥的 随机数 发送给服务器; 2. 服务器从算法列表中 选择一种加密算法 ,并将它和一份包含服务器公用密钥的 证书 发送给客户端;该证书还包含了用于认证目的的服务器标识,服务器同时还提供了一个用作产生密钥的 随机数 ; 3. 客户端对服务器的证书进行验证(有关验证证书,可以参考 数字签名 ),并抽取服务器的公用密钥;然后,再产生一个称作 pre_master_secret 的随机密码串,并使用服务器的公用密钥对其进行加密(参考 非对称加/解密 ),并将加密后的信息发送给服务器; 4. 客户端与服务器端根据pre_master_secret以及客户端与服务器的随机数值 独立计算出加密和MAC密钥 (参考 DH密钥交换算法 )。 5. 客户端将所有握手消息的MAC值发送给服务器; 6. 服务器将所有握手消息的MAC值发送给客户端。 第5与第6步用以防止握手本身遭受篡改。设想一个攻击者想要控制客户端与服务器所使用的算法。客户端提供多种算法的情况相当常见,某些强度弱而某些强度强,以便能够与仅支持弱强度算法的服务器进行通信。攻击者可以删除客户端在第1步所提供的所有高强度算法,于是就迫使服务器选择一种弱强度的算法。第5步与第6步的MAC交换就能阻止这种攻击,因为客户端的MAC是根据原始消息计算得出的