游戏编程精粹学习 - 使用Bloom过滤来提高计算性能(BloomFilter)
原文在《游戏编程精粹2》的1.2中,BloomFilter是一种可以快速检测是否存在集合包含关系的数据结构,但有一定的误识别率。
该结构的优点
- 判断包含关系时效率较高,粗略测试了下比List快一倍(不拆分哈希)
- 由于内部是位数组BitArray,做交集并集几乎不产生开销
该结构的缺点
- 有一定的误识别率
- 使用情境有限
我在Github找了一个BloomFilter的库(这个库使用时会产生大量GC,但学习来用够了):
https://github.com/joeyrobert/bloomfilter
首先构建一个长度为N的位数组,将传入数据的哈希值按位拆分成不同段,每一个段作为一个Key放入这个长度为N的位数组。
判断包含时再把对象的多个key与位数组进行比较即可。
当然既然都存在误判率,而且是以效率为优先的话,也可以不按位拆分哈希,我写了一个最简单的版本:
public class MyBloomFilter<T>
{
BitArray mBitArray; public MyBloomFilter(int bitLength)
{
mBitArray = new BitArray(bitLength);
} public void Add(T obj)
{
var key = Mathf.Abs(obj.GetHashCode()) % mBitArray.Length; mBitArray[key] = true;
} public bool Contains(T obj)
{
var key = Mathf.Abs(obj.GetHashCode()) % mBitArray.Length;
return mBitArray[key];
}
}
注意C#已经内置了位数组这样的数据结构BitArray。
结合之前的可预测随机数(http://www.cnblogs.com/hont/p/8716586.html),我写了这样一个例子

假设这是一个草药采集的功能,每一个不同颜色的方块代表一颗草药
鼠标点击来采集它们。
代码如下
using System.Collections.Generic;
using UnityEngine; public class HerbGenerator : MonoBehaviour
{
public int x;
public int y;
public int probability = ;
List<HerbObject> mCreatedHerbList = new List<HerbObject>();
MyBloomFilter<int> mCollectedHerbList = new MyBloomFilter<int>(); void Update()
{
GetArea(x - , y - , x + , y + ); if (Input.GetMouseButtonDown())
{
var hit = default(RaycastHit);
var isHit = Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit);
if (isHit)
{
var herbObject = hit.transform.GetComponent<HerbObject>();
mCollectedHerbList.Add(herbObject.seed); Destroy(hit.transform.gameObject);
}
}
} void GetArea(int beginX, int beginY, int endX, int endY)
{
for (int i = ; i < mCreatedHerbList.Count; i++)
{
if (!mCreatedHerbList[i]) continue;
Destroy(mCreatedHerbList[i].gameObject);
} var cacheState = Random.state; mCreatedHerbList.Clear(); float spacingScale = 1f;//增加间距防止两颗草药同时消失.
for (int x = beginX, k = ; x < endX; x++)
{
for (int y = beginY; y < endY; y++, k++)
{
var seed = + x + y * (endX - beginX); if (mCollectedHerbList.Contains(seed)) continue; Random.InitState(seed);
var r = (int)(Random.value * ); if (r % < probability)
{
var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
var herbObject = cube.AddComponent<HerbObject>();
herbObject.seed = seed; cube.transform.position = new Vector3(x * spacingScale, , y * spacingScale); GalaxyBuild(r, cube); mCreatedHerbList.Add(herbObject);
}
}
} Random.state = cacheState;
} void GalaxyBuild(int seed, GameObject go)
{
var cacheState = Random.state;
Random.InitState(seed);
var meshRenderer = go.GetComponent<MeshRenderer>();
switch ((int)(Random.value * % ))
{
case ://草药类型1
meshRenderer.material.color = Color.red;
break; case ://草药类型2
meshRenderer.material.color = Color.blue;
break; case ://草药类型3
meshRenderer.material.color = Color.green;
break;
} Random.state = cacheState;
}
}
HerbGenerator
出现误判时会发生A草药采完后B草药同时消失的情况,只能增加草药刷新的间距来缓解这个问题。
游戏编程精粹学习 - 使用Bloom过滤来提高计算性能(BloomFilter)的更多相关文章
- C++游戏编程(一开篇)
本系列文章由zhmxy555(毛星云)编写,转载请注明出处. http://blog.csdn.net/zhmxy555/article/details/7318264 作者:毛星云 邮箱: h ...
- c++游戏编程书籍
如果要自学游戏程序开发的话,可以看看下面的,呵呵. 游戏开发资料(PDF书都是中文版的,非英文,很多是本人自己扫描制作,从未网上发布过,所以独家啦): 1.Gamebryo 2.2游戏引擎(盛大.腾 ...
- DirectX 11游戏编程学习笔记之8: 第6章Drawing in Direct3D(在Direct3D中绘制)(习题解答)
本文由哈利_蜘蛛侠原创,转载请注明出处.有问题欢迎联系2024958085@qq.com 注:我给的电子版是700多页,而实体书是800多页,所以我在提到相关概念的时候 ...
- 工作流程,编程,调试,性能:Unity游戏开发者应该学习的20个改进技巧
Unity 是一个备受欢迎的游戏开发平台.它的功能令人印象深刻,同时也迎合了不同的游戏开发需求.游戏开发者可以使用 Unity 创建任何类型的游戏,从世界级的 RPG 游戏到最流行的增强现实游戏 Po ...
- 【Visual C++】游戏编程学习笔记之五:单一背景滚动
本系列文章由@二货梦想家张程 所写,转载请注明出处. 本文章链接:http://blog.csdn.net/terence1212/article/details/44224963 作者:ZeeCod ...
- 【Visual C++】游戏编程学习笔记之四:透明动画实现
本系列文章由@二货梦想家张程 所写,转载请注明出处. 本文章链接:http://blog.csdn.net/terence1212/article/details/44224963 作者:ZeeCod ...
- 【Visual C++】游戏编程学习笔记之三:游戏循环的使用
本系列文章由@二货梦想家张程 所写,转载请注明出处. 本文章链接:http://blog.csdn.net/terence1212/article/details/44208419 作者:Zee ...
- 【Visual C++】游戏编程学习笔记之八:鼠标输入消息(小demo)
本系列文章由@二货梦想家张程 所写,转载请注明出处. 作者:ZeeCoder 微博链接:http://weibo.com/zc463717263 我的邮箱:michealfloyd@126.c ...
- 【Visual C++】游戏编程学习笔记之七:键盘输入消息
本系列文章由@二货梦想家张程 所写,转载请注明出处. 作者:ZeeCoder 微博链接:http://weibo.com/zc463717263 我的邮箱:michealfloyd@126.c ...
随机推荐
- 利用jQuery-UI和jsPlumb实现拖拽连接模型
简介 之前公司需要做一个自定义数据搜索模型的功能,大体是这样的:左边显示的每一个模型对应于数据库中的一个表,把左边的模型拉入右边的容器内,会显示这个模型(也就是表)下的列信息,然后通过连线确定各独立的 ...
- Storm中关于Topology的设计
一:介绍Storm设计模型 1.Topology Storm对任务的抽象,其实 就是将实时数据分析任务 分解为 不同的阶段 点: 计算组件 Spout Bolt 边: 数据流向 数据从上 ...
- 素数筛选-hdu1262
题目描述: 代码实现: #include<stdio.h> using namespace std; ]; void sieve(int n) { ;i<;i++) prime[i] ...
- 《Gradle权威指南》--Java Gradle插件
No1: dependencies{ compile group: 'com.squareup.okhttp3',name:'okhttp',version:'3.0.1' } //缩写 depend ...
- iOS 技术篇:__VA_ARGS__实现自定义NSLog
系统的NSLog 我个人觉得有bug时,没准确的说明哪一行出现的问题,所以为了方便自己开发查找问题,附上自己的NSLog 创建定义方式: 1:在创建好的pch文件里 配置: 2:在pch文件里添加上这 ...
- Microsoft Corporation 去掉 windows 修改 启动加载 版权
windows 修改 开机界面 boot启动界面 windows 修改 启动加载 版权 windows 系统如何修改开机画面的版权文字“Microsoft Corporation ... ◎Micro ...
- bzoj4503: 两个串 bitset
目录 题目链接 题解 代码 题目链接 bzoj4503: 两个串 题解 暴一发bitset f[i][j] 表示 S[1..i] 是否有个后缀能匹配 T[1..j] 那么假设 S[i+1] 能匹配 T ...
- PHP+Mysql学习笔记
1. PHP is Hypertext Preproocessor. 2. Hello World: <?php Echo 'Hello World!'; ?> 3. ...
- 2016年3月10日Android实习日记
待解决问题: *1:内部ScrollView与外部手势事件滑动冲突问题. *2:Linearlayout+View+LinearLayout横向排列,这其中两个LinearLayout内部各有3个竖向 ...
- Docker machine(Docker 虚拟机)
安装docker [root@lianxi ~]# yum -y install docker 启动docker [root@lianxi ~]# systemctl start docker 下载D ...