C#,数值计算——堆选择(Heap Select)的计算方法与源程序

news2024/10/7 8:22:08

1 简述

HeapSelect 是一种用于选择数组中第 K 个最大元素的算法。它是选择问题的变体,涉及在无序或偏序集合中查找特定元素。

算法概要:数组被转换为最大堆,然后反复删除根节点并替换为下一个最大的元素,直到找到第 K 个最大的元素。

2 Heapselect


We saw a randomized algorithm with n + O(log n) comparison expected. Can we get the same performance out of an unrandomized algorithm?
Think about basketball tournaments, involving n teams. We form a complete binary tree with n leaves; each internal node represents an elimination game. So at the bottom level, there are n/2 games, and the n/2 winners go on to a game at the next level of the tree. Assuming the better team always wins its game, the best team always wins all its games, and can be found as the winner of the last game.

(This could all easily be expressed in pseudo code. So far, it's just a complicated algorithm for finding a minimum or maximum, which has some practical advantages, namely that it's parallel (many games can be played at once) and fair (in contrast, if we used algorithm min above, the teams placed earlier in L would have to play many more games and be at a big disadvantage).

Now, where in the tree could the second best team be? This team would always beat everyone except the eventual winner. But it must have lost once (since only the overall winner never loses). So it must have lost to the eventual winner. Therefore it's one of the log n teams that played the eventual winner and we can run another tournament algorithm among these values.

If we express this as an algorithm for finding the second best, it uses only n + ceil(log n) comparisons, even better than the average case algorithm above.

If you think about it, the elimination tournament described above is similar in some ways to a binary heap. And the process of finding the second best (by running through the teams that played the winner) is similar to the process of removing the minimum from a heap. We can therefore use heaps to extend idea to other small values of k:

    heapselect(L,k)
    {
    heap H = heapify(L)
    for (i = 1; i < k; i++) remove min(H)
    return min(H)
    }
The time is obviously O(n + k log n), so if k = O(n/log n), the result is O(n). Which is interesting, but still doesn't help for median finding.

3 C#源程序

using System;

namespace Legalsoft.Truffer
{
    public class Heapselect
    {
        private int m { get; set; }
        private int n { get; set; }
        private int srtd { get; set; }
        private double[] heap { get; set; }

        public Heapselect(int mm)
        {
            this.m = mm;
            this.n = 0;
            this.srtd = 0;
            this.heap = new double[mm];
            for (int i = 0; i < mm; i++)
            {
                heap[i] = 1.0E99;
            }
        }

        public void add(double val)
        {
            if (n < m)
            {
                heap[n++] = val;
                if (n == m)
                {
                    Array.Sort(heap);
                }
            }
            else
            {
                if (val > heap[0])
                {
                    heap[0] = val;
                    for (int j = 0; ;)
                    {
                        int k = (j << 1) + 1;
                        if (k > m - 1)
                        {
                            break;
                        }
                        if (k != (m - 1) && heap[k] > heap[k + 1])
                        {
                            k++;
                        }
                        if (heap[j] <= heap[k])
                        {
                            break;
                        }
                        Globals.SWAP(ref heap[k], ref heap[j]);
                        j = k;
                    }
                }
                n++;
            }
            srtd = 0;
        }

        public double report(int k)
        {
            int mm = Math.Min(n, m);
            if (k > mm - 1)
            {
                throw new Exception("Heapselect k too big");
            }
            if (k == m - 1)
            {
                return heap[0];
            }
            if (srtd == 0)
            {
                Array.Sort(heap);
                srtd = 1;
            }
            return heap[mm - 1 - k];
        }
    }
}
 

4 可参考的C 代码

/***********************************************************************
 * Author: Isai Damier
 * Title: Find the Greatest k values
 * Project: geekviewpoint
 * Package: algorithms
 *
 * Statement:
 *   Given a list of values, find the top k values.
 *
 * Time Complexity: O(n log n)
 * 
 * Sample Input: {21,3,34,5,13,8,2,55,1,19}; 4
 * Sample Output: {19,21,34,55}
 * 
 * Technical Details: This selection problem is a classic and so has
 *   many very good solutions. In fact, any sorting algorithm can be
 *   modified to solve this problem. In the worst case, the problem
 *   can indeed be reduced to a sorting problem: where the collection
 *   is first sorted and then the element at indices 0 to k-1 are
 *   retrieved.
 *   
 *   Presently the problem is solved using a modified version of
 *   heapsort called heapselect.
 **********************************************************************/
 public int[] heapselectTopK(int[] G, int k) {
  int last = G.length - 1;
  //convert array to heap in O(n)
  int youngestParent = last / 2;//l = 2*p+1: p=(l-1)/2
  for (int i = youngestParent; i >= 0; i--) {
    moveDown(G, i, last);
  }
  //sort up to k (i.e. find the kth)
  int limit = last - k;
  for (int i = last; i > limit; i--) {
    if (G[0] > G[i]) {
      swap(G, 0, i);
      moveDown(G, 0, i - 1);
    }
  }
  return Arrays.copyOfRange(G, G.length - k, G.length);
}
 
private void moveDown(int[] A, int first, int last) {
  int largest = 2 * first + 1;
  while (largest <= last) {
    if (largest < last && A[largest] < A[largest + 1]) {
      largest++;
    }
    if (A[first] < A[largest]) {
      swap(A, first, largest);
      first = largest;
      largest = 2 * first + 1;
    } else {
      return;
    }
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/841419.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023《财富》500强|500强中超过10%已是盖雅客户,100强中已合作超过1/4

7月11日 &#xff0c;财富中文网发布了 &#xff0c;该榜单覆盖范围包括在中国境内外上市的所有中国公司&#xff0c;根据全球范围内最大的中国上市企业过去一年的业绩和成就进行排名。因此&#xff0c;上榜的上市公司不仅是经营规模大&#xff0c;绝大多数也是各自行业的龙头…

【LeetCode】240.搜索二维矩阵Ⅱ

题目 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,…

【无标题】云原生在工业互联网的落地及好处!

什么是工业互联网&#xff1f; 工业互联网&#xff08;Industrial Internet&#xff09;是新一代信息通信技术与工业经济深度融合的新型基础设施、应用模式和工业生态&#xff0c;通过对人、机、物、系统等的全面连接&#xff0c;构建起覆盖全产业链、全价值链的全新制造和服务…

软件测试工程师的基础必备技能:功能测试解读

什么是功能测试&#xff1f; 根据百科的官方定义&#xff1a;功能测试就是对产品的各功能进行验证&#xff0c;根据功能 测试用例&#xff0c;逐项测试&#xff0c;检查产品是否达到用户要求的功能。 通俗的解读&#xff1a; 功能测试&#xff0c;也叫行为测试&#xff0c;即测…

【mysql】实现递归查询

mysql实现递归查询的方法&#xff1a;首先创建表&#xff0c;并初始化数据&#xff1b;然后向下递归&#xff0c;利用find_in_set()函数和group_concat()函数、with recursive实现递归查询。 mysql实现递归查询的方法&#xff1a; 1、创建表 DROP TABLE IF EXISTS t_areainf…

微信小程序分享实现拉新绑定(用户关系绑定)

分享人此时已经是登陆状态&#xff0c;所以在分享的时候直接从本地存储中拿到用户的userId并拼接到分享链接上&#xff0c;其他用户在点击链接打开详情页之后会判断当前链接参数中有无uid有的话则直接存入本地中用作新用户登录注册时候请求接口的判断&#xff0c;最后在砍价记录…

win10 2022unity设置中文

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言解决方法 前言 在Edit->preferences里找不到language选项。 解决方法 【1】打开下面地址 注意 :把{version}换成你当前安装的版本&#xff0c;比如说如果…

Hive创建外部表详细步骤

① 在hive中执行HDFS命令&#xff1a;创建/data目录 hive命令终端输入&#xff1a; hive> dfs -mkdir -p /data; 或者在linux命令终端输入&#xff1a; hdfs dfs -mkdir -p /data; ② 在hive中执行HDFS命令&#xff1a;上传/emp.txt至HDFS的data目录下&#xff0c;并命名为…

高德地图实现点聚合功能的详细步骤

目录 介绍准备工作1.注册并登录高德地图开放平台&#xff0c;申请密钥2.在Vue项目中安装高德地图的相关库/插件。 一、点聚合1.引入高德地图API<font color purple>initializeMap()<font color purple>loadData()<font color purple>createMarkerClustere…

4 三组例子,用OpenCV玩转图像-AI-python

读取&#xff0c;缩放&#xff0c;旋转&#xff0c;写入图像 首先导入包&#xff0c;为了显示导入matplotlib/为了在matplotlib显示 导入CV2/查看版本 导入图片/查看图片类型 图片数组 数组大小 对于opencv通道顺序蓝色B、绿色G、红色R matplotlib通道顺序为 红色R、绿色G、蓝…

前端架构师岗位的工作职责(合集)

前端架构师岗位的工作职责1 职责&#xff1a; 1.制定前端的标准和规范&#xff0c;并推广和应用&#xff0c;提高团队的开发效率; 2.前端架构的框架或核心模块的设计与实现; 3.在前端架构、设计与开发上对团队进行足够的指导; 4.在日常的系统设计与优化上与服务端团队紧密合…

深度学习基础知识扫盲

深度学习 监督学习&#xff08;Supervised learning&#xff09;监督学习分类 无监督学习&#xff08;Non-supervised learning&#xff09;无监督学习的算法无监督学习使用场景 术语特征值特征向量特征工程&#xff08;Feature engineering&#xff09;特征缩放Sigmod functio…

【果树农药喷洒机器人】Part2:机器人变量喷药系统硬件选型

本专栏介绍&#xff1a;付费专栏&#xff0c;持续更新机器人实战项目&#xff0c;欢迎各位订阅关注。 关注我&#xff0c;带你了解更多关于机器人、嵌入式、人工智能等方面的优质文章&#xff01; 文章目录 一、引言二、变量喷药系统总体要求2.1系统功能要求2.2系统技术要求 三…

怎样能做成小米左侧边栏效果

1、现在我想做成小米左侧边栏这样的效果&#xff0c;该怎么做呢&#xff1f; 2、小米商城触碰之后会显示出新的商品案例 3、一碰到之后会出现这个列表 4、这里涉及到了元素显示模式&#xff1a; 5、用人进行划分可以分为男人和女人&#xff0c;根据男人和女人的特性进行相应的…

JJWT快速入门

本篇介绍使用 JJWT&#xff08;Java JWT&#xff09;库来生成 JWT Token&#xff0c;步骤如下&#xff1a; 添加依赖&#xff1a; 在项目中添加 JJWT 依赖项。对于 Maven 项目&#xff0c;可以在 pom.xml 文件中添加以下依赖项&#xff1a; <dependency><groupId>…

通用FIR滤波器的verilog实现(内有Lowpass、Hilbert参数生成示例)

众所周知&#xff0c;Matlab 中的 Filter Designer 可以直接生成 FIR 滤波器的 verilog 代码&#xff0c;可以方便地生成指定阶数、指定滤波器参数的高通、低通、带通滤波器&#xff0c;生成的 verilog 代码也可以指定输入输出信号的类型和位宽。然而其生成的代码实在算不上美观…

uniapp实现支付宝菜单展开与收起

需求实现支付宝类似的效果&#xff1a; 思路&#xff1a; 1.首先建立展开收起按钮&#xff0c;这里使用的是uview里面的icon图标。 2.其次建立展开菜单内容&#xff0c;这里只演示了文本信息&#xff0c;后期引入首页应用。 3.最后写js逻辑&#xff0c;展开收起时改变盒子高度和…

windows .gitignore 加入文件名后 依然可以从git status中看到文件问题

最近在学git&#xff0c;对着b站的视频操作&#xff0c;结果很简单的添加.gitignore文件操作&#xff0c;up主的正常隐藏&#xff0c;我的却一直出问题。 百思不得其解&#xff0c;网上各种啥啥啥清缓存都没讲到点上。 最后发现是.gitignore文件有问题&#xff0c;windows默认…

【网络基础知识铺垫】

文章目录 1 :peach:计算机网络背景:peach:1.1 :apple:网络发展:apple: 2 :peach:协议:peach:2.1 :apple:协议分层:apple:2.2 :apple:OSI七层模型:apple:2.3 :apple:TCP/IP模型:apple:2.4 :apple:TCP/IP模型与操作系统的关系:apple: 3 :peach:网络传输基本流程:peach:4 :peach:网…

Autoware.ai1.14.0自动驾驶-Demo运行

Autoware.ai1.14.0自动驾驶-Demo运行 数据准备 下载数据&#xff1a; wget https://autoware-ai.s3.us-east-2.amazonaws.com/sample_moriyama_data.tar.gz wget https://autoware-ai.s3.us-east-2.amazonaws.com/sample_moriyama_150324.tar.gz一定要注意解压文件是在.auto…