| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> 【SPH】邻域搜索中的紧凑哈希(compact hash)算法讲解 -> 正文阅读 |
|
[数据结构与算法]【SPH】邻域搜索中的紧凑哈希(compact hash)算法讲解 |
引子:为什么会提出紧凑哈希?常规的Grid-Based邻域搜索我们之前讲过:http://t.csdn.cn/Ytwuy 常规方法有一个缺陷:那就是占用内存过高。 想象一下:你要存储两个庞大的二维数组。 第一个数组记录了每个网格里都有哪些粒子。我们姑且称为网格内粒子列表。particleInCellList 这两个列表的占用内存都很多。 第一个列表,假设每个网格最多有100个粒子,那么就需要网格数量*100 个int类型字节的内存。 实际上,在3D模拟中粒子数量要比网格数量少得多。这是因为3D网格有类似“维度爆炸”的问题。假设2D网格为100*100,也就是横向100个网格,纵向100个网格,那么3D场景就变为了100*100*100个网格。这就意味着网格数量增大了100倍。这是非常大的数量级。 因此实际上内存的主要开销在于第一个列表。紧凑哈希表也是针对节约第一个列表的内存而发明的算法,它对邻域列表(第二个列表)的内存没有任何影响。 算法原理讲解该算法实际上非常简单。 怎么节约网格内存呢?那么就不要那么浪费网格就好了!也就是把用不到的网格不去占用内存。 你可能会立马想到稀疏数据结构,但是紧凑哈希是比稀疏数据结构更为简单的算法。 我们先要理解SPH中的网格的本质:在SPH中的网格,实际上只是一个辅助工具。它是用来帮助粒子建立拓扑关系的。说人话,就是它是用来帮粒子定位自己在哪的。 什么叫拓扑?北航在中国北京市海淀区学院路37号。这就是拓扑。我不知道北航的经纬度,但是我能够通过这样的地址找到北航。我会去先找中国在哪,再找北京在哪,然后找海淀区在哪,学院路在哪,最后找到北航在哪。所谓的拓扑,就是你和别人的相对关系,或者说就是相对位置。你的绝对位置可以变,但是相对位置没变,那么拓扑就没变。所以,我们建立网格的作用,就是给粒子一个家。用一个个小格子,把粒子的空间位置描述出来。粒子所在的网格,就是它所在的街道,或者说,它的门牌号。 既然它所在的网格本身只是一个用来指示地址的门牌号,那么我们完全不用遵循几何中的真实位置。 我们假设某个网格的索引为 c = ( i , j , k ) \mathbf{c} = (i, j, k) c=(i,j,k) 有用的只是i,j,k这三个索引,而不是i, j , k这三个索引的几何意义。所以我们完全可以将i,j,k经过一个奇怪的运算,得到一个数。我们只需要尽量保证每套索引值得到的是不同的数。计算方法如下: 这就是所谓的哈希函数。哈希函数的意义就是算出一个与众不同的数字。其中p1, p2, p3都是很大的质数。 XOR代表异或, mod代表取余数。 m是你给定的哈希表的大小。 为什么会给定一个m呢?因为当你剥离掉ijk的几何意义,这个表的大小就随意确定了。你想给定多少,就给定多少。但是实际上,要是给得太小,会造成哈希冲突,也就是不同的ijk值得到了相同的哈希值。也就是可能本来相距很远的粒子,被强行放到一个网格里了。 这个算法最早是由Ihmsen等人提出来的,他建议m的取值为2倍的粒子数。 到这里你或许还会有一个疑问: 怎么根据哈希值还原回网格索引呢? 答案是:不需要还原。 你又会问:那我怎么确定网格之间的拓扑关系呢,或者说怎么知道这个网格的上下左右邻居都是谁? 答案是:计算的时候,你仍然采用原始的索引值,哈希表对原本的网格空间结构没有任何破坏,它只是用来优化存储的。 比如说:你现在的网格编号是a,b,c。你想知道它头顶的网格是谁。假设y坐标是朝上的,那么它的顶部的网格就是(a, b+1, c)。在你计算的时候,仍然使用(a, b+1, c)。 但是你并不一定需要开辟一块对应网格(a, b+1, c)的内存。 而是先计算(a, b+1, c)的哈希值,鬼知道这个哈希值是多少,然后你用这个哈希值作为编号存到哈希表的一个元素里。这个哈希表的大小是确定的,就是你给定的m。假如哈希表大小不够用了,它就会自动循环(这也是为什么哈希函数最后除以m取余数)。 算法的额外开销所有的开销就是每个使用的网格要计算一次哈希函数。这就是节约了内存所造成的时间的额外开销。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 23:47:04- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |