精华内容
下载资源
问答
  • 优化,借鉴CMAES与DE,吸收两个算法的优点
  • 12有EBOwithCMAR和jSO各种参数都可以调整,包括种群数量、F因子、变异率、交叉率等
  • top2 of CEC2017_jso算法_jso_CEC2017_IEEECEC2017top算法.zip
  • top2 of CEC2017_jso算法_jso_CEC2017_IEEECEC2017top算法_源码.zip
  • 机器学习萌新必学的Top10算法

    千次阅读 多人点赞 2018-03-16 00:00:00
    机器学习萌新必学的Top10算法在机器学习领域里,不存在一种万能的算法可以完美解决所有问题,尤其是像预测建模的监督学习里。【转自搜狐科技】比方说,神经网络不见得比决策树好,同样反过来也不成立。最后的结果是...
    机器学习萌新必学的Top10算法

    在机器学习领域里,不存在一种万能的算法可以完美解决所有问题,尤其是像预测建模的监督学习里。【转自搜狐科技】


    比方说,神经网络不见得比决策树好,同样反过来也不成立。最后的结果是有很多因素在起作用的,比方说数据集的大小以及组成。所以,针对你要解决的问题,最好是尝试多种不同的算法。并借一个测试集来评估不同算法之间的表现,最后选出一个结果最好的。

    当然,你要选适合解决你问题的算法来尝试。比方说,要打扫房子,你会用真空吸尘器,扫把,拖把;你绝对不会翻出一把铲子来开始挖坑,对吧。不过呢,对于所有预测建模的监督学习算法来说,还是有一些通用的底层原则的。


    机器学习算法,指的是要学习一个目标函数,能够尽可能地还原输入和输出之间的关系。

    然后根据新的输入值X,来预测出输出值Y。精准地预测结果是机器学习建模的任务。


    所以我们来了解一下,Top10机器学习算法


    1线性回归

    统计学与机器学习领域里研究最多的算法。做预测建模,最重要的是准确性(尽可能减小预测值和实际值的误差)。哪怕牺牲可解释性,也要尽可能提高准确性。为了达到这个目的,我们会从不同领域(包括统计学)参考或照搬算法。线性回归可用一条线表示输入值X和输出值Y之间的关系,这条线的斜率的值,也叫系数。

    比方说,y = B0 + B1*x,我们就可以根据X值来预测Y值。机器学习的任务就是找出系数B0和B1。从数据中建立线性回归的模型有不同的方法,比方说线性代数的最小二乘法、梯度下降优化。线性回归已经存在了200多年,相关研究已经很多了。用这个算法关键在于要尽可能地移除相似的变量以及清洗数据。对算法萌新来说,是最简单的算法了。

    2逻辑回归

    这方法来自统计学领域,是一种可以用在二元分类问题上的方法。逻辑回归,和线性回归相似,都是要找出输入值的系数权重。不同的地方在于,对输出值的预测改成了逻辑函数。逻辑函数看起来像字母S,输出值的范围是0到1。把逻辑函数的输出值加一个处理规则,就能得到分类结果,非0即1。比方说,可以规定输入值小于0.5,那么输出值就是1。

    这个算法还可以用来预测数据分布的概率,适用于需要更多数据论证支撑的预测。和线性回归相似,如果把和输出不相干的因子或者相近的因子剔除掉的话,逻辑回归算法的表现会更好。对于二元分类问题,逻辑回归是个可快速上手又有效的算法。

    3线性判别分析

    逻辑回归算法,只能用于二分问题。当输出的结果类别超过两类的时候,就要用线性判别分析算法了。这种算法的可视化结果还比较一目了然,能看出数据在统计学上的特征。这上面的结果都是分别计算得到的,单一的输入值可以是每一类的中位数,也可以是每一类值的跨度。

    基于对每种类别计算之后所得到的判别值,取最大值做出预测。这种方法是假定数据符合高斯分布。所以,最好在预测之前把异常值先踢掉。对于分类预测问题来说,这种算法既简单又给力。

    4分类与回归树

    预测模型里,决策树也是非常重要的一种算法。可以用分两叉的树来表示决策树的模型。每一个节点代表一个输入,每个分支代表一个变量(默认变量是数字类型)

    • 决策树

    决策树的叶节点指的是输出变量。预测的过程会经过决策树的分岔口,直到最后停在了一个叶节点上,对应的就是输出值的分类结果。决策树很好学,也能很快地得到预测结果。对于大部分问题来说,得到的结果还挺准确,也不要求对数据进行预处理。

    5朴素贝叶斯分类器

    这种预测建模的算法强大到超乎想象。这种模型,可以直接从你的训练集中计算出来两种输出类别的概率。一个是每种输出种类的概率;另外一个,是根据给定的x值,得到的是有条件的种类概率。一旦计算之后,概率的模型可以用贝叶斯定理预测新的数据。当你的数据是实数值,那么按理说应该是符合高斯分布的,也就很容易估算出这个概率。

    • 贝叶斯定理

    朴素贝叶斯定理之所以名字里有个“朴素”,是因为这种算法假定每个输入的变量都是独立的。不过,真实的数据不可能满足这个隐藏前提。尽管如此,这个方法对很多复杂的问题还是很管用的。

    6K近邻算法

    最近K近邻的模型表示,就是整个训练集。很直截了当,对吧?对新数据的预测,是搜索整个训练集的值,找到K个最近的例子(literally的邻居)。然后总结K个输出的变量。这种算法难就难在,怎么定义两个数据的相似度(相距多近算相似)。如果你的特征(attributes)属于同一个尺度的话,那最简单的方法是用欧几里得距离。这个数值,你可以基于每个输入变量之间的距离来计算得出。

    最近邻法,需要占用大量的内存空间来放数据,这样在需要预测的时候就可以进行即时运算(或学习)。也可以不断更新训练集,使得预测更加准确。距离或亲密度这个思路遇到更高维度(大量的输入变量)就行不通了,会影响算法的表现。这叫做维度的诅咒。当(数学)空间维度增加时,分析和组织高维空间(通常有成百上千维),因体积指数增加而遇到各种问题场景。所以最好只保留那些和输出值有关的输入变量。

    7学习矢量量化

    最近邻法的缺点是,你需要整个训练集。而学习矢量量化(后简称LVQ)这个神经网络算法,是自行选择训练样例。

    LVQ,是一组矢量,也叫码本。一开始,矢量是随机选的,经过几次学习算法迭代之后,慢慢选出最能代表训练集的矢量。学习完成后,码本就可以用来预测了,就像最近邻法那样。计算新输入样例和码本的距离,可以找出最相近的邻居,也就是最匹配的码本。如果你重新调整数据尺度,把数据归到同一个范围里,比如说0到1之间,那就可以获得最好的结果。如果用最近邻法就获得了不错的结果,那么可以再用LVQ优化一下,减轻训练集储存压力。

    8支持向量机(简称SVM)

    这可能是机器学习里最受欢迎的算法了。超平面是一条可以分割输入变量的空间的“线”。支持向量机的超平面,是能把输入变量空间尽可能理想地按种类切割,要么是0,要么是1。在二维空间里,你可以把超平面可以分割变量空间的那条“线”。这条线能把所有的输入值完美一分为二。SVM的学习目标就是要找出这个超平面。

    超平面和挨得最近的数据点之间的距离,叫做边缘。最理想的超平面,是可以无误差地划分训练数据。 也就是说,每一类数据里距离超平面最近的向量与超平面之间的距离达到最大值。这些点就叫做支持向量,他们定义了超平面。从实际操作上,最理想的算法是能找到这些把最近矢量与超平面值距离最大化的点。支持向量可能是最强的拿来就用的分类器了。值得用数据集试试。

    9随机森林

    随机森林,属于一种重复抽样算法,是最受欢迎也最强大的算法之一。在统计学里,bootstrap是个估算值大小很有效的方法。比方说估算平均值。从数据库中取一些样本,计算平均值,重复几次这样的操作,获得多个平均值。然后平均这几个平均值,希望能得到最接近真实的平均值。而bagging算法,是每次取多个样本,然后基于这些样本建模。当要预测新数据的时候,之前建的这些模型都做次预测,最后取这些预测值的平均数,尽力接近真实的输出值。

    随机森林在这个基础上稍微有点变化。它包含多个决策树的分类器, 并且其输出的类别是由个别树输出的类别的众数而定。如果你的高方差算法取得了不错的结果(比方说决策树),那么用随机森林的话会进一步拿到更好的结果。

    10提升(Boosting)算法和自适应增强(Adaboost)算法

    Boosting的核心是,对同一个训练集训练不同的分类器(弱分类器),然后把这些弱分类器集合起来,构成一个更强的最终分类器(强分类器)。所得到的第二个弱分类器会纠正第一个弱分类器的误差。弱分类器的不断叠加,直到预测结果完美为止。Adaboost算法是首个成功用于二元分类问题的提升算法。现在有很多提升方法都是基于Adaboost。


    AdaBoost适用于短的决策树。在第一个树建立出来之后,不同的样本训练之后的表现可以作参考,用不同的样本训练弱分类器,然后根据错误率给样本一个权重。很难预测的训练数据应该给更多的权重,反过来,好预测的就少一点权重。模型按顺序一个一个建,每个训练数据的权重都会受到上一个决策树表现的影响。当所有的决策树都建好之后,看新数据的预测表现,结果准不准。因为训练数据对于矫正算法非常重要,所以要确保数据清洗干净了,不要有奇奇怪怪的偏离值。


    最后的最后面对海量的机器学习算法,萌新最爱问的是,“我该选什么算法?”在回答这个问题之前,要先想清楚:

    1)数据的数量、质量、本质;

    2)可供计算的时间;

    3)这个任务的紧急程度;

    4)你用这个数据想做什么。

    要知道,即使是老司机,也无法闭着眼睛说哪个算法能拿到最好的结果。还是得动手试。其实机器学习的算法很多的,以上只是介绍用得比较多的类型,比较适合萌新试试手找找感觉。

    ML & AI   一个有用的公众号

    长按,识别二维码,加关注

    获取更多干货!

    展开全文
  • top10算法PDF

    2008-10-10 16:13:51
    top 10 算法简单介绍,记得是简单介绍。。详细内容可以查询。 随便发下,看过的就打酱油去
  • Top K算法分析

    万次阅读 多人点赞 2018-10-04 20:35:33
    TopK,是问得比较多的几个问题之一,到底有几种方法,这些方案里蕴含的优化思路究竟是怎么样的,今天和大家聊一聊。 问题描述: 从arr[1, n]这n个数中,找出最大的k个数,这就是经典的TopK问题。 栗子: 从arr[1...

    个人博客请访问 http://www.x0100.top 

    TopK,是问得比较多的几个问题之一,到底有几种方法,这些方案里蕴含的优化思路究竟是怎么样的,今天和大家聊一聊。

    问题描述

    从arr[1, n]这n个数中,找出最大的k个数,这就是经典的TopK问题。

    栗子

    从arr[1, 12]={5,3,7,1,8,2,9,4,7,2,6,6} 这n=12个数中,找出最大的k=5个。

     

    一、排序

    排序是最容易想到的方法,将n个数排序之后,取出最大的k个,即为所得。

     

    伪代码

    sort(arr, 1, n);

    return arr[1, k];

     

    时间复杂度:O(n*lg(n))
     

    分析:明明只需要TopK,却将全局都排序了,这也是这个方法复杂度非常高的原因。那能不能不全局排序,而只局部排序呢?这就引出了第二个优化方法。

     

    二、局部排序

    不再全局排序,只对最大的k个排序。

    冒泡是一个很常见的排序方法,每冒一个泡,找出最大值,冒k个泡,就得到TopK。

     

    伪代码

    for(i=1 to k){

             bubble_find_max(arr,i);

    }

    return arr[1, k];

     

    时间复杂度:O(n*k)

     

    分析:冒泡,将全局排序优化为了局部排序,非TopK的元素是不需要排序的,节省了计算资源。不少朋友会想到,需求是TopK,是不是这最大的k个元素也不需要排序呢?这就引出了第三个优化方法。

     

    三、堆

    思路:只找到TopK,不排序TopK。

    先用前k个元素生成一个小顶堆,这个小顶堆用于存储,当前最大的k个元素。

     

    接着,从第k+1个元素开始扫描,和堆顶(堆中最小的元素)比较,如果被扫描的元素大于堆顶,则替换堆顶的元素,并调整堆,以保证堆内的k个元素,总是当前最大的k个元素。

     

    直到,扫描完所有n-k个元素,最终堆中的k个元素,就是猥琐求的TopK。

     

    伪代码

    heap[k] = make_heap(arr[1, k]);

    for(i=k+1 to n){

             adjust_heap(heep[k],arr[i]);

    }

    return heap[k];

     

    时间复杂度:O(n*lg(k))

    画外音:n个元素扫一遍,假设运气很差,每次都入堆调整,调整时间复杂度为堆的高度,即lg(k),故整体时间复杂度是n*lg(k)。

     

    分析:堆,将冒泡的TopK排序优化为了TopK不排序,节省了计算资源。堆,是求TopK的经典算法,那还有没有更快的方案呢?

     

    四、随机选择

    随机选择算在是《算法导论》中一个经典的算法,其时间复杂度为O(n),是一个线性复杂度的方法。

     

    这个方法并不是所有同学都知道,为了将算法讲透,先聊一些前序知识,一个所有程序员都应该烂熟于胸的经典算法:快速排序。

    画外音:

    (1)如果有朋友说,“不知道快速排序,也不妨碍我写业务代码呀”…额...

    (2)除非校招,我在面试过程中从不问快速排序,默认所有工程师都知道;

     

    其伪代码是

    void quick_sort(int[]arr, int low, inthigh){

             if(low== high) return;

             int i = partition(arr, low, high);

             quick_sort(arr, low, i-1);

             quick_sort(arr, i+1, high);

    }

     

    其核心算法思想是,分治法。

     

    分治法(Divide&Conquer),把一个大的问题,转化为若干个子问题(Divide),每个子问题“”解决,大的问题便随之解决(Conquer)。这里的关键词是“都”。从伪代码里可以看到,快速排序递归时,先通过partition把数组分隔为两个部分,两个部分“都”要再次递归。

     

    分治法有一个特例,叫减治法。

     

    减治法(Reduce&Conquer),把一个大的问题,转化为若干个子问题(Reduce),这些子问题中“”解决一个,大的问题便随之解决(Conquer)。这里的关键词是“只”

     

    二分查找binary_search,BS,是一个典型的运用减治法思想的算法,其伪代码是:

    int BS(int[]arr, int low, inthigh, int target){

             if(low> high) return -1;

             mid= (low+high)/2;

             if(arr[mid]== target) return mid;

             if(arr[mid]> target)

                       return BS(arr, low, mid-1, target);

             else

                       return BS(arr, mid+1, high, target);

    }

     

    从伪代码可以看到,二分查找,一个大的问题,可以用一个mid元素,分成左半区,右半区两个子问题。而左右两个子问题,只需要解决其中一个,递归一次,就能够解决二分查找全局的问题。

     

    通过分治法与减治法的描述,可以发现,分治法的复杂度一般来说是大于减治法的:

    快速排序:O(n*lg(n))

    二分查找:O(lg(n))

     

    话题收回来,快速排序的核心是:

    i = partition(arr, low, high);

     

    这个partition是干嘛的呢?

    顾名思义,partition会把整体分为两个部分。

    更具体的,会用数组arr中的一个元素(默认是第一个元素t=arr[low])为划分依据,将数据arr[low, high]划分成左右两个子数组:

    • 左半部分,都比t大

    • 右半部分,都比t小

    • 中间位置i是划分元素

    以上述TopK的数组为例,先用第一个元素t=arr[low]为划分依据,扫描一遍数组,把数组分成了两个半区:

    • 左半区比t大

    • 右半区比t小

    • 中间是t

    partition返回的是t最终的位置i。

     

    很容易知道,partition的时间复杂度是O(n)。

    画外音:把整个数组扫一遍,比t大的放左边,比t小的放右边,最后t放在中间N[i]。

     

    partition和TopK问题有什么关系呢?

    TopK是希望求出arr[1,n]中最大的k个数,那如果找到了第k大的数,做一次partition,不就一次性找到最大的k个数了么?

    画外音:即partition后左半区的k个数。

     

    问题变成了arr[1, n]中找到第k大的数。

     

    再回过头来看看第一次partition,划分之后:

    i = partition(arr, 1, n);

    • 如果i大于k,则说明arr[i]左边的元素都大于k,于是只递归arr[1, i-1]里第k大的元素即可;

    • 如果i小于k,则说明说明第k大的元素在arr[i]的右边,于是只递归arr[i+1, n]里第k-i大的元素即可;

    画外音:这一段非常重要,多读几遍。

     

    这就是随机选择算法randomized_select,RS,其伪代码如下:

    int RS(arr, low, high, k){

      if(low== high) return arr[low];

      i= partition(arr, low, high);

      temp= i-low; //数组前半部分元素个数

      if(temp>=k)

          return RS(arr, low, i-1, k); //求前半部分第k大

      else

          return RS(arr, i+1, high, k-i); //求后半部分第k-i大

    }

     

    这是一个典型的减治算法,递归内的两个分支,最终只会执行一个,它的时间复杂度是O(n)。

     

    再次强调一下:

    • 分治法,大问题分解为小问题,小问题都要递归各个分支,例如:快速排序

    • 减治法,大问题分解为小问题,小问题只要递归一个分支,例如:二分查找,随机选择

     

    通过随机选择(randomized_select),找到arr[1, n]中第k大的数,再进行一次partition,就能得到TopK的结果。

     

    五、总结

    TopK,不难;其思路优化过程,不简单:

    • 全局排序,O(n*lg(n))

    • 局部排序,只排序TopK个数,O(n*k)

    • ,TopK个数也不排序了,O(n*lg(k))

    • 分治法,每个分支“都要”递归,例如:快速排序,O(n*lg(n))

    • 减治法,“只要”递归一个分支,例如:二分查找O(lg(n)),随机选择O(n)

    • TopK的另一个解法:随机选择+partition

     

    知其然,知其所以然。

    思路比结论重要。

    更多精彩内容扫描下方二维码进入网站。。。。。

    关注微信公众号。。。。。

     

    展开全文
  • 一个简单的top-k实现

    2018-09-18 16:26:37
    这是一个简单的实现top-k的算法,高效的获取前K个值。
  • 经典Top N算法

    千次阅读 2019-07-27 18:09:00
    01TOP N的处理方式top n 如果是直接针对的可排序的数据集合,并且不需要二次计算的话,则全局的top n就是可以分散到局部的top n再聚合。如果数据集不是可排序...

    0

    1

    TOP N的处理方式

    top n 如果是直接针对的可排序的数据集合,并且不需要二次计算的话,则全局的top n就是可以分散到局部的top n再聚合。

    如果数据集不是可排序的,并且也需要进行二次计算,类似按某个统计指标来取 top n,可能就不能直接用局部的top n来并行计算。

    抽象的来说,同一个top n算法要适应不同的动态数据分布是很难的,top n不是处理特定的数据分布的,而是要通用型的

    top n或许可以从满足充分必要条件来做一些反向推导,得到一些限制条件,从而过滤掉数据,让数据量减少,逐步收敛于某个范围。

    如果采用过滤数据量的话,需要借助一些统计的指标,如:记录的总数等。

    top N一般的做法就是将数据先局部处理,例如:计算单词的出现的个数 top N,可先局部统计每个区域中的单词的次数,重新写入临时文件,后续再进行数据的合并。

    top N还有一种做法就是将数据按照key进行独立计算,区域是按照key进行分区,譬如:按照单词来直接得到它的统计总数,这个类似storm的处理方式。

    0

    2

    案例实现

    使用快排法,查找最小的n个数。

    public static void main(String[] args) {	
    
    	
            int [] arr = {2, 6, 3, 8, 9, 1, 16, 18, 0, 4};	
            int N = 3;	
            getTopNMinBySort(arr, 0, arr.length - 1, N);	
    
    	
            for (int i = 0; i < N; i++) {	
                System.out.print(arr[i] + " ");	
            }	
    
    	
        }	
    
    	
       private static  int partion(int [] arr, int first, int end) {	
            int i = first;	
            int main = arr[end];	
            for (int j = first; j < end; j++) {	
                if (arr[j] < main) {	
                    int temp = arr[j];	
                    arr[j] = arr[i];	
                    arr[i] = temp;	
                    i++;	
                }	
            }	
            arr[end] = arr[i];	
            arr[i] = main;	
            return i;	
        }	
    
    	
       private static void getTopNMinBySort(int [] arr, int first, int end, int n) {	
            if (first < end) {	
                int partionIndex = partion(arr, first, end);	
                if (partionIndex == n - 1) {	
                    return;	
                } else if (partionIndex > n - 1) {	
                    getTopNMinBySort(arr, first, partionIndex - 1, n);	
                } else {	
                    getTopNMinBySort(arr, partionIndex + 1, end, n);	
                }	
            }	
        }

    展开全文
  • python 的topk算法实例

    2020-09-17 14:58:46
    主要介绍了python 的topk算法实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 主要介绍了使用堆实现Top K算法,即JS实现,文中详细介绍了Top K算法,感兴趣的小伙伴们可以参考一下
  • 在分析MapReduce、Hive、Redis和Storm、Spark等工具实现分组Top n问题前,我们先看下java最原始实现Top的方法有哪些,为后面奠定些基础,这也是我要整理成一个系列的原因。 对于Top n问题,这里根据数据特点用合并法...

    前言:

    在分析MapReduce、Hive、Redis和Storm、Spark等工具实现分组Top n问题前,我们先看下java最原始实现Top的方法有哪些,为后面奠定些基础,这也是我要整理成一个系列的原因。

    对于Top n问题,这里根据数据特点用合并法、快排过程法、大小顶堆和PriorityQueue固定队列四种方式来实现。

    合并法:

    数据描述:这种方法适用于几个数组有序的情况,来求Top k。

    实现描述:采用Merge的方法,设定一个数组下标扫描位置记录临时数组和top结果数组,然后从临时数组记录下标开始遍历所有数组并比较大小,将最大值存入结果数组,最大值对应所在数组下标加一存入临时数组,以使其从下位开始遍历,时间复杂度为O(k*m)。(m:为数组的个数)。

    具体实现:

    package fjdm;
    import java.util.ArrayList;
    import java.util.List;
    /**
     * 已知几个递减有序的m个数组,求这几个数据前k大的数
     * a[4,3,2,1],b[6,5,3,1] -> result[6,5,4]
     * @author 张恩备
     * @date 2016-11-25 上午10:57:03
     */
    public class TopKByMerge{
     public static int[] getTopK(List<List<Integer>>input,int k){
    	int index[]=new int[input.size()];//保存每个数组下标扫描的位置;
    	int result[]=new int[k];
    	for(int i=0;i<k;i++){
    	   int max=Integer.MIN_VALUE;
    	   int maxIndex=0;
    	   for(int j=0;j<input.size();j++){
    		   if(index[j]<input.get(j).size()){
    				if(max<input.get(j).get(index[j])){
    					max=input.get(j).get(index[j]);
    					maxIndex=j;
    				}
    		   }
    	   }
    	   if(max==Integer.MIN_VALUE){
    		   return result;
    	   }
    	   result[i]=max;
    	   index[maxIndex]+=1;
    	   
    	}
    	return result;
     } 
     public static void main(String[] args) {
    	 List<Integer> a = new ArrayList<Integer>();
    	 a.add(4);
    	 a.add(3);
    	 a.add(2);
    	 a.add(1);
    	 List<Integer> b = new ArrayList<Integer>();
    	 b.add(6);
    	 b.add(5);
    	 b.add(3);
    	 b.add(1);
    	 List<List<Integer>> ab = new ArrayList<List<Integer>>();
    	 ab.add(a);
    	 ab.add(b);
    	 int r[] = getTopK(ab, 3);
    	 for (int i = 0; i < r.length; i++) {
    		System.out.println(r[i]);
    	}
    }
    }

    快排过程法:

    数据描述:适用于无序单个数组,快排过程法利用快速排序的过程来求Top k。

    实现步骤:根据快排规则,选择一个数为基准(代码是以最后一个数)分化数据,并记录基准数最后的落点下标,最后判断下标和k-1值大小(下标从0开始),不相等就继续朝k-1数量方向分化:

    下标小于k-1,对下标右侧(partion,end)继续二分;

    下标大于k-1,对下标左侧(first,partion)继续二分;

    直到k个数为top,但这k个数并没有顺序。

    具体实现:

    package fjdm;
    
    /**
     * 利用快速排序的过程来求最小的k个数
     * @author 张恩备
     * @date 2016-11-25 上午11:59:45
     */
    public class TopK{
    	int partion(int a[],int first,int end){
    		  int i=first;
    		  int main=a[end];
    		  for(int j=first;j<end;j++){
    				 if(a[j]<main){
    					 int temp=a[j];
    					 a[j]=a[i];
    					 a[i]=temp;
    					 i++;
    				 }
    		  }
    		  a[end]=a[i];
    		  a[i]=main;
    		  return i;	 
    	}
    	void getTopKMinBySort(int a[],int first,int end,int k){
    		if(first<end){
    			 int partionIndex=partion(a,first,end);
    			 if(partionIndex==k-1)return;
    			 else if(partionIndex>k-1)getTopKMinBySort(a,first,partionIndex-1,k);
    			 else getTopKMinBySort(a,partionIndex+1,end,k);
    		}
    	}
    public static void main(String []args){
    		int a[]={2,20,3,7,9,1,17,18,0,4};
    		int k=6;
    		new TopK().getTopKMinBySort(a,0,a.length-1,k);
    		for(int i=0;i<k;i++){
    			System.out.print(a[i]+" ");
    		}
    	}
    }

    采用小顶堆或者大顶堆:

    数据描述:求最大K个采用小顶堆,而求最小K个采用大顶堆。

    实现步骤:根据数据前K个建立K个节点的小顶堆,在后面的N-K的数据的扫描中,

    如果数据大于小顶堆的根节点,则根节点的值覆为该数据,并调节节点至小顶堆。

    如果数据小于或等于小顶堆的根节点,小根堆无变化。

    求最小K个跟这求最大K个类似。时间复杂度O(nlogK)(n:数据的长度),特别适用于大数据的求Top K。

    具体实现:

    package fjdm;
    
    /**
     * 求前面的最大K个 解决方案:小根堆 (数据量比较大(特别是大到内存不可以容纳)时,偏向于采用堆)
     * @author 张恩备
     * @date 2016-11-25 下午12:15:36
     */
    public class TopKByHeap {
    	/**
    	 * 创建k个节点的小根堆
    	 * 
    	 * @param a
    	 * @param k
    	 * @return
    	 */
    	int[] createHeap(int a[], int k) {
    		int[] result = new int[k];
    		for (int i = 0; i < k; i++) {
    			result[i] = a[i];
    		}
    		for (int i = 1; i < k; i++) {
    			int child = i;
    			int parent = (i - 1) / 2;
    			int temp = a[i];
    			while (parent >= 0 &&child!=0&& result[parent] >temp) {
    				result[child] = result[parent];
    				child = parent;
    				parent = (parent - 1) / 2;
    			}
    			result[child] = temp;
    		}
    		return result;
    
    	}
    
    	void insert(int a[], int value) {
    		 a[0]=value;
    		 int parent=0;
    		 
    		 while(parent<a.length){
    			 int lchild=2*parent+1;
    			 int rchild=2*parent+2;
    			 int minIndex=parent;
    			 if(lchild<a.length&&a[parent]>a[lchild]){
    				 minIndex=lchild;
    			 }
    			 if(rchild<a.length&&a[minIndex]>a[rchild]){
    				 minIndex=rchild;
    			 }
    			 if(minIndex==parent){
    				 break;
    			 }else{
    				 int temp=a[parent];
    				 a[parent]=a[minIndex];
    				 a[minIndex]=temp;
    				 parent=minIndex;
    			 }
    		 }
    	}
    
    	int[] getTopKByHeap(int input[], int k) {
    		int heap[] = this.createHeap(input, k);
    		for(int i=k;i<input.length;i++){
    			if(input[i]>heap[0]){
    				this.insert(heap, input[i]);
    			}
    		}
    		return heap;
    	}
    
    	public static void main(String[] args) {
    		int a[] = { 4, 3, 5, 1, 2,8,9,10};
    		int result[] = new TopKByHeap().getTopKByHeap(a, 3);
    		for (int temp : result) {
    			System.out.println(temp);
    		}
    	}
    }

    PriorityQueue优先队列:

    数据描述:PriorityQueue是从JDK1.5开始提供的新的数据结构接口,它是一种基于优先级堆的极大优先级队列。优先级队列是不同于先进先出队列的另一种队列。每次从队列中取出的是具有最高优先权的元素。如果不提供Comparator的话,优先队列中元素默认按自然顺序排列,也就是数字默认是小的在队列头,字符串则按字典序排列(参阅 Comparable),也可以根据 Comparator 来指定,这取决于使用哪种构造方法。优先级队列不允许 null 元素。依靠自然排序的优先级队列还不允许插入不可比较的对象(这样做可能导致 ClassCastException)。

    实现步骤:PriorityQueue构造固定容量的优先队列,模拟大顶堆,这种队列本身数组实现,无容量限制,可以指定队列长度和比较方式,然后将数据依次压入,当队列满时会poll出小值,最后需要注意的是,priorityQueue本身遍历是无序的,可以使用内置poll()方法,每次从队首取出元素。

    具体实现:

    package fjdm;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.Iterator;
    import java.util.List;
    import java.util.PriorityQueue;
    import java.util.Random;
    /**
     * 固定容量的优先队列,模拟大顶堆,用于解决求topN小的问题
     * @author 张恩备
     * @date 2016-11-25 下午02:29:31
     */
    public class FixSizedPriorityQueue<E extends Comparable> {
    	private PriorityQueue<E> queue;
    	private int maxSize; // 堆的最大容量
    
    	public FixSizedPriorityQueue(int maxSize) {
    		if (maxSize <= 0)
    			throw new IllegalArgumentException();
    		this.maxSize = maxSize;
    		this.queue = new PriorityQueue(maxSize, new Comparator<E>() {
    			public int compare(E o1, E o2) {
    				// 生成最大堆使用o2-o1,生成最小堆使用o1-o2, 并修改 e.compareTo(peek) 比较规则
    				return (o2.compareTo(o1));
    			}
    		});
    	}
    
    	public void add(E e) {
    		if (queue.size() < maxSize) { // 未达到最大容量,直接添加
    			queue.add(e);
    		} else { // 队列已满
    			E peek = queue.peek();
    			if (e.compareTo(peek) < 0) { // 将新元素与当前堆顶元素比较,保留较小的元素
    				queue.poll();
    				queue.add(e);
    			}
    		}
    	}
    
    	public List<E> sortedList() {
    		List<E> list = new ArrayList<E>(queue);
    		Collections.sort(list); // PriorityQueue本身的遍历是无序的,最终需要对队列中的元素进行排序
    		return list;
    	}
    
    	public static void main(String[] args) {
    		final FixSizedPriorityQueue pq = new FixSizedPriorityQueue(10);
    		Random random = new Random();
    		int rNum = 0;
    		System.out.println("100 个 0~999 之间的随机数:-----------------------------------");
    		for (int i = 1; i <= 100; i++) {
    			rNum = random.nextInt(1000);
    			System.out.println(rNum);
    			pq.add(rNum);
    		}
    		System.out.println("PriorityQueue 本身的遍历是无序的:-----------------------------------");
    		Iterable<Integer> iter = new Iterable<Integer>() {
    			public Iterator<Integer> iterator() {
    				return pq.queue.iterator();
    			}
    		};
    		for (Integer item : iter) {
    			System.out.print(item + ", ");
    		}
    		System.out.println();
    		System.out.println("PriorityQueue 排序后的遍历:-----------------------------------");
    		/*
    		 * for (Integer item : pq.sortedList()) { System.out.println(item); }
    		 */
    		// 或者直接用内置的 poll() 方法,每次取队首元素(堆顶的最大值)
    		while (!pq.queue.isEmpty()) {
    			System.out.print(pq.queue.poll() + ", ");
    		}
    	}
    }


    展开全文
  • 该方法使用多尺度top-hat变换提取图像多尺度下的亮、暗细节特征,并根据多尺度下局部细节特征的重要性,利用非线性函数对这些特征进行反差增强,突出图像隐藏的信息。实验结果表明,与传统算法相比,该方法有效的增强了...
  • 现有的标签推荐算法没有考虑用户的连续行为所产生的影响,而传统的基于马尔可夫链(Markov Chain)的推荐算法虽然侧重于研究用户的连续行为来产生推荐,但它是直接作用于用户与物品的二维关系,并不适用于基于UGC的...
  • top N 算法

    2013-03-20 15:26:55
    top N 算法,我只是转载,感谢原作者,求实严谨的态度,学习 http://blog.chinaunix.net/uid/20528042.html
  • Hadoop1.x中MapReduce中TopK算法Top100算法
  • topk算法实现

    千次阅读 2019-03-01 11:07:27
    1.1 算法思路 这里假设你对快排已经熟悉。我们知道快排是随机找个标识,然后用此标识进行排序。 我们进行降序排序的方式,第一次进行排序后,就能获得在序列中的大小位置。如果它正好是第k大,那么它左边的数组就是...
  • * 获取topN音乐的控制方法 */ public void TopNMusic(){ //设置文件输入路径 String fileInput= "/music/orgmusic.txt" ; Path fileInPath= new Path(fileInput); //设置文件输出路径 //String ...
  • python TopK算法

    千次阅读 2019-09-20 10:42:43
    TopK算法 寻找数组中的最小的k个数,也叫topk问题。 该算法要解决的问题是:在线性时间内找到一个无序序列中第kk大的数。 如:输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个...
  • top k 算法

    2013-10-15 20:37:56
    top k 算法实现 ,以及算法的具体描述
  • top-K 算法总结

    千次阅读 2020-09-08 21:21:52
    1000000)个数,求出其中的前K个最小的数(又被称作topK问题) 1 最基本思路 将N个数进行完全排序,从中选出排在前K的元素即为所求。有了这个思路,我们可以选择相应的排序算法进行处理,目前来看快速排序,堆排序和...
  • TopN算法

    千次阅读 2017-07-19 21:39:47
    在系统中,我们经常会遇到这样的需求:将大量(比如几十万、甚至上百万)的对象进行排序,然后只需要取出最Top的前N名作为排行榜的数据,这即是一个TopN算法。常见的解决方案有三种: (1)直接使用List的Sort方法...
  • Top-N算法的实现(Java版)

    千次阅读 2013-10-23 22:27:00
    以下是我写的一个Top-N的演示程序。主要用到的数据结构是TreeSet,TreeSet会自动化实现插入排序,前提是该类要实现Comparable接口。 实体类 /* * $filename: Student.java,v $ * $Date: 2013-10-
  • TOPK算法的Hash实现

    2012-11-15 10:53:16
    该代码为TOPK算法的Hash实现,简要说明请见博客http://blog.csdn.net/yankai0219/article/details/8185872
  • [Spark的TopN算法实现]

    万次阅读 多人点赞 2018-06-09 22:35:54
    一、TopN算法 MapRedce中的TopN算法是一个经典的算法,由于每个map都只是实现了本地的TopN算法,而假设map有M个,在归约的阶段只有M x N次运算,这个结果是可以接受的并不会造成性能瓶颈。 MapRedce中的TopN算法在...
  • MapReduce编程场景之TopN 算法实现

    千次阅读 2019-02-17 09:51:55
    MapReduce编程场景之TopN 算法实现 (一)需求 求出每个班参考学生成绩最高的学生的信息,班级,姓名和平均分 (二)分析 1、利用“班级和平均分”作为 key,可以将 map 阶段读取到的所有学生成绩数据按照班级和成绩...
  • top k算法讲解

    万次阅读 2017-06-22 15:28:55
    在实际工作中,我们时常会有寻找长度为n的数组中,排在前k的元素,对于top k的问题,最暴力的处理方式就是直接对数组进行排序,然后再去截取前多少个数字,从而达到自己的目的,这种算法的实现复杂度为O(nlogn),...
  • 吴信东--数据挖掘top10算法

    千次阅读 2009-12-31 21:53:00
    背景: 09年12.31日下午,应清华大学智能计算实验室邀请,吴教授在...附数据挖掘top 10算法列表:  C4.5, k-Means, SVM, Apriori, EM, PageRank, AdaBoost, kNN, Naive Bayes, and CART 详细论文请参阅: ...
  • TopK算法 排序

    千次阅读 2018-02-23 09:41:09
    不难分析出,这样,算法的最坏时间复杂度是N*K, 其中K是指top多少。 算法三:堆 在算法二中,我们已经将时间复杂度由NlogN优化到NK,不得不说这是一个比较大的改进了,可是有没有更好的办法呢? 每次查找...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 277,572
精华内容 111,028
关键字:

top算法