• 2021-04-18 08:19:47

Quick search for local extremes

The new function extr.m analyses the given real vector carrying a sequence of samples to be analyzed. At the end, it returns a cell array of extreme positions in the sequence. The cell array consists of two cells only. The first one contains the logical vector of maxima and the other the similar one of minima. Should more equal values be present in adjacent elements of the vector, only one position is returned. The attention is also paid on low memory requirements and a speed of the procedure.

Forms of calls:

L = extr(x); % Find true local extremes

% ..... x vector containing a sequence to be analyzed,

% ..... L cell array {L(1), L(2)}, where

% ..... L(1) is logical vector of positions of maxima,

% ..... L(2) is logical vector of positions of minima.

There are also circumstances, when the processing time is critical for a user, while the exact true extrems are of less priority. In that case he may use:

L = extr(c,0); % Find true and false local extrems.

False extrems form pairs of equal value minimum-maximum laying somewhere on the trend of the sequence. They are not extrems, but they do not harm in certain cases of consecutive processing.

Examples:

demoXtr; % See the program and figure demoXtr.jpg

L = extr(x);

y = x(L(1)|L(2)); % y is a vector of all extremes

clear, x=rand(1e7,1)-.5; tic, L=extr(x); toc

Elapsed time is 2.974584 seconds. % (3GHz PC, Windows XP Prof.)

clear, x=rand(1e7,1)-.5; tic, L=extr(x,0); toc

Elapsed time is 1.392926 seconds. % (3GHz PC, Windows XP Prof.)

Hopefully, the function is error-free. If not, please, let me know.

更多相关内容
• 为求得类似仿真函数的黑箱函数优化问题的全部局部极值点，提出了一种基于适应值曲面分析的新算法。首先，对适应值距离相关系数(fitness distance correlation, FDC)进行了改进，探讨了改进FDC指标与适应值曲面崎岖度...
• 遗传算法是基于达尔文进化论和孟德尔遗传学而发展形成，它是处理非线性模型参数估计的一类通用性较强的寻优方法。遗传算法寻求最优解的基本思想是：从代表问题的可能潜在解集的一个种群出发，此种群由基因编码的一定...
• 本次实验利用了基于局部极值的分水岭算法来实现圆斑点的检测。在OPENCV中提供了simpleBlobDetector特征检测器来实现这种斑点检测算法，正如它的名称，该算法使用最简单的方式来检测斑点类的特征点，效果较好，设置...

本次实验利用了基于局部极值的分水岭算法来实现圆斑点的检测。在OPENCV中提供了simpleBlobDetector特征检测器来实现这种斑点检测算法，正如它的名称，该算法使用最简单的方式来检测斑点类的特征点，效果较好，设置较为宽松的参数，就能取得较好的效果。

### 一 算法的步骤

#### 第一步 多次二值化图像

首先通过一系列连续的阈值把输入的灰度图像转换为一个二值图像的集合，阈值范围为[T1, T2]，步长为t，则所有阈值为：
T1，T1+t，T1+2t，T1+3t，……，T2

#### 第二步 确定候选圆点

通过检测每一幅二值图像的边缘的方式提取出每一幅二值图像的连通区域，我们可以认为由边界所围成的不同的连通区域就是该二值图像的斑点。其中，并不是所有的二值图像的连通区域都可以认为是二值图像的斑点，我们通过一些限定条件来得到更准确的斑点。这些限定条件包括颜色，面积和形状，斑点的形状又可以用圆度，偏心率，或凸度来表示，具体参数和计算方法查看参数部分介绍。

#### 第三步 对图像圆点进行分类，确定目标圆点

根据所有二值图像斑点的中心坐标对二值图像斑点进行分类，从而形成灰度图像的斑点，属于一类的那些二值图像斑点最终形成灰度图像的斑点，具体来说就是，灰度图像的斑点是由中心坐标间的距离小于阈值的那些二值图像斑点所组成的，即这些二值图像斑点属于该灰度图像斑点；

### 二 参数部分

filterByColor斑点颜色。

filterByArea斑点面积。连通区域的面积太大和太小都不是斑 。所以我们需要计算连通区域的面积，只有当该面积在我们所设定的最大面积和最小面积之间时，该连通区域才作为斑点被保留下来。

filterByCircularity 斑点圆度。任意形状的圆度C定义为：

其中，S和p分别表示该形状的面积和周长，当C为1时，表示该形状是一个完美的圆形，而当C为0时，表示该形状是一个逐渐拉长的多边形。

filterByInertia斑点惯性率。偏心率是指某一椭圆轨道与理想圆形的偏离程度，长椭圆轨道的偏心率高，而近于圆形的轨道的偏心率低。圆形的偏心率等于0，椭圆的偏心率介于0和1之间，而偏心率等于1表示的是抛物线。直接计算斑点的偏心率较为复杂，但利用图像矩的概念计算图形的惯性率，再由惯性率计算偏心率较为方便。偏心率E和惯性率I之间的关系为：

因此圆形的惯性率等于1，惯性率越接近1，圆形的程度越高（在实际操作中并没有用到）。
filterByConvexity 表示斑点凸度。在平面中，凸形图指的是图形的所有部分都在由该图形切线所围成的区域的内部。我们可以用凸度来表示斑点凹凸的程度，凸度V的定义为：

其中，H表示该斑点的凸壳面积
minDistBetweenBlobs斑点距离的最小阈值，中心坐标间的距离小于该值就认为为同一个斑点。

### 三 源码

#include "opencv2/opencv.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/features2d/features2d.hpp"

using namespace cv;
using namespace std;

int main(int argc, char* argv[])
{
Mat srcGrayImage, srcGrayImage1, srcImage1, keyPointImage11, keyPointImage21;
if (srcImage.channels() == 3)
{
cvtColor(srcImage, srcGrayImage, CV_RGB2GRAY);
}
else
{
srcImage.copyTo(srcGrayImage);
}
GaussianBlur(srcGrayImage, srcGrayImage1,Size(11,11),0,0);
vector<KeyPoint>detectKeyPoint;
Mat keyPointImage1, keyPointImage2;

SimpleBlobDetector::Params params;

params.filterByArea = true;
params.minArea = 15;
params.maxArea = 1500;

params.thresholdStep = 10;    //二值化的阈值步长，即公式1的t
params.minThreshold = 50 ;
params.maxThreshold = 200;

params.filterByCircularity = true;  //斑点圆度
params.minCircularity = 0.8;
params.maxCircularity = 1;

params.filterByConvexity = false;    //斑点凸度
params.minConvexity = (float)0.5;
params.maxConvexity = 1;

params.filterByInertia = false;  //斑点惯性率
params.minInertiaRatio = (float)0.4;
params.maxInertiaRatio = 1;

params.filterByColor = true;
params.blobColor = 255;//白色

params.minRepeatability = 2;//重复的最小次数，
params.minDistBetweenBlobs = 20; //最小的斑点距离
Ptr<SimpleBlobDetector> sbd = SimpleBlobDetector::create(params);
sbd->detect(srcGrayImage1, detectKeyPoint);
drawKeypoints(srcImage, detectKeyPoint, keyPointImage1, Scalar(0, 255, 0), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);

resize(srcImage, srcImage1, Size(srcImage.cols / 4, srcImage.rows / 4), 0, 0, INTER_LINEAR);
imshow("src image", srcImage1);
resize(keyPointImage1, keyPointImage11, Size(keyPointImage1.cols /4, keyPointImage1.rows /4), 0, 0, INTER_LINEAR);
imshow("keyPoint image1", keyPointImage11);
imwrite("spos71_run7_img190.jpg", keyPointImage1);

waitKey(0);
return 0;
}

![这里写图片描述]

## 五 补充说明

保存特征点，绘制特征点，在使用中是不透明的，下面做一个简要介绍。

1.KeyPoint特征点类
保存特征点各种信息的KeyPoint类在使用的主要属性：

class KeyPoint
{
Point2f  pt;  //特征点坐标
float  size; //特征点邻域直径
float  angle; //特征点的方向，值为0~360，负值表示不使用
float  response; //特征点的响应强度，代表了该点是特征点的程度，可以用于后续处理中特征点排序
int  octave; //特征点所在的图像金字塔的组
int  class_id; //用于聚类的id
}

主要包含的特征点信息有：位置、邻域直径、特征的方向、响应强度、多尺度信息和分类等。特征点匹配的实现就是通过逐个匹配特征点的这些信息。

2.drawKeypoints特征点绘制

opencv提供了一个快速绘制特征点的函数drawKeypoints，函数原型：

void drawKeypoints( const Mat& image, const vector<KeyPoint>& keypoints, CV_OUT Mat& outImage,  const Scalar&color=Scalar::all(-1), int flags=DrawMatchesFlags::DEFAULT );  

第一个参数image：原始图像，可以使三通道或单通道图像；
第二个参数keypoints：特征点向量，向量内每一个元素是一个KeyPoint对象，包含了特征点的各种属性信息；
第三个参数outImage：特征点绘制的画布图像，可以是原图像；
第四个参数color：绘制的特征点的颜色信息，默认绘制的是随机彩色；
第五个参数flags：特征点的绘制模式，其实就是设置特征点的那些信息需要绘制，那些不需要绘制，有以下几种模式可选：
DEFAULT：只绘制特征点的坐标点,显示在图像上就是一个个小圆点,每个小圆点的圆心坐标都是特征点的坐标。
DRAW_OVER_OUTIMG：函数不创建输出的图像,而是直接在输出图像变量空间绘制,要求本身输出图像变量就 是一个初始化好了的,size与type都是已经初始化好的变量
NOT_DRAW_SINGLE_POINTS：单点的特征点不被绘制
DRAW_RICH_KEYPOINTS：绘制特征点的时候绘制的是一个个带有方向的圆,这种方法同时显示图像的坐,size，和方向,是最能显示特征的一种绘制方式。

### 六 参考

展开全文
• 特里斯坦·乌塞尔图像极值查找器... 某些极值可能无法在单个点上进行数学定义，即鞍点下方的示例是像素双峰——这是一个图像离散化的特性，不是算法的问题。 图像边缘不能出现图像极值。 如果噪声是一个问题，您可以
• robot容易陷入局部极小值：当所受引力与斥力的合立场在某一点有局部极值时，在局部极小值点周围的各个位置的合力场梯度都指向局部极小值，导致robot在局部极小值点周围振荡，无法自行走出该区域。
• ## 局部搜索算法总结

千次阅读 2021-05-26 06:10:43
通常考察一个算法的性能通常...一般的局部搜索算法一旦陷入局部极值点，算法就在该点处结束，这时得到的可能是一个糟糕的结果。解决的方法就，目标函数差的点，被选中的概率小。考虑归一化问题，使得邻域内所有点被...

通常考察一个算法的性能通常用局部搜索能力和全局收敛能力这两个指标。局部搜索是指能够无穷接近最优解的能力，而全局收敛能力是指找到全局最优解所在大致位置的能力。局部搜索能力和全局搜索能力，缺一不可。向最优解的导向，对于任何智能算法的性能都是很重要的。

局部最优问题(或叫局部峰值局部陷井)：现实问题中，f在D上往往有多个局部的极值点。一般的局部搜索算法一旦陷入局部极值点，算法就在该点处结束，这时得到的可能是一个糟糕的结果。解决的方法就，目标函数差的点，被选中的概率小。考虑归一化问题，使得邻域内所有点被选中的概率和为1。总的来说，局部搜索的方法，就是依赖于对解空间进行按邻域搜索。

起始点问题：一般的局部搜索算法是否能找到全局最优解，与初始点的位置有很大的依赖关系。解决的方法就是随机生成一些初始点，从每个初始点出发进行搜索，找到各自的最优解。再从这些最优解中选择一个最好的结果作为最终的结果。

学习的重要性：
1、直接用于无约束的实际问题；
2、其基本思想和逻辑结构可以推广到约束问题；
3、约束问题可以转化成无约束问题求解。

方法分类：
1、间接法：对简单问题，求解必要条件或充分条件；
2、迭代算法：
零阶法：只需计算函数值 f(x) （直接法）
一阶法：需计算 ▽f(x)       （梯度法）
二阶法：需计算 ▽2f(x)      （梯度法）

直接搜索法优点：计算不太复杂；易于实施与快速调试；所需的准备时间较少
一、单纯形搜索法：

1962年由Spendley, Hext和Himsworth提出，80年代得到证明。单纯形搜索法是一种无约束最优化的直接方法。单纯形法是求解非线性多元函数、无约束最小化问题的有效方法之一。在许多技术领域内，都取得了有效的成果。

所谓的单纯形是指n维空间E^n中具有n+1个顶点的凸多面体。比如一维空间中的线段，二维空间中的三角形，三维空间中的四面体等，均为相应空间中的单纯形。单纯形搜索法与其它直接方法相比，基本思想有所不同，在这种方法中，给定维空间E^n中一个单纯形后，求出n+1个顶点上的函数值，确定出有最大函数值的点(称为最高点)和最小函数值的点(称为最低点)，然后通过反射、扩展、压缩等方法(几种方法不一定同时使用)求出一个较好点，用它取代最高点，构成新的单纯形，或者通过向最低点收缩形成新的单纯形，用这样的方法逼近极小点。
单纯形搜索法的基本思想是：先找出一个基本可行解，对它进行鉴别，看是否是最优解；若不是，则按照一定法则转换到另一改进的基本可行解,再鉴别；若仍不是，则再转换，按此重复进行。因基本可行解的个数有限，故经有限次转换必能得出问题的最优解。

一般解题步骤可归纳如下：

①把线性规划问题的约束方程组表达成典范型方程组，找出基本可行解作为初始基本可行解。

②若基本可行解不存在，即约束条件有矛盾，则问题无解。

③若基本可行解存在，从初始基本可行解作为起点，根据最优性条件和可行性条件，引入非基变量取代某一基变量，找出目标函数值更优的另一基本可行解。

④按步骤3进行迭代,直到对应检验数满足最优性条件（这时目标函数值不能再改善），即得到问题的最优解。

⑤若迭代过程中发现问题的目标函数值无界，则终止迭代。

二、Powell共轭方向法（方向加速法）

1964年由Powell提出，后经Zangwoll（1967年）和Brent（1973年）改进。该算法有效地利用了迭代过程中的历史信息，建立起能加速收敛的方向。

理论基础：以二次对称函数为模型进行研究。

在非线性目标函数中，最简单的是二次函数，故任何对一般函数有效的方法首先应对二次函数有效；在最优点附近，非线性函数可用一个二次函数作近似，故对二次函数使用良好的方法，通常对一般函数也有效；很多实际问题的目标函数是二次函数。

设A是n×n阶对称正定矩阵，p(0), p(1)为两个n维向量，若 成立p(0)T A p(1) = 0，则称向量p(0)与p(1)为A共轭或A正交，称该两向量的方向为A共轭方向。

特点：Powell法本质上是以正定二次函数为背景，以共轭方向为基础的一种方法。不同于其他的直接法, Powell法有一套完整的理论体系，故其计算效率高于其他直接法。若每次迭代的前n 个搜索方向都线性无关时，则原始Powell法具有二次终止性 Powell法使用一维搜索，而不是跳跃的探测步。Powell法的搜索方向不一定为下降方向。

不足：在原始Powell法中，必须保持每次迭代中前n个搜索方向线性无关，否则将永远得不到问题的最优解。

为了避免出现搜索方向组线性相关的现象，Powell及其他人对原始Powell法进行修正：

三、梯度法

又名最速下降法，求解无约束多元函数极值的数值方法，早在1847年就已由柯西(Cauchy))提出。它是导出其他更为实用、更为有效的优化方法的理论基础。因此，梯度法是无约束优化方法中最基本的方法之一。该方法选取搜索方向Pκ的出发点是：怎样选取Pk可使ƒ(X)下降得最快？或者说使ƒ(Xκ+λΡκ)-ƒ(Χκ)<0且不等式左式的绝对值尽量大。

目标：求出平稳点（满足Ñf(x)=0的x * ）。对给定的解，按负梯度方向搜索其邻域解，若邻域中有更优的解（根据给定的评估函数评定），则移动至该邻域解，继续寻找，直至找不到为止。此时，就找到了局部最优解。方法非常简单，但是缺陷也很明显，即陷入到局部最优解之后无法跳出。

注意：最速下降法的搜索路径呈直角锯齿形，相邻两个搜索方向是正交的。

1、优点：计算简单，需记忆的容量小；对初始点要求低，稳定性高；远离极小点时收敛快，常作为其它方法的第一步。

2、缺点：收敛速度较慢（线性或不高于线性），原因是最速下降方向只有在该点附近有意义。直线搜索可能会产生一些问题，可能会“之字型”地下降。尤其当目标函数等值面是很扁的椭圆、椭球或类似图形时，收敛更慢。

四、Newton法

由最速下降法可知，从全局角度来看，负梯度方向一般不是一个特别好的方向，有没有更好的方向？

基本思想：利用目标函数f(x)在x(k)处的二阶Taylor展开式去近似目标函数，用二次函数的极小点去逼近目标函数的极小点。

或

1、Newton法的最大优点是：Newton法是局部收敛的，当初始点选得合适时收敛很快，具有二阶收敛速度，是目前算法中最快的一种。 对初始点要求高，一般要求初始点离极小点较近，否则不收敛。有时即使是收敛的，但因初始点离极大点或鞍点较近，会收敛于极大点或鞍点。

2、Newton法的搜索方向－H (x)－1 g(x)，称为Newton方向，是一个好方向，对二次函数此方向直指平稳点。如果H(x(k))是正定的，则H(x(k))－1必存在，从而算法是可行的，并且保证求得的平稳点是极小点。但在迭代过程中要求H(x(k))是正定的这一条件不一定能保证，因而它不一定是下降方向。一般在极小点附近的Hesse矩阵容易为正定的。所以基本Newton法在极小点附近才比较有效。

五、共轭梯度法

共轭梯度法最早是又Hestenes和Stiefle（1952）提出来的，用于解正定系数矩阵的线性方程组，在这个基础上，Fletcher和Reeves （1964）首先提出了解非线性最优化问题的共轭梯度法。由于共轭梯度法不需要矩阵存储，且有较快的收敛速度和二次终止性等优点，现在共轭梯度法已经广泛地应用与实际问题中。

共轭梯度法是一个典型的共轭方向法，它的每一个搜索方向是互相共轭的，而这些搜索方向d仅仅是负梯度方向与上一次迭代的搜索方向的组合。在各种优化算法中，共轭梯度法是非常重要的一种。其优点是所需存储量小，具有步收敛性，稳定性高，而且不需要任何外来参数。

1、共轭梯度法不需要预先估计任何参数就可以计算，每次迭代所需的计算，主要是向量之间的运算，便于并行化。程序简单，对大规模问题很有吸引力。对一般函数为超线性收敛。

2、共轭梯度法的收敛速度比最速下降法要快得多，同时也避免了要求海塞矩阵的计算。收敛速度依赖于一维搜索的精确性及Hesse矩阵的特征值的分布。

一、爬山法(Hill-Climbing)

爬山算法是一种简单的贪心搜索算法，该算法每次从当前解的临近解空间中选择一个最优解作为当前解，直到达到一个局部最优解。爬山算法实现很简单，其主要缺点是会陷入局部最优解，而不一定能搜索到全局最优解。如下图所示：假设C点为当前解，爬山算法搜索到A点这个局部最优解就会停止搜索，因为在A点无论向那个方向小幅度移动都不能得到更优的解。

爬山法是向值增加的方向持续移动到简单循环过程，算法在到达一个“峰顶”时终止，此时相邻状态中没有比该“峰顶”更高的值。爬山法不维护搜索树，当前节点只需要记录当前状态及其目标函数值；爬山法不会前瞻与当前状态不直接相邻的状态的值——“就像健忘的人在大雾中试图登顶珠峰一样”。爬山法从来不会“下山”，只会向值比当前节点好的方向搜索，因而肯定不完备，很容易停留在局部极值上。
function HillClimbing(problem) return 一个局部最优状态
输入：problem
局部变量：current, 一个节点
neighbor，一个节点
current= MakeNode(Initial-State(problem));
loop do
neighbor= a highest-valued successor of current ;
if VALUE[neighbor] <= VALUE[current] then return STATE[current];
current= neighbor ;
爬山法又称贪婪局部搜索，只是选择相邻状态中最好的一个。尽管贪婪是七宗罪之一，但是贪婪算法往往能够获得很好的效果。当然，爬山法会遇到以下问题：

（1）局部极值

（2）山脊：造成一系列的局部极值

（3）高原：平坦的局部极值区域——解决办法：继续侧向移动
随机爬山法：在上山移动中，随机选择下一步，选择的概率随着上山移动到陡峭程度而变化。

首选爬山法：随机地生成后继节点直到生成一个优于当前节点的后继。

随机重新开始的爬山法：“如果一开始没有成功，那么尝试，继续尝试”算法通过随机生成的初始状态来进行一系列的爬山法搜索，找到目标时停止搜索。该算法以概率1接近于完备：因为算法最终会生成一个目标状态作为初始状态。如果每次爬山搜索成功的概率为p，则需要重新开始搜索的期望次数为 1/p。

二、模拟退火算法（Simulated Annealing)

“模拟退火”算法是源于对热力学中退火过程的模拟，在某一给定初温下，通过缓慢下降温度参数，使算法能够在多项式时间内给出一个近似最优解。

爬山法是完完全全的贪心法，每次都鼠目寸光的选择一个当前最优解，因此只能搜索到局部的最优值。模拟退火其实也是一种贪心算法，但是它的搜索过程引入了随机因素。模拟退火算法与爬山法类似，但是它没有选择最佳的移动，而是选择随机的移动。如果该移动使情况得到改善，那么接受该移动；否则，算法以某个概率接受该移动。因此有可能会跳出这个局部的最优解，达到全局的最优解。以上图为例，模拟退火算法在搜索到局部最优解A后，会以一定的概率接受到E的移动。也许经过几次这样的不是局部最优的移动后会到达D点，于是就跳出了局部最大值A。

模拟退火的原理：我们将热力学的理论套用到统计学上，将搜寻空间内每一点想像成空气内的分子；分子的能量，就是它本身的动能；而搜寻空间内的每一点，也像空气分子一样带有“能量”，以表示该点对命题的合适程度。算法先以搜寻空间内一个任意点作起始：每一步先选择一个“邻居”，然后再计算从现有位置到达“邻居”的概率。可以证明，模拟退火算法所得解依概率收敛到全局最优解。

当陷入局部最优之后，模拟退火算法要求概率根据算法进行过程中，逐步降低（逐渐降低才能趋向稳定）其跳出局部最优的概率，使其越来越趋于稳定。这一特性增加也同样存在缺陷，即对于全局最优解，也存在一定概率跳出，从而使得求解过程不稳定。

随着邻域的范围的增大，跳出局部极小区域,最终进入全局极小区域的概率越来越大，但是代价是总的迭代次数增加。但是随着邻域范围的增大，会出现所谓的在极值附近来回”振荡”而无法落入极值点的现象。可以推测,随着邻域范围的进一步增大及其随机特性，模拟退火算法将退化到随机寻找极值并进行记录极值的算法。当然这种算法也存在问题，即对于某些情况下，也不易达到全局最优。例如，解空间中仅有两个局部最优，其中一个是全局最优，那么模拟退火似乎并不一定总能进入到全局最优解当中。

Create initial solution S

repeat

for i=1 to iteration-length do

Generate a random transition from S to Si

If ( C(S) <= C(Si) ) then

S=Si

else if( exp(C(S)-C(Si))/kt > random[0,1) ) then

S=Si

Reduce Temperature t

until ( no change in C(S) )

C(S): Cost or Loss function of Solution S.

1、在其他参数合适的情况下，初始解的位置与邻域结构是2个重要因素。

2、初始解的位置与邻域结构的设计之间对于找到最优解的问题而言存在依赖关系。随着邻域的范围的增大，跳出局部极小区域,最终进入全局极小区域的概率越来越大，同时也可能会产生振荡,无法落入极值区域。

3、模拟退火本质上也是一种 暴力搜索，只不过是利用随机的性质和局部极值区域连续(也取决于求解问题中邻域的结构)的特性避免了大量计算，进而在较短时间内从某种概率上逼近局部最优值和全局最优值。

三、禁忌搜索（Tabu Search或Taboo Search，TS）

禁忌搜索（Tabu Search或Taboo Search，简称TS）的思想最早由Glover(1986)提出，它是对局部领域搜索的一种扩展，是一种全局逐步寻优算法，是对人类智力过程的一种模拟。TS算法通过引入一个灵活的存储结构和相应的禁忌准则来避免迂回搜索，并通过藐视准则来赦免一些被禁忌的优良状态，进而保证多样化的有效探索以最终实现全局优化。相对于模拟退火和遗传算法，TS是又一种搜索特点不同的meta-heuristic算法。

禁忌搜索是人工智能的一种体现，是局部领域搜索的一种扩展。禁忌搜索最重要的思想是标记对应已搜索的局部最优解的一些对象，并在进一步的迭代搜索中尽量避开这些对象（而不是绝对禁止循环），从而保证对不同的有效搜索途径的探索。禁忌搜索涉及到领域（neighborhood）、禁忌表（tabu list）、禁忌长度（tabu 1ength）、候选解（candidate）、藐视准则（candidate）等概念。

简单TS算法的基本思想描述如下：

（1）给定算法参数，随机产生初始解x，置禁忌表为空。

（2）判断算法终止条件是否满足？若是，则结束算法并输出优化结果；否则，继续以下步骤。

（3）利用当前解的邻域函数产生其所有（或若干）邻域解，并从中确定若干候选解。

（4）对候选解判断特赦准则是否满足？若成立，则用满足特赦准则的最佳状态y替代x成为新的当前解，即x=y，并用与y对应的禁忌对象替换最早进入禁忌表的禁忌对象，同时用y替换“best so far”状态，然后转步骤6；否则，继续以下步骤。

（5）判断候选解对应的各对象的禁忌属性，选择候选解集中非禁忌对象对应的最佳状态为新的当前解，同时用与之对应的禁忌对象替换最早进入禁忌表的禁忌对象元素。

（6）转步骤（2）。

局部搜索，模拟退火，遗传算法，禁忌搜索的形象比喻：为了找出地球上最高的山，一群有志气的兔子们开始想办法。
1、兔子朝着比现在高的地方跳去。他们找到了不远处的最高山峰。但是这座山不一定是珠穆朗玛峰。这就是局部搜索，它不能保证局部最优值就是全局最优值。
2、兔子喝醉了。他随机地跳了很长时间。这期间，它可能走向高处，也可能踏入平地。但是，他渐渐清醒了并朝最高方向跳去。这就是模拟退火。
3、兔子们吃了失忆药片，并被发射到太空，然后随机落到了地球上的某些地方。他们不知道自己的使命是什么。但是，如果你过几年就杀死一部分海拔低的兔子，多产的兔子们自己就会找到珠穆朗玛峰。这就是遗传算法。
4、兔子们知道一个兔的力量是渺小的。他们互相转告着，哪里的山已经找过，并且找过的每一座山他们都留下一只兔子做记号。他们制定了下一步去哪里寻找的策略。这就是禁忌搜索。

展开全文
• 它是完全矢量化的，而且速度非常快。 设计用于 EMD/HHT 算法
• 利用matlab，自编的二维曲线极值点寻找方法。代码里面对输入输出有详细的描述。
• 当出现局部极大值的时候，会有明显的特征nums[i]>nums[i-1]&&nums[i]>nums[i+1]，依据这个方法进行数组遍历寻找适合的极值点。 记录INT_MIN的使用，在c++中INT_MIN代表一个极小的数。具有头文件约束limits.h。 #...

## 寻找峰值-LeetCode.162

问题
峰值元素是指其值大于左右相邻值的元素。

给你一个输入数组 nums，找到峰值元素并返回其索引。数组可能包含多个峰值，在这种情况下，返回 任何一个峰值 所在位置即可。

你可以假设 nums[-1] = nums[n] = -∞ 。

示例1

输入：nums = [1,2,3,1]
输出：2
解释：3 是峰值元素，你的函数应该返回其索引 2。
示例2
输入：nums = [1,2,1,3,5,6,4]
输出：1 或 5
解释：你的函数可以返回索引 1，其峰值元素为 2；
或者返回索引 5， 其峰值元素为 6。

方法1
拿到题首先使用暴力法求解，即判断局部极大值的特点。当出现局部极大值的时候，会有明显的特征nums[i]>nums[i-1]&&nums[i]>nums[i+1]，依据这个方法进行数组遍历寻找适合的极值点。
记录INT_MIN的使用，在c++中INT_MIN代表一个极小的数。具有头文件约束limits.h。
#define INT_MAX 2147483647
#define INT_MIN -2147483648

暴力法代码：

class Solution {
public:
int findPeakElement(vector<int>& nums) {
//暴力法
if(nums.empty()){
return -1;
} else if(nums.size()==1){
return 0;
}
int N=nums.size();
nums.insert(nums.begin(),INT_MIN);//注意题目假设假设 nums[-1] = nums[n] = -∞
nums.push_back(INT_MIN);//为了循环时候遍历到所有的元素
for(int i=1;i<=N;i++){
if(nums[i]>nums[i-1]&&nums[i]>nums[i+1]){
return i-1;
}
}
return -1;
}
};


方法二
观察题目要求，查找峰值时必然会出现nums[i]>nums[i+1]，数组两边可以看成无穷小，即不论如何数组都会出现峰值趋势的拐点，数组下降趋势，则第一个点是峰值点，上升趋势则最后一个点是峰值点。
代码：

class Solution {
public:
int findPeakElement(vector<int>& nums) {
//二分法
if(nums.empty()){
return -1;
}
int N=nums.size();
for(int i=0;i<N-1;i++){
if(nums[i]>nums[i+1])
return i;
}
return N-1;
}
};


方法三
二分法，使用二分法，需要理解二分法的原理。理解如下：

 nums[mid] > nums[mid+1]降序，说明峰值在左边
nums[mid] < nums[mid+1]升序，说明峰值在右边


代码：

class Solution {
public:
int findPeakElement(vector<int>& nums) {
//二分法
if(nums.empty()){
return -1;
} else if(nums.size()==1)   return 0;
int N=nums.size();
int left=0,right=N-1,mid=0;
while(left<right){
mid=left+(right-left)/2;
if(nums[mid]>nums[mid+1]) right=mid;
else left=mid+1;
}
return left;
}
};


如有错误，欢迎评论批评指教，谢谢！

展开全文
• 结果表明，Matlab最优化工具箱中的导数算法在多层膜局部优化设计上具有更好的局部极值搜索性能和收敛速度；非导数算法性能较差且收敛时间较长，但具有更多的搜索路径，较适用于设计初期开拓搜索方向。在多层膜反演中...
• 针对非局部平均(NLM)方法对椒盐噪声图像滤波效果较差的问题。通过引入噪声检测结果扩展NLM方法去除图像中椒盐噪声。在噪声检测阶段，利用图像的两个极值Lmin和Lmax, 把图像像素点分为非噪声点和噪声点。在滤波阶段，...
• 本文提出了一种利用不断调大学习率的方法试图跳出SGD优化过程中的局部极小值或者鞍点的方法，并提出了两种具体的方法：随机漫步起跳法和历史最优起跳法，实验证明相对常规优化方法有一定性能提升。
• 真的结束于最优点吗？...我们知道，在局部最优点附近，各个维度的导数都接近0，而我们训练模型最常用的梯度下降法又是基于导数与步长的乘积去更新模型参数的，因此一旦陷入了局部最优点，...
• 好几个星期没有更新博客了，最近也是考试多，抽不出多少时间，今天在看书的时候看到了详细的求解极值算法，都是最基本的，就准备写下来当做学习记录。 （一）最速下降法（梯度下降法）  描述：先给出 f（X）极...
• 针对互信息配准方法中目标函数因存在多极值而容易陷入局部最优的问题,提出了一种基于萤火虫算法改进优化策略的互信息医学图像配准算法。该算法使用归一化互信息作为相似性测度,用萤火虫所处位置来表示配准参数,根据...
• 多层感知机解决了之前无法模拟异或逻辑的缺陷，同时更多的层数也让网络更能够刻画现实世界中的复杂情形。...但是随着神经网络层数的加深，优化函数越来越容易陷入局部最优解（即过拟合，在训练样本上有很好的拟
• 为了应用SIFT对图像的描述能力及其鲁棒性，并提高效率，对SIFT的提取算法进行了修改，消除可以引起边缘响应的部分极值点，消除图像细节丰富的局部过邻近点，消除图像背景中的低对比度点，以降低算法复杂度。...
• 局部极值提取算法 这是http://www.imagepy.org/的作者原创，我只是对其理解之后改进和说明，欢迎大家使用这个小软件！ 有需要C++的朋友，可有留邮箱，经测试和改进的版本！ 算法原理：（按照程序思路来，...
• 算法充分考虑粒子群算法与复形法的特性，将复形法的局部搜索与粒子群算法的全局搜索结合起来，以提高算法搜索能力，克服粒子群算法与复形法易陷局部极值的不足。通过性能测试效果良好，同时算法简便、可行、高效。...
• ## 局部搜索算法详解

万次阅读 多人点赞 2017-05-19 09:35:02
1.局部搜索通常考察一个算法的性能通常用局部搜索能力和全局收敛能力这两个指标。局部搜索是指能够无穷接近最优解的能力，而全局收敛能力是指找到全局最优解所在大致位置的能力。局部搜索能力和全局搜索能力，...
• 针对粒子对算法存在过早陷入局部最优导致精度不是很高的问题，建议了一种新的基于粒子对(PPO)与极值优化(EO)混合算法。该算法利用PPO和EO的优点，借助K-means快速聚类的结果初始化其中一个粒子，并根据一定迭代次数...
• 由于变量的适应度最优与问题的目标函数最优无法达到一致，从而利用极值过程原则的局部搜索算法对TSP问题效果不好，而通过改变变量的适应度，使其与目标函数相关，就能够提高个体解的搜索能力。比较参数取不同值时...
• 算法将布谷鸟全局搜索能力与Powell方法的局部寻优性能有机地结合，并根据适应度值逐步构建精英种群候选解池在迭代后期牵引Powell搜索的局部优化，在保证求解速度、尽可能找到全局极值点的同时提高算法的求解精度。...
• 从下图中可以看出,该函数有多个极值点，如果使用其他的搜寻方法,很容易陷人局部最小点,而不能搜寻到真正的全局最小点,但遗传算法可以较好地弥补这个缺陷。 遗传算法的具体实现如下。 问题分析 在本题中,设定自...
• 针对磷虾觅食算法存在容易陷入局部极值、收敛速度慢的问题, 提出一种新的改进算法. 首先, 给出启发式二次对立点的定义并证明其性能优势, 进而构造一种启发式二次对立搜索算子, 以加快算法的收敛速度, 提高全局探索...
• 针对4个benchmark函数对新算法做了测试，并与粒子群优化算法以及已有的几个算法进行了比较，结果表明该算法跳出局部极值点的能力较强、收敛速度更快、寻优精度较高；最后将新算法应用到焊接梁的优化设计问题中，仿真...
• 模拟退火算法是一种基于贪心算法算法，来源于固体退火原理，当固体加热至充分高，再让其冷却的过程中，固体内部粒子再不断运动中，当冷却时候有，粒子趋于有序，当温度达到环境王文度的时候，内能最低，缺点是可能...
• 用C++实现了模拟退火算法求多元函数极值，可以避免陷入局部最优解。

...