7

スペースをランダムに塗りつぶす/覆うことができるサンプルポイントを生成したいと思います(添付の画像のように)。このようなサンプル点を生成できる「準ランダム」という方法があると思います。しかし、それは私の知識とは少しかけ離れています。誰かが提案をしたり、これを行うことができるライブラリを見つけるのを手伝ってくれませんか? または、そのようなプログラムを書き始める方法を提案しますか?

サンプル ポイントはスペースをカバーします

この画像では、256 個のサンプル ポイントが指定された空間に適用され、指定された空間全体をカバーするようにランダムな位置に配置されています。

更新: Halton Quasi-random Sequence のコードをいくつか使用して、以下の友人が投稿した疑似乱数の結果と比較してみました。私の意見では、ハルトンの方法の結果の方が優れています。以下にいくつかの結果を共有したいと思います。

擬似乱数と 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

中途半端な回答をしてしまいます。ただし、このトピックは文献で広く研究されているため、ウィキペディアやオンラインの他の場所からの要約を参照するだけにとどめます。

あなたが望むものは、低矛盾シーケンス(またはあなたが指摘したように準ランダム)とも呼ばれます。詳細については、http: //en.wikipedia.org/wiki/Low-discrepancy_sequenceを参照してください。これは、数値積分や、最近では網膜神経節モザイクのシミュレーションなど、さまざまなことに役立ちます。

低差異シーケンス (または疑似準ランダム シーケンス:p) を生成する方法は多数あります。これらの一部は、ACM Collected Algorithms (http://www.netlib.org/toms/index.html) にあります。

その中で最も一般的なのは、Sobol シーケンス (ACM のアルゴリズム 659) と呼ばれるものだと思います。詳細については、こちらをご覧ください: http://en.wikipedia.org/wiki/Sobol_sequence

ほとんどの場合、あなたが本当にそれに夢中でない限り、それはかなり恐ろしく見えます. 迅速な結果を得るには、GNU の GSL (GNU Scientific Library) を使用します: http://www.gnu.org/software/gsl/

このライブラリには、ソボル シーケンス (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

これは「低不一致シーケンス」と呼ばれます。リンクされたWikiページでは、それらを生成する方法について説明しています。

しかし、あなたの画像はウィキペディアの2,3ハルトン列の例に非常に似ているので、あなたはすでにこれを知っていると思います

于 2013-01-14T08:44:12.133 に答える
0

等間隔のポイント (すべてのポイントが隣接するポイントから同じ距離にある) を作成し、2 番目のステップで各ポイントを少しランダムに移動して、それらが「ランダム」に見えるようにすることができます。

2 つ目のアイデアは次のとおり
です。 1. 1 つの領域から始めます。
2. エリアの「中央」にランダム ポイント P rand を作成します。
3. その点でエリアを 4 つのエリアに分割します。P は、左下サブエリアの右上隅、右下エリアの左上隅などです。
4. 4 つのサブ領域すべてについて、手順 2..4 を繰り返します。もちろん、いつまでもというわけではありませんが、満足するまでです。

このアルゴリズムにより、各「穴」(つまり、新しいサブエリア) がポイントで埋められます。

更新: ステップ (2) により、最初の領域は領域の 2 倍になるはずです。これにより、エッジとコーナーにもポイントが確保されます。

于 2013-01-14T06:50:03.490 に答える
-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 に答える