Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 生成一组随机的x、y、z数字,这些数字之间的差值在定义的限值之间最小_C++_Algorithm_Random - Fatal编程技术网

C++ 生成一组随机的x、y、z数字,这些数字之间的差值在定义的限值之间最小

C++ 生成一组随机的x、y、z数字,这些数字之间的差值在定义的限值之间最小,c++,algorithm,random,C++,Algorithm,Random,所以我试着做一个分子动力学模拟,试着用随机粒子填充一个三维矩形的体积,这些粒子均匀分布在整个体积上。每个分子都有一个固定的半径r(球体),其中r对于每个分子都是不同的。因此,我希望在体积中生成球体,然后在距离该点(2(r+公差))的距离内不应存在其他球体(公差将非常小,如10^-6) 此外,通道将具有指定的长度、宽度和宽度,因此随机化应在上述条件类似的单个方向上的限制范围内进行,即,如果分子离壁的距离超过其半径+公差,则不应生成分子 我最初尝试的是一个结构化的晶格,但这意味着分子的数量将与维度相

所以我试着做一个分子动力学模拟,试着用随机粒子填充一个三维矩形的体积,这些粒子均匀分布在整个体积上。每个分子都有一个固定的半径r(球体),其中r对于每个分子都是不同的。因此,我希望在体积中生成球体,然后在距离该点(2(r+公差))的距离内不应存在其他球体(公差将非常小,如10^-6)

此外,通道将具有指定的长度、宽度和宽度,因此随机化应在上述条件类似的单个方向上的限制范围内进行,即,如果分子离壁的距离超过其半径+公差,则不应生成分子

我最初尝试的是一个结构化的晶格,但这意味着分子的数量将与维度相关,这对我来说是行不通的。所以我写了下面的算法(我想粘贴我的代码,但它不起作用,它现在是一个大的,夸张的混乱,几乎崩溃了我的电脑一次)

所以逻辑是

1.)对于每个粒子,使max_X=X-(半径+tol)。对Y和Z做同样的操作

2.)对于每个粒子,生成介于0和max_X之间的随机数

3.)计算每个粒子之间的距离,并创建违反上述任何条件的粒子列表

4.)浏览列表并重新生成这些粒子

5.)创建另一个违反粒子对的列表

6)过去。冲洗并重复,直到列表的大小为零

所以,它不起作用。我需要这段代码最终对大量粒子执行,所以我需要它尽可能高效和OpenMP并行化。我在for循环前面使用标准的cliched#pragma omp parallel for方法来并行计算,但在运行时,在超级风扇噪音5-10分钟后,无论是否使用pragma,它都不起作用

<>我是一个来自非编码背景的人,最近开始学习C++编写复杂代码,所以我现在不能做一些像结构、类或指针之类的东西。不过我正在使用std::vectors。如果你们能告诉我一条出去的路,我会很高兴的。如果你们在罗利附近,我会亲自开车过来递给你们一杯冰镇啤酒。我已经尝试这么做了好几天了,这是我代码中唯一主要的非功能性内容

救命

PS/编辑:我要说清楚,这不是家庭作业,否则我现在就应该问教授了。它是一个独立项目的一部分,我将在完成后免费分发。

完全满足您的需要,但请:


“我不能做一些像结构、类或指针之类的花哨的事情”,这对你毫无帮助。我们可以帮助您实现这一目标,但您还需要了解至少结构、类和STL。

我将首先介绍到目前为止所采用的方法:

  • 首先,应调查少量粒子(例如1、2、10)发生的情况,以了解其未完成的原因
  • 我怀疑问题在于违反约束的列表永远不会变为空。可能代码中有错误,或者粒子很难适应矩形体积
  • 步骤3)和步骤4)的组合似乎效率低下。不能保证违反约束的球体列表会从一个步骤减少到下一个步骤。例如,对于许多球体,每个球体都可能至少有一个其他球体重叠。在这种情况下,每次都需要重新生成所有球体,这不会导致任何进展
  • 在步骤3)和4)中,如果一对球体违反约束,则将重新生成两个球体。考虑只生成其中一个(可能随机选择)可能有用。
另一种方法是逐个生成球体。 当新添加的球体与先前放置的球体违反任何约束时,请重试随机放置。如果它没有违反任何约束,请固定其位置,然后继续下一个球体

“3.)计算每个粒子之间的距离,并创建违反上述任何条件的粒子列表。”

这是一个
O(N*N)
算法。而且你一直在重复。这可能取决于分子的密度,但我希望你不是在模拟固体

有一个正确的方法可以做到这一点。将体积切成小方框,大致为
半径^3
的大小。现在,您只需要检查每个框内的碰撞,以及与26个相邻框的碰撞。如果你有很多很多这样的小盒子,只检查27个小盒子会更有效率


如果使用整数/定点坐标,并且精确的框大小为2的幂,则查找正确的框很容易。例如,如果半径为250,则将方框设为256x256x256,这样可以通过除以256找到正确的方框。这是硬件方面的一点变化。

我知道有两个很好的答案

一种是泊松圆盘抽样的推广,称为泊松球分布。泊松圆盘采样被发明用于以最小距离采样2D点(因此圆盘)

泊松球体用于在3D中进行采样,论文:


另一种方法是使用准随机数。对于准随机Sobol序列,有一种说法称,点之间存在最小正距离,该距离等于0.5*sqrt(d)/N,其中
d
是问题的维度(在您的例子中为3),而
N
是在超立方体中采样的点数。这张纸是他自己寄来的

Sobo的合理实施