3

我希望在具有以下约束的正方形中创建一组 2D 的 N 点(通常为 1e2 - 1e4):

  • 所有点之间应有最小距离(硬核禁区)

  • 填充正方形的点数是预先给出的(或近似估计),因为我想获得固定的密度(如果需要,我可以在之后稍微调整正方形的大小)。

  • 模式应该是合理的“随机”

  • 快速解决方案是首选

我以前在包 spatstat 中使用过 rStrauss,但我永远无法弄清楚如何可靠地获得给定数量的点,而且该功能经常会使我的机器停顿 10 分钟,大概是因为任务太难了。我猜可能有更合适的功能。

## regular grid of 1e2 points in [-10, 10]^2
xy = expand.grid(x=seq(-10, 10, length=10), y=seq(-10, 10, length=10))
N = NROW(xy)

编辑:如答案中所建议

xyr = rSSI(r=0.1, N, win = owin(c(-10,10),c(-10,10)), N)
plot(xyr)

pp

4

2 回答 2

3

rSSI,也在 spatstat 包中,根据您的标准处理您的问题,除了可能的速度。它有一个核心抑制距离,并且会达到目标点数(或放弃尝试——你可以设置放弃的阈值),并且放置是随机的。我不认为它特别快,但我能够在大约 30 秒内1e6以抑制距离在单位正方形中创建点。1e-4速度和成功率在很大程度上取决于您相对于点数的抑制距离。

于 2011-11-19T22:35:52.680 回答
2

主要是作为了解更多有关 Rcpp 的借口,这是我尝试使用一个小功能来做到这一点:

require(inline)
require(Rcpp)

randPoints = cxxfunction(signature(r_n='int', r_mindist='float', r_maxiter='int'), body = 
' 
  using namespace std;

  int n = as<int> (r_n);
  float mindist = as<float> (r_mindist);
  int maxiter = as<int> (r_maxiter);

  RNGScope scope;
  bool tooclose;
  int iter;
  NumericVector rands (2);
  NumericMatrix points (n, 2);
  NumericVector dist (2);

  for (int i=0; i < n; i++) {
    iter = 0;
    do {
      iter++;
      tooclose = false;
      rands = runif(2, 0, 1);
      for (int idist=0; idist < i; idist++) {
        dist = rands - points(idist, _);
        dist = dist * dist;
        if (sqrt(accumulate(dist.begin(), dist.end(), 0.0)) < mindist) {
          tooclose = true;
          break;
        }
      }
    } while (tooclose & iter < maxiter);
    if (iter == maxiter) {
      Rprintf("%d iterations reached\\nOnly %d points found\\n", maxiter, i+1);
      break;
    }
    NumericMatrix::Row target(points, i);
    target = rands;
  }

  return(wrap(points));
'
, plugin='Rcpp')

然后你可以像这样使用它:

> x = randPoints(1000, 0.05, 10000)
10000 iterations reached
Only 288 points found

这是情节:

x = x[as.logical(rowMeans(x != 0)), ]
dev.new(width=4, height=4)
plot(x)

在此处输入图像描述

于 2011-11-21T00:19:00.380 回答