2013-01-14 27 views
7

Tôi muốn tạo các điểm mẫu có thể điền/che khoảng trống một cách ngẫu nhiên (như trong hình đính kèm). Tôi nghĩ rằng họ có một phương pháp gọi là "Quasi-random" có thể tạo ra các điểm mẫu như vậy. Tuy nhiên, đó là một chút xa kiến ​​thức của tôi. Ai đó có thể đưa ra đề xuất hoặc giúp tôi tìm một thư viện có thể làm điều này không? Hoặc đề xuất cách bắt đầu viết một chương trình như vậy?Làm thế nào để chọn ngẫu nhiên các điểm mẫu để tối đa hóa sự chiếm đóng không gian?

Sample points cover the space

Trong hình ảnh, 256 điểm mẫu được áp dụng trên không gian nhất định, đặt tại các vị trí ngẫu nhiên để trang trải toàn bộ cho không gian.

Cập nhật: Tôi chỉ cố gắng sử dụng một số mã từ Halton Quasi-random Sequence và so sánh với kết quả của giả ngẫu nhiên được đăng bởi bạn bè bên dưới. Kết quả của phương pháp Halton là tốt hơn trong quan điểm của tôi. Tôi muốn chia sẻ một số kết quả như sau;

Pseudo-random and Halton's sequence

Mã này mà tôi đã viết là

#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; 
} 

Như tôi chút quen thuộc với OpenCV, tôi đã viết mã này bằng âm mưu trên ma trận của OpenCV (Mat). "I4_to_halton_sequence()" là hàm từ thư viện mà tôi đã đề cập ở trên.

Kết quả không tốt hơn, nhưng có thể được sử dụng bằng cách nào đó cho công việc của tôi. Ai đó có ý tưởng khác?

+0

@ acheong87 cảm ơn bạn đã cải thiện ngữ pháp của mình. – mojiiz

+0

Hình ảnh ví dụ của bạn có nhiều đối xứng - đó có phải là thứ bạn cần từ giải pháp không? – JasonD

+0

ví dụ của bạn chính xác là chuỗi Sobol. bạn đã nhận được nó từ wikipedia? – thang

Trả lời

6

Tôi sẽ đưa ra một câu trả lời rằng sẽ có vẻ nửa assed. Tuy nhiên, chủ đề này đã được nghiên cứu rộng rãi trong các tài liệu, vì vậy tôi sẽ chỉ giới thiệu cho bạn một số tóm tắt từ Wikipedia và những nơi khác trực tuyến.

Điều bạn muốn cũng được gọi là chuỗi sai lệch thấp (hoặc bán ngẫu nhiên, như bạn đã chỉ ra). Bạn có thể đọc thêm tại đây: http://en.wikipedia.org/wiki/Low-discrepancy_sequence. Nó hữu ích cho một số thứ, bao gồm tích hợp số và, gần đây hơn, mô phỏng khảm hạch võng mạc.

Có nhiều cách để tạo ra các chuỗi sai lệch thấp (hoặc chuỗi ngẫu nhiên giả ngẫu nhiên: p). Một số trong số này là trong các thuật toán thu thập ACM (http://www.netlib.org/toms/index.html).

Phổ biến nhất trong số đó, tôi nghĩ, được gọi là chuỗi Sobol (thuật toán 659 từ điều ACM). Bạn có thể nhận được một số chi tiết về điều này tại đây: http://en.wikipedia.org/wiki/Sobol_sequence

Đối với hầu hết các phần, trừ khi bạn thực sự tham gia, nội dung đó trông khá đáng sợ. Để có kết quả nhanh chóng, tôi sẽ sử dụng GSL của GNU (Thư viện Khoa học GNU): http://www.gnu.org/software/gsl/

Thư viện này bao gồm mã để tạo các chuỗi bán ngẫu nhiên (http://www.gnu.org/software/gsl/manual/html_node/Quasi_002dRandom -Sequences.html) bao gồm chuỗi Sobol (http://www.gnu.org/software/gsl/manual/html_node/Quasi_002drandom-number-generator-examples.html).

Nếu bạn vẫn bị kẹt, tôi có thể dán một số mã vào đây, nhưng bạn nên đào sâu vào GSL.

+0

Tôi không biết về gcc và tôi sử dụng MS Window, tôi sẽ thử GSL sau khi tôi tìm cách cài đặt nó. :) – mojiiz

+0

Tôi tò mò là tại sao OP lại có [hình ảnh từ bài viết trên wiki về chuỗi Sobol] (http://en.wikipedia.org/wiki/File:Sobol_sequence_2D.svg) nếu anh ta chưa biết về chúng .. –

+2

cũng GSL là mã nguồn mở. Bạn có thể trích xuất các chức năng đó ngay từ thư viện mà không phải xử lý gcc hoặc bất kỳ công cụ nào trong gnu: gsl_qrng_niederreiter_2, gsl_qrng_sobol, gsl_qrng_halton và gsl_qrng_reversehalton. – thang

-3

Bạn chỉ cần thư viện rand() chức năng:

#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; 
} 
+2

-1 đó không phải là những gì anh ta yêu cầu –

+0

@FominArseniy, cảm ơn bạn đã viết mã. Tuy nhiên, theo phương pháp mà bạn cung cấp có vẻ như các điểm không bao gồm toàn bộ khối (100x100). Các điểm là ngẫu nhiên nhưng, vẫn còn trống trong một số khu vực của khối. – mojiiz

+0

@MojiizAlamode: Thật vậy, đây chỉ là những điểm ngẫu nhiên. –

0

Bạn có thể tạo điểm cách đều (tất cả các điểm có cùng khoảng cách đến các nước láng giềng của họ) và sau đó, trong một bước thứ hai, di chuyển mỗi điểm ngẫu nhiên một chút để rằng chúng xuất hiện 'ngẫu nhiên'.

Ý tưởng thứ hai tôi có là:
1. Bắt đầu với một khu vực.
2. Tạo một điểm ngẫu nhiên P rand về 'trung' của khu vực của bạn.
3. Chia khu vực thành 4 khu vực theo điểm đó. P là góc trên bên phải của subarea dưới bên trái, góc trên bên trái của khu vực phía dưới bên phải và như vậy.
4. Lặp lại các bước 2..4 cho tất cả 4 vùng phụ. Tất nhiên, không phải mãi mãi, nhưng cho đến khi bạn hài lòng.

Thuật toán này đảm bảo rằng mỗi 'lỗ' (tức là khu vực phụ mới) được lấp đầy bằng một điểm.

Cập nhật: Khu vực ban đầu của bạn phải lớn gấp đôi diện tích của bạn, vì bước (2). Điều này đảm bảo có điểm ở các cạnh và góc là tốt.

3

Đây là một cách khác để thực hiện bán ngẫu nhiên bao gồm toàn bộ không gian.

Vì bạn có 256 điểm để sử dụng, bạn có thể bắt đầu bằng cách vẽ các điểm đó dưới dạng lưới 16x16.

Sau đó, áp dụng một số hàm cho phép bù trừ ngẫu nhiên cho mỗi điểm (nói 0 đến ± 2 đến các tọa độ x và y).

0

Đây được gọi là "low discrepancy sequence". Wikipage được liên kết giải thích cách bạn có thể tạo ra chúng.

Nhưng tôi nghi ngờ bạn đã biết điều này, vì hình ảnh của bạn là rất giống với 2,3 Halton sequence example từ Wikipedia

+0

Lưu ý rằng trong một số trường hợp, phân phối hardcore có bán kính đĩa thích hợp có thể hoạt động (tôi không nói nó sẽ tốt hơn). –

+0

@MSalters có, tôi biết đây là hình ảnh chuỗi Halton như tôi đã đề cập ở trên. Nhưng, quan điểm của tôi là bước thực hiện hơi khó khăn đối với tôi. Và tôi cần giúp đỡ? :) – mojiiz

Các vấn đề liên quan