2017-01-23 2 views
1

| x-y |が0になるように区間[1、N]からランダムに2つの整数xとyをサンプリングしたいとします。 > = D、いくつかのD < N.以下のコード(Rで書かれている)は、私が使ってきたものですが、それはひどく非効率です。この種のサンプリングにはより良い方法がありますか?ありがとうございました。距離条件付きランダムサンプリング

N <- 100; D <- 10; 

i <- sample(1:N, 2) 

while (abs(i[1] - i[2]) < D){ 
    i <- sort(sample(1:N, 2)) 
} 
+0

全く効率が悪いように見えるのですが、なぜそれを言うのですか? 10の距離と1から100までの値のために、あなたは 'sample'を1回だけ呼び出す必要があります。 – rawr

+0

効率は特定のユースケースに依存しますが、最も重要なことに、このアルゴリズムは' 1 - [(Nx)/ N +(x-0)/ N + 2D/N]の行に沿ったものです。 N&Dの任意のx、yに対して、P(x)= 1/Nであり、 sample() 'が何度も増えています。 – miraculixx

答えて

1

私は、yがx(またはその逆)に依存していることを理解することが重要だと思います。ここで最も三の段階でで動作するはずのアルゴリズムは次のとおり

1. sample x from [1:N] 
2. sample y from [1:(x-D)] if (x-D) >= 1 
    sample y from [x + D:N] if (x+D) <= N 
3. If both conditions for y are met, choose one of the generated y uniform at random 

アイデアは、xはサンプリングした後、Y [1:(XDの)]の範囲内にあることが必要であるということであるか、[X + D:N] | xy |を満足するためには、 > = D.

例:

N = 100。 Dは10

a) x is close to N 

1. x is sampled from 1:N as 95 
2. to satisfy |x-y| >= D, y can be at most 85, so the range to sample y is [1:85] 

b) x is close to 1 

1. x is sampled from 1:N as 9 
2. y must be at least 19, so the range to sample y is [19:N] 

c) x is close to 50 

1. x is sampled from 1:N as 45 
2. y must be either at most 35, or at least 55, so the ranges to sample from are [1:35] and [55:N] 
0

私はランダム以上Dに等しい数の差をサンプリング最初することによってこれを近づけることになります=換言すれば、DN-1の間の番号をサンプルしたいとします。

difference <- sample(D:(N-1), 20, replace = TRUE) 

は、今、私たちが行う必要があるすべては 1N - differenceの間の数を選択することで、私たちの小さい番号を選択しています。これは vapplyを使用して行うことができます。

lowerval <- vapply(N - difference, sample, numeric(1), 1) 

最後に、差を下限値に加算して上限値を取得します。

upperval <- lowerval + difference 
+0

このアルゴリズムを使用した配布は、OPのアルゴリズムを使用した配布とは異なることに注意してください。したがって、無作為抽出から必要とされる他の要件に応じて、これは必要な場合とそうでない場合があります。 – Dason