2017-01-23 5 views
1

Я хочу случайным образом выбрать два целых числа x и y из интервала [1, N], для которых | x-y | > = D, для некоторого D < N. Код, приведенный ниже (написанный на R), является тем, что я использовал, но он ужасно неэффективен. Есть ли лучшие методы для такого рода отбора проб? Спасибо в adv.Случайная выборка с условием расстояния

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' – rawr

+0

Я полагаю, что эффективность (в) зависит от конкретного варианта использования, но, самое главное, этот алгоритм не является постоянным временем, P (| xy |> = D) 'для любого вызова выборки (1: N, 2) - это что-то по строке« 1 - [(Nx)/N + (x-0)/N + 2D/N] ', причем P (x) = 1/N, для любых x, y в [1: N] и D 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 

Идея заключается в том, что когда-х отбирали, у должен быть в диапазоне [1: (XD)] или [х + Д: Н] чтобы удовлетворить | xy | > = 0.

Примеры:

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. Другими словами, мы хотим отбирать номера между D и N-1 с заменой.

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

Теперь все, что нам нужно сделать, это выбрать нашу меньшее число, выбрав число между 1 и N - difference. Мы можем сделать это, используя vapply.

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

Наконец, мы получаем верхнее значение, добавляя разницу к более низкому значению.

upperval <- lowerval + difference 
+0

Следует отметить, что распределение с использованием этого алгоритма будет отличаться от распределения с использованием алгоритма OP. Поэтому в зависимости от любых других требований, которые необходимы от случайной выборки, это может быть или не быть тем, что они хотят. – Dason

Смежные вопросы