首页 > 编程语言 >C# 蓄水池抽样

C# 蓄水池抽样

时间:2022-11-14 14:15:13浏览次数:63  
标签:抽样 抽取 C# List 蓄水池 titleIndexList eigenValueList 数据

C# 蓄水池抽样

 

蓄水池采样算法解决的是在给定但长度未知的大数据集中,随机等概率抽取一个数据。如果知道数据的长度,可以用随机数rand()%n得到一个确切的随机位置,或者分块取值来构造随机,那么该位置的对象就是所求的对象,选中的概率是1/n。那长度未知特别是如果这个大数据集不能一次性放入内存中,蓄水池抽样算法就非常有用,在我的项目中采用的蓄水池随机抽样还加入了权重的计算。

其中方法中核心代码,也就是蓄水池抽样就是如下代码。

if (i < spotQuantity)
{
    titleIndexList.Add(i);
    eigenValueList.Add(tempEigenValue);
}
else
{
    double minEigenValue = eigenValueList.Min();
    int minIndex = eigenValueList.IndexOf(minEigenValue);

    if (tempEigenValue > minEigenValue)
    {
        eigenValueList[minIndex] = tempEigenValue;
        titleIndexList[minIndex] = i;
    }
}

首先从计算出的要抽取多少数量,根据数据循环,先让抽取数量的数据放入池子中titleIndexList,并且将对应数据的权重放入到抽取数据的权重列表。
在后面的循环中,判断抽取的权重如果大于已经抽取的最小权重则替换最小权重的数据为当前循环的数据。
如果你不是按照权重,则可以产生一个随机数,如果随机数落在已经抽取队列的数组下标内,则替换掉原来的下标数据也能实现随机性。

        public static void WeightedSampling(List<article> articleList, int grade)
        {
            //根据传入的grade 计算一个抽样数量。
            double sampleFactor = (double)Math.Pow((double)1 / (1 + grade), Math.E);
            var spotQuantity = (int)Math.Ceiling(articleList.Count() * sampleFactor);
            //如果规则抽的数量已经超过随机抽取数则不再抽取
            var spotedCount = articleList.Where(t => t.isspot == 1).Count();
            if (spotedCount >= spotQuantity)
                return;
            //如果数量不足则补齐
            spotQuantity -= spotedCount;
            var spotTitleList = articleList.Where(t => t.isspot != 1).ToList();
            //实例化池子和数据权重List
            List<int> titleIndexList = new List<int>();
            List<double> eigenValueList = new List<double>();

            if (spotArticle.Count() <= spotQuantity)
            {
                for (int i = 0; i < spotArticle.Count(); i++)
                {
                    spotArticle[i].isspot = 1;
                }
            }
            else
            {
                var random = new Random();
                for (int i = 0; i < spotTitleList.Count; i++)
                {
                    double tempWeight = spotTitleList[i].eigenvalue;
                    double tempEigenValue = Math.Pow(random.NextDouble(), 1 / tempWeight);

                    if (i < spotQuantity)
                    {
                        titleIndexList.Add(i);
                        eigenValueList.Add(tempEigenValue);
                    }
                    else
                    {
                        double minEigenValue = eigenValueList.Min();
                        int minIndex = eigenValueList.IndexOf(minEigenValue);

                        if (tempEigenValue > minEigenValue)
                        {
                            eigenValueList[minIndex] = tempEigenValue;
                            titleIndexList[minIndex] = i;
                        }
                    }
                }
                //将抽取出来的对象isspot 抽取标志设置为1
                foreach (var index in titleIndexList)
                {
                    spotTitleList[index].isspot = 1;
                }
            }
        }

该方法对于我们平时项目中抽取不知道数据长度的随机数是非常好用的算法,同时该算法不复杂其时间复杂度为O(n)。

作者:SunSpring

出处:https://www.cnblogs.com/SunSpring/p/16308794.html

本文版权归作者所有,欢迎转载,但未经作者同意需在文章页面明显位置给出原文链接。

标签:抽样,抽取,C#,List,蓄水池,titleIndexList,eigenValueList,数据
From: https://www.cnblogs.com/sexintercourse/p/16888862.html

相关文章

  • C# 图片沿中心点进行角度旋转
    C#图片沿中心点进行角度旋转 Image图片沿中心点进行任意角度旋转publicstaticImageRotateImg(Imageb,intangle){angle=ang......
  • centos 8 rc.local不生效的问题
    具体可以操作红帽的官方文档(英文):https://www.jianshu.com/p/96a2075ad784 使rc.local生效的操作如下:chmoda+x/etc/rc.d/rc.localsystemctlenablerc-local......
  • C# 图片处理生成缩略图
    C#图片处理生成缩略图 缩略图通常是将图片内容进行一定的缩小展现,或裁剪展现,主要有两个目的,一是提供一定的预览功能,二是节省屏幕展示空间、节省流量。在网站中我们通......
  • 真趣科技:多业务形态的企业需要灵活可配置的CRM系统
    苏州真趣信息科技有限公司,物联网领域国家高新技术企业。位置物联网领域博士后、博士领衔科研团队,荣获300余项专利、重磅荣誉、国际国内权威机构认证。公司旗下拥有“真趣......
  • C# iText 7 切分PDF,处理PDF页面大小,添加水印
    C#iText7切分PDF,处理PDF页面大小,添加水印 一、itext我要使用itext做一个pdf的页面大小一致性处理,然后再根据数据切分出需要的pdf.iText的官网有关于它的介绍,http......
  • Failed to check the status of the service XXX.XXX. No provider available for the
    TheDubboConsumerCANNOTFIND service 1.检查消费者端配置version是否和提供者一致,有时候你消费者配置version="*"也是不行的2.检查group分组,如果有分组,则检查消......
  • Canal安装配置(消息队列类型:RabbitMQ)
    1.Mysql配置canal支持源端MySQL版本包括5.1.x,5.5.x,5.6.x,5.7.x,8.0.x1.1.查看mysqlbinlog是否开启:SHOWVARIABLESLIKE'log_bin' ON标识开启,如果m......
  • Oracle19c下载、安装及卸载
    1、官网下载地址:DatabaseSoftwareDownloads|Oracle  *安装zip文件,see all文件是对应客户端的下载位置(用于自学无需下载) 2、登陆Oracle账号,若无Oracle......
  • 2022 China Collegiate Programming Contest (CCPC) Weihai Site
    比赛链接:https://codeforces.com/gym/104023A.Dunai题意:\(n\)个队伍获得过冠军,告知每个队伍中的人及对应的位置,现在已知\(m\)个选手及它们的位置,问能组成多少个五......
  • C和C++的区别
    一、面向过程语言和面向对象语言C语言是面向过程语言,而C++是面向对象语言(一)面向过程和面向对象的区别(1)面向过程:面向过程编程就是分析出解决问题的步骤,然后把这些步骤一......