7

我想生成可以随机填充/覆盖空间的样本点(如附图中所示)。我认为他们有一种称为“准随机”的方法可以生成这样的样本点。但是,这离我的知识有点远。有人可以提出建议或帮助我找到可以做到这一点的图书馆吗?或者建议如何开始编写这样的程序?

样本点覆盖空间

在图像中,256 个采样点应用于给定空间,随机放置在整个给定空间。

更新:我只是尝试使用Halton Quasi-random Sequence中的一些代码,并与下面朋友发布的伪随机结果进行比较。在我看来,Halton 方法的结果更好。我想分享一些结果如下;

伪随机序列和 Halton 序列

我写的代码是

#include "halton.hpp"
#include "opencv2/opencv.hpp"
int main()
{
    int m_dim_num = 2;
    int m_n = 50;
    int m_seed[2], m_leap[2], m_base[2];
    double m_r[100];
    for (int i = 0; i < m_dim_num; i++)
    {
        m_seed[i] = 0;
        m_leap[i] = 1;
        m_base[i] = 2+i;
    }

    cv::Mat out(100, 100, CV_8UC1);
    i4_to_halton_sequence( m_dim_num, m_n, 0, m_seed, m_leap, m_base, m_r);

    int displaced = 100;
    for (int i = 0; i < 100; i=i+2)
    {
        cv::circle(out, cv::Point2d((m_r[i])*displaced, (m_r[i+1])*displaced), 1, cv::Scalar(0, 255, 0), 1, 8, 0);
    }
    cv::imshow("test", out);
    cv::waitKey(0);

    return 0;
}

由于我对 OpenCV 有点熟悉,我在 OpenCV (Mat) 的矩阵上绘制了这段代码。“i4_to_halton_sequence()”是我上面提到的库中的函数。

结果并没有更好,但可能会以某种方式用于我的工作。有人有其他想法吗?

4

5 回答 5

6

我将给出一个看似半途而废的答案。但是,该主题已在文献中进行了广泛的研究,因此我将仅向您推荐来自 Wikipedia 和其他在线地方的一些摘要。

您想要的也称为低差异序列(或准随机,正如您所指出的)。您可以在此处阅读更多相关信息:http ://en.wikipedia.org/wiki/Low-discrepancy_sequence 。它对许多事情都很有用,包括数值积分,以及最近模拟视网膜神经节马赛克。

有很多方法可以生成低差异序列(或伪准随机序列:p)。其中一些在 ACM 收集算法 (http://www.netlib.org/toms/index.html) 中。

我认为,其中最常见的称为 Sobol 序列(来自 ACM 的算法 659)。你可以在这里得到一些细节:http ://en.wikipedia.org/wiki/Sobol_sequence

在大多数情况下,除非你真的很喜欢它,否则这些东西看起来很可怕。为了快速获得结果,我会使用 GNU 的 GSL(GNU 科学图书馆):http ://www.gnu.org/software/gsl/

该库包括生成准随机序列的代码 (http://www.gnu.org/software/gsl/manual/html_node/Quasi_002dRandom-Sequences.html),包括 Sobol 序列 (http://www.gnu.org/software /gsl/manual/html_node/Quasi_002drandom-number-generator-examples.html)。

如果你仍然卡住,我可以在这里粘贴一些代码,但你最好还是深入研究 GSL。

于 2013-01-14T08:51:10.963 回答
3

那么这是另一种方法来做覆盖整个空间的准随机。

由于您有 256 个点可供使用,您可以首先将这些点绘制为 16x16 网格。

然后应用一些函数,为每个点提供一些随机偏移(比如点的 x 和 y 坐标为 0 到 ±2)。

于 2013-01-14T07:10:40.160 回答
0

您可以创建等距点(所有点与相邻点的距离相同),然后在第二步中随机移动每个点,使它们看起来“随机”。

我的第二个想法是:
1.从一个领域开始。
2. 在您所在区域的“中间”创建一个随机点 P rand。
3. 按该点将区域划分为 4 个区域。P是左下子区域的右上角,右下区域的左上角等等。
4. 对所有 4 个子区域重复步骤 2..4。当然,不是永远,而是直到你满意为止。

该算法确保每个“洞”(即新的子区域)都被一个点填充。

更新:由于步骤 (2),您的初始区域应该是您的区域的两倍。这确保在边缘和角落也有点。

于 2013-01-14T06:50:03.490 回答
0

这被称为“低差异序列”。链接的 Wikipage 解释了如何生成它们。

但我怀疑您已经知道这一点,因为您的图像与 Wikipedia中的2,3 Halton 序列示例非常相似

于 2013-01-14T08:44:12.133 回答
-3

您只需要库 rand() 函数:

#include <stdlib.h>
#include <time.h>

unsigned int N = 256; //number of points
int RANGE_X = 100; //x range to put sample points in
int RANGE_Y = 100;

void PutSamplePoint(int x, int y)
{
   //some your code putting sample point on field
}

int main()
{
    srand((unsigned)time(0)); //initialize random generator - uses current time as seed
    for(unsigned int i = 0; i < N; i++)
    {
        int x = rand() % RANGE_X; //returns random value in range [0, RANGE_X)
        int y = rand() % RANGE_Y;
        PutSamplePoint(x, y);
    }

    return 0;
}
于 2013-01-14T06:08:21.610 回答