在100W个数中获得最大/小的50个数

本文讨论了在一百万个数中寻找最大或最小的50个数的不同算法,包括快速排序、插入排序、堆排序等,并通过实验对比了这些方法的效率。
        前年有个朋友在南大考研复试时被老师一个题目问住了,“如何在100W个数中选最大/小的50个?”当时他的回答是快速排序。那么快排的平均比较次数是m*nlogn(log以2为底,m是个常数),所以总共的比较次数大约是100W*20m(2的10次方大约为1000,所以2的20次方大约是100W)。
        当时我的想法是用插入排序维护1个容量为50的数组。这个数组保存着最小的50个数,每次比较都把最大的那个数给抛弃。当随着比较次数的增多,从概率上讲,越到后面的元素越有可能只需比较1次(因为这个数会比数组中最大的数更大)。但因为这个涉及到概率问题,所以很难计算平均比较次数。但可以算得最坏比较次数大约是50*100W,即5000W次。当时也懒得实验一下我的想法效果如何,就没继续实验了。
        后来,有个两个同学告诉我正确解法应该是堆排序。构建好初始堆后每次取出最小的数最多只需log(n)的比较,所以总共比较次数不会大于m*50*log(100W),即m*50*20=1000次(其实最后一次取出最小元素无需再维护堆这个数据结构,实际上应该是49*20*m次)。但是他们忽略了一点,构建初始堆的复杂度为O(N),所以实际上总的比较次数应该是s*100W+1000*m(s和m是常数)。
        当然,如果直接暴力点用选择排序的变形也是可以的。用选择排序直接选出最小的50个,比较次数为(100w-1)+(100w-2)+...+100w(-50),省略后面一堆尾巴,最后比较次数大约是5000w次。
         前段时间由于需要完成一个TOP K的功能,所以封装了一个TOP K的数据结构(class TopK<T>,即用插入排序维护一个容量为K的数组,这个数组保存的是最大或最小的K个元素。T是泛型)。今天正好来验证我当时的想法。不过效果很不理想,我猜测是频繁类型转换以及拆箱装箱导致的。(使用时只能用TopK<Integer>。由于JAVA的泛型和C++以及C#的泛型不同,JAVA的泛型其实就是Object+自动类型转换)。最后不使用封装重新写了一遍这个数据结构,效果好了许多。
        至于堆排序,本来使用JAVA自带的优先队列PriorityQueue
。效果差得令人发指。我稍微看了下源代码,也没搞懂为什么会这么慢。感觉即使是频繁的类型转换和拆箱装箱也不应该差这么多。最后从网上找了堆排序,效果挺好。(我一开始就指定了优先队列的容量,所以不是扩容的问题)
    以下是实验结果,第一幅图是100W数据的实验结果,第二幅是1000W数据的实验结果。





快速排序用的是JAVA自带的Arrays.sort。效果不好可能是频繁的递归以及赋值花销过大。实验证明,我的算法比较次数大概是1.015*n,而堆排序大概是1.882*n。至于交换次数,我的方法比堆排序不在一个数量级上。
     


内容概要:本研究聚焦于绿电直连型电氢氨园区的优化运行,提一种集成绿色电力直接供给、电解水制氢及氢气合成氨工艺的综合能源系统架构。通过建立包含风光发电、电解槽、氨合成反应器、储氢罐、电网交互及多类型负荷在内的系统模型,综合考虑绿电直供优先、能量梯级利用与多能互补原则,构建以系统综合运行成本最小化为目标的优化调度模型。研究采用Matlab与Python工具进行算法求解和仿真分析,利用实际气象与负荷数据完成案例验证,评估了不同运行策略下系统的经济性、可再生能源消纳能力与碳减排效益,为新型电氢氨一体化园区的规划与运行提供了理论依据和技术支撑。; 适合人群:具备一定电力系统、新能源或化工背景的研究生、科研人员及从事综合能源系统规划与优化工作的工程技术人员。; 使用场景及目标:①用于科研学习,理解电-氢-氨多能转换系统的建模与优化方法;②为工业园区的低碳化、智能化改造提供技术参考与决策支持;③作为开发类似综合能源管理系统的理论基础。; 阅读建议:此资源包含完整的模型代码、数据与论文,使用者应结合代码仔细研读论文中的模型构建部分,重点关注目标函数与约束件的设计逻辑,并尝试修改参数进行仿真,以深入掌握优化算法在实际系统中的应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值