`
winxpxt
  • 浏览: 28407 次
  • 性别: Icon_minigender_2
  • 来自: 厦门
社区版块
存档分类

疯狂位图之——位图生成12GB无重复随机乱序大整数集

 
阅读更多

    上一篇讲述了用位图实现无重复数据的排序,排序算法一下就写好了,想弄个大点数据测试一下,因为小数据在内存中快排已经很快。

一、生成的数据集要求

  1、数据为0--2147483647(2^31-1)范围内的整数;

  2、数据集包含60%的0--2^31-1的整数,即踢去40%的数;

  3、数据集中无重复数据,即任意两个数不相等;

  4、生成的数据尽可能乱序。

二、方案分析

  开始只是想弄个大点数据玩一下而已,觉得测试数据应该要满足上面的要求,动手写的时候发现,满足前3个要求都很容易,实现尽可能的乱序不好处理,计算一下这样的数据大概有多大,每个整数按10个字符计算,60%2^31*10B=12GB,存在磁盘中需要12GB空间,如果能放入内存,整数按4字节整数计算60%*2^31*4B=4.8GB。

  可以先生成满足1-3的条件的数据:

for(long num=0;num<=LONG_MAX;num++){
    if (rand() <= 0.6*RAND_MAX)//利用随机数实现抽样60%
        saveData(num);
}

  接下来再进行乱序处理,和排序算法一下,一个可选的方案是进行分段归并乱序处理。不过我在想既然可以用位图排序,为什么不能用位图生成。受到散列表的启发,设计了一个用位图生成的方法。步骤如下:

  1、在内存中申请一个2147483647位大小的位图B,需要内存为2^31/8B=256MB的内存;

  2、将位图的所有位设置为0(B[i]=0),表示0-2147483647的所有数均未使用过;

  3、生成一个0-2147483647之间的随机数random,在位图中检查B[random]是否等于0,如果为0,表示这个数没有用过,把random写入文件,并置B[random]为1;如果为1,表示这个数已经被使用过了,此时去检查random+1是否等于0,等于0就保存(random+1),并置(random+1)为1,如果不为0,则再探测random-1,random+2,random-2...,直到遇到一个为0的位,这和散列表的冲突处理类似,我这里用摆动线性探测。

  伪代码如下:

复制代码
void generatorData(){
    B = new bitset(LONG_MAX);
    B.reset();//将位图置0
    count = 0;//计数器
    while(count <= 0.6*LONG_MAX){
        random = getLongRand();    
        offset = 0;
        while(B[random+offset]==1){
            offset = getNextIndex();//获取下一个探测偏移量
        }
        saveData(random+offset);
        count++;
        B[random+offset]==1//该数已经被使用
        }        
    }
}
复制代码

  按照算法思想,每次产生一个随机数,如果这个随机数未被使用过,就保存,否则就找一个离这个随机数最近且未被使用的数保存。这里有两个关键的地方,一个是getLongRand(),这个产生0-LONG_MAX随机数的随机性直接影响了整个数据集的随机性,如果getLongRand()满足随机,那生产的数据也会是随机的。另外一个就是getNextIndex(),如果随机数已经被使用,需要在其周围探测,这个探测序列的设计的优劣将影响算法的实现效率,如果总是探测失败,就会在探测上花费太多时间,特别是在后期,很多数都已经被使用了,需要的探测的次数变得很多。如果用这个算法生成100%的数而不是60%,将会非常耗时,试想最后几个数总是要遍历整个数空间,但我们只生成60%的数据,位图中的0还不至于非常稀疏,不需要进行耗时的查询。

  实现代码如下:

复制代码
 1 /*********生成一个左右摆动的序列:1,-1,2,-2...**************/
 2 long getNextIndex(long size,long index){
 3     static short tag = -1;
 4     static long left = 0;
 5     static long right = 0;
 6     if (index == -1){//对不同的index,需要将static变量重置
 7         tag = -1;
 8         left = 0;
 9         right = 0;
10     }
11     if(index + (left - 1) < 0 && index +(right + 1) >= size)  
12         return 0;//已经遍历完,不需要再找了
13     if (index + (left - 1) < 0)
14         return ++right;//左边已经越出界限了,试探右边
15     if (index+(right + 1)>=size) 
16         return --left;//右边已经越出界限了,试探左边
17     if (tag == -1){//左右都没有出界,左右依次试探    
18         tag *= -1;
19         return ++right;
20     }else{
21         tag *= -1;
22         return --left;
23     }
24 }
25 
26 void makePhoneNum(unsigned char *bitmap,long maxNum,short bitSize){
27     FILE * phoneNumFile = fopen("phoneNumber.txt","w");
28     long count = 0;
29     long percent = 0.6*maxNum;
30     while(true){
31         long index = randLong(bitSize);
32         long offset = 0;
33         while(find(bitmap,index+offset) == 1){//这个数已经用过或者不存在
34             offset = getNextIndex(maxNum,index);
35             if(offset == 0){//查找的偏移量为0说明数都用过了
36                 fclose(phoneNumFile);
37                 return;
38             }
39         }
40         getNextIndex(maxNum,-1);//将static变量重置
41         long loc = index+offset;
42         setOne(bitmap,loc);
43         fprintf(phoneNumFile,"%ld\n",loc);
44         if(++count > percent)//保存了80%终止
45             break;
46         if(count%1000000==0)
47             printf("count:\t%ld\n",count);
48     }
49     fclose(phoneNumFile);
50 }
复制代码

    数据生成完后,发现其实可以生成一个降序的文件,再按升序排序也能验证排序算法。最后发现生成12G的数据将近要2天,需要探测的次数变多后变得很慢,这次属于瞎折腾了,不过结果不重要,通过这次折腾还是熟悉了位图的基本操作,并对随机数有了新的认识,而且我自认为这个位图+冲突处理的方法还是很有启发的。

1
2
分享到:
评论
1 楼 nubix 2013-07-03  
不知道该说什么了

相关推荐

    VC代码 透明位图显示——背景透明

    在计算机图形学中,透明位图是一种特殊类型的图像,它允许背景透过图像的某些部分显示出来,从而实现图像与背景的自然融合。在VC(Visual C++)编程环境中,实现透明位图显示是一项常见的任务,尤其在开发GUI(图形...

    RGB数据生成BMP位图(其中包括RGB数组随机生成)

    1. **创建RGB数组**:根据指定的图像尺寸,生成一个二维数组,每个元素包含红、绿、蓝三个分量的随机整数。 2. **计算位图大小**:根据RGB数组的尺寸和颜色深度,计算出位图文件的实际大小。由于BMP文件的行必须是4...

    windows 下的位图生成工具

    位图生成工具在Windows操作系统中的应用是一个常见的需求,特别是在图形设计、编程以及游戏开发等领域。本文将详细解析“windows下的位图生成工具”的工作原理、使用方法及其相关知识点。 位图,也称为栅格图像,是...

    位图字体生成工具

    位图字体生成工具是一种在计算机图形学领域中用于创建特殊效果或者定制化字体的软件工具。这类工具通常允许用户将矢量字体转换为位图格式,以便在特定的应用场景下,如游戏开发、UI设计或者网页设计中使用。位图字体...

    C#生成单色位图的方法.zip_C# 单色位图_C# 单色位图_C# 图片转单色_c#单色位图

    在C#编程中,生成单色位图是一种常见的图像处理技术,主要应用于简化图像、创建二值化图像或实现特定的视觉效果。本教程将详细解释如何使用C#来生成单色位图,并且添加信息头,使得图像更加规范且易于处理。 首先,...

    疯狂内核之——Linux虚拟内存

    - **数据结构**:通常使用位图来表示可用的内存块状态。 - **块分配**:根据请求大小分配合适的内存块。 - **块释放**:释放内存块时可能与其他相邻块合并成更大的块。 ##### 2.3 Linux页面级内存管理 页面管理...

    位图文件生成G代码

    简单的 G代码生成软件,处理简单的平面雕刻,软件有三个按钮...打开:打开位图文件,如打开的位图已经画好了边缘则不用扫描边缘直接生成G代码 如果是钻孔的话,图片里钻孔的位置放一个像素的黑点 需要些图片处理的功底

    疯狂内核之——虚拟文件系统

    - **2.3.5 安装根文件系统**:根文件系统是系统启动后访问的第一个文件系统,它的安装过程有一些特殊之处。 - **2.3.6 卸载文件系统**:卸载文件系统前,需要确保所有相关的文件都已关闭,没有进程正在访问该文件...

    BMP(Bitmap)生成器,纯C++实现由数组生成位图

    BMP(Bitmap)是一种常见的图像文件格式,用于存储位图图像。在Windows操作系统中,它被广泛使用,并且可以用纯C++来实现从数组生成BMP文件。本篇将深入探讨BMP格式的基本结构以及如何使用C++编程语言来创建一个BMP...

    易语言字节集转位图功能源码

    在IT行业中,字节集(Byte Array)是一种常见的数据结构,用于存储和传输二进制数据,例如图像、音频或视频文件。易语言是一种中国本土开发的编程语言,旨在简化编程,让普通人也能进行程序设计。在易语言中,处理...

    MFC位图随机切换显示

    在本文中,我们将深入探讨如何在MFC(Microsoft Foundation Classes)框架下实现“位图随机切换显示”的功能。MFC是微软提供的一套C++类库,用于构建基于Windows的应用程序,它为开发者提供了丰富的控件和接口,使得...

    创建位图,并生成BMP文件

    它是由像素阵列组成的,每个像素都有自己的颜色值,这使得位图能够精确地表示图像的细节,但同时也导致文件尺寸通常较大。BMP(Bitmap Picture)文件是微软操作系统中的一种位图图像文件格式,它不包含任何压缩,...

    易语言位图句柄取位图模块

    在IT行业中,位图处理是图像编程中的一个重要环节,尤其在图形用户界面(GUI)的开发中。"易语言位图句柄取位图模块"是一个专为易语言设计的库,用于帮助开发者高效地管理和操作位图资源。易语言是一种以中文为编程...

    一个生成8位位图文件的c源码

    8位位图中,每行数据的字节数可能是像素宽度的整数倍,也可能需要填充字节以保持对齐。 在`bitmap.c`源码中,你需要实现创建并写入这些结构的功能。首先,计算出图像数据的大小和在文件中的偏移量,然后根据位图...

    LCD 位图 生成工具 用于嵌入式位图的生产。希望有用

    LCD位图生成工具是针对嵌入式系统设计中不可或缺的一部分,尤其在开发具有图形用户界面(GUI)的设备时。嵌入式系统通常资源有限,因此需要高效且优化的位图处理方法。位图,也称为光栅图像,是由像素阵列组成的,每...

    directx利用位图生成地图

    在本主题“利用位图生成地图”中,我们将探讨如何使用DirectX与图像处理技术来创建地形,并通过键盘交互控制游戏或应用中的视角移动。 首先,我们需要了解位图(Bitmap)的基本概念。位图是一种像素阵列,每个像素...

    源码-多格式位图转化+简易画图

    平台:DEV-C++ 5.8.3 语言:C++ 功能: 1)1、4、8(灰度、色彩)、16(565、555)、24、...2)可用C++在源码级别生成位图,画个小画;读入位图数据,转换位图格式。 3)将图片转化为单片机开发能用到的液晶坐标文件。

    MCGS位图.rar

    2. 位图复用:尽量使用相同的位图资源创建多个相似的元件,以减少项目中的重复位图,提高程序效率。 3. 位图分辨率:根据触摸屏的分辨率选择合适的位图尺寸,过大或过小都可能影响显示效果。 总结,MCGS位图是构建...

Global site tag (gtag.js) - Google Analytics