IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: 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
第二个数组记录了每个粒子的邻域都有哪些粒子。我们姑且称为邻域列表。neighborList

这两个列表的占用内存都很多。

第一个列表,假设每个网格最多有100个粒子,那么就需要网格数量*100 个int类型字节的内存。
第二个列表,假设每个粒子最多有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取余数)。

算法的额外开销

所有的开销就是每个使用的网格要计算一次哈希函数。这就是节约了内存所造成的时间的额外开销。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-07-17 16:48:40  更:2022-07-17 16:52:48 
 
开发: 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-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码