精华内容
下载资源
问答
  • 数据流聚类算法

    2021-02-28 08:02:47
    1.数据流数据流的产生:实时监控系统、气象卫星遥感、网络通信量监测和电力供应网等数据流的特点:海量的(massive)、时序的(temporally ordered)、快速变化的和潜在无限、高维的(potentially infinite)。数据流挖掘...

    1.数据流

    数据流的产生:实时监控系统、气象卫星遥感、网络通信量监测和电力供应网等

    数据流的特点:海量的(massive)、时序的(temporally ordered)、快速变化的和潜在无限、高维的(potentially infinite)。

    数据流挖掘的特点---挑战:

    (a)数据是海量的,不可能在内存及硬盘上存储整个流数据集。

    (b)单次线性扫描(单遍扫描)(single pass)的过程;数据元素只能按其流入顺序依次读取一次,随机访问是不现实的。

    (c)数据流是持续变化的,所以不可能看到数据流的中的每一个数据元素(data point),我们只能通过分析部分数据元素来做出决策。

    (d)大多数应用要求及时响应,对时间复杂度、空间复杂度要求很高,并且挖掘应该是一个连续、在线的过程。

    (e)数据流往往是高维的(High-Dimensional),不同的领域的数据流挖掘面临的挑战也不一样。

    (f)时间局部性(temporal locality),过去的历史数据或许与将来的关系越来越小,只与当前时间点很相关

    (g)可扩展性(scalability)

    所以:数据流算法经常采用精度换时间的方法,尽量在对数据的一次访问中获得较优的解.一般来说,数据流算法是不可回溯的;其次,数据流算法有很多特点,一些数据库应用中常用的操作在数据流中都是不可行的.如,Sort,Max,Count等操作。

    1.2数据流模型

    数据流中的数据项x1,…, xi,…, xn依次按下标顺序到达,它们描述了一个信号A。

    1.2.1按xi描述信号A的方式,数据流模型可分为以下几类:

    (1)时序( Time

    Series)模型:A [ i ] = xi,用来描述时间序列数据。此时,数据流中的每个数据项都代表一个独立的信号。

    (2)现金登记(Cash

    Register)模型:令xi= ( j,Ii) ,且Ii≥0,则Ai [ j ] =Ai-1[ j ] + Ii。此时,数据流中的多个数据项增量式地表达一个A [ j ]。

    (3)十字转门(

    Turnstile)模型:令xi= ( j,Ui) ,则Ai[ j ] =Ai

    -1[ j ] +Ui。其中, Ui可为正数,也可为负数。此时,数据流中的多个数据项表达一个A [ j ]。A[ j ]随着数据的流入,可能会增加,也可能会减小。

    1.2.2按照算法处理数据流时所采用的时序范围,数据流模型可分为以下几类:

    (1)快照模型( Snapshot Model) :处理数据的范围限制在两个预定义的时间戳之间。

    (2)界标模型(Landmark Model) :处理数据的范围从某一个已知的初始时间点到当前时间点为止。

    (3)滑动窗口模型(Sliding Window Model) :处理数据的范围由某个固定大小的滑动窗口确定,此滑动窗口的终点永远为当前时刻。其中,滑动窗口的大小可以由一个时间区间定义,也可以由窗口所包含的数据项数目定义。

    72c55c9fb67dd4a4b7271344390404bb.png

    2.数据流聚类基本知识

    2.1聚类方法

    聚类(Clustering)是指对一个数据对象集合,将其中相似的对象划分为一个或多个组(称为“簇”,Cluster)的过程。同一个簇中的元素是彼此相似的,而与其它簇中的元素相异。

    考虑时间局部性:基于流数据快照的方法(snapshot-based

    methods),基于衰减的技术(decay-based techniques),滑动窗口方法windowing

    数据流聚类要求:适合于数据流模型的、仅使用有界内存和有限处理时间的单遍扫描数据的高效聚类方法。

    一个好的数据流聚类算法应该具备的3个要求:

    (a)对已发现的簇提供一个简洁的表示方法(representation);

    (b)对新的数据元素的处理应该是增量式的方式(incremental processing),并且应该它是快速的;

    (c)有清晰而快速地孤立点检测(outlier detection)的能力。

    2.2支撑技术

    基于数据的技术(Data-based Techniques)

    抽样(Sampling)

    使用水库抽样(reservior sampling)的技术来解决这个问题:在“水库”中维护s个候选的样本,形成目前看到的流的随机样本集,随着数据流的流动,新的数据元素都有一定的概率替代水库中的元素。

    梗概(Sketching)

    梗概是一个将数据流中的数据向量做一个随机投影的过程。它建立这些分布向量(如直方图)的小空间汇总。梗概广泛用于不同数据流的比较和聚集查询。梗概是对精度和存储空间进行折衷的极佳范例,精度问题是它的主要缺陷。

    大纲数据结构(Synopsis Data

    Structure)

    通过应用概要技术(summarization techniques),生成的比当前数据流小得多的数据结构。它是当前数据流的概要描述。已经被提出的概要技术包括:小波分析、直方图(histogram)和频率矩(frequency moment)等。

    大纲数据结构不可能表示出原数据流的所有特性,使用大纲数据结构只能得到一个近似结果。

    聚集运算(Aggregation)

    聚集运算试图通过计算一些统计度量,诸如平均数和方差等来概括当前的数据流。不过类似所有统计学的方法,它不适合速率高度摇摆和分布式的数据流

    2.3基于任务的技术(Task-based

    Techniques)

    滑动窗口(Sliding

    Window)

    滑动窗口模型基于这样一个事实:“用户对于最近的数据更感兴趣。”这样,我们可以对少量的近期数据做细节分析,而对大量的历史数据,仅仅给出一个概要试图。这样,只需存储小的数据窗口,减少了对内存的需求。缺陷是要求用户预先指定窗口的尺寸,而在很多应用中,窗口的大小不可能事先知道。

    衰减函数(Fading

    Function)

    另一种强调近期数据的重要性、消减历史数据对计算结果影响的方法是衰减因子和衰减函数。数据元素在参与计算前,先经过衰减函数的作用。因此,每个数据元素对最终结果的影响将随着时间的推移逐渐减小。一种常用的衰减函数形式为指数形式,例如Den-Stream算法使用的衰减函数为:

    倾斜时间框架(Titled Time

    Frame)

    滑动窗口和衰减函数都只能在单一时间维的窗口上得到计算结果。然而,很多应用要求在不同的时间粒度层上进行分析和挖掘。比如,用户通常对细粒度层上的当前变化感兴趣,而在粗粒度层上对长期变化感兴趣。最近的数据在最细的粒度层上记录和运算,较久远的数据在较粗的粒度上记录和运算。

    三种倾斜时间框架模型:自然倾斜时间框架模型(natural)、对数尺度倾斜时间框架模型(logarithmic scale)和渐进对数时间框架模型(progressive logarithmic)。如图1

    0c27407c67a366b78919479147708f5d.png

    图1倾斜时间框架的三种模式

    Aggarwal等在文献[8]中提出的CluStream聚类算法就是基于一种称为Pyramidal Time Frame的渐进对数倾斜时间框架模型,如表1所示

    表1金字塔时间框架模型(An example of snapshots stored for α=2)

    37a4106600a31243852261218def6ae8.png

    距离当前越近的时间戳,快照存储的密度就越高。并且,渐进对数时间框架维护了一个替代算法,使新的流数据到来时能插入正确的时间粒度层,以替代最老的数据。

    不同时间粒度层中的数据存在重叠(表中划横线的数据即为重叠数据)。并且可知,重叠数据为每层上能被αi整除的数据。

    3.数据流聚类算法

    3.1基于划分的方法---STREAM算法

    S. Guha等人在提出了基于K-Means的STREAM算法,使用质心(中心点,中位数)和权值(类中数据个数)表示聚类。STREAM算法采用批处理方式,每次批处理的数据点个数受内存大小的限制。对于每一批数据Bi,STREAM算法对其进行聚类,得到加权的聚类质心集Ci。

    STREAM算法采用分级聚类的方法,如图1所示,首先对最初的m个输入数据进行聚类得到O(K)个1级带权质心,然后将上述过程重复m/O(K)次,得到m个1级带权质心,然后对这m个1级带权质心再进行聚类得到O(K)个2级带权质心;同理,每当得到m个i级带权质心时,就对这些质心进行一次聚类得到O(K)个i+1级带权质心;重复这一过程直到得到最终的O(K)个质心。对于每个第i+1级带权质心而言,其权值是与它对应的i级质心的权值之和。

    a3234441ba66a7325c125f8f40f4b496.png

    ---------------------------------------------------------------------------------------------------------------------------

    STREAM算法聚焦于解决k-中位数问题(k-medians),即把度量空间中的n个数据点聚类成k个簇,使得数据点与其簇之间的误差平方和(SSQ)最小。

    STREAM算法处理m个数据点的桶中的数据流,桶的大小与内存相符。算法把每个桶的数据点分成k个簇,并且仅仅保留k个簇中心点(而丢弃其余的数据)来汇总桶中的所有数据。每个中心点的权(weight)为该簇中数据点的个数。随着数据流的流入,这个过程不断地被重复,每次处理的数据个数为m个。

    此外,STREAM算法采用分级聚类的技术,使用Local Search算法改进了k-平均算法(k-means),使“k”更灵活:在算法的中间步骤中,簇的个数不再是一个固定的值,而是一个更合理的值,仅仅在算法结束时趋向于k。得到了更好的性能和更高质量的结果簇。

    如上所述,STREAM算法实现了单次扫描,时间复杂度为O(kn)。

    优点和缺点:

    STREAM算法与传统数据的聚类算法相比(与BIRCH相比较),有更好的性能,并能产生更高质量的聚类结果。

    (1)STREAM算法没有考虑数据流的演变,即算法没有给予最近的数据较大的权重。聚类的结果可能受控于过期的数据点。(2)STREAM算法更趋近与一个批处理的过程,无法给出一个anytime的回应,即算法无法在任意时刻给出当前数据流的聚类结果。(3)STREAM的不足还包括无法给出不同时间粒度的聚类结果等等。

    3.2基于层次的方法---CluStream

    CluStream是一个数据流聚类的处理框架,它把聚类过程分为两个部分:联机的微聚类(micro

    clustering)和脱机的宏聚类(macro

    clustering)。CluStream的提出的这个两阶段处理框架被许许多多后来的数据流聚类算法所采用和遵循。

    CluStream是一个数据流的聚类分析框架。CluStream算法解决了STREAM算法的两个问题。即它是增量式(incremental)的聚类算法,在每个数据项到来时进行处理,能给出anytime的回应;并且,它使用Pyramidal时间框架,能给出不同时间粒度的聚类结果。这对于希望分别考察诸如上周、上月以及去年的聚类分析结果的用户意义重大!

    联机部分使用微簇(micro cluster)计算和存储数据流的汇总统计信息,实现增量的联机聚类查询;脱机部分则进行宏聚类(macro clustering),利用Pyramidal时间框架提供用户感兴趣的不同时间粒度上的聚类结果。CluStream的这个两阶段处理框架被许许多多后来的数据流聚类算法所效仿和采纳。

    cdc1d8885fb7a4e658d8e7d15223e06f.png

    由BIRCH中CF的可加减性,不难推导出CluStream中的聚类特征的可加减性。籍此,CluStream算法成为一个增量式的处理过程。

    联机的微簇维护过程由初始化和更新阶段组成:首先初始化q个微簇M1…Mq,q根据内存的情况取尽可能大的值,q个微簇根据当前数据的统计信息用k-means算法得到。然后,更新微簇。每个新数据点根据是否落在某个微簇的边界之内,选择加入某个微簇或者新建一个微簇。前者根据可加性被已存在的微簇“吸收”,后者则需要删除一个最近最少用的微簇或者合并存在的微簇以保持q值不变。

    脱机部分实现用户指导的宏聚类和聚类演变分析。宏聚类提供用户要求的不同时间粒度的聚类结果;聚类演变分析考察聚类结果如何随时间变化。通过Pyramidal时间框架和聚类特征的可加减性,这两点都不难实现。前者根据当前时间tc和用户指定的时间范围h,在Pyramidal时间框架中找到t时刻的快照S(t)和(tc-h)时刻的快照S(tc-h),相减得到(tc-h)到tc之间生成的微簇集N(tc, h)。N(tc, h)即是加权虚拟点集。然后用STREAM算法进行聚类,得到h时间范围内的数据流聚类结果。

    聚类演变分析(Evolution Analysis)告诉用户在哪些数据点在t1时刻的簇中出现而在t2时刻的簇中消失,哪些数据点在两个时刻的簇中都存在。给定t1、t2和h,计算出N(t1, h)和N(t2, h)。通过比较N(t1, h)和N(t2, h),就不难回答上述的问题。

    CluStream通过使用倾斜时间框架,保存了数据流演变的历史信息,在数据流变化剧烈时仍可以产生高质量的聚类结果,并且提供了丰富的功能。但是,它没有考虑历史数据的衰减问题,即没有体现出近期数据的重要性。此外,当被应用于高维数据流的聚类时,CluStream算法往往表现不佳。

    HPStream基于“众多数据流天生就是高维的。”这个事实,通过引入投影技术(project

    clustering)和衰减簇结构(fading

    cluster structure),来更好地支持高维数据流的聚类分析。CluStream和HPStream是两种被广泛认可、并且十分流行的数据流聚类算法。

    HPStream针对高维数据流,较之CluStream主要做了如下改进:首先,HPSream引进了投影聚类技术(projected clustering)来处理高维的数据流,这比STREAM和CluStream中对所有相关维做全维聚类(full dimensional clustering)要高效和合理。其次,与CluStream在整个数据流上计算微簇不同的是,HPStream使用衰减簇结构(fading cluster structure)来保存历史数据。衰减簇结构使用衰减因子,随着时间的推进,不断衰减历史数据对当前聚类结果的影响,更好地将当前数据和历史数据集成起来。

    3.3基于密度的算法---DenStream

    面向数据流的基于密度的聚类算法DenStream。它采用CluStream算法中提出的两阶段处理框架,并引入了潜在簇结构和孤立点簇结构。实际上,当聚类请求到达时,DenStream仍然采用DBSCAN算法来得到最后的聚类结果。

    扩展划分和层次的方法,诸如STREAM、CluStream和HPStream等算法的主要问题在于:它们仅仅对球形的数据流进行聚类分析时表现良好,但由于采用距离度量,它们不能很好地处理任意形状的数据流。

    DenStream算法扩展了传统数据集聚类算法中基于密度的方法DBSCAN,着眼于处理任意形状的数据流聚类问题。同时,它强调了孤立点检测问题,将孤立点与正常数据元素区分开来。

    DenStream算法沿袭了CluStream的处理框架,把聚类分析的过程划分为联机和脱机两个部分。

    在联机部分中,算法维护了两类微簇结构:潜在微簇(p-micro-cluster)和孤立点微簇(o-micro-cluster),这两个微簇结构的不同之处仅仅在于其约束条件——密度小于某个阈值的簇被当作孤立点簇,而密度超过该阈值的簇被视为潜在微簇。当一个新的数据点到来时,算法(1)首先试图将它合并到其最邻近的p-micro-cluster中;若失败,则(2)试图将其合并到最邻近的o-micro-cluster中去。若合并成功,检测该o-micro-cluster的密度是否大于阈值,若是,则将该o-micro-cluster转换为p-micro-cluster;(3)如果仍然无法找到最邻近的o-micro-cluster,则新建一个o-micro-cluster来容纳该数据点。该子算法的流程见图4。

    对于脱机部分,当用户的聚类要求到来时,DenStream算法先忽略密度不足够的两类微簇,然后使用DBSCAN算法,对当前的p-micro-cluster和o-micro-cluster进行处理,得到聚类结果并返回。

    3.4基于网格的方法---D-Stream

    D-Stream就是一个基于网格和密度的数据流聚类算法。它使用密度网格(Density grid),基于密度和网格产生高质量的聚类结果。

    D-Stream算法是一个基于密度和网格的算法。与DenStream算法一样,D-Stream算法也着力解决对任意形状的数据流聚类问题、强调了孤立点探测,并且依据密度来判断聚类。所不同的是,它是一个基于网格的算法,使用密度网格(Density Grid)结构。

    D-Stream算法同样分为联机和脱机两个部分。联机部分将接受到的每个数据元素映射到某个网格中,而脱机部分计算这些网格的密度,并且基于密度将这些网格进行聚类。

    9029d0fbc3c2ca2cbc88f6f38141ac92.png

    使用密度网格来进行聚类的过程如图5所示。联机部分持续地读入新的数据元素,并将多维的数据元素映射到多维空间内对应的离散的密度网格中,同时更新密度网格的特征向量。脱机部分在每隔一个时间隙(gap time)后动态地调整当前的簇。初始簇在第一个时间隙后形成,此后算法周期性地移除零星的簇,并调节已经生成的簇。通过使用网格结构,我们无需保留大量的原始数据,而仅仅需要对网格进行操作。

    由于联机部分仅仅是将数据元素映射到相应的网格中,而无需计算距离或权值,D-Stream相比不使用网格的算法更高效。并且它的可扩展性更好,即算法不会随着数据量的增大而变慢。但是,D-Stream算法的问题是对于高维数据流,所需要的网格的数量可能会非常大。

    3.5其他方法

    基于模型的方法试图为数据集假定一个数学模型,诸如统计学模型和神经网络模型[1]。基于模型的方法如EM算法(Expectation-Maximization)、COBWEB等。

    利用回归分析实现数据流聚类的算法CFR

    Domingos等扩展了机器学习中的算法,提出的基于Hoeffding界和k-平均算法的VFKM算法(Very Fast K-Means);Gaber等提出的基于AOG(Algorithm Output Granularity)的面向传感器网络中数据流的LWC算法(Lightweight Clustering)等

    1b0346ef71f4ad9885afdaeb9578bc19.png

    几乎所有2003年以后的数据流聚类算法都实现了增量式的处理方式,可以满足用户anytime的聚类请求。E-Stream算法实现对数据流演化的表示方式。CluStream算法框架实现了数据流的聚类演变分析,这在网络入侵检测中非常有用,可以识别网络上新的攻击类型[1]。通过使用倾斜时间框架,聚类算法可以提供不同时间粒度的聚类结果。而使用衰减函数,近期的数据得到了更大的重视。几乎所有的两阶段聚类算法都可以支持用户的联机聚类请求。

    为了处理高维数据流,HPStream算法使用了投影聚类技术。而大多数基于密度及网格的方法都能对任意形状的数据流进行聚类分析。

    展开全文
  • 聚类算法之CluStream

    2021-11-25 14:55:43
    本文简要介绍了数据流聚类算法中的CluStream算法,从算法的切入点、算法核心思想、算法的两阶段流程以及缺点进行阐述。 一、CluStream算法的切入点 (1)可以有效的存储在连续数据流中的摘要信息的性质是什么? (2...


    前言

    本文简要介绍了数据流聚类算法中的CluStream算法,从算法的切入点、算法核心思想、算法的两阶段流程以及缺点进行阐述。


    一、CluStream算法的切入点

    (1)可以有效的存储在连续数据流中的摘要信息的性质是什么?

    (2)摘要信息什么时候被存储在磁盘上?

    (3)如何使用周期的数据在用户指定的时间范围内提供聚类的结果?

    二、CluStream算法核心思想

      对于一个d维的数据集xi1,xi2,…,xin ,并且带有时间戳Ti1,Ti2,…,Tin,在磁盘中存储的是关键集群的统计信息
    在这里插入图片描述
      该信息具有可加性,方便在用户需要某一时间段的聚类结果时,进行操作;

      微簇存储在流中的特定时刻叫做快照。但是不能将每一时刻的快照都存储下来,因此引入了加粗样式,并且将快照存储在不同的粒度级别上。快照被分为不同的顺序,从1到log(T),每一个粒度存储的快照数目为(2α+1),所以在时间T范围内,存储的最大的快照的数目为(2α+1)log(T)
    在这里插入图片描述

    三、CluStream算法的两阶段

    3.1 在线阶段

      首先根据K-mens算法生成p个初始的聚类中心,并为每一个簇提供一个独一无二的ID,其中P是大于具体的聚类数目但是要远远小于具体数据点的个数。

      对于每一个到来的数据点,要么被现有的微集群吸收(是否在一个集群的最大边界内-均值根偏差RMS),要么自己成立一个集群。但是数据点不属于现有的集群有两种情况,一种是该点是一个异常点,第二种是该点是一个新集群的起始点。

      那么如果要新建立一个集群的话,就需要将已有的集群删除一个或者合并两个相似的集群。若要删除一个集群的话,首先判断删除该集群是否会有不良的影响,所以根据该集群的数据点的时间戳信息来判断,如果该簇的时间戳不满足设定的阈值,将其删除。合并集群的话,将两个最近的集群进行合并。

    3.2 离线阶段

      根据用户输入的需要查看的时间,从特征金字塔中取出两个时间段的汇总信息,相减之后就得到用户所需时间段的近似数据集,在此基础上进行聚类即可。

    CluStream算法的缺点

      CluStream通过使用倾斜时间框架,保存了数据流演变的历史信息,在数据流变化剧烈时仍可以产生高质量的聚类结果,并且提供了丰富的功能。但是,它没有考虑历史数据的衰减问题,即没有体现出近期数据的重要性。此外,当被应用于高维数据流的聚类时,CluStream算法往往表现不佳。


    总结

    本文简单对CluStream算法进行了总结概括,如果有不足之处或者表述不当的地方欢迎大家指正。

    展开全文
  • rsa加密算法c语言代码

    2021-05-24 07:20:10
    如何用C语言实现RSA算法?上学期交的作业,已通过老师在运行时间上的测试 #include #include unsigned long prime1,prime2,ee; unsigned long *kzojld(unsigned long p,unsigned long q) //扩展欧几里得算法CSS布局...

    如何用C语言实现RSA算法?

    上学期交的作业,已通过老师在运行时间上的测试 #include #include unsigned long prime1,prime2,ee; unsigned long *kzojld(unsigned long p,unsigned long q) //扩展欧几里得算法CSS布局HTML小编今天和大家分享模逆 { unsigned long i=0,a=1,b=0,c=0,d=1,temp,mid

    高手请指点#include#include#include#include#includechars[100],*c;intn,e,d,i,C,j,k=0,len;intstr[100],b[30];unsignedgcd(unsigneda,unsignedb){if(a%b==0)returnb;elsereturngcd(b,a%b);}voidEgcd(inta,intb,int&x,int&y){//ax-by=1if(b==0||a==0){x=1

    72b81dfe5cef4fbf262ab1cc711f177e.gif

    RSA加密解密算法C语言代码

    #include#include#include#include#include#include#defineMAX100#defineLENsizeof(structslink)voidsub(inta[MAX],intb[MAX],intc[MAX]);structslink{intbignum[MAX];/*bignum[98]用来标记正负号,1正,0负bignum[99]来标记实际长度*/structsli

    RSA加密解密算法c语言程序

    #include#include#include//将十进制数转换成二进制,用于检验大素数p和qintzhuan_huan(intb,inta[],intk){intt,temp=-1;while(b>0){t=b%2;temp++;a[temp]=t;b=b/2;}returntemp;}//欧几里得算法,用于判断加密指数e是否符合要CSS布局HTML小编今天和大家分享intgcd(intn,intb

    RSA算法它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字 命名:Ron Rivest, Adi Shamir 和Leonard Adleman。但RSA的安全性一直未能得到理论上的证明。

    RSA加密算法怎样用C语言实现? 急急急。。。

    输入数据 P=43, q=59 e=13 n=2537 d=937 =>(e=13,n=2537)为公钥,(d=937)/*数据只能是大写字母组成的字符串。 加密的时候,输入Y,然后输入要加密的文本(大写字母) 解密的时候,输入N,然后输入一个整数n表示密文的个数,然后n个整数表示加密时候得到的密文。 */ /*RSA algorithm */ #include #include #include #de

    CSS布局HTML小编今天和大家分享RSA算法的源代码(c语言)

    急CSS布局HTML小编今天和大家分享DES加密和RSA加密算法源代码(C语言版)

    如何用C语言来使用openssl rsa进行公钥加密,已有想要完整的程序,。

    1. 本程序使用2048位密钥对,每次加密时,原始数据的最大长度为245字节,加密后的密文长度为256字节.(采用打PADDING 的加密方式) 2. 如果所加密数据长度大于245字节,请分多次加密,后将密文按顺序存储;解密时,每次读取256字节,进行解密,将解密后的数

    如何用C语言程序实现RSA算法?

    CSS布局HTML小编今天和大家分享~具体程序

    #include "stdafx.h" #include #include int isP(int m) { int i; for(i=2;i0;m++) if(isP(m)) { k; return m; } } int main(int argc, char* argv[]) { int P,Q,E,D,i,k,fn,c=0,j=0,t=1,f1=1,l=2; int a[10]; long N0,N1; long PT,CT,N; prin

    展开全文
  • 《堆》中等02 —— LeetCode 703. 数据流中的第 K 大元素

    一、题目

    1、题目描述

      设计一个找到数据流中第 k 大元素的类(class)。注意是排序后的第 k 大元素,不是第 k 个不同的元素。请实现 KthLargest 类:
      1)KthLargest(int k, int[] nums) 使用整数 k 和整数流 nums 初始化对象。
      2)int add(int val) 将 val 插入数据流 nums 后,返回当前数据流中第 k 大的元素。
      样例输入: ["KthLargest", "add", "add", "add", "add", "add"] [[3, [4, 5, 8, 2]], [3], [5], [10], [9], [4]]
      样例输出: [null, 4, 5, 5, 8, 8]

    2、基础框架

    • C语言 版本给出的基础框架代码如下:
    typedef struct {
    
    } KthLargest;
    
    
    KthLargest* kthLargestCreate(int k, int* nums, int numsSize) {
    
    }
    
    int kthLargestAdd(KthLargest* obj, int val) {
    
    }
    
    void kthLargestFree(KthLargest* obj) {
    
    }
    

    3、原题链接

    剑指 Offer II 059. 数据流的第 K 大数值
    LeetCode 703. 数据流中的第 K 大元素

    二、解题报告

    1、思路分析

       维护一个小顶堆,堆的元素始终保持 k k k 个,那么堆顶的就一定是第 k k k 大的元素。

    2、时间复杂度

      创建堆的过程为 O ( n l o g 2 n ) O(nlog_2n) O(nlog2n),每次执行插入,都要执行弹出操作,单次插入删除的时间复杂度为 O ( l o g 2 n ) O(log_2n) O(log2n)

    3、代码详解

    
    /**********************************小顶堆模板************************************/
    #define lson(idx) (idx << 1|1)
    #define rson(idx) ((idx + 1) << 1)
    #define parent(idx) ((idx - 1) >> 1)
    #define root 0
    #define DataType int
    
    // -1 和 1 交换,就变成了大顶堆
    int compareData(const DataType* a, const DataType* b) {
        if(*a < *b) {
            return -1;
        }else if(*a > *b) {
            return 1;
        }
        return 0;
    }
    
    void swap(DataType* a, DataType* b) {
        DataType tmp = *a;
        *a = *b;
        *b = tmp;
    }
    
    typedef struct {
        DataType *data;
        int size;
        int capacity;
    }Heap;
    
    // 内部接口,小写驼峰
    
    // heapShiftDown 这个接口是一个内部接口,所以用小写驼峰区分,用于对堆中元素进行删除的时候的下沉调整;
    void heapShiftDown(Heap* heap, int curr) {
        int son = lson(curr);
    
        while(son < heap->size) {
            if( rson(curr) < heap->size ) {
                if( compareData( &heap->data[rson(curr)], &heap->data[son] ) < 0 ) {
                    son = rson(curr);                        // 始终选择值更小的结点
                }        
            }
            if( compareData( &heap->data[son], &heap->data[curr] ) < 0 ) {
                swap(&heap->data[son], &heap->data[curr]);   // 子结点的值小于父结点,则执行交换;
                curr = son;
                son = lson(curr);
            }else {
                break;                                       // 子结点的值大于父结点,说明已经正确归位,下沉操作结束,跳出循环;
            }
        }
    }
    
    // heapShiftUp 这个接口是一个内部接口,所以用小写驼峰区分,用于对堆中元素进行插入的时候的上浮调整;
    void heapShiftUp(Heap* heap, int curr) {
        int par = parent(curr);
        while(par >= root) {
            if( compareData( &heap->data[curr], &heap->data[par] ) < 0 ) {
                swap(&heap->data[curr], &heap->data[par]);   // 子结点的值小于父结点,则执行交换;
                curr = par;
                par = parent(curr);
            }else {
                break;                                       // 子结点的值大于父结点,说明已经正确归位,上浮操作结束,跳出循环;
            }
        }
    }
    
    bool heapIsFull(Heap *heap) {
        return heap->size == heap->capacity;
    }
    
    // 外部接口,大写驼峰
    
    // 堆的判空
    bool HeapIsEmpty(Heap *heap) {
        return heap->size == 0;
    }
    
    int HeapSize(Heap *heap) {
        return heap->size;
    }
    
    // 堆的插入
    // 插到最后一个位置,然后不断进行上浮操作
    bool HeapPush(Heap* heap, DataType data) {
        if( heapIsFull(heap) ) {
            return false;
        }
        heap->data[ heap->size++ ] = data;
        heapShiftUp(heap, heap->size-1);
        return true;
    }
    
    
    // 堆的删除
    // 1、删除堆顶元素时,将堆底部的下标最大的元素放入对顶;
    // 2、然后调用 shiftDown 将这个元素进行下沉操作;
    // 对于小顶堆来说,从根到叶子的路径必然是单调不降的,所以下沉操作一定会终止在路径的某个点,并且保证所有的堆路径还是能够维持单调不降;
    bool HeapPop(Heap *heap) {
        if(HeapIsEmpty(heap)) {
            return false;
        }
        heap->data[root] = heap->data[ --heap->size ];
        heapShiftDown(heap, root);
        return true;
    }
    
    DataType HeapTop(Heap *heap) {
        assert(!HeapIsEmpty(heap));
        return heap->data[root];
    }
    
    // 创建堆
    Heap* HeapCreate(DataType *data, int dataSize, int maxSize) {
        int i;
        Heap *h = (Heap *)malloc( sizeof(Heap) );
        
        h->data = (DataType *)malloc( sizeof(DataType) * maxSize );
        h->size = 0;
        h->capacity = maxSize;
    
        for(i = 0; i < dataSize; ++i) {
            HeapPush(h, data[i]);
        }
        return h;
    }
    
    // 销毁堆
    void HeapFree(Heap *heap) {
        free(heap->data);
        free(heap);
    }
    
    /**********************************小顶堆模板************************************/
    
    
    typedef struct {
        Heap *heap;
        int K;
    } KthLargest;
    
    
    KthLargest* kthLargestCreate(int k, int* nums, int numsSize) {
        KthLargest *KL = (KthLargest *)malloc( sizeof(KthLargest) );
        KL->K = k;
        KL->heap = HeapCreate(nums, numsSize, 100000);  // (1)
        return KL;
    }
    
    int kthLargestAdd(KthLargest* obj, int val) {
        HeapPush(obj->heap, val);
        while(HeapSize(obj->heap) > obj->K) {           // (2)
            HeapPop(obj->heap);
        }
        return HeapTop(obj->heap);
    }
    
    void kthLargestFree(KthLargest* obj) {
        HeapFree(obj->heap);
        free(obj);
    }
    
    /**
     * Your KthLargest struct will be instantiated and called as such:
     * KthLargest* obj = kthLargestCreate(k, nums, numsSize);
     * int param_1 = kthLargestAdd(obj, val);
     
     * kthLargestFree(obj);
    */
    
    • ( 1 ) (1) (1) 创建一个小顶堆;
    • ( 2 ) (2) (2) 维持堆元素个数始终为 k k k 个;

    三、本题小知识

      堆 可以用于实现 K K K 大数。


    四、加群须知

      相信看我文章的大多数都是「 大学生 」,能上大学的都是「 精英 」,那么我们自然要「 精益求精 」,如果你还是「 大一 」,那么太好了,你拥有大把时间,当然你可以选择「 刷剧 」,然而,「 学好算法 」,三年后的你自然「 不能同日而语 」
      那么这里,我整理了「 几十个基础算法 」 的分类,点击开启:

    🌌《算法入门指引》🌌

      如果链接被屏蔽,或者有权限问题,可以私聊作者解决。

      大致题集一览:


    在这里插入图片描述


      为了让这件事情变得有趣,以及「 照顾初学者 」,目前题目只开放最简单的算法 「 枚举系列 」 (包括:线性枚举、双指针、前缀和、二分枚举、三分枚举),当有 一半成员刷完 「 枚举系列 」 的所有题以后,会开放下个章节,等这套题全部刷完,你还在群里,那么你就会成为「 夜深人静写算法 」专家团 的一员。
      不要小看这个专家团,三年之后,你将会是别人 望尘莫及 的存在。如果要加入,可以联系我,考虑到大家都是学生, 没有「 主要经济来源 」,在你成为神的路上,「 不会索取任何 」
      🔥联系作者,或者扫作者主页二维码加群,加入刷题行列吧🔥


    🔥让天下没有难学的算法🔥

    C语言免费动漫教程,和我一起打卡!
    🌞《光天化日学C语言》🌞

    入门级C语言真题汇总
    🧡《C语言入门100例》🧡

    几张动图学会一种数据结构
    🌳《画解数据结构》🌳

    组团学习,抱团生长
    🌌《算法入门指引》🌌

    竞赛选手金典图文教程
    💜《夜深人静写算法》💜
    展开全文
  • 实战系列-Java实现限流算法

    千次阅读 2021-04-20 10:50:23
      在Java开发过程中,经常用到的限流算法有两种,一种是令牌桶算法,一种是漏斗桶算法,那么下面就来分别看看两种算法的Java实现方式。 文章目录限流算法之漏桶算法漏桶的实现限流算法之令牌桶法简单的令牌桶算法...
  • 来源 | 海豚数据科学实验室著作权归作者所有,本文仅作学术分享,若侵权,请联系后台删文处理聚类或聚类分析是无监督学习问题。它通常被用作数据分析技术,用于发现数据中的有趣模式,例如基于其行为...
  • 30 个重要数据结构和算法完整介绍(建议收藏保存)

    万次阅读 多人点赞 2021-06-07 08:02:06
    数据结构和算法 (DSA)通常被认为是一个令人生畏的话题——一种常见的误解。它们是技术领域最具创新性概念的基础,对于工作/实习申请者和有经验的程序员的职业发展都至关重要。话虽如此,我决定在CSDN新星计划挑战...
  • 《队列》简单02 —— LeetCode 346. 数据流中的移动平均值
  • LLE算法代码% LLE ALGORITHM (using K nearest neighbors)%% [Y] = lle(X,K,dmax)%% X = data as D x N matrix (D = dimensionality, N = #points)% K = number of neighbors(领域点的个数)% dmax = max embedding ...
  • 十本数据结构与算法书籍推荐

    千次阅读 2021-05-20 22:57:29
    在这里列出一些我看过或者准备看的算法书籍,以供参考。 第一名 原书名:The Art of Computer Programming 中文名:计算机程序设计艺术 作者:Donald E.Knuth 难度:★★★★★ 个人评价:★★★★★ 推荐...
  • 常用的限流算法

    2021-06-10 19:46:43
    常用的限流算法 1.计数器(固定窗口)算法 介绍 计数器算法是使用计数器在周期内累加访问次数,当达到设定的限流值时,触发限流策略。下一个周期开始时,进行清零,重新计数。 假设1min内服务器的负载能力为100,...
  • 处理限的过程中发现gateway提供了一种基于令牌桶的分布式限实现,非常感兴趣,于是在经过一番处理,从gateway的源码中提取出一个轻量的基于令牌桶算法的分布式限工具,供参考选用。SpringCloudGateway将限的...
  • 算法数据结构》题海战术篇

    万次阅读 多人点赞 2021-07-15 06:13:43
    刷了 3333 题 算法题 后的一点点经验总结 —— 题不是这么刷的!
  • 小店已开展代查业务,有任何问题随时联系小店qq 1981389505 或者微信 18451578808教程名称:数据结构与算法之美(完结)教程目录:|- 总结课讲在实际开发中,如何权衡选择使用哪种数据结构和算法.pdf - 836.00 kB|- ...
  • 面试官:说说你了解几种限流算法,手写个demo?

    千次阅读 多人点赞 2021-12-04 18:10:13
    在流量突增的场景下,为了保证后端服务在整体上一个稳定性,我们需要对请求进行限流,来避免系统崩溃。 不过限流会对少部分用户的请求直接进行...本文会介绍一些常见的限流算法,并在最后附上对分布式限流的一些思考。
  • 上文简单介绍过限流中的计数器法,详情参考:限流算法之计数器算法(Java实现)计数器法有个缺点就是临界问题。举个例子,我们限制每分钟调用接口不能超过1000次,用计数器法实现时,如果恶意用户在01:59秒一秒内发送...
  • TMDS数据编码算法

    2021-05-06 10:33:57
    TMDS,Transition Minimized Differential Signaling,即最小化差分传输信号,在DVI(数字视频接口,只能传输视频)和HDMI(音视频均...然后在并串转换阶段将上述的字符流转换成串行数据流,并将其从三个差分输出通道发
  • 一些经典的数据结构和算法...本书全面、系统地讲解了常用、常考的数据结构和算法,并结合 300多幅图和上百段代码,让内容变得更加通俗易懂。同时,对于每个知识点,本书结合真实的应用场景进行讲解,采用一问一答的讲解
  • 背景:算法数据结构作为技术开发者最基本的技术修养,在日常开发出现的频率非常高 本文目的:花尽可能短的时间,快速学习常见的数据结构知识及算法 适用阅读人群:所有技术开发者 本文主要内容: 常见、常考的...
  • 如内存已无空闲页框,缺页中断服务程序就会调用页面置换算法,页面置换算法的目.最佳置换法(OPT)三种置换算法模拟页面置换过程并计算其缺页率并分析结。//熬夜弄出来的,记得加分哦#includevoid Print(int bc[],int...
  • 关于neighborhood serach,这里有好多种衍生和变种出来的胡里花俏的算法。大家在上网搜索的过程中可能看到什么Large Neighborhood Serach,也可能看到Very Large Scale Neighborhood Search或者今天介绍的Adaptive ...
  • 流算法, 以 Golang 方式

    万次阅读 2021-06-11 15:07:31
    流算法, 以 Golang 方式 速率限制 在 Web Server、TCP 通讯、API 交互等领域中,速率限制,Rate Limit,一般是面向请求次数、流量等参数进行速率控制。有的时候它又被称作流量控制。 谈论流量控制时,大抵上要考虑...
  • 常用的限流算法有:滑动窗口、漏斗以及令牌桶。得益于redis的数据结构特点,redis实现滑动窗口限流和漏斗限流的非常的便捷。滑动窗口限流的原理和实现以xx论坛限制用户行为为例子,比如一秒内进行...
  • 模拟退火算法及MATLAB代码

    千次阅读 2020-12-20 13:16:33
    对模拟退火算法简要的介绍和matlab源码,分享了部份国内研究学者的主页。
  • Prony算法步骤及示例代码

    千次阅读 2021-11-02 10:17:16
    本文算法步骤及代码对有噪声的数据可能效果不好,还需要改进
  • 以上三本书籍对数据结构和算法整体与局部的把握较合理,讲解清晰,对于基本原理,例子,实现,证明都有所涵盖,涵盖了常用数据结构与算法。 以CLRS为主,参考Weiss和Horowitz的书。并将CLRS中未涉及的内容作为补充...
  •   我们前面的两篇文章初步给大家介绍了数据结构与算法的工具推荐以及最常用最核心的十大排序算法。众所周知,数据结构与算法在计算机行业是最核心的,也是最基础的,当然在计算机的基础知识中,这部分内容是最难的...
  • stream 的特点 ①只能遍历一次: 数据流的从一头获取数据源,在流水线上依次对元素进行操作,当元素通过流水线,便无法再对其进行操作,可以重新在数据源获取一个新的数据流进行操作; ②采用内部迭代的方式: 对...
  • 利用遗传算法优化 BP 神经网络的权值和阈值, 然后训练 BP 神经网络预测模型以求得最优解, 并将该预测方法应用到几个典型混沌时间序列和实测短时交通时间序列进行有效性验证. 仿真结果表明, 该方法对典型混沌时间...
  • 数据结构与算法之并查集

    千次阅读 多人点赞 2021-11-25 16:12:47
    并查集是一种树型的数据结构 ,并查集可以高效地进行如下操作: 查询元素 p和元素q是否属于同一组 合并元素 p和元素q所在的组 1.1.并查集结构 并查集也是一种树型结构,但这棵树跟我们之前讲的二叉树、红黑树、B...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 321,676
精华内容 128,670
关键字:

数据流算法代码