连续向量最大和(一维模式识别)算法的分析与优化

简介: 输入:n个互相没有关联的数字(正负随机) 输出:该数组中连续数字的最大和     如在数组3 -4 5 2 -5 5 9 -9 -2 8中,连续数字最大和为5 2 -5 5 9这个数字序列的和,最大和为16 一、简单迭代算法    遇到这种问题,头脑中冒出的最直接最简单的就是这种算法。

输入:n个互相没有关联的数字(正负随机)

输出:该数组中连续数字的最大和

    如在数组3 -4 5 2 -5 5 9 -9 -2 8中,连续数字最大和为5 2 -5 5 9这个数字序列的和,最大和为16

一、简单迭代算法

    遇到这种问题,头脑中冒出的最直接最简单的就是这种算法。用一个双重循环,一个代表起始位置,一个标注末尾,计算其中元素的和,在与最大值比较,得出新的最大值。

  1. for(int i = 0;i<N;i++)  
  2.     {  
  3.         int sum = 0;  
  4.         for(int j = i;j<N;j++)  
  5.         {  
  6.             sum += arr[j];  
  7.             max = MAX(sum,max);  
  8.         }  
  9.     }

    对于输入规模n来说,该解法会执行n^2步,所以该算法为平方时间。

二、动态规划的迭代算法

    我们可以用一个数组sum[i],代表前i个整数和这样一种状态。所以后一个状态就由前一个状态加arr[i]得到,而两个状态相减则得到了两个整数中间数的和。

  1. for(int i = 1;i<N;i++)  
  2.     sum[i] = sum[i-1]+arr[i];  
  3.     
  4. for(int i = N-1;i>=0;i--)  
  5.     for(int j = i;j>=0;j--)  
  6.     {  
  7.         int sum1 = sum[i] - sum[j];  
  8.         max = MAX(max,sum1);  
  9.     }  

    对于输入规模n来说,该解法会执行n^2步,所以该算法仍然为平方时间。

三、分治算法

    将一个数组的最大和问题转换为两个数组的最大和问题,然后递归的找出两个向量的最大和。不过要考虑一种情况就是和最大的那一组数组可能跨越两个子数组的边界,所以需要对边界的数组进行处理。对于跨越边界的问题,分别在两个数组中从边界开始,计算边界的最大和,再将两个边界最大和相加,与子数组的最大和比较。

  1. float maxsum3(int l,int u)  
  2. {  
  3.     if(l>u)  
  4.         return 0;  
  5.     if(l == u)  
  6.         return MAX(0,arr[l]);  
  7.     int m = (l+u)/2;  
  8.         
  9.     int lmax = 0,sum = 0;  
  10.     for(int i = m;i>=l;i--)  
  11.     {  
  12.         sum += arr[i];  
  13.         lmax = MAX(lmax,sum);  
  14.     }  
  15.         
  16.     int rmax = 0;  
  17.     sum = 0;  
  18.     for(int i = m+1;i<=u;i++)  
  19.     {  
  20.         sum += arr[i];  
  21.         rmax = MAX(rmax,sum);  
  22.     }  
  23.         
  24.     return max((float)lmax+rmax,maxsum3(l,m),maxsum3(m+1,u));  
  25. }  

    可以看到子数组求值的方向都是从边界(中间)向两边展开的。

    该算法每次执行n次操作,递归总共有log n次,所以时间复杂度为O(n lon n)。

四、扫描算法

    在这个问题中,正负数随机出现,所以我们默认在一个较长的数组里,最大和是大于零的。对一个元素不多的数组进行直觉运算时,我们总是习惯于从左往右开始扫描数字,当发现几个数字的和小于0时就直接略过前面的数字,从新位置开始扫描,并记录下出现过的最大值,直到扫描完整个数组。1977年,当这个问题(模式匹配)被布朗大学的Grenander提出时,他独立设计出了两个平方算法。后来他将问题讲给Michael Shamos听,后者提出了分治算法。那时,他们俩都认为没有更好的算法了,直到后来Michael Shamos在卡耐基——梅隆大学的一次研讨会上提起了这个问题,而参会的一个统计学家Jay Kadane在一分钟内就设计除了线性时间的扫描算法。不过这下,应该不会再有更优的算法了,毕竟任何算法都至少要花费O(n)的时间。

  1. int maxsofar = 0,maxendinghere = 0;  
  2.     
  3. for(int i = 0;i<N;i++)  
  4. {  
  5.     maxendinghere = MAX(maxendinghere+arr[i],0);  
  6. printf("%d %d",i,maxendinghere);   
  7.     maxsofar = MAX(maxsofar,maxendinghere);  
  8. printf(" %d\n",maxsofar);  
  9. }  
  10. printf("%d",maxsofar);  

    对于{3,-4,2,5,-5,5,9,-9,-2,8}这个数组,过程是这样的:

    线性时间的算法,效率嘛,谁用谁知道。

 

注:四个算法的代码在最大和详细代码

目录
相关文章
|
1月前
|
机器学习/深度学习 人工智能 监控
AI算法分析,智慧城管AI智能识别系统源码
AI视频分析技术应用于智慧城管系统,通过监控摄像头实时识别违法行为,如违规摆摊、垃圾、违章停车等,实现非现场执法和预警。算法平台检测街面秩序(出店、游商、机动车、占道)和市容环境(垃圾、晾晒、垃圾桶、路面不洁、漂浮物、乱堆物料),助力及时处理问题,提升城市管理效率。
AI算法分析,智慧城管AI智能识别系统源码
|
19小时前
|
算法 数据可视化 大数据
圆堆图circle packing算法可视化分析电商平台网红零食销量采集数据
圆堆图circle packing算法可视化分析电商平台网红零食销量采集数据
28 13
|
7天前
|
算法 数据可视化 Python
Python中LARS和Lasso回归之最小角算法Lars分析波士顿住房数据实例
Python中LARS和Lasso回归之最小角算法Lars分析波士顿住房数据实例
11 0
|
7天前
|
算法 定位技术 Windows
R语言最大流最小割定理和最短路径算法分析交通网络流量拥堵问题
R语言最大流最小割定理和最短路径算法分析交通网络流量拥堵问题
13 4
|
8天前
|
算法
R语言使用随机技术差分进化算法优化的Nelson-Siegel-Svensson模型
R语言使用随机技术差分进化算法优化的Nelson-Siegel-Svensson模型
16 0
|
15天前
|
算法 数据处理 C语言
【数据结构与算法】快速排序(详解:快排的Hoare原版,挖坑法和双指针法|避免快排最坏时间复杂度的两种解决方案|小区间优化|非递归的快排)
【数据结构与算法】快速排序(详解:快排的Hoare原版,挖坑法和双指针法|避免快排最坏时间复杂度的两种解决方案|小区间优化|非递归的快排)
|
17天前
|
算法 索引
【算法与数据结构】深入二叉树实现超详解(全源码优化)
【算法与数据结构】深入二叉树实现超详解(全源码优化)
|
30天前
|
机器学习/深度学习 算法 大数据
基于PyTorch对凸函数采用SGD算法优化实例(附源码)
基于PyTorch对凸函数采用SGD算法优化实例(附源码)
29 3
|
30天前
|
算法
TOP-K问题和向上调整算法和向下调整算法的时间复杂度问题的分析
TOP-K问题和向上调整算法和向下调整算法的时间复杂度问题的分析
19 1
|
1月前
|
算法 搜索推荐 测试技术
python排序算法及优化学习笔记1
python实现的简单的排序算法,以及算法优化,学习笔记1
33 1