科研中碰到问题,想请教一下,谢谢了!

biglate 2009-10-10 09:26:04
我的程序模拟的是一个粒子体系中的电作用以及粒子移动.
问题如下:
在三维空间中有n(100~10000)个粒子,这些粒子是不断移动的,但知道每一个粒子任意时刻的三维坐标.
在某一时刻,给出一个空间中的三维坐标,我想找出与这个坐标点的距离小于给定长度r的粒子.
要实现这一功能,用什么数据结构来组织粒子,或者什么算法来查找出满足条件的粒子,使计算时间最少?

我现在用的是笨办法,很耗时,即顺序存储+遍历查找。
...全文
441 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
这个办法很好!
这样不用分成r*r*r那么多格子了。
3*r就行了
[Quote=引用 7 楼 goonyangxiaofang 的回复:]
先按x轴淘汰一部分;依次y、z。最后再求。
[/Quote]
bearxjie 2010-01-15
  • 打赏
  • 举报
回复
只有有序的数据才能避免遍历的算法,你这个得分解为2个问题进行求解:
存储方式确定以后:
1、粒子数据更新的算法复杂度
2、给定座标,查找粒子的算法复杂度

其实在运算速度足够快、资源也足够的情况下,这个问题一点都不难:
建立一个10000X10000X10000的数组,数组下标直接就代表x,y,z,数组元素就是粒子编号n组成的链表
1、解决数据更新后排序的问题:
采用增量方式更新最快(前提是你的数据刷新速度够快,如果不够,遍历的范围就扩大了),
每次粒子n运动时,都只可能运动到相邻的小立方体中,因此每个粒子最多1次更新数据,其实就是移到另一个位置(添加到另一个(x,y,z)的链表中)。
2、解决搜索问题,这就很简单了,找到符合你查找条件的小立方体,其中的链表全取出来就是。
具体的算法上面各位提得很多了。

最关键的地方是要认识到,你用的是数值计算方法,不要老想着是画个圆球,而是找出一个一个小的立方体,这中间存在着一定程度的近似算法。
Dolphin_001 2010-01-14
  • 打赏
  • 举报
回复
实际就是求出所有满足
(x - x0)^2 + (y - y0)^2 + (z - z0)^2 <= r^2的所有点。
如果点是动态生成的,那么你只能遍历一次,复杂度 O(n)
只是这种算法最浪费时间的就在于算平方和了。
可用公式(x - x0)^2<= r^2 && (y - y0)^2 <= r^2 && (z - z0)^2<= r^2过滤掉大部分的点
当然,算平方的速度比不上算加减,所以可以进一步优化成
x - x0 <= r <= -x + x0 && y - y0 <= r <= -y + y0, z - z0 <= r <= -z + z0,
满足条件的再用(x - x0)^2 + (y - y0)^2 + (z - z0)^2 <= r^2来验证是否最终满足条件。
无论怎么快的算法,复杂度都得O(n)
z569362161 2010-01-14
  • 打赏
  • 举报
回复
但知道每一个粒子任意时刻的三维坐标.我想找出与这个坐标点的距离小于给定长度r的粒子

用尺子量
xidiancjw 2010-01-14
  • 打赏
  • 举报
回复
好高深啊,学习了
qiuzhenguang 2009-10-16
  • 打赏
  • 举报
回复
学习。
Tiger_Zhao 2009-10-15
  • 打赏
  • 举报
回复
10000 个点而已,顺序遍历需要多少时间?
只要排除以下不当行为:
a)不用 Variant 变量,坐标最好用 Long(等比放大),实在不行用 Double
b)检测是不要直接计算点到 (x0,y0,z0) 的距离,而是逐个判断(不要用 And 将判断合在一起)
1. (x0-r) <= x <= (x0+r)
2. (y0-r) <= y <= (y0+r)
3. (z0-r) <= z <= (z0+r)
4. 以上3个条件满足才计算 (x,y,z) 到 (x0,y0,z0) 的距离是否小于 r
帖子不能编辑 2009-10-15
  • 打赏
  • 举报
回复
我同意
依次按照x,y,z坐标剔出节点。
然后再对剩下节点算距离的做法。

因为坐标点是时刻变化的,又没有什么特征可言。想不到好的方法了。

showjim 2009-10-13
  • 打赏
  • 举报
回复
设点为p{x,y,z,s=x+y+z,m=y+z},点集分级排序存储s->x->m->y->z

设球为o{x,y,z,r}
1.计算s的最大范围与最小范围(1/8球的中点为关键点),二分查找并遍历这些点集合;
2.计算x的最大范围(o.x+r)与最小范围(o.x-r),迭代查找并遍历这些点集合.
3.计算m的最大范围与最小范围(1/4弧形的中点为关键点),迭代查找并遍历这些点集合;
4.计算y的最大范围(o.y+r)与最小范围(o.y-r),迭代查找并遍历这些点集合;|o.z-z|<=r-|o.x-y|-|o.x-y|的点绝对在圆内,其它要计算距离
当r较小时,可以考虑将球由x轴切成2r平面片,确定了每个平面圆的半径后,第4步可以只计算平面距离.
Cumt_FireFly 2009-10-12
  • 打赏
  • 举报
回复
呵呵 八叉树 第一次听哦 学习下
LeonTown 2009-10-12
  • 打赏
  • 举报
回复
或许可以建立一个三维的位图,
位图中的每个点为一个坐标,并且用10个bit表示最多1000个粒子。

粒子移动时,更新该位图中相关的点。
xingzhe2001 2009-10-12
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 donkey301 的回复:]
引用 11 楼 xingzhe2001 的回复:
用八叉树(OctTree),将空间划分上下个四块,不断地划分下去,这样如果给定一个3维坐标,从根节点开始很容易找到它在哪个子节点,你只要搜索满足 <r的相邻子节点就可以了。
http://202.116.160.98:8000/course/gis/Section/2/251.htm网上搜一下八叉树有很多资料。

想法挺好的,不过就算你把空间划分成小方块存在八叉树里,对每一个粒子你还要确定它在哪个八叉树的节点所代表的小方块内,那还不如直接判断空间点的位置关系。
[/Quote]

八叉树是个图形学里很普及的3D对象管理方法
绿色夹克衫 2009-10-12
  • 打赏
  • 举报
回复
用hash试试,将立方体分为n^3个小块,假设点p在i,j,k内,那么其相邻的块一定距离小于r,而某些块,其距离一定大于r,只有某些特殊的块需要专门演算一遍!
GoonYangXiaofang 2009-10-11
  • 打赏
  • 举报
回复
先按x轴淘汰一部分;依次y、z。最后再求。
euroman 2009-10-11
  • 打赏
  • 举报
回复
这个情况下,我建议用球坐标来对每个点进行描述,

前提是,以给出的坐标点作为空间的原点。

也就是说,

1.空间平移,把所有粒子在绝对空间中的坐标平移,以给定的点的坐标作为原点,复杂度为O(N)
2.把所有点变换成球面坐标,复杂度为O(N)
3.储存的时候可以采用AVL树来操作,那么可以使查找时间降低到O(logN)。(刚刚建立所有粒子的AVL树的复杂度是O(N×logN))

P.S.如果按照LZ的方法,那么复杂度是O(N),AVL树的查找、删除、插入的复杂度都是O(logN)。

针对粒子来说,可以用这样的结构(具体其他方法的话可以自行补充):
class par_xyz{
double x;
double y;
double z;
par_xyz zero;

public:
par_Sphere transToSphere();
};

class par_Sphere{
double r;
double lenda;
double fi;

par_Sphere zero;
public:
par_xyz transToXYZ();
};
xingzhe2001 2009-10-11
  • 打赏
  • 举报
回复
用八叉树(OctTree),将空间划分上下个四块,不断地划分下去,这样如果给定一个3维坐标,从根节点开始很容易找到它在哪个子节点,你只要搜索满足<r的相邻子节点就可以了。
http://202.116.160.98:8000/course/gis/Section/2/251.htm网上搜一下八叉树有很多资料。
zeroieme 2009-10-11
  • 打赏
  • 举报
回复
多体问题是世界难题
  • 打赏
  • 举报
回复
这些粒子是不断移动的,但知道每一个粒子任意时刻的三维坐标.

有规律不?没规律就只能遍历来判断离该坐标最近点了。
或者人为预处理,排序。
donkey301 2009-10-11
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 biglate 的回复:]
这个不错,会快一些,但好像还是要遍历?
是不是可以这样:
以x坐标为序做一个有顺序的粒子集合,比如说Java里的Treeset
然后从集合找一个x0-r到x0+r的子集,从子集中找满足y0-r <y <y0+r&&z0-r <z <z0+r的点,再判断距离.

感觉还是挺笨的.
引用 1 楼 chenyijiu 的回复:
可以先确定个较小的范围,如该点中心坐标的球体或立方体,这样直接可以取坐标就可以判断,不必取空间距离

[/Quote]
粒子集合没必要,如果以x坐标为序做一个有顺序的粒子集合,那么每次这个集合插入一个新元素,需要比较很多次,还不如直接判断这个x是不是在(x0-r,x0+r)内。

如果嫌速度慢,可以用平行计算,反正研究所一般都有大型服务器。像这种求大量粒子移动的研究一般都做成平行的。
donkey301 2009-10-11
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 xingzhe2001 的回复:]
用八叉树(OctTree),将空间划分上下个四块,不断地划分下去,这样如果给定一个3维坐标,从根节点开始很容易找到它在哪个子节点,你只要搜索满足 <r的相邻子节点就可以了。
http://202.116.160.98:8000/course/gis/Section/2/251.htm网上搜一下八叉树有很多资料。
[/Quote]
想法挺好的,不过就算你把空间划分成小方块存在八叉树里,对每一个粒子你还要确定它在哪个八叉树的节点所代表的小方块内,那还不如直接判断空间点的位置关系。
加载更多回复(7)

33,028

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧