游戏编程精粹学习 - 使用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 ...
随机推荐
- mysql_union操作符
MySQL UNION操作符 union操作符合并两个或多个 SELECT 语句的结果集. union:去重 union all:不去重 UNION 结果集中的列名总是等于 UNION 中第一个 S ...
- BZOJ1898 [Zjoi2005]Swamp 沼泽鳄鱼 矩阵
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1898 题意概括 有一个无向图. 其中,有许多条鱼在以循环的规律出现,比如循环在1,2,3这些点出现 ...
- [OpenCV-Python] OpenCV 中计算摄影学 部分 IX 对象检测 部分 X
部分 IX计算摄影学 OpenCV-Python 中文教程(搬运)目录 49 图像去噪目标 • 学习使用非局部平均值去噪算法去除图像中的噪音 • 学习函数 cv2.fastNlMeansDenoisi ...
- 《Gradle权威指南》--Groovy基础
No1: Groovy中分号不是必须的 No2: Groovy中,单引号和双引号都可以定义一个字符串常量,不同的是单引号标记的是纯粹的字符串常量,而不是对字符串里的表达式做运算,但是双引号可以. ta ...
- Digital biquad filter
Direct Form 1 The most straightforward implementation is the Direct Form 1, which has the following ...
- pandas学习(创建数据,基本操作)
pandas学习(一) Pandas基本数据结构 Series类型数据 Dataframe类型 基本操作 Pandas基本数据结构 两种常用数据结构: Series 一维数组,与Numpy中的一维ar ...
- Burp Suite之爬网模块(二)
Spider功能 Burp Spider爬网介绍 Burp Spider 是一个映射 web 应用程序的工具.它使用多种智能技术对一个应用程序的内容和功能进行全面的清查. 通过跟踪 HTML 和 Ja ...
- Codeforces.600E.Lomsat gelral(dsu on tree)
题目链接 dsu on tree详见这. \(Description\) 给定一棵树.求以每个点为根的子树中,出现次数最多的颜色的和. \(Solution\) dsu on tree模板题. 用\( ...
- node+koa2获取请求参数
1.get方式: http://localhost:3000/?user=000001&body=0002&age=26 const router = require('koa-rou ...
- C++中extern “C”含义及extern、static关键字浅析
https://blog.csdn.net/bzhxuexi/article/details/31782445 1.引言 C++语言的创建初衷是“a better C”,但是这并不意味着C++中类似C ...